aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/connection.cpp10
-rw-r--r--lib/connection.h2
-rw-r--r--lib/events/roomcanonicalaliasevent.h75
-rw-r--r--lib/events/simplestateevents.h2
-rw-r--r--lib/room.cpp77
-rw-r--r--lib/room.h7
-rw-r--r--libquotient.pri1
7 files changed, 136 insertions, 38 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 0e6b1c84..7400c82d 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -92,7 +92,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;
@@ -1068,7 +1068,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);
@@ -1078,17 +1078,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 9b222ca8..350571f1 100644
--- a/lib/connection.h
+++ b/lib/connection.h
@@ -329,7 +329,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..311a5959
--- /dev/null
+++ b/lib/events/roomcanonicalaliasevent.h
@@ -0,0 +1,75 @@
+/******************************************************************************
+ * Copyright (C) 2020 QMatrixClient project
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+#include "stateevent.h"
+
+namespace Quotient {
+namespace EventContent{
+ class AliasesEventContent {
+
+ public:
+
+ template<typename T1, typename T2>
+ AliasesEventContent(T1&& canonicalAlias, T2&& altAliases)
+ : canonicalAlias(std::forward<T1>(canonicalAlias))
+ , altAliases(std::forward<T2>(altAliases))
+ { }
+
+ AliasesEventContent(const QJsonObject& json)
+ : canonicalAlias(fromJson<QString>(json["alias"]))
+ , altAliases(fromJson<QStringList>(json["alt_aliases"]))
+ { }
+
+ QJsonObject toJson() const
+ {
+ return { { "alias", Quotient::toJson(canonicalAlias) },
+ { "alt_aliases", Quotient::toJson(altAliases) } };
+ }
+
+ QString canonicalAlias;
+ QStringList altAliases;
+ };
+} // namespace EventContent
+
+class RoomCanonicalAliasEvent
+ : public StateEvent<EventContent::AliasesEventContent> {
+public:
+ DEFINE_EVENT_TYPEID("m.room.canonical_alias", RoomCanonicalAliasEvent)
+
+ explicit RoomCanonicalAliasEvent(const QJsonObject& obj)
+ : StateEvent(typeId(), obj)
+ { }
+
+ explicit RoomCanonicalAliasEvent(const QString& canonicalAlias, const QStringList& altAliases = {})
+ : StateEvent(typeId(), matrixTypeId(), QString(),
+ canonicalAlias, altAliases)
+ { }
+
+ explicit RoomCanonicalAliasEvent(QString&& canonicalAlias, QStringList&& altAliases = {})
+ : StateEvent(typeId(), matrixTypeId(), QString(),
+ std::move(canonicalAlias), std::move(altAliases))
+ { }
+
+ QString alias() const { return content().canonicalAlias; }
+
+ QStringList altAliases() const { return content().altAliases; }
+};
+REGISTER_EVENT_TYPE(RoomCanonicalAliasEvent)
+} // namespace Quotient
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 2945111a..6ac2673e 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>
@@ -519,11 +520,21 @@ QString Room::name() const
return d->getCurrentState<RoomNameEvent>()->name();
}
+QStringList Room::aliases() const
+{
+ const auto* evt = d->getCurrentState<RoomCanonicalAliasEvent>();
+ return QStringList(evt->altAliases()) << evt->alias();
+}
+
+QStringList Room::altAliases() const
+{
+ return d->getCurrentState<RoomCanonicalAliasEvent>()->altAliases();
+}
+
QStringList Room::localAliases() const
{
- return d
- ->getCurrentState<RoomAliasesEvent>(
- connection()->domain())
+ return d->getCurrentState<RoomAliasesEvent>(
+ connection()->domain())
->aliases();
}
@@ -1461,7 +1472,7 @@ void Room::updateData(SyncRoomData&& data, bool fromCache)
if (roomChanges & TopicChange)
emit topicChanged();
- if (roomChanges & NameChange)
+ if (roomChanges & (NameChange | AliasesChange))
emit namesChanged(this);
if (roomChanges & MembersChange)
@@ -1740,13 +1751,12 @@ void Room::setName(const QString& newName)
void Room::setCanonicalAlias(const QString& newAlias)
{
- d->requestSetState<RoomCanonicalAliasEvent>(newAlias);
+ d->requestSetState<RoomCanonicalAliasEvent>(newAlias, altAliases());
}
void Room::setLocalAliases(const QStringList& aliases)
{
- d->requestSetState<RoomAliasesEvent>(connection()->homeserver().authority(),
- aliases);
+ d->requestSetState<RoomCanonicalAliasEvent>(canonicalAlias(), aliases);
}
void Room::setTopic(const QString& newTopic)
@@ -2401,30 +2411,41 @@ Room::Changes Room::processStateEvent(const RoomEvent& e)
}
, [this,oldStateEvent] (const RoomAliasesEvent& ae) {
// clang-format on
- if (ae.aliases().isEmpty()) {
- if (d->aliasServers.remove(ae.stateKey()))
- qCDebug(STATE).noquote()
- << ae.stateKey() << "no more has aliases for room"
- << objectName();
- } else {
- d->aliasServers.insert(ae.stateKey());
- qCDebug(STATE).nospace().noquote()
- << "New server with aliases for room " << objectName()
- << ": " << ae.stateKey();
- }
- const auto previousAliases =
+ // This event has been removed by MSC-2432
+ return NoChange;
+ // clang-format off
+ }
+ , [this, oldStateEvent] (const RoomCanonicalAliasEvent& cae) {
+ // clang-format on
+ setObjectName(cae.alias().isEmpty() ? d->id : cae.alias());
+ QString previousCanonicalAlias =
oldStateEvent
- ? static_cast<const RoomAliasesEvent*>(oldStateEvent)->aliases()
+ ? static_cast<const RoomCanonicalAliasEvent*>(oldStateEvent)
+ ->alias()
+ : QString();
+
+ auto previousAltAliases =
+ oldStateEvent
+ ? static_cast<const RoomCanonicalAliasEvent*>(oldStateEvent)
+ ->altAliases()
: QStringList();
- connection()->updateRoomAliases(id(), ae.stateKey(),
- previousAliases, ae.aliases());
- return OtherChange;
+
+ if (!previousCanonicalAlias.isEmpty()) {
+ previousAltAliases.push_back(previousCanonicalAlias);
+ }
+
+ const auto previousAliases = std::move(previousAltAliases);
+
+ auto newAliases = cae.altAliases();
+
+ if (!cae.alias().isEmpty()) {
+ newAliases.push_front(cae.alias());
+ }
+
+ connection()->updateRoomAliases(id(), previousAliases, newAliases);
+ return AliasesChange;
// clang-format off
}
- , [this] (const RoomCanonicalAliasEvent& evt) {
- setObjectName(evt.alias().isEmpty() ? d->id : evt.alias());
- return CanonicalAliasChange;
- }
, [] (const RoomTopicEvent&) {
return TopicChange;
}
@@ -2671,7 +2692,7 @@ QString Room::Private::calculateDisplayname() const
return dispName;
// 3. m.room.aliases - only local aliases, subject for further removal
- const auto aliases = q->localAliases();
+ const auto aliases = q->aliases();
if (!aliases.isEmpty())
return aliases.front();
diff --git a/lib/room.h b/lib/room.h
index d78a7bfc..6f5751f9 100644
--- a/lib/room.h
+++ b/lib/room.h
@@ -142,7 +142,8 @@ public:
enum Change : uint {
NoChange = 0x0,
NameChange = 0x1,
- CanonicalAliasChange = 0x2,
+ AliasesChange = 0x2,
+ CanonicalAliasChange = AliasesChange,
TopicChange = 0x4,
UnreadNotifsChange = 0x8,
AvatarChange = 0x10,
@@ -189,11 +190,15 @@ public:
QString name() const;
/// Room aliases defined on the current user's server
/// \sa remoteAliases, setLocalAliases
+ [[deprecated("Use aliases()")]]
QStringList localAliases() const;
/// Room aliases defined on other servers
/// \sa localAliases
+ [[deprecated("Use aliases()")]]
QStringList remoteAliases() const;
QString canonicalAlias() const;
+ QStringList altAliases() const;
+ QStringList aliases() const;
QString displayName() const;
QString topic() const;
QString avatarMediaId() const;
diff --git a/libquotient.pri b/libquotient.pri
index 85b663ee..df58d35b 100644
--- a/libquotient.pri
+++ b/libquotient.pri
@@ -38,6 +38,7 @@ HEADERS += \
$$SRCPATH/events/eventcontent.h \
$$SRCPATH/events/roommessageevent.h \
$$SRCPATH/events/simplestateevents.h \
+ $$SRCPATH/events/roomcanonicalaliasevent.h \
$$SRCPATH/events/roomcreateevent.h \
$$SRCPATH/events/roomtombstoneevent.h \
$$SRCPATH/events/roommemberevent.h \