diff --git a/src/controller.cpp b/src/controller.cpp index ccc7d4bf3..6a15b00f6 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -116,6 +116,9 @@ Controller::Controller(QObject *parent) connection->setupPushNotifications(endpoint); } }); + connect(connector, &KUnifiedPush::Connector::messageReceived, this, [this](const QByteArray &data) { + NotificationsManager::instance().postPushNotification(data); + }); connector->registerClient(i18n("Receiving push notifications")); diff --git a/src/neochatconnection.cpp b/src/neochatconnection.cpp index a5d008c2a..66245c43e 100644 --- a/src/neochatconnection.cpp +++ b/src/neochatconnection.cpp @@ -262,21 +262,15 @@ QCoro::Task NeoChatConnection::setupPushNotifications(QString endpoint) const auto &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(); - - callApi(pushkey, + callApi(endpoint, QStringLiteral("http"), QStringLiteral("org.kde.neochat"), QStringLiteral("NeoChat"), deviceId(), QString(), // profileTag is intentionally left empty for now, it's optional - QStringLiteral("en"), - PostPusherJob::PusherData{QUrl::fromUserInput(gatewayEndpoint.toString()), QStringLiteral(" ")}); + QStringLiteral("en-US"), + PostPusherJob::PusherData{QUrl::fromUserInput(gatewayEndpoint.toString()), QStringLiteral(" ")}, + false); qInfo() << "Registered for push notifications"; } else { diff --git a/src/notificationsmanager.cpp b/src/notificationsmanager.cpp index b489c6134..b75188f56 100644 --- a/src/notificationsmanager.cpp +++ b/src/notificationsmanager.cpp @@ -292,6 +292,46 @@ void NotificationsManager::clearInvitationNotification(const QString &roomId) } } +void NotificationsManager::postPushNotification(const QByteArray &message) +{ + const auto json = QJsonDocument::fromJson(message).object(); + + const auto type = json["notification"_ls]["type"_ls].toString(); + + // the only two types of push notifications we support right now + if (type == QStringLiteral("m.room.message") || type == QStringLiteral("m.room.encrypted")) { + auto notification = new KNotification("message"_ls); + + const auto sender = json["notification"_ls]["sender_display_name"_ls].toString(); + const auto roomName = json["notification"_ls]["room_name"_ls].toString(); + const auto roomId = json["notification"_ls]["room_id"_ls].toString(); + + if (roomName.isEmpty() || sender == roomName) { + notification->setTitle(sender); + } else { + notification->setTitle(i18n("%1 (%2)", sender, roomName)); + } + + if (type == QStringLiteral("m.room.message")) { + const auto text = json["notification"_ls]["content"_ls]["body"_ls].toString(); + notification->setText(text.toHtmlEscaped()); + } else if (type == QStringLiteral("m.room.encrypted")) { + notification->setText(i18n("Encrypted Message")); + } + + auto openAction = notification->addAction(i18n("Open NeoChat")); + connect(openAction, &KNotificationAction::activated, this, [=]() { + WindowController::instance().showAndRaiseWindow(notification->xdgActivationToken()); + }); + + notification->sendEvent(); + + m_notifications.insert(roomId, notification); + } else { + qWarning() << "Skipping unsupported push notification" << type; + } +} + QPixmap NotificationsManager::createNotificationImage(const QImage &icon, NeoChatRoom *room) { // Handle avatars that are lopsided in one dimension diff --git a/src/notificationsmanager.h b/src/notificationsmanager.h index cd1e4d0e2..7b2892c6c 100644 --- a/src/notificationsmanager.h +++ b/src/notificationsmanager.h @@ -83,6 +83,11 @@ public: */ void clearInvitationNotification(const QString &roomId); + /** + * @brief Display a native notification for the given push notification. + */ + void postPushNotification(const QByteArray &message); + /** * @brief Handle the notifications for the given connection. */