From: Claudio Cambra Date: Tue, 8 Nov 2022 15:16:39 +0000 (+0100) Subject: Add Talk message type of notifications to native macOS notifications X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~11^2~78^2~2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=d2e0afa0709faac8926f07d8b28993f937f4c3b7;p=nextcloud-desktop.git Add Talk message type of notifications to native macOS notifications Signed-off-by: Claudio Cambra --- diff --git a/src/gui/systray.mm b/src/gui/systray.mm index ddcd4f362..d9e5d03d0 100644 --- a/src/gui/systray.mm +++ b/src/gui/systray.mm @@ -1,5 +1,10 @@ #include "QtCore/qurl.h" +#include "account.h" +#include "accountstate.h" +#include "accountmanager.h" #include "config.h" +#include "systray.h" +#include "tray/talkreply.h" #include #include #include @@ -9,6 +14,58 @@ Q_LOGGING_CATEGORY(lcMacSystray, "nextcloud.gui.macsystray") +/************************* Private utility functions *************************/ + +namespace { + +void sendTalkReply(UNNotificationResponse *response, UNNotificationContent* content) +{ + if (!response || !content) { + qCWarning(lcMacSystray()) << "Invalid notification response or content." + << "Can't send talk reply."; + return; + } + + UNTextInputNotificationResponse *textInputResponse = (UNTextInputNotificationResponse*)response; + + if (!textInputResponse) { + qCWarning(lcMacSystray()) << "Notification response was not a text input response." + << "Can't send talk reply."; + return; + } + + NSString *reply = textInputResponse.userText; + NSString *token = [content.userInfo objectForKey:@"token"]; + NSString *account = [content.userInfo objectForKey:@"account"]; + NSString *replyTo = [content.userInfo objectForKey:@"replyTo"]; + + const auto qReply = QString::fromNSString(reply); + const auto qReplyTo = QString::fromNSString(replyTo); + const auto qToken = QString::fromNSString(token); + const auto qAccount = QString::fromNSString(account); + + const auto accountState = OCC::AccountManager::instance()->accountFromUserId(qAccount); + + if (!accountState) { + qCWarning(lcMacSystray()) << "Could not find account matching" << qAccount + << "Can't send talk reply."; + return; + } + + qCDebug(lcMacSystray()) << "Sending talk reply from macOS notification." + << "Reply is:" << qReply + << "Replying to:" << qReplyTo + << "Token:" << qToken + << "Account:" << qAccount; + + QPointer talkReply = new OCC::TalkReply(accountState.data(), OCC::Systray::instance()); + talkReply->sendReplyMessage(qToken, qReply, qReplyTo); +} + +} // anonymous namespace + +/**************************** Objective-C classes ****************************/ + @interface NotificationCenterDelegate : NSObject @end @implementation NotificationCenterDelegate @@ -34,23 +91,24 @@ Q_LOGGING_CATEGORY(lcMacSystray, "nextcloud.gui.macsystray") UNNotificationContent* content = response.notification.request.content; if ([content.categoryIdentifier isEqualToString:@"UPDATE"]) { - if ([response.actionIdentifier isEqualToString:@"DOWNLOAD_ACTION"] || [response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]) - { + if ([response.actionIdentifier isEqualToString:@"DOWNLOAD_ACTION"] || [response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]) { qCDebug(lcMacSystray()) << "Opening update download url in browser."; [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[content.userInfo objectForKey:@"webUrl"]]]; } + } else if ([content.categoryIdentifier isEqualToString:@"TALK_MESSAGE"]) { + + if ([response.actionIdentifier isEqualToString:@"TALK_REPLY_ACTION"]) { + sendTalkReply(response, content); + } } completionHandler(); } @end -namespace OCC { +/********************* Methods accessible to C++ Systray *********************/ -enum MacNotificationAuthorizationOptions { - Default = 0, - Provisional -}; +namespace OCC { double menuBarThickness() { @@ -93,10 +151,24 @@ void registerNotificationCategories(const QString &localisedDownloadString) { intentIdentifiers:@[] options:UNNotificationCategoryOptionNone]; - [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObjects:generalCategory, updateCategory, nil]]; + // Create the custom action for talk notifications + UNTextInputNotificationAction* talkReplyAction = [UNTextInputNotificationAction + actionWithIdentifier:@"TALK_REPLY_ACTION" + title:QObject::tr("Reply").toNSString() + options:UNNotificationActionOptionNone + textInputButtonTitle:QObject::tr("Reply").toNSString() + textInputPlaceholder:QObject::tr("Send a Nextcloud Talk reply").toNSString()]; + + UNNotificationCategory* talkReplyCategory = [UNNotificationCategory + categoryWithIdentifier:@"TALK_MESSAGE" + actions:@[talkReplyAction] + intentIdentifiers:@[] + options:UNNotificationCategoryOptionNone]; + + [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObjects:generalCategory, updateCategory, talkReplyCategory, nil]]; } -void checkNotificationAuth(MacNotificationAuthorizationOptions additionalAuthOption = MacNotificationAuthorizationOptions::Provisional) +void checkNotificationAuth(MacNotificationAuthorizationOptions additionalAuthOption) { UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert + UNAuthorizationOptionSound; @@ -170,6 +242,30 @@ void sendOsXUpdateNotification(const QString &title, const QString &message, con [center addNotificationRequest:request withCompletionHandler:nil]; } +void sendOsXTalkNotification(const QString &title, const QString &message, const QString &token, const QString &replyTo, const AccountStatePtr accountState) +{ + UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; + checkNotificationAuth(); + + if (!accountState || !accountState->account()) { + sendOsXUserNotification(title, message); + return; + } + + NSString *accountNS = accountState->account()->displayName().toNSString(); + NSString *tokenNS = token.toNSString(); + NSString *replyToNS = replyTo.toNSString(); + + UNMutableNotificationContent* content = basicNotificationContent(title, message); + content.categoryIdentifier = @"TALK_MESSAGE"; + content.userInfo = [NSDictionary dictionaryWithObjects:@[accountNS, tokenNS, replyToNS] forKeys:@[@"account", @"token", @"replyTo"]]; + + UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats: NO]; + UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"NCTalkMessageNotification" content:content trigger:trigger]; + + [center addNotificationRequest:request withCompletionHandler:nil]; +} + void setTrayWindowLevelAndVisibleOnAllSpaces(QWindow *window) { NSView *nativeView = (NSView *)window->winId(); @@ -185,5 +281,4 @@ bool osXInDarkMode() return [osxMode containsString:@"Dark"]; } -} - +} // OCC namespace