From 058bdfbced2e9c8676f87f3461273203c52528de Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Mon, 29 May 2017 20:02:33 +1000 Subject: [PATCH] Use NotificationPresenter - macOS --- atom/browser/api/atom_api_notification_mac.mm | 93 ++++++------------- .../ui/notification_delegate_adapter.cc | 3 + .../ui/notification_delegate_adapter.h | 1 + .../browser/linux/libnotify_notification.cc | 4 +- .../browser/linux/libnotify_notification.h | 4 +- brightray/browser/mac/cocoa_notification.h | 5 +- brightray/browser/mac/cocoa_notification.mm | 13 ++- .../mac/notification_center_delegate.mm | 10 +- brightray/browser/notification.h | 4 +- brightray/browser/notification_delegate.h | 4 + .../browser/notification_delegate_adapter.cc | 4 + .../browser/platform_notification_service.cc | 3 +- brightray/browser/win/win32_notification.cc | 3 +- brightray/browser/win/win32_notification.h | 3 +- .../browser/win/windows_toast_notification.cc | 4 +- .../browser/win/windows_toast_notification.h | 4 +- default_app/default_app.js | 11 ++- 17 files changed, 93 insertions(+), 80 deletions(-) diff --git a/atom/browser/api/atom_api_notification_mac.mm b/atom/browser/api/atom_api_notification_mac.mm index c56955da2e..fed369c15b 100644 --- a/atom/browser/api/atom_api_notification_mac.mm +++ b/atom/browser/api/atom_api_notification_mac.mm @@ -7,89 +7,48 @@ #import #include "atom/browser/browser.h" +#include "atom/browser/ui/notification_delegate_adapter.h" #include "base/mac/mac_util.h" #include "base/mac/scoped_nsobject.h" #include "base/strings/sys_string_conversions.h" - -std::map> native_notifications_; - -@interface AtomNotificationCenter : NSObject { -} -@end - -@implementation AtomNotificationCenter -- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center - shouldPresentNotification:(NSUserNotification *)notification { - return YES; - } - -- (void)userNotificationCenter:(NSUserNotificationCenter *)center - didActivateNotification:(NSUserNotification *)notification { - int n_id = [[notification.userInfo objectForKey:@"id"] intValue]; - if (atom::api::Notification::HasID(n_id)) { - auto atomNotification = atom::api::Notification::FromID(n_id); - - if (notification.activationType == NSUserNotificationActivationTypeReplied){ - atomNotification->OnReplied([notification.response.string UTF8String]); - } else { - atomNotification->OnClicked(); - } - } - } -@end +#include "brightray/browser/notification.h" +#include "brightray/browser/notification_presenter.h" +#include "brightray/browser/mac/notification_presenter_mac.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/codec/png_codec.h" +#include "url/gurl.h" namespace atom { namespace api { -AtomNotificationCenter* del = [[AtomNotificationCenter alloc] init]; -bool set_del_ = false; +brightray::NotificationPresenterMac* presenter; void Notification::Show() { - base::scoped_nsobject notification_ = native_notifications_[id_]; - [NSUserNotificationCenter.defaultUserNotificationCenter - deliverNotification:notification_]; - OnShown(); -} - -void Notification::OnInitialProps() { - if (!set_del_) { - [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:del]; - set_del_ = true; + SkBitmap image = *(new SkBitmap); + if (has_icon_) { + image = *(icon_.ToSkBitmap()); } - base::scoped_nsobject notification_; - notification_.reset([[NSUserNotification alloc] init]); + std::unique_ptr adapter( + new AtomNotificationDelegateAdapter(this)); + auto notif = presenter->CreateNotification(adapter.get()); + if (notif) { + ignore_result(adapter.release()); // it will release itself automatically. + GURL nullUrl = *(new GURL); + notif->Show(title_, body_, "", nullUrl, image, silent_, has_reply_, reply_placeholder_); + } +} - native_notifications_[id_] = notification_; - - NotifyPropsUpdated(); +bool initialized_ = false; +void Notification::OnInitialProps() { + if (!initialized_) { + presenter = new brightray::NotificationPresenterMac; + initialized_ = true; + } } void Notification::NotifyPropsUpdated() { - base::scoped_nsobject notification_ = native_notifications_[id_]; - - [notification_ setTitle:base::SysUTF16ToNSString(title_)]; - [notification_ setInformativeText:base::SysUTF16ToNSString(body_)]; - - NSDictionary * userInfo = [NSMutableDictionary dictionary]; - [userInfo setValue:[NSNumber numberWithInt:id_] forKey:@"id"]; - [notification_ setUserInfo:userInfo]; - - if ([notification_ respondsToSelector:@selector(setContentImage:)] && has_icon_) { - [notification_ setContentImage:icon_.AsNSImage()]; - } - - if (has_reply_) { - [notification_ setResponsePlaceholder:base::SysUTF16ToNSString(reply_placeholder_)]; - [notification_ setHasReplyButton:true]; - } - - if (silent_) { - [notification_ setSoundName:nil]; - } else { - [notification_ setSoundName:NSUserNotificationDefaultSoundName]; - } } } // namespace api diff --git a/atom/browser/ui/notification_delegate_adapter.cc b/atom/browser/ui/notification_delegate_adapter.cc index d44557daa9..b91a1a97d5 100644 --- a/atom/browser/ui/notification_delegate_adapter.cc +++ b/atom/browser/ui/notification_delegate_adapter.cc @@ -20,6 +20,9 @@ void AtomNotificationDelegateAdapter::NotificationClosed() {} void AtomNotificationDelegateAdapter::NotificationClick() { observer_->OnClicked(); } +void AtomNotificationDelegateAdapter::NotificationReplied(std::string reply) { + observer_->OnReplied(reply); +} void AtomNotificationDelegateAdapter::NotificationDestroyed() {} void AtomNotificationDelegateAdapter::NotificationFailed() {} diff --git a/atom/browser/ui/notification_delegate_adapter.h b/atom/browser/ui/notification_delegate_adapter.h index 087a207f80..e0c56e3fa8 100644 --- a/atom/browser/ui/notification_delegate_adapter.h +++ b/atom/browser/ui/notification_delegate_adapter.h @@ -21,6 +21,7 @@ class AtomNotificationDelegateAdapter : public brightray::NotificationDelegate { void NotificationClick(); void NotificationDestroyed(); void NotificationFailed(); + void NotificationReplied(std::string reply); }; } // namespace atom diff --git a/brightray/browser/linux/libnotify_notification.cc b/brightray/browser/linux/libnotify_notification.cc index 9706fbd3d6..27120068ba 100644 --- a/brightray/browser/linux/libnotify_notification.cc +++ b/brightray/browser/linux/libnotify_notification.cc @@ -88,7 +88,9 @@ void LibnotifyNotification::Show(const base::string16& title, const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) { + const bool silent, + const bool has_reply, + const base::string16 reply_placeholder) { notification_ = libnotify_loader_.notify_notification_new( base::UTF16ToUTF8(title).c_str(), base::UTF16ToUTF8(body).c_str(), diff --git a/brightray/browser/linux/libnotify_notification.h b/brightray/browser/linux/libnotify_notification.h index b6163ae9b5..861ddce5fa 100644 --- a/brightray/browser/linux/libnotify_notification.h +++ b/brightray/browser/linux/libnotify_notification.h @@ -27,7 +27,9 @@ class LibnotifyNotification : public Notification { const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) override; + const bool silent, + const bool has_reply, + const base::string16 reply_placeholder) override; void Dismiss() override; private: diff --git a/brightray/browser/mac/cocoa_notification.h b/brightray/browser/mac/cocoa_notification.h index e95b490a70..c269dd2602 100644 --- a/brightray/browser/mac/cocoa_notification.h +++ b/brightray/browser/mac/cocoa_notification.h @@ -26,10 +26,13 @@ class CocoaNotification : public Notification { const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) override; + const bool silent, + const bool hasReply, + const base::string16 replyPlaceholder) override; void Dismiss() override; void NotificationDisplayed(); + void NotificationReplied(std::string reply); NSUserNotification* notification() const { return notification_; } diff --git a/brightray/browser/mac/cocoa_notification.mm b/brightray/browser/mac/cocoa_notification.mm index 354dc8d484..010f9ba427 100644 --- a/brightray/browser/mac/cocoa_notification.mm +++ b/brightray/browser/mac/cocoa_notification.mm @@ -28,7 +28,9 @@ void CocoaNotification::Show(const base::string16& title, const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) { + const bool silent, + const bool has_reply, + const base::string16 reply_placeholder) { notification_.reset([[NSUserNotification alloc] init]); [notification_ setTitle:base::SysUTF16ToNSString(title)]; [notification_ setInformativeText:base::SysUTF16ToNSString(body)]; @@ -46,6 +48,11 @@ void CocoaNotification::Show(const base::string16& title, [notification_ setSoundName:NSUserNotificationDefaultSoundName]; } + if (has_reply) { + [notification_ setResponsePlaceholder:base::SysUTF16ToNSString(reply_placeholder)]; + [notification_ setHasReplyButton:true]; + } + [NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification_]; } @@ -61,4 +68,8 @@ void CocoaNotification::NotificationDisplayed() { delegate()->NotificationDisplayed(); } +void CocoaNotification::NotificationReplied(const std::string reply) { + delegate()->NotificationReplied(reply); +} + } // namespace brightray diff --git a/brightray/browser/mac/notification_center_delegate.mm b/brightray/browser/mac/notification_center_delegate.mm index 42632cd8a9..0f21ec88b0 100644 --- a/brightray/browser/mac/notification_center_delegate.mm +++ b/brightray/browser/mac/notification_center_delegate.mm @@ -21,15 +21,21 @@ - (void)userNotificationCenter:(NSUserNotificationCenter*)center didDeliverNotification:(NSUserNotification*)notif { auto notification = presenter_->GetNotification(notif); - if (notification) + if (notification) notification->NotificationDisplayed(); } - (void)userNotificationCenter:(NSUserNotificationCenter*)center didActivateNotification:(NSUserNotification *)notif { auto notification = presenter_->GetNotification(notif); - if (notification) + if (notification) { notification->NotificationClicked(); + if (notif.activationType == NSUserNotificationActivationTypeReplied){ + notification->NotificationReplied([notif.response.string UTF8String]); + } else { + notification->NotificationClicked(); + } + } } - (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center diff --git a/brightray/browser/notification.h b/brightray/browser/notification.h index e59cab7a0c..f575753fea 100644 --- a/brightray/browser/notification.h +++ b/brightray/browser/notification.h @@ -26,7 +26,9 @@ class Notification { const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) = 0; + const bool silent, + const bool hasReply, + const base::string16 replyPlaceholder) = 0; // Closes the notification, this instance will be destroyed after the // notification gets closed. virtual void Dismiss() = 0; diff --git a/brightray/browser/notification_delegate.h b/brightray/browser/notification_delegate.h index c036b83bcf..848af0122d 100644 --- a/brightray/browser/notification_delegate.h +++ b/brightray/browser/notification_delegate.h @@ -6,6 +6,7 @@ #define BRIGHTRAY_BROWSER_NOTIFICATION_DELEGATE_H_ #include "content/public/browser/desktop_notification_delegate.h" +#include namespace brightray { @@ -16,6 +17,9 @@ class NotificationDelegate : public content::DesktopNotificationDelegate { // Failed to send the notification. virtual void NotificationFailed() {} + + // Notification was replied to + virtual void NotificationReplied(std::string reply) {} }; } // namespace brightray diff --git a/brightray/browser/notification_delegate_adapter.cc b/brightray/browser/notification_delegate_adapter.cc index 60405f9ef8..4b515d0e88 100644 --- a/brightray/browser/notification_delegate_adapter.cc +++ b/brightray/browser/notification_delegate_adapter.cc @@ -30,4 +30,8 @@ void NotificationDelegateAdapter::NotificationClick() { delegate_->NotificationClick(); } +// void NotificationDelegateAdapter::NotificationReplied(std::string reply) { +// delegate_->NotificationReplied(reply); +// } + } // namespace brightray diff --git a/brightray/browser/platform_notification_service.cc b/brightray/browser/platform_notification_service.cc index 1c88a7461d..99ab54080c 100644 --- a/brightray/browser/platform_notification_service.cc +++ b/brightray/browser/platform_notification_service.cc @@ -4,6 +4,7 @@ #include "brightray/browser/platform_notification_service.h" +#include "base/strings/utf_string_conversions.h" #include "brightray/browser/browser_client.h" #include "brightray/browser/notification.h" #include "brightray/browser/notification_delegate_adapter.h" @@ -30,7 +31,7 @@ void OnWebNotificationAllowed(base::WeakPtr notification, return; if (allowed) notification->Show(data.title, data.body, data.tag, data.icon, icon, - audio_muted ? true : data.silent); + audio_muted ? true : data.silent, false, base::UTF8ToUTF16("")); else notification->Destroy(); } diff --git a/brightray/browser/win/win32_notification.cc b/brightray/browser/win/win32_notification.cc index 21e3b6ce8f..9aed1de051 100644 --- a/brightray/browser/win/win32_notification.cc +++ b/brightray/browser/win/win32_notification.cc @@ -12,7 +12,8 @@ namespace brightray { void Win32Notification::Show( const base::string16& title, const base::string16& msg, const std::string& tag, const GURL& icon_url, - const SkBitmap& icon, const bool silent) { + const SkBitmap& icon, const bool silent, + const bool has_reply, const base::string16 reply_placeholder) { auto presenter = static_cast(this->presenter()); if (!presenter) return; diff --git a/brightray/browser/win/win32_notification.h b/brightray/browser/win/win32_notification.h index ce0ba3a092..2136551f56 100644 --- a/brightray/browser/win/win32_notification.h +++ b/brightray/browser/win/win32_notification.h @@ -12,7 +12,8 @@ class Win32Notification : public brightray::Notification { } void Show(const base::string16& title, const base::string16& msg, const std::string& tag, const GURL& icon_url, - const SkBitmap& icon, const bool silent) override; + const SkBitmap& icon, const bool silent, + const bool has_reply, const base::string16 reply_placeholder) override; void Dismiss() override; const DesktopNotificationController::Notification& GetRef() const { diff --git a/brightray/browser/win/windows_toast_notification.cc b/brightray/browser/win/windows_toast_notification.cc index 5b5b7764eb..2744958c42 100644 --- a/brightray/browser/win/windows_toast_notification.cc +++ b/brightray/browser/win/windows_toast_notification.cc @@ -89,7 +89,9 @@ void WindowsToastNotification::Show(const base::string16& title, const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) { + const bool silent, + const bool hasReply, + const base::string16 replyPlaceholder) { auto presenter_win = static_cast(presenter()); std::wstring icon_path = presenter_win->SaveIconToFilesystem(icon, icon_url); diff --git a/brightray/browser/win/windows_toast_notification.h b/brightray/browser/win/windows_toast_notification.h index b36a5cc379..62303054f6 100644 --- a/brightray/browser/win/windows_toast_notification.h +++ b/brightray/browser/win/windows_toast_notification.h @@ -55,7 +55,9 @@ class WindowsToastNotification : public Notification { const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) override; + const bool silent, + const bool has_reply, + const base::string16 reply_placeholder) override; void Dismiss() override; private: diff --git a/default_app/default_app.js b/default_app/default_app.js index 2a3ce3a85e..e1ef319091 100644 --- a/default_app/default_app.js +++ b/default_app/default_app.js @@ -1,4 +1,4 @@ -const {app, BrowserWindow} = require('electron') +const {app, BrowserWindow, Notification} = require('electron') const path = require('path') let mainWindow = null @@ -27,5 +27,14 @@ exports.load = (appUrl) => { mainWindow = new BrowserWindow(options) mainWindow.loadURL(appUrl) mainWindow.focus() + + const n = new Notification({ + title: 'Foo', + body: 'Bar', + hasReply: true, + replyPlaceholder: 'foo' + }); + n.on('reply', (...args) => console.log(args)); + n.show(); }) }