|
1 | 1 | import { SharedNotificationDelegateCommon } from './common';
|
2 | 2 |
|
3 | 3 | type DeferedPromise<T> = {
|
4 |
| - promise: Promise<T>; |
5 |
| - resolve: (value?: T | PromiseLike<T>) => void; |
6 |
| - reject: (reason?: any) => void; |
| 4 | + promise: Promise<T>; |
| 5 | + resolve: (value?: T | PromiseLike<T>) => void; |
| 6 | + reject: (reason?: any) => void; |
7 | 7 | };
|
8 | 8 | function createDeferedPromise<T>(): DeferedPromise<T> {
|
9 |
| - const deferred: DeferedPromise<T> = { |
10 |
| - promise: undefined, |
11 |
| - reject: undefined, |
12 |
| - resolve: undefined |
13 |
| - }; |
14 |
| - |
15 |
| - deferred.promise = new Promise<T>((resolve, reject) => { |
16 |
| - deferred.resolve = resolve; |
17 |
| - deferred.reject = reject; |
18 |
| - }); |
19 |
| - return deferred; |
| 9 | + const deferred: DeferedPromise<T> = { |
| 10 | + promise: undefined, |
| 11 | + reject: undefined, |
| 12 | + resolve: undefined, |
| 13 | + }; |
| 14 | + |
| 15 | + deferred.promise = new Promise<T>((resolve, reject) => { |
| 16 | + deferred.resolve = resolve; |
| 17 | + deferred.reject = reject; |
| 18 | + }); |
| 19 | + return deferred; |
20 | 20 | }
|
21 | 21 |
|
22 | 22 | type StopNextPromise = {
|
23 |
| - stop: () => void, |
24 |
| - next: () => void |
| 23 | + stop: () => void; |
| 24 | + next: () => void; |
25 | 25 | } & DeferedPromise<boolean>;
|
26 | 26 |
|
27 | 27 | function createStopNextPromise(): StopNextPromise {
|
28 |
| - const deferred = createDeferedPromise<boolean>(); |
29 |
| - return { |
30 |
| - ...deferred, |
31 |
| - next: () => deferred.resolve(false), |
32 |
| - stop: () => deferred.resolve(true) |
33 |
| - }; |
| 28 | + const deferred = createDeferedPromise<boolean>(); |
| 29 | + return { |
| 30 | + ...deferred, |
| 31 | + next: () => deferred.resolve(false), |
| 32 | + stop: () => deferred.resolve(true), |
| 33 | + }; |
34 | 34 | }
|
35 | 35 |
|
36 | 36 | @NativeClass()
|
37 | 37 | class UNUserNotificationCenterDelegateImpl extends NSObject implements UNUserNotificationCenterDelegate {
|
38 |
| - public static ObjCProtocols = []; |
39 |
| - |
40 |
| - static new(): UNUserNotificationCenterDelegateImpl { |
41 |
| - if (UNUserNotificationCenterDelegateImpl.ObjCProtocols.length === 0 && typeof (UNUserNotificationCenterDelegate) !== "undefined") { |
42 |
| - UNUserNotificationCenterDelegateImpl.ObjCProtocols.push(UNUserNotificationCenterDelegate); |
43 |
| - } |
44 |
| - return <UNUserNotificationCenterDelegateImpl>super.new(); |
45 |
| - } |
46 |
| - |
47 |
| - private _owner: WeakRef<SharedNotificationDelegateImpl>; |
48 |
| - |
49 |
| - public static initWithOwner(owner: WeakRef<SharedNotificationDelegateImpl>): UNUserNotificationCenterDelegateImpl { |
50 |
| - const delegate = <UNUserNotificationCenterDelegateImpl>UNUserNotificationCenterDelegateImpl.new(); |
51 |
| - delegate._owner = owner; |
52 |
| - return delegate; |
53 |
| - } |
54 |
| - |
55 |
| - public userNotificationCenterWillPresentNotificationWithCompletionHandler(center: UNUserNotificationCenter, notification: UNNotification, completionHandler: (p1: UNNotificationPresentationOptions) => void): void { |
56 |
| - let promise = Promise.resolve(false); |
57 |
| - const owner = this._owner.get(); |
58 |
| - if (owner) { |
59 |
| - owner._observers.forEach(({ observer }) => { |
60 |
| - if (observer.userNotificationCenterWillPresentNotificationWithCompletionHandler) { |
61 |
| - promise = promise.then((skip: boolean) => { |
62 |
| - if (skip) { return true; } |
63 |
| - const defPromise = createStopNextPromise(); |
64 |
| - const childHandler: (p1: UNNotificationPresentationOptions) => void = (p1: UNNotificationPresentationOptions) => { |
65 |
| - defPromise.stop(); |
66 |
| - completionHandler(p1); |
67 |
| - }; |
68 |
| - try { |
69 |
| - observer.userNotificationCenterWillPresentNotificationWithCompletionHandler(center, notification, childHandler, defPromise.next); |
70 |
| - } catch (ignore) { |
71 |
| - defPromise.next(); |
72 |
| - } |
73 |
| - return defPromise.promise; |
74 |
| - }); |
75 |
| - } |
76 |
| - }); |
77 |
| - promise.then((handled: boolean) => { |
78 |
| - if (!handled) { |
79 |
| - completionHandler(0); |
80 |
| - } |
81 |
| - return true; |
82 |
| - }); |
83 |
| - } |
84 |
| - } |
85 |
| - |
86 |
| - public userNotificationCenterOpenSettingsForNotification(center: UNUserNotificationCenter, notification: UNNotification): void { |
87 |
| - let promise = Promise.resolve(false); |
88 |
| - const owner = this._owner.get(); |
89 |
| - if (owner) { |
90 |
| - owner._observers.forEach(({ observer }) => { |
91 |
| - if (observer.userNotificationCenterOpenSettingsForNotification) { |
92 |
| - promise = promise.then((skip: boolean) => { |
93 |
| - if (skip) { return true; } |
94 |
| - const defPromise = createStopNextPromise(); |
95 |
| - try { |
96 |
| - observer.userNotificationCenterOpenSettingsForNotification(center, notification, defPromise.stop, defPromise.next); |
97 |
| - } catch (ignore) { |
98 |
| - defPromise.next(); |
99 |
| - } |
100 |
| - return defPromise.promise; |
101 |
| - }); |
102 |
| - } |
103 |
| - }); |
104 |
| - } |
105 |
| - } |
106 |
| - |
107 |
| - public userNotificationCenterDidReceiveNotificationResponseWithCompletionHandler(center: UNUserNotificationCenter, response: UNNotificationResponse, completionHandler: () => void): void { |
108 |
| - let promise = Promise.resolve(false); |
109 |
| - const owner = this._owner.get(); |
110 |
| - if (owner) { |
111 |
| - owner._observers.forEach(({ observer }) => { |
112 |
| - if (observer.userNotificationCenterDidReceiveNotificationResponseWithCompletionHandler) { |
113 |
| - promise = promise.then((skip: boolean) => { |
114 |
| - if (skip) { return true; } |
115 |
| - const defPromise = createStopNextPromise(); |
116 |
| - const childHandler: () => void = () => { |
117 |
| - defPromise.stop(); |
118 |
| - completionHandler(); |
119 |
| - }; |
120 |
| - try { |
121 |
| - observer.userNotificationCenterDidReceiveNotificationResponseWithCompletionHandler(center, response, childHandler, defPromise.next); |
122 |
| - } catch (ignore) { |
123 |
| - defPromise.next(); |
124 |
| - } |
125 |
| - return defPromise.promise; |
126 |
| - }); |
127 |
| - } |
128 |
| - }); |
129 |
| - promise.then((handled: boolean) => { |
130 |
| - if (!handled) { |
131 |
| - if (!owner.disableUnhandledWarning) { |
132 |
| - console.log("WARNING[shared-notification-delegate]: Notification was received but was not handled by any observer"); |
133 |
| - } |
134 |
| - completionHandler(); |
135 |
| - } |
136 |
| - return true; |
137 |
| - }); |
138 |
| - } |
139 |
| - } |
| 38 | + public static ObjCProtocols = []; |
| 39 | + |
| 40 | + static new(): UNUserNotificationCenterDelegateImpl { |
| 41 | + if (UNUserNotificationCenterDelegateImpl.ObjCProtocols.length === 0 && typeof UNUserNotificationCenterDelegate !== 'undefined') { |
| 42 | + UNUserNotificationCenterDelegateImpl.ObjCProtocols.push(UNUserNotificationCenterDelegate); |
| 43 | + } |
| 44 | + return <UNUserNotificationCenterDelegateImpl>super.new(); |
| 45 | + } |
| 46 | + |
| 47 | + private _owner: WeakRef<SharedNotificationDelegateImpl>; |
| 48 | + |
| 49 | + public static initWithOwner(owner: WeakRef<SharedNotificationDelegateImpl>): UNUserNotificationCenterDelegateImpl { |
| 50 | + const delegate = <UNUserNotificationCenterDelegateImpl>UNUserNotificationCenterDelegateImpl.new(); |
| 51 | + delegate._owner = owner; |
| 52 | + return delegate; |
| 53 | + } |
| 54 | + |
| 55 | + public userNotificationCenterWillPresentNotificationWithCompletionHandler(center: UNUserNotificationCenter, notification: UNNotification, completionHandler: (p1: UNNotificationPresentationOptions) => void): void { |
| 56 | + const owner = this._owner.get(); |
| 57 | + if (owner) { |
| 58 | + let handled = false; |
| 59 | + const next = () => (handled = handled ? handled : false); |
| 60 | + const childHandler = (p1: UNNotificationPresentationOptions) => { |
| 61 | + if (handled) { |
| 62 | + return; |
| 63 | +
57AE
} |
| 64 | + handled = true; |
| 65 | + completionHandler(p1); |
| 66 | + }; |
| 67 | + owner._observers.some(({ observer }) => { |
| 68 | + if (observer.userNotificationCenterWillPresentNotificationWithCompletionHandler) { |
| 69 | + try { |
| 70 | + observer.userNotificationCenterWillPresentNotificationWithCompletionHandler(center, notification, childHandler, next); |
| 71 | + } catch (ignore) { |
| 72 | + next(); |
| 73 | + } |
| 74 | + } |
| 75 | + return handled; |
| 76 | + }); |
| 77 | + if (!handled) { |
| 78 | + if (!owner.disableUnhandledWarning) { |
| 79 | + console.log('WARNING[shared-notification-delegate]: Notification was received for presentation but was not handled by any observer'); |
| 80 | + } |
| 81 | + childHandler(0); |
| 82 | + } |
| 83 | + } |
| 84 | + } |
| 85 | + |
| 86 | + public userNotificationCenterOpenSettingsForNotification(center: UNUserNotificationCenter, notification: UNNotification): void { |
| 87 | + let promise = Promise.resolve(false); |
| 88 | + const owner = this._owner.get(); |
| 89 | + if (owner) { |
| 90 | + owner._observers.forEach(({ observer }) => { |
| 91 | + if (observer.userNotificationCenterOpenSettingsForNotification) { |
| 92 | + promise = promise.then((skip: boolean) => { |
| 93 | + if (skip) { |
| 94 | + return true; |
| 95 | + } |
| 96 | + const defPromise = createStopNextPromise(); |
| 97 | + try { |
| 98 | + observer.userNotificationCenterOpenSettingsForNotification(center, notification, defPromise.stop, defPromise.next); |
| 99 | + } catch (ignore) { |
| 100 | + defPromise.next(); |
| 101 | + } |
| 102 | + return defPromise.promise; |
| 103 | + }); |
| 104 | + } |
| 105 | + }); |
| 106 | + } |
| 107 | + } |
| 108 | + |
| 109 | + public userNotificationCenterDidReceiveNotificationResponseWithCompletionHandler(center: UNUserNotificationCenter, response: UNNotificationResponse, completionHandler: () => void): void { |
| 110 | + let promise = Promise.resolve(false); |
| 111 | + const owner = this._owner.get(); |
| 112 | + if (owner) { |
| 113 | + owner._observers.forEach(({ observer }) => { |
| 114 | + if (observer.userNotificationCenterDidReceiveNotificationResponseWithCompletionHandler) { |
| 115 | + promise = promise.then((skip: boolean) => { |
| 116 | + if (skip) { |
| 117 | + return true; |
| 118 | + } |
| 119 | + const defPromise = createStopNextPromise(); |
| 120 | + const childHandler: () => void = () => { |
| 121 | + defPromise.stop(); |
| 122 | + completionHandler(); |
| 123 | + }; |
| 124 | + try { |
| 125 | + observer.userNotificationCenterDidReceiveNotificationResponseWithCompletionHandler(center, response, childHandler, defPromise.next); |
| 126 | + } catch (ignore) { |
| 127 | + defPromise.next(); |
| 128 | + } |
| 129 | + return defPromise.promise; |
| 130 | + }); |
| 131 | + } |
| 132 | + }); |
| 133 | + promise.then((handled: boolean) => { |
| 134 | + if (!handled) { |
| 135 | + if (!owner.disableUnhandledWarning) { |
| 136 | + console.log('WARNING[shared-notification-delegate]: Notification was received but was not handled by any observer'); |
| 137 | + } |
| 138 | + completionHandler(); |
| 139 | + } |
| 140 | + return true; |
| 141 | + }); |
| 142 | + } |
| 143 | + } |
140 | 144 | }
|
141 | 145 |
|
142 | 146 | export interface DelegateObserver {
|
143 |
| - userNotificationCenterDidReceiveNotificationResponseWithCompletionHandler?(center: UNUserNotificationCenter, response: UNNotificationResponse, completionHandler: () => void, next: () => void): void; |
144 |
| - userNotificationCenterOpenSettingsForNotification?(center: UNUserNotificationCenter, notification: UNNotification, stop: () => void, next: () => void): void; |
145 |
| - userNotificationCenterWillPresentNotificationWithCompletionHandler?(center: UNUserNotificationCenter, notification: UNNotification, completionHandler: (p1: UNNotificationPresentationOptions) => void, next: () => void): void; |
146 |
| - /** |
147 |
| - * if set to not null/undefined, will ensure only one is registered |
148 |
| - */ |
149 |
| - observerUniqueKey?: any; |
| 147 | + userNotificationCenterDidReceiveNotificationResponseWithCompletionHandler?(center: UNUserNotificationCenter, response: UNNotificationResponse, completionHandler: () => void, next: () => void): void; |
| 148 | + userNotificationCenterOpenSettingsForNotification?(center: UNUserNotificationCenter, notification: UNNotification, stop: () => void, next: () => void): void; |
| 149 | + userNotificationCenterWillPresentNotificationWithCompletionHandler?(center: UNUserNotificationCenter, notification: UNNotification, completionHandler: (p1: UNNotificationPresentationOptions) => void, next: () => void): void; |
| 150 | + /** |
| 151 | + * if set to not null/undefined, will ensure only one is registered |
| 152 | + */ |
| 153 | + observerUniqueKey?: any; |
150 | 154 | }
|
151 | 155 | export class SharedNotificationDelegateImpl extends SharedNotificationDelegateCommon {
|
152 |
| - _observers: Array<{ observer: DelegateObserver, priority: number }> = []; |
153 |
| - disableUnhandledWarning = false; |
154 |
| - private delegate: UNUserNotificationCenterDelegateImpl; |
155 |
| - |
156 |
| - constructor() { |
157 |
| - super(); |
158 |
| - if (SharedNotificationDelegateImpl.isUNUserNotificationCenterAvailable()) { |
159 |
| - this.delegate = UNUserNotificationCenterDelegateImpl.initWithOwner(new WeakRef(this)); |
160 |
| - UNUserNotificationCenter.currentNotificationCenter().delegate = this.delegate; |
161 |
| - } |
162 |
| - } |
163 |
| - |
164 |
| - static isUNUserNotificationCenterAvailable(): boolean { |
165 |
| - try { |
166 |
| - // available since iOS 10 |
167 |
| - return !!UNUserNotificationCenter; |
168 |
| - } catch (ignore) { |
169 |
| - return false; |
170 |
| - } |
171 |
| - } |
172 |
| - |
173 |
| - addObserver(observer: DelegateObserver, priority: number = 100) { |
174 |
| - if (observer.observerUniqueKey != null) { |
175 |
| - this.removeObserverByUniqueKey(observer.observerUniqueKey); |
176 |
| - } |
177 |
| - this._observers.push({ observer, priority }); |
178 |
| - this.sortObservers(); |
179 |
| - } |
180 |
| - |
181 |
| - removeObserver(observer: DelegateObserver) { |
182 |
| - this._observers = this._observers.filter((v) => v.observer !== observer); |
183 |
| - } |
184 |
| - |
185 |
| - removeObserverByUniqueKey(key: string) { |
186 |
| - if (key == null) { |
187 |
| - console.log("SharedNotificationDelegate Warning: tried to remove null/undefined keys."); |
188 |
| - return; |
189 |
| - } |
190 |
| - this._observers = this._observers.filter((v) => v.observer.observerUniqueKey !== key); |
191 |
| - } |
192 |
| - |
193 |
| - clearObservers() { |
194 |
| - this._observers = []; |
195 |
| - } |
196 |
| - |
197 |
| - private sortObservers() { |
198 |
| - this._observers.sort((a, b) => a.priority > b.priority ? 1 : (a.priority < b.priority ? -1 : 0)); |
199 |
| - } |
| 156 | + _observers: Array<{ observer: DelegateObserver; priority: number }> = []; |
| 157 | + disableUnhandledWarning = false; |
| 158 | + private delegate: UNUserNotificationCenterDelegateImpl; |
| 159 | + |
| 160 | + constructor() { |
| 161 | + super(); |
| 162 | + if (SharedNotificationDelegateImpl.isUNUserNotificationCenterAvailable()) { |
| 163 | + this.delegate = UNUserNotificationCenterDelegateImpl.initWithOwner(new WeakRef(this)); |
| 164 | + UNUserNotificationCenter.currentNotificationCenter().delegate = this.delegate; |
| 165 | + } |
| 166 | + } |
| 167 | + |
| 168 | + static isUNUserNotificationCenterAvailable(): boolean { |
| 169 | + try { |
| 170 | + // available since iOS 10 |
| 171 | + return !!UNUserNotificationCenter; |
| 172 | + } catch (ignore
10A1B
) { |
| 173 | + return false; |
| 174 | + } |
| 175 | + } |
| 176 | + |
| 177 | + addObserver(observer: DelegateObserver, priority: number = 100) { |
| 178 | + if (observer.observerUniqueKey != null) { |
| 179 | + this.removeObserverByUniqueKey(observer.observerUniqueKey); |
| 180 | + } |
| 181 | + this._observers.push({ observer, priority }); |
| 182 | + this.sortObservers(); |
| 183 | + } |
| 184 | + |
| 185 | + removeObserver(observer: DelegateObserver) { |
| 186 | + this._observers = this._observers.filter((v) => v.observer !== observer); |
| 187 | + } |
| 188 | + |
| 189 | + removeObserverByUniqueKey(key: string) { |
| 190 | + if (key == null) { |
| 191 | + console.log('SharedNotificationDelegate Warning: tried to remove null/undefined keys.'); |
| 192 | + return; |
| 193 | + } |
| 194 | + this._observers = this._observers.filter((v) => v.observer.observerUniqueKey !== key); |
| 195 | + } |
| 196 | + |
| 197 | + clearObservers() { |
| 198 | + this._observers = []; |
| 199 | + } |
| 200 | + |
| 201 | + private sortObservers() { |
| 202 | + this._observers.sort((a, b) => (a.priority > b.priority ? 1 : a.priority < b.priority ? -1 : 0)); |
| 203 | + } |
200 | 204 | }
|
201 | 205 |
|
202 | 206 | const instance = new SharedNotificationDelegateImpl();
|
|
0 commit comments