diff options
Diffstat (limited to 'src/notifications/ManagerMac.mm')
-rw-r--r-- | src/notifications/ManagerMac.mm | 229 |
1 files changed, 152 insertions, 77 deletions
diff --git a/src/notifications/ManagerMac.mm b/src/notifications/ManagerMac.mm index d5d900a7..4865e30d 100644 --- a/src/notifications/ManagerMac.mm +++ b/src/notifications/ManagerMac.mm @@ -1,112 +1,187 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// SPDX-FileCopyrightText: 2022 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "notifications/NotificationManagerProxy.h" +#include "notifications/MacNotificationDelegate.h" #include "notifications/Manager.h" -#import <Foundation/Foundation.h> +#include "ChatPage.h" + #import <AppKit/NSImage.h> +#import <Foundation/Foundation.h> #import <UserNotifications/UserNotifications.h> -#include <QtMac> #include <QImage> +#include <QtMac> @interface UNNotificationAttachment (UNNotificationAttachmentAdditions) - + (UNNotificationAttachment *) createFromImageData:(NSData*)imgData identifier:(NSString *)imageFileIdentifier options:(NSDictionary*)attachmentOptions; ++ (UNNotificationAttachment*)createFromImageData:(NSData*)imgData + identifier:(NSString*)imageFileIdentifier + options: + (NSDictionary*)attachmentOptions; @end @implementation UNNotificationAttachment (UNNotificationAttachmentAdditions) - + (UNNotificationAttachment *) createFromImageData:(NSData*)imgData identifier:(NSString *)imageFileIdentifier options:(NSDictionary*)attachmentOptions { - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *tmpSubFolderName = [[NSProcessInfo processInfo] globallyUniqueString]; - NSURL *tmpSubFolderURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:tmpSubFolderName] isDirectory:true]; - NSError *error = nil; - [fileManager createDirectoryAtURL:tmpSubFolderURL withIntermediateDirectories:true attributes:nil error:&error]; - if(error) { - NSLog(@"%@",[error localizedDescription]); - return nil; - } - NSURL *fileURL = [tmpSubFolderURL URLByAppendingPathComponent:imageFileIdentifier]; - [imgData writeToURL:fileURL atomically:true]; - UNNotificationAttachment *imageAttachment = [UNNotificationAttachment attachmentWithIdentifier:@"" URL:fileURL options:attachmentOptions error:&error]; - if(error) { - NSLog(@"%@",[error localizedDescription]); - return nil; - } - return imageAttachment; - ++ (UNNotificationAttachment*)createFromImageData:(NSData*)imgData + identifier:(NSString*)imageFileIdentifier + options: + (NSDictionary*)attachmentOptions +{ + NSFileManager* fileManager = [NSFileManager defaultManager]; + NSString* tmpSubFolderName = + [[NSProcessInfo processInfo] globallyUniqueString]; + NSURL* tmpSubFolderURL = [NSURL + fileURLWithPath:[NSTemporaryDirectory() + stringByAppendingPathComponent:tmpSubFolderName] + isDirectory:true]; + NSError* error = nil; + [fileManager createDirectoryAtURL:tmpSubFolderURL + withIntermediateDirectories:true + attributes:nil + error:&error]; + if (error) { + NSLog(@"%@", [error localizedDescription]); + return nil; } + NSURL* fileURL = + [tmpSubFolderURL URLByAppendingPathComponent:imageFileIdentifier]; + [imgData writeToURL:fileURL atomically:true]; + UNNotificationAttachment* imageAttachment = + [UNNotificationAttachment attachmentWithIdentifier:@"" + URL:fileURL + options:attachmentOptions + error:&error]; + if (error) { + NSLog(@"%@", [error localizedDescription]); + return nil; + } + return imageAttachment; +} @end -NotificationsManager::NotificationsManager(QObject *parent): QObject(parent) +NotificationsManager::NotificationsManager(QObject* parent) + : QObject(parent) { - } -void -NotificationsManager::objCxxPostNotification(const QString &room_name, - const QString &room_id, - const QString &event_id, - const QString &subtitle, - const QString &informativeText, - const QString &bodyImagePath) +void NotificationsManager::objCxxPostNotification( + const QString& room_name, + const QString& room_id, + const QString& event_id, + const QString& subtitle, + const QString& informativeText, + const QString& bodyImagePath, + const QString& respondStr, + const QString& sendStr, + const QString& placeholder) { + // Request permissions for alerts (the generic type of notification), sound playback, + // and badges (which allows the Nheko app icon to show the little red bubble with unread count). + // NOTE: Possible macOS bug... the 'Play sound for notification checkbox' doesn't appear in + // the Notifications and Focus settings unless UNAuthorizationOptionBadges is also + // specified UNAuthorizationOptions options = UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNAuthorizationOptionBadge; - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + UNUserNotificationCenter* center = + [UNUserNotificationCenter currentNotificationCenter]; + // TODO: Move this somewhere that isn't dependent on receiving a notification + // to actually request notification access. [center requestAuthorizationWithOptions:options - completionHandler:^(BOOL granted, NSError * _Nullable error) { - if (!granted) { - NSLog(@"No notification access"); - if (error) { - NSLog(@"%@",[error localizedDescription]); + completionHandler:^(BOOL granted, + NSError* _Nullable error) { + if (!granted) { + NSLog(@"No notification access"); + if (error) { + NSLog(@"%@", [error localizedDescription]); + } + } + }]; + + UNTextInputNotificationAction* replyAction = [UNTextInputNotificationAction actionWithIdentifier:@"ReplyAction" + title:respondStr.toNSString() + options:UNNotificationActionOptionNone + textInputButtonTitle:sendStr.toNSString() + textInputPlaceholder:placeholder.toNSString()]; + + UNNotificationCategory* category = [UNNotificationCategory categoryWithIdentifier:@"ReplyCategory" + actions:@[ replyAction ] + intentIdentifiers:@[] + options:UNNotificationCategoryOptionNone]; + + NSString* title = room_name.toNSString(); + NSString* sub = subtitle.toNSString(); + NSString* body = informativeText.toNSString(); + NSString* threadIdentifier = room_id.toNSString(); + NSString* identifier = event_id.toNSString(); + NSString* imgUrl = bodyImagePath.toNSString(); + + NSSet* categories = [NSSet setWithObject:category]; + [center setNotificationCategories:categories]; + [center getNotificationSettingsWithCompletionHandler:^( + UNNotificationSettings* _Nonnull settings) { + if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) { + UNMutableNotificationContent* content = + [[UNMutableNotificationContent alloc] init]; + + content.title = title; + content.subtitle = sub; + content.body = body; + content.sound = [UNNotificationSound defaultSound]; + content.threadIdentifier = threadIdentifier; + content.categoryIdentifier = @"ReplyCategory"; + + if ([imgUrl length] != 0) { + NSURL* imageURL = [NSURL fileURLWithPath:imgUrl]; + NSData* img = [NSData dataWithContentsOfURL:imageURL]; + NSArray* attachments = [NSMutableArray array]; + UNNotificationAttachment* attachment = [UNNotificationAttachment + createFromImageData:img + identifier:@"attachment_image.jpeg" + options:nil]; + if (attachment) { + attachments = [NSMutableArray arrayWithObjects:attachment, nil]; + content.attachments = attachments; + } } - } - }]; - UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; - - content.title = room_name.toNSString(); - content.subtitle = subtitle.toNSString(); - content.body = informativeText.toNSString(); - content.sound = [UNNotificationSound defaultSound]; - content.threadIdentifier = room_id.toNSString(); - - if (!bodyImagePath.isEmpty()) { - NSURL *imageURL = [NSURL fileURLWithPath:bodyImagePath.toNSString()]; - NSData *img = [NSData dataWithContentsOfURL:imageURL]; - NSArray *attachments = [NSMutableArray array]; - UNNotificationAttachment *attachment = [UNNotificationAttachment createFromImageData:img identifier:@"attachment_image.jpeg" options:nil]; - if (attachment) { - attachments = [NSMutableArray arrayWithObjects: attachment, nil]; - content.attachments = attachments; - } - } + UNNotificationRequest* notificationRequest = + [UNNotificationRequest requestWithIdentifier:identifier + content:content + trigger:nil]; - UNNotificationRequest *notificationRequest = [UNNotificationRequest requestWithIdentifier:event_id.toNSString() content:content trigger:nil]; + [center addNotificationRequest:notificationRequest + withCompletionHandler:^(NSError* _Nullable error) { + if (error != nil) { + NSLog(@"Unable to Add Notification Request: %@", [error localizedDescription]); + } + }]; - [center addNotificationRequest:notificationRequest withCompletionHandler:^(NSError * _Nullable error) { - if (error != nil) { - NSLog(@"Unable to Add Notification Request"); + [content autorelease]; } }]; - - [content autorelease]; } -//unused -void -NotificationsManager::actionInvoked(uint, QString) +void NotificationsManager::attachToMacNotifCenter() { -} + UNUserNotificationCenter* center = + [UNUserNotificationCenter currentNotificationCenter]; -void -NotificationsManager::notificationReplied(uint, QString) -{ -} + std::unique_ptr<NotificationManagerProxy> proxy = std::make_unique<NotificationManagerProxy>(); -void -NotificationsManager::notificationClosed(uint, uint) -{ + connect(proxy.get(), &NotificationManagerProxy::notificationReplied, ChatPage::instance(), &ChatPage::sendNotificationReply); + + MacNotificationDelegate* notifDelegate = [[MacNotificationDelegate alloc] initWithProxy:std::move(proxy)]; + + center.delegate = notifDelegate; } -void -NotificationsManager::removeNotification(const QString &, const QString &) -{} +// unused +void NotificationsManager::actionInvoked(uint, QString) { } + +void NotificationsManager::notificationReplied(uint, QString) { } + +void NotificationsManager::notificationClosed(uint, uint) { } +void NotificationsManager::removeNotification(const QString&, const QString&) { } |