API  1.0.0
CPUserNotificationCenter.j
Go to the documentation of this file.
1 /*
2  * CPUserNotificationCenter.j
3  * Foundation
4  *
5  * Created by Alexandre Wilhelm.
6  * Copyright 2015, 280 North, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 @protocol CPUserNotificationCenterDelegate <CPObject>
25 
26 @optional
27 - (BOOL)userNotificationCenter:(CPUserNotificationCenter)center shouldPresentNotification:(CPUserNotification)notification;
28 - (void)userNotificationCenter:(CPUserNotificationCenter)center didDeliverNotification:(CPUserNotification)notification;
29 - (void)userNotificationCenter:(CPUserNotificationCenter)center didActivateNotification:(CPUserNotification)notification;
30 
31 @end
32 
33 // Remove compiling warnings
34 
35 @global CPApp
36 
40 
42 
48 @implementation CPUserNotificationCenter : CPObject
49 {
50  CPArray _deliveredNotifications;
51  CPArray _scheduledNotifications;
52  id <CPUserNotificationCenterDelegate> _delegate;
53 
54  CPInteger _implementedDelegateMethods;
55  CPMutableDictionary _timersForUserNotification;
56 }
57 
58 
59 #pragma mark -
60 #pragma mark Creating Default User Notification Center
61 
65 + (CPNotificationCenter)defaultUserNotificationCenter
66 {
69 
71 }
72 
73 - (id)init
74 {
75  self = [super init];
76 
77  if (self)
78  {
79  _deliveredNotifications = [];
80  _scheduledNotifications = [];
81  _timersForUserNotification = @{};
82  }
83 
84  return self;
85 }
86 
87 
88 #pragma mark -
89 #pragma mark Getting and Setting the Delegate
90 
91 - (void)setDelegate:(id <CPUserNotificationCenterDelegate>)aDelegate
92 {
93  if (_delegate === aDelegate)
94  return;
95 
96  _delegate = aDelegate;
97  _implementedDelegateMethods = 0;
98 
99  if ([_delegate respondsToSelector:@selector(userNotificationCenter:shouldPresentNotification:)])
101 
102  if ([_delegate respondsToSelector:@selector(userNotificationCenter:didDeliverNotification:)])
104 
105  if ([_delegate respondsToSelector:@selector(userNotificationCenter:didActivateNotification:)])
107 }
108 
109 
110 #pragma mark -
111 #pragma mark Managing the Scheduled Notification Queue
112 
117 - (void)scheduleNotification:(CPUserNotification)anUserNotification
118 {
119  var scheduledDate = [[anUserNotification deliveryDate] copy];
120  [scheduledDate _dateWithTimeZone:[anUserNotification deliveryTimeZone]];
121 
122  var timer = [[CPTimer alloc] initWithFireDate:scheduledDate
123  interval:[anUserNotification deliveryRepeatInterval]
124  target:self
126  userInfo:anUserNotification
127  repeats:([anUserNotification deliveryRepeatInterval] ? YES : NO)];
128 
129  [_scheduledNotifications addObject:anUserNotification];
130  _timersForUserNotification[[anUserNotification UID]] = timer;
131 
132  [[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
133 }
134 
135 - (void)_scheduledUserNotificationTimerDidFire:(CPTimer)aTimer
136 {
137  [self deliverNotification:[aTimer userInfo]];
138 }
139 
144 - (void)removeScheduledNotification:(CPUserNotification)anUserNotification
145 {
146  if ([_scheduledNotifications indexOfObject:anUserNotification] != CPNotFound)
147  {
148  [_scheduledNotifications removeObject:anUserNotification];
149  [_timersForUserNotification[[anUserNotification UID]] invalidate];
150  delete _timersForUserNotification[[anUserNotification UID]];
151  }
152 }
153 
154 
155 #pragma mark -
156 #pragma mark Managing the Delivered Notifications
157 
162 - (void)deliverNotification:(CPUserNotification)aNotification
163 {
164  [self _launchUserNotification:aNotification];
165 }
166 
171 - (void)removeDeliveredNotification:(CPUserNotification)aNotification
172 {
173  [_deliveredNotifications removeObject:aNotification];
174 }
175 
179 - (void)removeAllDeliveredNotifications
180 {
181  [_deliveredNotifications removeAllObjects];
182 }
183 
184 
185 #pragma mark -
186 #pragma mark Permission Utilities
187 
188 - (void)_askPermissionForUserNotification:(CPUserNotification)anUserNotification
189 {
190  Notification.requestPermission(function (permission) {
191  if (permission == "granted")
192  // We need to relaunch the notification if the permission are granted
193  [self _launchUserNotification:anUserNotification];
194  });
195 }
196 
197 
198 #pragma mark -
199 #pragma mark Notification Utilities
200 
201 - (void)_launchUserNotification:(CPUserNotification)anUserNotification
202 {
203  // If the browser version is unsupported, remain silent.
204  if (!window || !'Notification' in window)
205  return;
206 
207  if (Notification.permission === 'default')
208  [self _askPermissionForUserNotification:anUserNotification];
209 
210  if (Notification.permission === 'granted')
211  {
212  if (([self _delegateRespondsToShouldPresentNotification] && [self _sendDelegateShouldPresentNotification:anUserNotification])
213  || ![CPApp isActive])
214  {
215  var notification = new Notification(
216  [anUserNotification title],
217  {
218  'body': [anUserNotification informativeText],
219  'icon': [[anUserNotification contentImage] filename],
220  // ...prevent duplicate notifications
221  'tag' : [anUserNotification identifier]
222  }
223  );
224 
225  anUserNotification._presented = YES;
226 
227  notification.onclick = function () {
228  anUserNotification._activationType = CPUserNotificationActivationTypeContentsClicked;
229  [self _sendDelegateDidActivateNotification:anUserNotification];
230 
231  // Remove the notification from Notification Center when clicked.
232  this.close();
233  };
234 
235  // Callback function when the notification is closed.
236  notification.onclose = function () {
237 
238  };
239  }
240  else
241  {
242  anUserNotification._presented = NO;
243  }
244 
245  anUserNotification._activationType = CPUserNotificationActivationTypeNone;
246  anUserNotification._actualDeliveryDate = [CPDate date];
247  [_deliveredNotifications addObject:anUserNotification];
248 
249  if (![anUserNotification deliveryRepeatInterval])
250  [self removeScheduledNotification:anUserNotification];
251 
252  [self _sendDelegateDidDeliverNotification:anUserNotification];
253  }
254 }
255 
256 @end
257 
258 
260 
261 - (BOOL)_delegateRespondsToShouldPresentNotification
262 {
264 }
265 
266 - (BOOL)_sendDelegateShouldPresentNotification:(CPUserNotification)aNotification
267 {
268  return [_delegate userNotificationCenter:self shouldPresentNotification:aNotification];
269 }
270 
271 - (void)_sendDelegateDidActivateNotification:(CPUserNotification)aNotification
272 {
274  return;
275 
276  [_delegate userNotificationCenter:self didActivateNotification:aNotification];
277 }
278 
279 - (void)_sendDelegateDidDeliverNotification:(CPUserNotification)aNotification
280 {
282  return;
283 
284  [_delegate userNotificationCenter:self didDeliverNotification:aNotification];
285 }
286 
287 @end
288 
290 
294 - (CPArray)deliveredNotifications
295 {
296  return _deliveredNotifications;
297 }
298 
302 - (void)setDeliveredNotifications:(CPArray)aValue
303 {
304  _deliveredNotifications = aValue;
305 }
306 
310 - (CPArray)scheduledNotifications
311 {
312  return _scheduledNotifications;
313 }
314 
318 - (void)setScheduledNotifications:(CPArray)aValue
319 {
320  _scheduledNotifications = aValue;
321 }
322 
323 @end
id init()
Definition: CALayer.j:126
A representation of a single point in time.
Definition: CPDate.h:2
global CPApp var CPUserNotificationCenterDelegate_userNotificationCenter_shouldPresentNotification_
The main run loop for the application.
Definition: CPRunLoop.h:2
id initWithFireDate:interval:target:selector:userInfo:repeats:(CPDate aDate, [interval] CPTimeInterval seconds, [target] id aTarget, [selector] SEL aSelector, [userInfo] id userInfo, [repeats] BOOL shouldRepeat)
Definition: CPTimer.j:125
CPRunLoop currentRunLoop()
Definition: CPRunLoop.j:232
CPTimeInterval deliveryRepeatInterval()
global CPApp var CPUserNotificationCenterDelegate_userNotificationCenter_didActivateNotification_
global CPApp var CPUserNotificationCenterDelegate_userNotificationCenter_didDeliverNotification_
The CPUserNotificationCenter class delivers user notifications to the user from applications or helpe...
var CPUserNotificationDefaultCenter
id copy()
Definition: CPDate.j:222
id userInfo()
Definition: CPTimer.j:229
A timer object that can send a message after the given time interval.
Definition: CPTimer.h:2
CPNotFound
Definition: CPObjJRuntime.j:62
id init()
Definition: CPObject.j:145
Sends messages (CPNotification) between objects.
CPUserNotificationActivationTypeContentsClicked
void addTimer:forMode:(CPTimer aTimer, [forMode] CPString aMode)
Definition: CPRunLoop.j:313
id date()
Definition: CPDate.j:42
CPUserNotificationAction typedef CPUserNotificationActivationType CPUserNotificationActivationTypeNone
The CPUserNotification class is used to configure a notification that is scheduled for display by the...
CPString UID()
Definition: CPObject.j:552
id alloc()
Definition: CPObject.j:130