diff options
-rw-r--r-- | lib/connection.cpp | 10 | ||||
-rw-r--r-- | lib/connection.h | 2 | ||||
-rw-r--r-- | lib/events/roomcanonicalaliasevent.h | 86 | ||||
-rw-r--r-- | lib/events/simplestateevents.h | 2 | ||||
-rw-r--r-- | lib/room.cpp | 48 |
5 files changed, 129 insertions, 19 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp index 5bddbb83..f3d31d2d 100644 --- a/lib/connection.cpp +++ b/lib/connection.cpp @@ -87,7 +87,7 @@ public: QHash<QPair<QString, bool>, Room*> roomMap; /// Mapping from serverparts to alias/room id mappings, /// as of the last sync - QHash<QString, QHash<QString, QString>> roomAliasMap; + QHash<QString, QString> roomAliasMap; QVector<QString> roomIdsToForget; QVector<Room*> firstTimeRooms; QVector<QString> pendingStateRoomIds; @@ -891,7 +891,7 @@ Room* Connection::room(const QString& roomId, JoinStates states) const Room* Connection::roomByAlias(const QString& roomAlias, JoinStates states) const { - const auto id = d->roomAliasMap.value(serverPart(roomAlias)).value(roomAlias); + const auto id = d->roomAliasMap.value(roomAlias); if (!id.isEmpty()) return room(id, states); @@ -901,17 +901,15 @@ Room* Connection::roomByAlias(const QString& roomAlias, JoinStates states) const } void Connection::updateRoomAliases(const QString& roomId, - const QString& aliasServer, const QStringList& previousRoomAliases, const QStringList& roomAliases) { - auto& aliasMap = d->roomAliasMap[aliasServer]; // Allocate if necessary for (const auto& a : previousRoomAliases) - if (aliasMap.remove(a) == 0) + if (d->roomAliasMap.remove(a) == 0) qCWarning(MAIN) << "Alias" << a << "is not found (already deleted?)"; for (const auto& a : roomAliases) { - auto& mappedId = aliasMap[a]; + auto& mappedId = d->roomAliasMap[a]; if (!mappedId.isEmpty()) { if (mappedId == roomId) qCDebug(MAIN) diff --git a/lib/connection.h b/lib/connection.h index e4109fd4..c7e18c12 100644 --- a/lib/connection.h +++ b/lib/connection.h @@ -294,7 +294,7 @@ public: /// This is used to maintain the internal index of room aliases. /// It does NOT change aliases on the server, /// \sa Room::setLocalAliases - void updateRoomAliases(const QString& roomId, const QString& aliasServer, + void updateRoomAliases(const QString& roomId, const QStringList& previousRoomAliases, const QStringList& roomAliases); Q_INVOKABLE Quotient::Room* invitation(const QString& roomId) const; diff --git a/lib/events/roomcanonicalaliasevent.h b/lib/events/roomcanonicalaliasevent.h new file mode 100644 index 00000000..3f89f639 --- /dev/null +++ b/lib/events/roomcanonicalaliasevent.h @@ -0,0 +1,86 @@ +// Contains code for RoomCanonicalAlias Event +#pragma once + +#include "stateevent.h" + +namespace Quotient { +namespace EventContent{ + template <typename T1, typename T2> + class SimpleDualContent { + public: + using first_value_type = T1; + using second_value_type = T2; + + template <typename TT1, typename TT2> + SimpleDualContent(QString Key1Name, TT1&& value1, QString Key2Name, + TT2&& value2) + : value1(std::forward<TT1>(value1)) + , value2(std::forward<TT2>(value2)) + , key1(std::move(Key1Name)) + , key2(std::move(Key2Name)) + { } + + SimpleDualContent(const QJsonObject& json, QString key1Name, + QString key2Name) + : value1(fromJson<T1>(json[key1Name])) + , value2(fromJson<T2>(json[key2Name])) + , key1(std::move(key1Name)) + , key2(std::move(key2Name)) + { } + + QJsonObject toJson() const + { + return { { key1, Quotient::toJson(value1) }, + { key2, Quotient::toJson(value2) } }; + } + + public: + T1 value1; + T2 value2; + + protected: + QString key1; + QString key2; + }; +} // namespace EventContent + +class RoomCanonicalAliasEvent + : public StateEvent<EventContent::SimpleDualContent<QString, QStringList>> { +public: + DEFINE_EVENT_TYPEID("m.room.canonical_alias", RoomCanonicalAliasEvent) + + explicit RoomCanonicalAliasEvent(const QJsonObject& obj) + : StateEvent(typeId(), obj, QStringLiteral("alias"), + QStringLiteral("alt_aliases")) + { } + + RoomCanonicalAliasEvent(const QString& server, const QString& alias, + const QStringList& alt_aliases) + : StateEvent(typeId(), matrixTypeId(), server, QStringLiteral("alias"), + alias, QStringLiteral("alt_aliases"), alt_aliases) + { } + + // For compatibility used at Room::setCanonicalAlias + explicit RoomCanonicalAliasEvent(const QString& value1) + : RoomCanonicalAliasEvent(value1, QStringList()) + { } + + // Because, MSC2432 specifies, that alt_aliases may be present + // without aliases as well + explicit RoomCanonicalAliasEvent(const QStringList& value2) + : RoomCanonicalAliasEvent(QString(), value2) + { } + + template <typename T1, typename T2> + RoomCanonicalAliasEvent(T1&& value1, T2&& value2) + : StateEvent(typeId(), matrixTypeId(), QString(), + QStringLiteral("alias"), std::forward<T1>(value1), + QStringLiteral("alt_aliases"), std::forward<T2>(value2)) + { } + + QString alias() const { return content().value1; } + + QStringList alt_aliases() const { return content().value2; } +}; +REGISTER_EVENT_TYPE(RoomCanonicalAliasEvent) +} // namespace Quotient
\ No newline at end of file diff --git a/lib/events/simplestateevents.h b/lib/events/simplestateevents.h index eb1d2f7a..cde5b0fd 100644 --- a/lib/events/simplestateevents.h +++ b/lib/events/simplestateevents.h @@ -69,8 +69,6 @@ namespace EventContent { // End of macro DEFINE_SIMPLE_STATE_EVENT(RoomNameEvent, "m.room.name", QString, name) -DEFINE_SIMPLE_STATE_EVENT(RoomCanonicalAliasEvent, "m.room.canonical_alias", - QString, alias) DEFINE_SIMPLE_STATE_EVENT(RoomTopicEvent, "m.room.topic", QString, topic) class RoomAliasesEvent diff --git a/lib/room.cpp b/lib/room.cpp index b29f6f48..475c6570 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -56,6 +56,7 @@ #include "jobs/downloadfilejob.h" #include "jobs/mediathumbnailjob.h" #include "jobs/postreadmarkersjob.h" +#include "events/roomcanonicalaliasevent.h" #include <QtCore/QDir> #include <QtCore/QHash> @@ -107,6 +108,7 @@ public: QHash<StateEventKey, const StateEventBase*> currentState; /// Servers with aliases for this room except the one of the local user /// \sa Room::remoteAliases + // This may not be required anymore QSet<QString> aliasServers; Timeline timeline; @@ -432,12 +434,13 @@ QString Room::name() const QStringList Room::localAliases() const { - return d - ->getCurrentState<RoomAliasesEvent>( - connection()->domain()) - ->aliases(); + QStringList result(d + ->getCurrentState<RoomCanonicalAliasEvent>()->alias()); + result += d->getCurrentState<RoomCanonicalAliasEvent>()->alt_aliases(); + return result; } +// Not sure about this function, maybe it is no more required QStringList Room::remoteAliases() const { QStringList result; @@ -1697,8 +1700,7 @@ void Room::setCanonicalAlias(const QString& newAlias) void Room::setLocalAliases(const QStringList& aliases) { - d->requestSetState<RoomAliasesEvent>(connection()->homeserver().authority(), - aliases); + d->requestSetState<RoomCanonicalAliasEvent>(aliases); } void Room::setTopic(const QString& newTopic) @@ -2368,14 +2370,40 @@ Room::Changes Room::processStateEvent(const RoomEvent& e) oldStateEvent ? static_cast<const RoomAliasesEvent*>(oldStateEvent)->aliases() : QStringList(); - connection()->updateRoomAliases(id(), ae.stateKey(), - previousAliases, ae.aliases()); + connection()->updateRoomAliases(id(), previousAliases, ae.aliases()); return OtherChange; // clang-format off } - , [this] (const RoomCanonicalAliasEvent& evt) { - setObjectName(evt.alias().isEmpty() ? d->id : evt.alias()); + , [this, oldStateEvent] (const RoomCanonicalAliasEvent& cae) { + // clang-format on + setObjectName(cae.alias().isEmpty() ? d->id : cae.alias()); + QString previousCanonicalAlias = + oldStateEvent + ? static_cast<const RoomCanonicalAliasEvent*>(oldStateEvent) + ->alias() + : QString(); + + auto previousAltAliases = + oldStateEvent + ? static_cast<const RoomCanonicalAliasEvent*>(oldStateEvent) + ->alt_aliases() + : QStringList(); + + if (!previousCanonicalAlias.isEmpty()) { + previousAltAliases.push_back(previousCanonicalAlias); + } + + const auto previousAliases = std::move(previousAltAliases); + + auto newAliases = cae.alt_aliases(); + + if (!cae.alias().isEmpty()) { + newAliases.push_front(cae.alias()); + } + + connection()->updateRoomAliases(id(), previousAliases, newAliases); return CanonicalAliasChange; + // clang-format off } , [] (const RoomTopicEvent&) { return TopicChange; |