From 844ee0a3f436c9143aa31f43e80176f939d08b14 Mon Sep 17 00:00:00 2001 From: Zhuo Lu Date: Mon, 15 Jan 2018 20:50:03 -0800 Subject: [PATCH] Accept additional notification actions Change to the existing API definition: The first action with type `button` seen will be displayed on the notification, the rest listed as additional actions (shown when holding down on the primary action button) --- brightray/browser/mac/cocoa_notification.h | 5 ++- brightray/browser/mac/cocoa_notification.mm | 40 +++++++++++++++++-- .../mac/notification_center_delegate.mm | 11 +++-- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/brightray/browser/mac/cocoa_notification.h b/brightray/browser/mac/cocoa_notification.h index 9e7b55fabfdd..3f27039328de 100644 --- a/brightray/browser/mac/cocoa_notification.h +++ b/brightray/browser/mac/cocoa_notification.h @@ -9,6 +9,7 @@ #include #include +#include #include "base/mac/scoped_nsobject.h" #include "brightray/browser/notification.h" @@ -28,6 +29,7 @@ class CocoaNotification : public Notification { void NotificationDisplayed(); void NotificationReplied(const std::string& reply); void NotificationButtonClicked(); + void NotificationAdditionalActionClicked(NSUserNotificationAction* action); NSUserNotification* notification() const { return notification_; } @@ -35,7 +37,8 @@ class CocoaNotification : public Notification { void LogAction(const char* action); base::scoped_nsobject notification_; - int action_index_; + std::map additional_action_indices_; + unsigned action_index_; DISALLOW_COPY_AND_ASSIGN(CocoaNotification); }; diff --git a/brightray/browser/mac/cocoa_notification.mm b/brightray/browser/mac/cocoa_notification.mm index 94b8f93fdc3f..e1a8092d2ace 100644 --- a/brightray/browser/mac/cocoa_notification.mm +++ b/brightray/browser/mac/cocoa_notification.mm @@ -59,14 +59,31 @@ void CocoaNotification::Show(const NotificationOptions& options) { [notification_ setHasActionButton:false]; int i = 0; + action_index_ = UINT_MAX; + NSMutableArray* additionalActions = [[[NSMutableArray alloc] init] autorelease]; for (const auto& action : options.actions) { if (action.type == base::ASCIIToUTF16("button")) { - [notification_ setHasActionButton:true]; - [notification_ setActionButtonTitle:base::SysUTF16ToNSString(action.text)]; - action_index_ = i; + if (action_index_ == UINT_MAX) { + // First button observed is the displayed action + [notification_ setHasActionButton:true]; + [notification_ setActionButtonTitle:base::SysUTF16ToNSString(action.text)]; + action_index_ = i; + } else { + // All of the rest are appended to the list of additional actions + NSString* actionIdentifier = [NSString stringWithFormat:@"%@Action%d", identifier, i]; + NSUserNotificationAction* notificationAction = + [NSUserNotificationAction actionWithIdentifier:actionIdentifier + title:base::SysUTF16ToNSString(action.text)]; + [additionalActions addObject:notificationAction]; + additional_action_indices_.insert(std::make_pair(base::SysNSStringToUTF8(actionIdentifier), i)); + } } i++; } + if ([additionalActions count] > 0 && + [notification_ respondsToSelector:@selector(setAdditionalActions:)]) { + [notification_ setAdditionalActions:additionalActions]; // Requires macOS 10.10 + } if (options.has_reply) { [notification_ setResponsePlaceholder:base::SysUTF16ToNSString(options.reply_placeholder)]; @@ -108,6 +125,23 @@ void CocoaNotification::NotificationButtonClicked() { this->LogAction("button clicked"); } +void CocoaNotification::NotificationAdditionalActionClicked(NSUserNotificationAction* action) { + if (delegate()) { + unsigned index = action_index_; + std::string identifier = base::SysNSStringToUTF8(action.identifier); + for (const auto& it : additional_action_indices_) { + if (it.first == identifier) { + index = it.second; + break; + } + } + + delegate()->NotificationAction(index); + } + + this->LogAction("button clicked"); +} + void CocoaNotification::LogAction(const char* action) { if (getenv("ELECTRON_DEBUG_NOTIFICATIONS")) { NSString* identifier = [notification_ valueForKey:@"identifier"]; diff --git a/brightray/browser/mac/notification_center_delegate.mm b/brightray/browser/mac/notification_center_delegate.mm index 6c9fb7f277dd..e4c9ab8a6370 100644 --- a/brightray/browser/mac/notification_center_delegate.mm +++ b/brightray/browser/mac/notification_center_delegate.mm @@ -34,12 +34,15 @@ } if (notification) { - if (notif.activationType == NSUserNotificationActivationTypeReplied) { - notification->NotificationReplied([notif.response.string UTF8String]); + // Ref: https://developer.apple.com/documentation/foundation/nsusernotificationactivationtype?language=objc + if (notif.activationType == NSUserNotificationActivationTypeContentsClicked) { + notification->NotificationClicked(); } else if (notif.activationType == NSUserNotificationActivationTypeActionButtonClicked) { notification->NotificationButtonClicked(); - } else if (notif.activationType == NSUserNotificationActivationTypeContentsClicked) { - notification->NotificationClicked(); + } else if (notif.activationType == NSUserNotificationActivationTypeReplied) { + notification->NotificationReplied([notif.response.string UTF8String]); + } else if (notif.activationType == NSUserNotificationActivationTypeAdditionalActionClicked) { + notification->NotificationAdditionalActionClicked([notif additionalActivationAction]); } } }