Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve room alias management #618

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lib/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "csapi/account-data.h"
#include "csapi/capabilities.h"
#include "csapi/directory.h"
#include "csapi/joining.h"
#include "csapi/leaving.h"
#include "csapi/logout.h"
Expand Down Expand Up @@ -1492,6 +1493,23 @@ Room* Connection::roomByAlias(const QString& roomAlias, JoinStates states) const
return nullptr;
}

void Connection::mapAlias(const QString& roomId, const QString& alias)
{
auto getRoomIdByAliasJob = callApi<GetRoomIdByAliasJob>(alias);
connect(getRoomIdByAliasJob, &BaseJob::success, this, [this, getRoomIdByAliasJob, alias, roomId] {
if (!getRoomIdByAliasJob->roomId().isEmpty()) {
qWarning(MAIN) << "Alias" << alias << "is already mapped to" << getRoomIdByAliasJob->roomId();
} else {
callApi<SetRoomAliasJob>(alias, roomId);
}
});
}

void Connection::unmapAlias(const QString& alias)
{
callApi<DeleteRoomAliasJob>(alias);
}

void Connection::updateRoomAliases(const QString& roomId,
const QStringList& previousRoomAliases,
const QStringList& roomAliases)
Expand Down
15 changes: 15 additions & 0 deletions lib/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,21 @@ class QUOTIENT_API Connection : public QObject {
Q_INVOKABLE Quotient::Room* roomByAlias(
const QString& roomAlias,
Quotient::JoinStates states = JoinState::Invite | JoinState::Join) const;

//! \brief Map an alias to a room ID on the user's current server.
//!
//! This uses the room alias endpoint from the matrix specification
//! https://spec.matrix.org/v1.5/client-server-api/#room-aliases
//!
//! \note This is different to Room::setLocalAliases and
//! Room::setCanonicalAlias as they can only get the room to publish
//! an alias that is already mapped.
//! i.e. Use this function first to map an alias then Room::setLocalAliases
//! or Room::setCanonicalAlias to publish the alias officially.
//! \sa Room::setLocalAliases, Room::setCanonicalAlias
Q_INVOKABLE void mapAlias(const QString& roomId, const QString& alias);
//! Unmap an alias from a room ID on the user's current server.
Q_INVOKABLE void unmapAlias(const QString& alias);
//! \brief Update the internal map of room aliases to IDs
//!
//! This is used to maintain the internal index of room aliases.
Expand Down
29 changes: 27 additions & 2 deletions lib/room.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2306,9 +2306,27 @@ void Room::setName(const QString& newName)
setState<RoomNameEvent>(newName);
}

void Room::mapAlias(const QString& alias) const
{
connection()->mapAlias(id(), alias);
}

void Room::setCanonicalAlias(const QString& newAlias)
{
setState<RoomCanonicalAliasEvent>(newAlias, altAliases());
QString oldCanonicalAlias = canonicalAlias();
QStringList newAltAliases = altAliases();
// Set the old canonical alias as an alt alias.
if (!oldCanonicalAlias.isEmpty()) {
newAltAliases.append(oldCanonicalAlias);
}
// If the new canonical alias is already a published alt alias remove it
// otherwise it will be in both lists. The server doesn't prevent this so we
// need to handle it.
if (newAltAliases.contains(newAlias)) {
newAltAliases.removeAll(newAlias);
}

setState<RoomCanonicalAliasEvent>(newAlias, newAltAliases);
}

void Room::setPinnedEvents(const QStringList& events)
Expand All @@ -2317,7 +2335,14 @@ void Room::setPinnedEvents(const QStringList& events)
}
void Room::setLocalAliases(const QStringList& aliases)
{
setState<RoomCanonicalAliasEvent>(canonicalAlias(), aliases);
// If one of the new alt aliases is the current canonical alias set it to ""
// otherwise it will be in both lists. The server doesn't prevent this so we
// need to handle it.
QString currentCanonicalAlias = canonicalAlias();
if (aliases.contains(currentCanonicalAlias)) {
currentCanonicalAlias = "";
}
setState<RoomCanonicalAliasEvent>(currentCanonicalAlias, aliases);
}

void Room::setTopic(const QString& newTopic)
Expand Down
21 changes: 18 additions & 3 deletions lib/room.h
Original file line number Diff line number Diff line change
Expand Up @@ -836,10 +836,25 @@ public Q_SLOTS:
const QString& stateKey,
const QJsonObject& contentJson);
void setName(const QString& newName);
void setCanonicalAlias(const QString& newAlias);

//! \brief Map an alias to this room on the user's current server.
//!
//! Convenience function to call Connection::mapAlias with this room's ID
//! \sa Connection::mapAlias
Q_INVOKABLE void mapAlias(const QString& alias) const;
//! \brief Publish the given alias as the room's canonical alias.
//!
//! The alias that is published must already have been mapped to the room
//! on the server.
//! \sa Room::mapAlias
Q_INVOKABLE void setCanonicalAlias(const QString& newAlias);
void setPinnedEvents(const QStringList& events);
/// Set room aliases on the user's current server
void setLocalAliases(const QStringList& aliases);
/// \brief Publish list of alt aliases for the room on the user's current server.
//!
//! The aliases that are published must already have been mapped to the room
//! on the server.
//! \sa Room::mapAlias
Q_INVOKABLE void setLocalAliases(const QStringList& aliases);
void setTopic(const QString& newTopic);

/// You shouldn't normally call this method; it's here for debugging
Expand Down