Move push notification setup to NeoChatConnection

This commit is contained in:
Joshua Goins
2023-11-10 08:46:52 -05:00
parent 99f6778df4
commit 3fc125a798
4 changed files with 63 additions and 54 deletions

View File

@@ -43,14 +43,10 @@
#endif
#ifdef HAVE_KUNIFIEDPUSH
#include <QCoro>
#include <Quotient/csapi/pusher.h>
#include <Quotient/networkaccessmanager.h>
#include <kunifiedpush/connector.h>
#endif
using namespace Quotient;
using namespace Qt::StringLiterals;
Controller::Controller(QObject *parent)
: QObject(parent)
@@ -104,62 +100,27 @@ Controller::Controller(QObject *parent)
connect(connection, &NeoChatConnection::syncDone, this, [connection]() {
NotificationsManager::instance().handleNotifications(connection);
});
connect(connection, &NeoChatConnection::connected, this, [this, connection]() {
connection->setupPushNotifications(m_endpoint);
});
}
oldAccountCount = m_accountRegistry.size();
});
#ifdef HAVE_KUNIFIEDPUSH
auto connector = new KUnifiedPush::Connector(QStringLiteral("org.kde.neochat"));
connect(connector, &KUnifiedPush::Connector::endpointChanged, this, &Controller::setupPushNotifications);
connect(connector, &KUnifiedPush::Connector::endpointChanged, this, [this](const QString &endpoint) {
m_endpoint = endpoint;
for (auto &quotientConnection : m_accountRegistry) {
auto connection = dynamic_cast<NeoChatConnection *>(quotientConnection);
connection->setupPushNotifications(endpoint);
}
});
connector->registerClient(i18n("Receiving push notifications"));
#endif
}
QCoro::Task<void> Controller::setupPushNotifications(QString endpoint)
{
#ifdef HAVE_KUNIFIEDPUSH
while (!activeConnection()) {
co_await qCoro(this, &Controller::activeConnectionChanged);
}
QUrl gatewayEndpoint(endpoint);
gatewayEndpoint.setPath(QStringLiteral("/_matrix/push/v1/notify"));
QNetworkRequest checkGateway(gatewayEndpoint);
auto reply = co_await NetworkAccessManager::instance()->get(checkGateway);
// We want to check if this UnifiedPush server has a Matrix gateway
// This is because Matrix does not natively support UnifiedPush
const QJsonObject replyJson = QJsonDocument::fromJson(reply->readAll()).object();
if (replyJson["unifiedpush"_L1]["gateway"_L1].toString() == QStringLiteral("matrix")) {
// FIXME: Currently hardcoded for ntfy URLs
// We need to pass the ntfy topic as the pushkey. Is there a more generic way to handle this?
const QUrl endpointUrl(endpoint);
// Pop the slash off of the path
const QString pushkey = endpointUrl.path().removeFirst();
Controller::instance().activeConnection()->callApi<PostPusherJob>(
pushkey,
QStringLiteral("http"),
QStringLiteral("org.kde.neochat"),
QStringLiteral("NeoChat"),
Controller::instance().activeConnection()->deviceId(),
QString(), // FIXME: what is profileTag?
QStringLiteral("en"),
PostPusherJob::PusherData{QUrl::fromUserInput(gatewayEndpoint.toString()), QStringLiteral(" ")});
qInfo() << "Registered for push notifications";
} else {
qWarning() << "There's no gateway, not setting up push notifications.";
}
#else
co_return;
#endif
}
Controller &Controller::instance()
{
static Controller _instance;

View File

@@ -11,7 +11,6 @@
#include <Quotient/accountregistry.h>
#include <Quotient/jobs/basejob.h>
#include <Quotient/settings.h>
#include <qcorotask.h>
class NeoChatRoom;
class TrayIcon;
@@ -125,10 +124,6 @@ public:
private:
explicit Controller(QObject *parent = nullptr);
// note: this is intentionally a copied QString because
// the reference could be destroyed before the task is finished
QCoro::Task<void> setupPushNotifications(QString endpoint);
QPointer<NeoChatConnection> m_connection;
TrayIcon *m_trayIcon = nullptr;
@@ -140,6 +135,7 @@ private:
Quotient::AccountRegistry m_accountRegistry;
QStringList m_accountsLoading;
QString m_endpoint;
private Q_SLOTS:
void invokeLogin();

View File

@@ -21,7 +21,14 @@
#include <Quotient/settings.h>
#include <Quotient/user.h>
#ifdef HAVE_KUNIFIEDPUSH
#include <QCoro>
#include <Quotient/csapi/pusher.h>
#include <Quotient/networkaccessmanager.h>
#endif
using namespace Quotient;
using namespace Qt::StringLiterals;
NeoChatConnection::NeoChatConnection(QObject *parent)
: Connection(parent)
@@ -241,6 +248,46 @@ void NeoChatConnection::openOrCreateDirectChat(User *user)
requestDirectChat(user);
}
QCoro::Task<void> NeoChatConnection::setupPushNotifications(QString endpoint)
{
#ifdef HAVE_KUNIFIEDPUSH
QUrl gatewayEndpoint(endpoint);
gatewayEndpoint.setPath(QStringLiteral("/_matrix/push/v1/notify"));
QNetworkRequest checkGateway(gatewayEndpoint);
auto reply = co_await NetworkAccessManager::instance()->get(checkGateway);
// We want to check if this UnifiedPush server has a Matrix gateway
// This is because Matrix does not natively support UnifiedPush
const QJsonObject replyJson = QJsonDocument::fromJson(reply->readAll()).object();
if (replyJson["unifiedpush"_L1]["gateway"_L1].toString() == QStringLiteral("matrix")) {
// FIXME: Currently hardcoded for ntfy URLs
// We need to pass the ntfy topic as the pushkey. Is there a more generic way to handle this?
const QUrl endpointUrl(endpoint);
// Pop the slash off of the path
const QString pushkey = endpointUrl.path().removeFirst();
Controller::instance().activeConnection()->callApi<PostPusherJob>(
pushkey,
QStringLiteral("http"),
QStringLiteral("org.kde.neochat"),
QStringLiteral("NeoChat"),
Controller::instance().activeConnection()->deviceId(),
QString(), // FIXME: what is profileTag?
QStringLiteral("en"),
PostPusherJob::PusherData{QUrl::fromUserInput(gatewayEndpoint.toString()), QStringLiteral(" ")});
qInfo() << "Registered for push notifications";
} else {
qWarning() << "There's no gateway, not setting up push notifications.";
}
#else
co_return;
#endif
}
QString NeoChatConnection::deviceKey() const
{
return edKeyForUserDevice(userId(), deviceId());

View File

@@ -6,6 +6,7 @@
#include <QObject>
#include <QQmlEngine>
#include <QCoro/Task>
#include <Quotient/connection.h>
class NeoChatConnection : public Quotient::Connection
@@ -75,6 +76,10 @@ public:
*/
Q_INVOKABLE void openOrCreateDirectChat(Quotient::User *user);
// note: this is intentionally a copied QString because
// the reference could be destroyed before the task is finished
QCoro::Task<void> setupPushNotifications(QString endpoint);
QString deviceKey() const;
QString encryptionKey() const;