From e1b9bc7d0e97c54933a0888cbdbd83a46d0b2d7f Mon Sep 17 00:00:00 2001 From: Shooting Star Date: Fri, 17 Feb 2023 13:29:02 +0000 Subject: [PATCH] Add knock command --- src/models/actionsmodel.cpp | 34 ++++++++++++++++++++++++++++++++++ src/roommanager.cpp | 24 ++++++++++++++++++++++++ src/roommanager.h | 4 ++++ 3 files changed, 62 insertions(+) diff --git a/src/models/actionsmodel.cpp b/src/models/actionsmodel.cpp index 95a270f5c..e1accc5ed 100644 --- a/src/models/actionsmodel.cpp +++ b/src/models/actionsmodel.cpp @@ -209,6 +209,40 @@ QVector actions{ kli18n(""), kli18n("Joins the given room"), }, +#ifdef QUOTIENT_07 + Action{ + QStringLiteral("knock"), + [](const QString &text, NeoChatRoom *room) { + auto parts = text.split(QLatin1String(" ")); + QString roomName = parts[0]; + QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)")); + auto regexMatch = roomRegex.match(roomName); + if (!regexMatch.hasMatch()) { + Q_EMIT room->showMessage(NeoChatRoom::Error, + i18nc("'' does not look like a room id or alias.", "'%1' does not look like a room id or alias.", text)); + return QString(); + } + auto targetRoom = text.startsWith(QLatin1Char('!')) ? room->connection()->room(text) : room->connection()->roomByAlias(text); + if (targetRoom) { + RoomManager::instance().enterRoom(dynamic_cast(targetRoom)); + return QString(); + } + Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Knocking room .", "Knocking room %1.", text)); + auto connection = Controller::instance().activeConnection(); + const auto knownServer = roomName.mid(roomName.indexOf(":") + 1); + if (parts.length() >= 2) { + RoomManager::instance().knockRoom(connection, roomName, parts[1], QStringList{knownServer}); + } else { + RoomManager::instance().knockRoom(connection, roomName, QString(), QStringList{knownServer}); + } + return QString(); + }, + false, + std::nullopt, + kli18n(" []"), + kli18n("Requests to join the given room"), + }, +#endif Action{ QStringLiteral("j"), [](const QString &text, NeoChatRoom *room) { diff --git a/src/roommanager.cpp b/src/roommanager.cpp index 35713f67b..7de5d17e4 100644 --- a/src/roommanager.cpp +++ b/src/roommanager.cpp @@ -11,6 +11,9 @@ #include #include #include +#ifdef QUOTIENT_07 +#include +#endif #include #include @@ -209,6 +212,27 @@ void RoomManager::joinRoom(Quotient::Connection *account, const QString &roomAli }); } +// TODO: maybe need use the function upstream later +#ifdef QUOTIENT_07 +void RoomManager::knockRoom(Quotient::Connection *account, const QString &roomAliasOrId, const QString &reason, const QStringList &viaServers) +{ + auto *const job = account->callApi(roomAliasOrId, viaServers, reason); + // Upon completion, ensure a room object is created in case it hasn't come + // with a sync yet. If the room object is not there, provideRoom() will + // create it in Join state. finished() is used here instead of success() + // to overtake clients that may add their own slots to finished(). + connectSingleShot(job, &BaseJob::finished, this, [this, job, account] { + if (job->status() == Quotient::BaseJob::Success) { + connectSingleShot(account, &Quotient::Connection::newRoom, this, [this](Quotient::Room *room) { + Q_EMIT currentRoom()->showMessage(NeoChatRoom::Info, i18n("You requested to join '%1'", room->name())); + }); + } else { + Q_EMIT warning(i18n("Failed to request joining room"), job->errorString()); + } + }); +} +#endif + bool RoomManager::visitNonMatrix(const QUrl &url) { #ifdef Q_OS_ANDROID diff --git a/src/roommanager.h b/src/roommanager.h index f80e51c3b..212494f1e 100644 --- a/src/roommanager.h +++ b/src/roommanager.h @@ -59,6 +59,10 @@ public: // Overrided methods from UriResolverBase UriResolveResult visitUser(User *user, const QString &action) override; void joinRoom(Quotient::Connection *account, const QString &roomAliasOrId, const QStringList &viaServers) override; + // TODO: it need also override in the feature? +#ifdef QUOTIENT_07 + void knockRoom(Quotient::Connection *account, const QString &roomAliasOrId, const QString &reason, const QStringList &viaServers); +#endif Q_INVOKABLE void visitRoom(Quotient::Room *room, const QString &eventId) override; Q_INVOKABLE bool visitNonMatrix(const QUrl &url) override;