cordova-plugin-local-notifications-continued 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/FUNDING.yml +1 -0
- package/.github/ISSUE_TEMPLATE/report_issue.yml +126 -0
- package/CHANGELOG.md +358 -0
- package/LICENSE +202 -0
- package/README.md +1531 -0
- package/images/android-actions-with-input-clicked.png +0 -0
- package/images/android-actions-with-input-not-clicked.png +0 -0
- package/images/android-actions.png +0 -0
- package/images/android-alarms-and-reminders-in-app-settings.png +0 -0
- package/images/android-alarms-and-reminders-setting.png +0 -0
- package/images/android-app-hibernation-notification.png +0 -0
- package/images/android-app-hibernation-settings-android-12.png +0 -0
- package/images/android-app-hibernation-settings-android-13-14.png +0 -0
- package/images/android-app-hibernation-settings-android-15.png +0 -0
- package/images/android-attachments-image-folded.png +0 -0
- package/images/android-attachments-image-unfolded.png +0 -0
- package/images/android-chat.png +0 -0
- package/images/android-icon.svg +19 -0
- package/images/android-inbox.png +0 -0
- package/images/android-notification-example.png +0 -0
- package/images/android-progress.png +0 -0
- package/images/android-request-permission.png +0 -0
- package/images/android-stack.png +0 -0
- package/images/apple-icon.svg +1 -0
- package/images/cordova-app-notified-logo.png +0 -0
- package/images/ios-actions-with-input.png +0 -0
- package/images/ios-actions.png +0 -0
- package/images/ios-attachments-image-folded.png +0 -0
- package/images/ios-attachments-image-unfolded.png +0 -0
- package/images/ios-notification.png +0 -0
- package/images/ios-request-permission.png +0 -0
- package/images/logo.png +0 -0
- package/package.json +53 -0
- package/plugin.xml +266 -0
- package/src/android/ClickActivity.java +72 -0
- package/src/android/LocalNotification.java +779 -0
- package/src/android/Manager.java +327 -0
- package/src/android/Notification.java +844 -0
- package/src/android/Options.java +956 -0
- package/src/android/OptionsTrigger.java +104 -0
- package/src/android/action/Action.java +214 -0
- package/src/android/action/ActionGroup.java +135 -0
- package/src/android/build/localnotification.gradle +29 -0
- package/src/android/receiver/ClearReceiver.java +61 -0
- package/src/android/receiver/RestoreReceiver.java +70 -0
- package/src/android/receiver/TriggerReceiver.java +70 -0
- package/src/android/trigger/TriggerHandler.java +195 -0
- package/src/android/trigger/TriggerHandlerAt.java +63 -0
- package/src/android/trigger/TriggerHandlerEvery.java +257 -0
- package/src/android/trigger/TriggerHandlerIn.java +69 -0
- package/src/android/util/AssetUtil.java +385 -0
- package/src/android/util/CallbackContextUtil.java +88 -0
- package/src/android/util/PluginFileProvider.java +34 -0
- package/src/android/xml/shared_files_provider_paths.xml +38 -0
- package/src/ios/APPLocalNotification.h +56 -0
- package/src/ios/APPLocalNotification.m +650 -0
- package/src/ios/APPNotificationCategory.h +28 -0
- package/src/ios/APPNotificationCategory.m +107 -0
- package/src/ios/APPNotificationContent.h +32 -0
- package/src/ios/APPNotificationContent.m +122 -0
- package/src/ios/APPNotificationOptions.h +42 -0
- package/src/ios/APPNotificationOptions.m +689 -0
- package/src/ios/UNNotificationRequest+APPLocalNotification.h +32 -0
- package/src/ios/UNNotificationRequest+APPLocalNotification.m +100 -0
- package/src/ios/UNUserNotificationCenter+APPLocalNotification.h +60 -0
- package/src/ios/UNUserNotificationCenter+APPLocalNotification.m +344 -0
- package/www/local-notification.js +1104 -0
|
@@ -0,0 +1,1104 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Apache 2.0 License
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Sebastian Katzer 2017
|
|
5
|
+
*
|
|
6
|
+
* This file contains Original Code and/or Modifications of Original Code
|
|
7
|
+
* as defined in and that are subject to the Apache License
|
|
8
|
+
* Version 2.0 (the 'License'). You may not use this file except in
|
|
9
|
+
* compliance with the License. Please obtain a copy of the License at
|
|
10
|
+
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
|
|
11
|
+
* file.
|
|
12
|
+
*
|
|
13
|
+
* The Original Code and all software distributed under the License are
|
|
14
|
+
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
15
|
+
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
|
16
|
+
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
|
18
|
+
* Please see the License for the specific language governing rights and
|
|
19
|
+
* limitations under the License.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
var exec = require('cordova/exec'),
|
|
23
|
+
channel = require('cordova/channel');
|
|
24
|
+
|
|
25
|
+
// Options for every platform
|
|
26
|
+
exports._commonOptions = {
|
|
27
|
+
actions: [],
|
|
28
|
+
attachments: [],
|
|
29
|
+
// Custom data for the notification. Can be used, when the notification
|
|
30
|
+
// is send back to the app, e.g. by clicking on it.
|
|
31
|
+
data: null,
|
|
32
|
+
id: 1,
|
|
33
|
+
launch: true,
|
|
34
|
+
silent: false,
|
|
35
|
+
text: "",
|
|
36
|
+
// In Android 7, this sets the sound uri of a notification.
|
|
37
|
+
// Since Android 8, it sets the sound uri of a notification channel.
|
|
38
|
+
// The string 'default' represents the default notification sound and is not a path.
|
|
39
|
+
sound: 'default',
|
|
40
|
+
// If empty, the app name will be used
|
|
41
|
+
title: "",
|
|
42
|
+
// Default will be set on _prepareTrigger if nothing is set
|
|
43
|
+
trigger: null,
|
|
44
|
+
meta: {
|
|
45
|
+
plugin: 'cordova-plugin-local-notifications-continued',
|
|
46
|
+
version: '1.2.4' // Current plugin version
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
exports._androidAlarmTypes = {
|
|
51
|
+
RTC_WAKEUP: 0,
|
|
52
|
+
RTC: 1,
|
|
53
|
+
ELAPSED_REALTIME_WAKEUP: 2, // Not supported
|
|
54
|
+
ELAPSED_REALTIME: 3, // Not supported
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
exports._androidChannelImportanceTypes = {
|
|
58
|
+
IMPORTANCE_NONE: 0,
|
|
59
|
+
IMPORTANCE_MIN: 1,
|
|
60
|
+
IMPORTANCE_LOW: 2,
|
|
61
|
+
IMPORTANCE_DEFAULT: 3,
|
|
62
|
+
IMPORTANCE_HIGH: 4,
|
|
63
|
+
IMPORTANCE_MAX: 5
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
exports.androidUnusedAppRestrictionsStatusCodes = {
|
|
67
|
+
// The status of Unused App Restrictions could not be retrieved from this app e.g.
|
|
68
|
+
// if the app's target SDK version <30 or the user is in locked device boot mode
|
|
69
|
+
// Check the logs for the reason
|
|
70
|
+
ERROR: 0,
|
|
71
|
+
|
|
72
|
+
// There are no available Unused App Restrictions for this app (would only happen on Devices older then Android 7)
|
|
73
|
+
FEATURE_NOT_AVAILABLE: 1,
|
|
74
|
+
|
|
75
|
+
// Any available Unused App Restrictions on the device are disabled for this app.
|
|
76
|
+
// In other words, this app is exempt from having its permissions automatically removed or being hibernated.
|
|
77
|
+
DISABLED: 2,
|
|
78
|
+
|
|
79
|
+
// Unused App Restrictions introduced by Android API 30, and since made available on earlier (API 23-29) devices
|
|
80
|
+
// are enabled for this app: permission auto-reset. Note: This value is only used on API 29 or earlier devices.
|
|
81
|
+
API_30_BACKPORT: 3,
|
|
82
|
+
|
|
83
|
+
// Unused App Restrictions introduced by Android API 30 are enabled for this app: permission auto-reset.
|
|
84
|
+
// Note: This value is only used on API 30 or later devices.
|
|
85
|
+
API_30: 4,
|
|
86
|
+
|
|
87
|
+
// Unused App Restrictions introduced by Android API 31 are enabled for this app:
|
|
88
|
+
// permission auto-reset and app hibernation.
|
|
89
|
+
// Note: This value is only used on API 31 or later devices.
|
|
90
|
+
API_31: 5
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Options only available on Android
|
|
94
|
+
exports._androidSpecificOptions = {
|
|
95
|
+
androidAlarmType: exports._androidAlarmTypes.RTC_WAKEUP,
|
|
96
|
+
// Alarm will be allowed to execute even when the system is in low-power idle (a.k.a. doze) modes.
|
|
97
|
+
androidAllowWhileIdle: false,
|
|
98
|
+
// Make this notification automatically dismissed when the user touches it
|
|
99
|
+
androidAutoCancel : true,
|
|
100
|
+
androidChannelEnableLights: false,
|
|
101
|
+
androidChannelDescription: null,
|
|
102
|
+
androidChannelEnableVibration: false,
|
|
103
|
+
androidChannelId: "default_channel",
|
|
104
|
+
androidChannelImportance: exports._androidChannelImportanceTypes.IMPORTANCE_DEFAULT,
|
|
105
|
+
androidChannelName: "Default channel",
|
|
106
|
+
// soundUsage of a channel. Default is USAGE_NOTIFICATION
|
|
107
|
+
androidChannelSoundUsage: 5,
|
|
108
|
+
// The notification background color for the small icon
|
|
109
|
+
androidColor: null,
|
|
110
|
+
// Android 7 only: Sets the default notification options
|
|
111
|
+
androidDefaults: 0,
|
|
112
|
+
androidGroup: null,
|
|
113
|
+
androidGroupSummary: false,
|
|
114
|
+
androidMessages: null,
|
|
115
|
+
androidLargeIcon : null,
|
|
116
|
+
// Can be square or circle
|
|
117
|
+
androidLargeIconType: "square",
|
|
118
|
+
androidLockscreen: true,
|
|
119
|
+
androidOngoing: false,
|
|
120
|
+
androidOnlyAlertOnce: false,
|
|
121
|
+
androidProgressBar: null,
|
|
122
|
+
// If the Notification should show the when date
|
|
123
|
+
androidShowWhen: true,
|
|
124
|
+
androidSmallIcon: 'res://ic_popup_reminder',
|
|
125
|
+
androidSummary: null,
|
|
126
|
+
// Specifies a duration in milliseconds after which this notification should be canceled,
|
|
127
|
+
// if it is not already canceled.
|
|
128
|
+
androidTimeoutAfter: 0,
|
|
129
|
+
androidTitleCount: "%n%",
|
|
130
|
+
// Show the Notification#when field as a stopwatch. Instead of presenting when as a timestamp,
|
|
131
|
+
// the notification will show an automatically updating display of the minutes and seconds since when
|
|
132
|
+
androidUsesChronometer: false,
|
|
133
|
+
androidWakeUpScreen: true,
|
|
134
|
+
// Overwrites default
|
|
135
|
+
// Increments the badge by the specified number for that notification
|
|
136
|
+
badgeNumber: 1,
|
|
137
|
+
// Only for Android 7
|
|
138
|
+
led: false
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Options only available on iOS
|
|
142
|
+
exports._iOSSpecificOptions = {
|
|
143
|
+
// Overwrites default
|
|
144
|
+
// Set the badge directly.
|
|
145
|
+
// -1: The badge will not be changed
|
|
146
|
+
// 0: The badge will be cleared
|
|
147
|
+
badgeNumber: -1,
|
|
148
|
+
// Displays notification in foreground, when app is active.
|
|
149
|
+
iOSForeground : true
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
exports._deprecatedProperties = {
|
|
153
|
+
// Changes since version 1.1.0
|
|
154
|
+
autoClear: {newPropertyKey: 'androidAutoCancel', since: "1.1.0"},
|
|
155
|
+
badge: {newPropertyKey: 'badgeNumber', since: "1.1.0"},
|
|
156
|
+
channelDescription: {newPropertyKey: 'androidChannelDescription', since: "1.1.0"},
|
|
157
|
+
channelId: {newPropertyKey: 'androidChannelId', since: "1.1.0"},
|
|
158
|
+
channelImportance: {newPropertyKey: 'androidChannelImportance', since: "1.1.0"},
|
|
159
|
+
channelName: {newPropertyKey: 'androidChannelName', since: "1.1.0"},
|
|
160
|
+
clock: {message: "Use for 'clock: true' = 'androidShowWhen' and clock: 'chronometer' = 'androidUsesChronometer'", since: "1.1.0"},
|
|
161
|
+
color: {newPropertyKey: 'androidColor', since: "1.1.0"},
|
|
162
|
+
description: {newPropertyKey: 'androidChannelDescription', since: "1.1.0"},
|
|
163
|
+
defaults: {newPropertyKey: 'androidDefaults', since: "1.1.0"},
|
|
164
|
+
foreground: {newPropertyKey: 'iOSForeground', since: "1.1.0"},
|
|
165
|
+
group: {newPropertyKey: 'androidGroup', since: "1.1.0"},
|
|
166
|
+
groupSummary: {newPropertyKey: 'androidGroupSummary', since: "1.1.0"},
|
|
167
|
+
icon: {newPropertyKey: 'androidLargeIcon', since: "1.1.0"},
|
|
168
|
+
iconType: {renanewPropertyKeymedTo: 'androidLargeIconType', since: "1.1.0"},
|
|
169
|
+
importance: {newPropertyKey: 'androidChannelImportance', since: "1.1.0"},
|
|
170
|
+
lockscreen: {newPropertyKey: 'androidLockscreen', since: "1.1.0"},
|
|
171
|
+
mediaSession: {removed: true, since: "1.1.0", additionalMessage: "Not supported anymore."},
|
|
172
|
+
onlyAlertOnce: {newPropertyKey: 'androidOnlyAlertOnce', since: "1.1.0"},
|
|
173
|
+
prio: {additionalMessage: 'Use androidChannelImportance, androidAlarmType and androidAllowWhileIdle instead.', since: "1.1.0"},
|
|
174
|
+
priority: {additionalMessage: 'Use androidChannelImportance, androidAlarmType and androidAllowWhileIdle instead.', since: "1.1.0"},
|
|
175
|
+
progressBar: {newPropertyKey: 'androidProgressBar', since: "1.1.0"},
|
|
176
|
+
smallIcon: {newPropertyKey: 'androidSmallIcon', since: "1.1.0"},
|
|
177
|
+
soundUsage: {newPropertyKey: 'androidChannelSoundUsage', since: "1.1.0"},
|
|
178
|
+
sticky: {newPropertyKey: 'androidOngoing', since: "1.1.0"},
|
|
179
|
+
ongoing: {newPropertyKey: 'androidOngoing', since: "1.1.0"},
|
|
180
|
+
summary: {newPropertyKey: 'androidSummary', since: "1.1.0"},
|
|
181
|
+
timeoutAfter: {newPropertyKey: 'androidTimeoutAfter', since: "1.1.0"},
|
|
182
|
+
titleCount: {newPropertyKey: 'androidTitleCount', since: "1.1.0"},
|
|
183
|
+
vibrate: {newPropertyKey: 'androidChannelEnableVibration', since: "1.1.1"},
|
|
184
|
+
wakeup: {newPropertyKey: 'androidWakeUpScreen', since: "1.1.0"},
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Setting some things before 'deviceready' event has fired.
|
|
189
|
+
*/
|
|
190
|
+
channel.onCordovaReady.subscribe(function () {
|
|
191
|
+
channel.onCordovaInfoReady.subscribe(function () {
|
|
192
|
+
console.log("LocalNotification: onCordovaInfoReady");
|
|
193
|
+
|
|
194
|
+
// Set defaults
|
|
195
|
+
// To be compatible with Android 7 and a not updated WebView,
|
|
196
|
+
// Object.assign is used instead of a spread ... in object literals
|
|
197
|
+
exports._defaults = Object.assign(
|
|
198
|
+
{},
|
|
199
|
+
exports._commonOptions,
|
|
200
|
+
// Platform specific defaults
|
|
201
|
+
(device.platform == 'Android' ? exports._androidSpecificOptions : exports._iOSSpecificOptions)
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
exports._setLaunchDetails();
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// Called after 'deviceready' event
|
|
209
|
+
channel.deviceready.subscribe(function () {
|
|
210
|
+
console.log("LocalNotification: deviceready");
|
|
211
|
+
if (!window.skipLocalNotificationReady) {
|
|
212
|
+
exports.fireQueuedEvents();
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Set the launch details if the app was launched by clicking on a toast.
|
|
218
|
+
*/
|
|
219
|
+
exports._setLaunchDetails = function () {
|
|
220
|
+
exports._exec('launch', null, function (details) {
|
|
221
|
+
if (details) {
|
|
222
|
+
exports.launchDetails = details;
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* ====================
|
|
229
|
+
* Plugin methods
|
|
230
|
+
* ====================
|
|
231
|
+
**/
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Fire queued events once the device is ready and all listeners are registered.
|
|
235
|
+
*/
|
|
236
|
+
exports.fireQueuedEvents = function() {
|
|
237
|
+
exports._exec('ready');
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// Event listeners
|
|
241
|
+
// For an event, multiple listeners can be added.
|
|
242
|
+
exports._listeners = {};
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Overwrite default settings.
|
|
246
|
+
* @param {Object} newDefaults
|
|
247
|
+
*/
|
|
248
|
+
exports.setDefaults = function (newDefaults) {
|
|
249
|
+
Object.assign(this._defaults, newDefaults);
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Gets the default settings.
|
|
254
|
+
*/
|
|
255
|
+
exports.getDefaults = function () {
|
|
256
|
+
return this._defaults;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Android only: Create notification channel
|
|
261
|
+
* @param {Object} options channel options
|
|
262
|
+
* @param {Function} callback The function to be exec as the callback
|
|
263
|
+
* @param {Object} scope The callback function's scope
|
|
264
|
+
*/
|
|
265
|
+
exports.createChannel = function (options, callback, scope) {
|
|
266
|
+
options = exports._optionsWithDefaults(options)
|
|
267
|
+
exports._prepareOptions(options);
|
|
268
|
+
exports._exec('createChannel', options, callback, scope);
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Android only: Deletes a notification channel.
|
|
273
|
+
* If you create a new channel with this same id, the deleted channel will be un-deleted
|
|
274
|
+
* with all of the same settings it had before it was deleted
|
|
275
|
+
* See: https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#deleteNotificationChannel(java.lang.String)
|
|
276
|
+
*
|
|
277
|
+
* @param {string} channelId Channel ID to delete. Has to be a string like "my_channel_id"
|
|
278
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
279
|
+
* @param {Object} scope The callback function's scope.
|
|
280
|
+
*/
|
|
281
|
+
exports.deleteChannel = function (channelId, callback, scope) {
|
|
282
|
+
exports._exec('deleteChannel', channelId, callback, scope);
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Check permission to show notifications.
|
|
287
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
288
|
+
* @param {Object} scope The callback function's scope.
|
|
289
|
+
*/
|
|
290
|
+
exports.hasPermission = function (callback, scope) {
|
|
291
|
+
exports._exec('hasPermission', null, callback, scope);
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Request permission to show notifications.
|
|
296
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
297
|
+
* @param {Object} scope The callback function's scope.
|
|
298
|
+
*/
|
|
299
|
+
exports.requestPermission = function (callback, scope) {
|
|
300
|
+
console.log("Requesting permission");
|
|
301
|
+
exports._exec('requestPermission', null, callback, scope);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Android only: Check permission to schedule exact alarms.
|
|
306
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
307
|
+
* @param {Object} scope The callback function's scope.
|
|
308
|
+
*/
|
|
309
|
+
exports.canScheduleExactAlarms = function (callback, scope) {
|
|
310
|
+
exports._exec('canScheduleExactAlarms', null, callback, scope);
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Schedule notifications
|
|
315
|
+
* @param {Object|Array} optionsArg The notifications to schedule
|
|
316
|
+
* @param {Function} callback
|
|
317
|
+
* @param {Object} scope The callback function's scope.
|
|
318
|
+
* @param {Object} args Optional, can be {skipPermission: true} to skip the permission check
|
|
319
|
+
*/
|
|
320
|
+
exports.schedule = function (optionsArg, callback, scope, args) {
|
|
321
|
+
let optionsList = exports._toArray(optionsArg);
|
|
322
|
+
|
|
323
|
+
for (let i = 0; i < optionsList.length; i++) {
|
|
324
|
+
let options = exports._optionsWithDefaults(optionsList[i])
|
|
325
|
+
exports._prepareOptions(options);
|
|
326
|
+
// Store back the prepared options
|
|
327
|
+
optionsList[i] = options;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Filter out notifications where the trigger time is in the past
|
|
331
|
+
// On iOS notifications are ignored if the trigger time is in the past, so filter
|
|
332
|
+
// them already here out
|
|
333
|
+
optionsList = optionsList.filter((options) => {
|
|
334
|
+
|
|
335
|
+
// Don't filter out, if trigger.at is not set
|
|
336
|
+
if (!options.trigger || !options.trigger.at) {
|
|
337
|
+
return true;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Calculate difference to now
|
|
341
|
+
const triggerAtDiff = options.trigger.at - new Date().getTime();
|
|
342
|
+
|
|
343
|
+
// Trigger time is in the future don't filter out
|
|
344
|
+
if (triggerAtDiff > 0) return true;
|
|
345
|
+
|
|
346
|
+
// Trigger time is in the past, filter out
|
|
347
|
+
console.warn("Notification trigger time is in the past, ignoring it, options=", JSON.stringify(options));
|
|
348
|
+
|
|
349
|
+
return false;
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// Skip permission check if requested and schedule directly
|
|
353
|
+
if (args && args.skipPermission) {
|
|
354
|
+
console.log("Skip permission check");
|
|
355
|
+
exports._exec('schedule', optionsList, callback, scope);
|
|
356
|
+
|
|
357
|
+
// Ask for permission
|
|
358
|
+
} else {
|
|
359
|
+
exports.requestPermission((granted) => {
|
|
360
|
+
console.log("Permission granted=" + granted);
|
|
361
|
+
|
|
362
|
+
if (!granted) {
|
|
363
|
+
if (callback) callback.call(scope || this, false);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
exports._exec('schedule', optionsList, callback, scope);
|
|
368
|
+
}, this);
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Update notifications
|
|
374
|
+
* @param {Object|Array} options The notifications to update
|
|
375
|
+
* @param {Function} callback
|
|
376
|
+
* @param {Object} scope The callback function's scope.
|
|
377
|
+
* @param {Object} args Optional, can be {skipPermission: true} to skip the permission check
|
|
378
|
+
*/
|
|
379
|
+
exports.update = function (options, callback, scope, args) {
|
|
380
|
+
const optionsList = exports._toArray(options);
|
|
381
|
+
|
|
382
|
+
for (const options of optionsList) {
|
|
383
|
+
// Correct renamed properties and don't merge defaults
|
|
384
|
+
// The defaults are not merged, because otherwise, some values
|
|
385
|
+
// could be set back to a default value
|
|
386
|
+
exports._prepareOptions(options);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Skip permission check if requested and update directly
|
|
390
|
+
if (args && args.skipPermission) {
|
|
391
|
+
exports._exec('update', optionsList, callback, scope);
|
|
392
|
+
|
|
393
|
+
// Ask for permission
|
|
394
|
+
} else {
|
|
395
|
+
exports.requestPermission((granted) => {
|
|
396
|
+
if (!granted) {
|
|
397
|
+
if (callback) callback.call(scope || this, false);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
exports._exec('update', optionsList, callback, scope);
|
|
402
|
+
}, this);
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Clear one or multiple notifications by id/ids
|
|
408
|
+
* @param {Array<number>|number} ids One Id or an array of Ids
|
|
409
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
410
|
+
* @param {Object} scope The callback function's scope.
|
|
411
|
+
*/
|
|
412
|
+
exports.clear = function (ids, callback, scope) {
|
|
413
|
+
exports._exec('clear', exports._convertIdsToNumbers(ids), callback, scope);
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Clear all triggered notifications.
|
|
418
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
419
|
+
* @param {Object} scope The callback function's scope.
|
|
420
|
+
*/
|
|
421
|
+
exports.clearAll = function (callback, scope) {
|
|
422
|
+
exports._exec('clearAll', null, callback, scope);
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Clear one or multiple notifications by id/ids
|
|
427
|
+
* @param {Array<number>|number} ids One Id or an array of Ids
|
|
428
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
429
|
+
* @param {Object} scope The callback function's scope.
|
|
430
|
+
*/
|
|
431
|
+
exports.cancel = function (ids, callback, scope) {
|
|
432
|
+
exports._exec('cancel', exports._convertIdsToNumbers(ids), callback, scope);
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Cancel all scheduled notifications.
|
|
437
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
438
|
+
* @param {Object} scope The callback function's scope.
|
|
439
|
+
*/
|
|
440
|
+
exports.cancelAll = function (callback, scope) {
|
|
441
|
+
exports._exec('cancelAll', null, callback, scope);
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Check if a notification is present.
|
|
446
|
+
* @param {number} id The ID of the notification.
|
|
447
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
448
|
+
* @param {Object} scope The callback function's scope.
|
|
449
|
+
*/
|
|
450
|
+
exports.isPresent = function (id, callback, scope) {
|
|
451
|
+
exports.getType(id, function (type) {
|
|
452
|
+
exports._callbackWithScope(callback, scope)(type != 'unknown');
|
|
453
|
+
});
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Check if a notification is scheduled.
|
|
458
|
+
* @param {Int} id The ID of the notification.
|
|
459
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
460
|
+
* @param {Object} scope The callback function's scope.
|
|
461
|
+
*/
|
|
462
|
+
exports.isScheduled = function (id, callback, scope) {
|
|
463
|
+
exports.hasType(id, 'scheduled', callback, scope);
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Check if a notification was triggered.
|
|
468
|
+
* @param {Int} id The ID of the notification.
|
|
469
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
470
|
+
* @param {Object} scope The callback function's scope.
|
|
471
|
+
*/
|
|
472
|
+
exports.isTriggered = function (id, callback, scope) {
|
|
473
|
+
exports.hasType(id, 'triggered', callback, scope);
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Check if a notification has a given type.
|
|
478
|
+
* @param {number} id The ID of the notification.
|
|
479
|
+
* @param {string} type The type of the notification.
|
|
480
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
481
|
+
* @param {Object} scope The callback function's scope.
|
|
482
|
+
*/
|
|
483
|
+
exports.hasType = function (id, type, callback, scope) {
|
|
484
|
+
exports.getType(id, function (type2) {
|
|
485
|
+
exports._callbackWithScope(callback, scope)(type == type2);
|
|
486
|
+
});
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Get the type (triggered, scheduled) for the notification.
|
|
491
|
+
* @param {number} id The ID of the notification.
|
|
492
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
493
|
+
* @param {Object} scope The callback function's scope.
|
|
494
|
+
*/
|
|
495
|
+
exports.getType = function (id, callback, scope) {
|
|
496
|
+
exports._exec('type', id, callback, scope);
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* List of all notification ids.
|
|
501
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
502
|
+
* @param {Object} scope The callback function's scope.
|
|
503
|
+
*/
|
|
504
|
+
exports.getIds = function (callback, scope) {
|
|
505
|
+
exports._exec('ids', 0, callback, scope);
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* List of all scheduled notification IDs.
|
|
510
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
511
|
+
* @param {Object} scope The callback function's scope.
|
|
512
|
+
*/
|
|
513
|
+
exports.getScheduledIds = function (callback, scope) {
|
|
514
|
+
exports._exec('ids', 1, callback, scope);
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* List of all triggered notification IDs.
|
|
519
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
520
|
+
* @param {Object} scope The callback function's scope.
|
|
521
|
+
*/
|
|
522
|
+
exports.getTriggeredIds = function (callback, scope) {
|
|
523
|
+
exports._exec('ids', 2, callback, scope);
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* List of local notifications specified by id.
|
|
528
|
+
* If called without IDs, all notification will be returned.
|
|
529
|
+
*
|
|
530
|
+
* @param [ Array<Int> ] ids The IDs of the notifications.
|
|
531
|
+
* @param [ Function ] callback The function to be exec as the callback.
|
|
532
|
+
* @param [ Object ] scope The callback function's scope.
|
|
533
|
+
*
|
|
534
|
+
* @return [ Void ]
|
|
535
|
+
*/
|
|
536
|
+
exports.get = function () {
|
|
537
|
+
var args = Array.apply(null, arguments);
|
|
538
|
+
|
|
539
|
+
if (typeof args[0] == 'function') {
|
|
540
|
+
args.unshift([]);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
var ids = args[0], callback = args[1], scope = args[2];
|
|
544
|
+
|
|
545
|
+
if (!Array.isArray(ids)) {
|
|
546
|
+
this._exec('notification', Number(ids), callback, scope);
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
this._exec('notifications', [3, exports._convertIdsToNumbers(ids)], callback, scope);
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* List for all notifications.
|
|
555
|
+
*
|
|
556
|
+
* @param [ Function ] callback The function to be exec as the callback.
|
|
557
|
+
* @param [ Object ] scope The callback function's scope.
|
|
558
|
+
*
|
|
559
|
+
* @return [ Void ]
|
|
560
|
+
*/
|
|
561
|
+
exports.getAll = function (callback, scope) {
|
|
562
|
+
this._exec('notifications', 0, callback, scope);
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* List of all scheduled notifications.
|
|
567
|
+
*
|
|
568
|
+
* @param [ Function ] callback The function to be exec as the callback.
|
|
569
|
+
* @param [ Object ] scope The callback function's scope.
|
|
570
|
+
*/
|
|
571
|
+
exports.getScheduled = function (callback, scope) {
|
|
572
|
+
this._exec('notifications', 1, callback, scope);
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* List of all triggered notifications.
|
|
577
|
+
*
|
|
578
|
+
* @param [ Function ] callback The function to be exec as the callback.
|
|
579
|
+
* @param [ Object ] scope The callback function's scope.
|
|
580
|
+
*/
|
|
581
|
+
exports.getTriggered = function (callback, scope) {
|
|
582
|
+
this._exec('notifications', 2, callback, scope);
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Adds an action group with actions.
|
|
587
|
+
* @param {string} actionsGroupId
|
|
588
|
+
* @param {Array} actions The actions to add for the groupId
|
|
589
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
590
|
+
* @param {Object} scope The callback function's scope.
|
|
591
|
+
*/
|
|
592
|
+
exports.addActions = function (actionsGroupId, actions, callback, scope) {
|
|
593
|
+
this._exec('actions', [0, actionsGroupId, actions], callback, scope);
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Remove an actions group.
|
|
598
|
+
* @param {string} actionsGroupId
|
|
599
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
600
|
+
* @param {Object} scope The callback function's scope.
|
|
601
|
+
*/
|
|
602
|
+
exports.removeActions = function (actionsGroupId, callback, scope) {
|
|
603
|
+
this._exec('actions', [1, actionsGroupId], callback, scope);
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Check if a group of actions is defined.
|
|
608
|
+
* @param {string} actionsGroupId
|
|
609
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
610
|
+
* @param {Object} scope The callback function's scope.
|
|
611
|
+
*/
|
|
612
|
+
exports.hasActions = function (actionsGroupId, callback, scope) {
|
|
613
|
+
this._exec('actions', [2, actionsGroupId], callback, scope);
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Open native settings to enable notifications.
|
|
618
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
619
|
+
* @param {Object} scope The callback function's scope.
|
|
620
|
+
*/
|
|
621
|
+
exports.openNotificationSettings = function (callback, scope) {
|
|
622
|
+
this._exec('openNotificationSettings', null, callback, scope);
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Android only: Open native settings to enable alarms & reminders.
|
|
627
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
628
|
+
* @param {Object} scope The callback function's scope.
|
|
629
|
+
*/
|
|
630
|
+
exports.openAlarmSettings = function (callback, scope) {
|
|
631
|
+
this._exec('openAlarmSettings', null, callback, scope);
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* iOS only: Clear the badge of the app icon.
|
|
636
|
+
* @param {Function} callback
|
|
637
|
+
* @param {Object} scope
|
|
638
|
+
*/
|
|
639
|
+
exports.iOSClearBadge = function (callback, scope) {
|
|
640
|
+
this._exec('clearBadge', null, callback, scope);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Android only: Returns the status of Unused App Restrictions.
|
|
645
|
+
* @param {Function} successCallback The function to be exec as the callback.
|
|
646
|
+
* @param {Object} scope The callback function's scope.
|
|
647
|
+
*/
|
|
648
|
+
exports.getUnusedAppRestrictionsStatus = function (successCallback, scope) {
|
|
649
|
+
exports._exec('getUnusedAppRestrictionsStatus', null, successCallback, scope);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Android only: Redirects the user to manage their unused app restriction settings.
|
|
654
|
+
* @param {Function} successCallback The function to be exec as the callback.
|
|
655
|
+
* @param {Object} scope The callback function's scope.
|
|
656
|
+
*/
|
|
657
|
+
exports.openManageUnusedAppRestrictions = function (successCallback, scope) {
|
|
658
|
+
exports._exec('openManageUnusedAppRestrictions', null, successCallback, scope);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Register callback for a given event.
|
|
663
|
+
* @param {string} event The name of the event.
|
|
664
|
+
* @param {Function|string} callback The function to be exec as callback or the
|
|
665
|
+
* method name on the scope, which should be called.
|
|
666
|
+
* @param {Object} scope The callback function's scope.
|
|
667
|
+
*/
|
|
668
|
+
exports.on = function (event, callback, scope) {
|
|
669
|
+
// If callback is a string, a method on the scope schould be called
|
|
670
|
+
if (typeof callback !== 'function' && typeof callback !== 'string') return;
|
|
671
|
+
|
|
672
|
+
// Create empty array, if there are no listeners already
|
|
673
|
+
if (!this._listeners[event]) this._listeners[event] = [];
|
|
674
|
+
|
|
675
|
+
this._listeners[event].push([callback, scope || window]);
|
|
676
|
+
};
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Unregister callback for given event
|
|
680
|
+
* @param {string} event The name of the event
|
|
681
|
+
* @param {Function|string} callback Callback or method name for the scope, which should be unregistered
|
|
682
|
+
*/
|
|
683
|
+
exports.un = function (event, callback) {
|
|
684
|
+
// No listeners added to this event
|
|
685
|
+
if (!this._listeners[event]) return;
|
|
686
|
+
// Remove all listeners by callback or method name
|
|
687
|
+
this._listeners[event] = this._listeners[event].filter((listener) => listener[0] != callback);
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Fire the event with given arguments.
|
|
692
|
+
* @param {string} event The event's name.
|
|
693
|
+
* @param {...Object} args The callback's arguments. The first element, can be the options of a notification.
|
|
694
|
+
*/
|
|
695
|
+
exports.fireEvent = function (event, ...args) {
|
|
696
|
+
// No listeners added for this event
|
|
697
|
+
if (!this._listeners[event]) return;
|
|
698
|
+
|
|
699
|
+
// Convert custom notification data to object
|
|
700
|
+
if (args[0] && typeof args[0].data === 'string') {
|
|
701
|
+
args[0].data = JSON.parse(args[0].data);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
for (const listener of this._listeners[event]) {
|
|
705
|
+
const callback = listener[0];
|
|
706
|
+
const scope = listener[1];
|
|
707
|
+
|
|
708
|
+
// If callback is a string, a method on the scope schould be called
|
|
709
|
+
if (typeof callback === 'string') callback = scope[callback];
|
|
710
|
+
|
|
711
|
+
callback.apply(scope, args);
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Helper method to return the key for a value in an object.
|
|
717
|
+
* @param {Object} object
|
|
718
|
+
* @param {*} value
|
|
719
|
+
* @returns {string} The key of the value in the object or {@link undefined} if not found.
|
|
720
|
+
*/
|
|
721
|
+
exports.getKey = function (object, value) {
|
|
722
|
+
return Object.keys(object).find(key => object[key] === value);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* ====================
|
|
727
|
+
* Internal JS Methods for handling options etc.
|
|
728
|
+
* ====================
|
|
729
|
+
**/
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Adds defaults to options if not present.
|
|
733
|
+
* This will not merge options objects like trigger.
|
|
734
|
+
* They will just be overwritten by the user options and not merged.
|
|
735
|
+
* @param {*} options
|
|
736
|
+
* @returns {Object} User options with defaults
|
|
737
|
+
*/
|
|
738
|
+
exports._optionsWithDefaults = function (options) {
|
|
739
|
+
// Create a deep copy of defaults, so objects like trigger
|
|
740
|
+
// are copied and not referenced and changes on them would
|
|
741
|
+
// not impact the defaults
|
|
742
|
+
// To be compatible with Android 7 and a not updated WebView,
|
|
743
|
+
// Object.assign is used instead of a spread ... in object literals
|
|
744
|
+
return Object.assign({}, exports._deepCopy(exports._defaults), options)
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* - Correct renamed properties
|
|
749
|
+
* - Correct options to their required type
|
|
750
|
+
* - Warn about wrong smallIcon uri
|
|
751
|
+
* - Log unknown and deprecated properties
|
|
752
|
+
* - Remove null values, because of a Android bug
|
|
753
|
+
* @param {Object} options The options to convert
|
|
754
|
+
*/
|
|
755
|
+
exports._prepareOptions = function (options) {
|
|
756
|
+
exports._handleDeprecatedProperties(options)
|
|
757
|
+
|
|
758
|
+
// Convert custom data to string
|
|
759
|
+
options.data = JSON.stringify(options.data)
|
|
760
|
+
|
|
761
|
+
// No auto cancelling, if the notification is ongoing
|
|
762
|
+
if (options.androidOngoing) options.androidAutoCancel = false
|
|
763
|
+
|
|
764
|
+
exports._prepareTrigger(options);
|
|
765
|
+
exports._prepareActions(options);
|
|
766
|
+
exports._prepareAndroidProgressBar(options);
|
|
767
|
+
|
|
768
|
+
// Convert Enums
|
|
769
|
+
// Android: alarmType string to integer
|
|
770
|
+
if (typeof options.androidAlarmType === 'string') {
|
|
771
|
+
options.androidAlarmType = exports._androidAlarmTypes[options.androidAlarmType]
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// Android: channelImportance string to integer
|
|
775
|
+
if (typeof options.androidChannelImportance === 'string') {
|
|
776
|
+
options.androidChannelImportance = exports._androidChannelImportanceTypes[options.androidChannelImportance]
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
// Due to a Android bug, null values have to be removed
|
|
780
|
+
exports._removeNullValues(options);
|
|
781
|
+
exports._logUnknownProperties(options);
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Corrects renamed properties since Plugin version 1.1.0
|
|
786
|
+
* @param {Oject} options
|
|
787
|
+
*/
|
|
788
|
+
exports._handleDeprecatedProperties = function (options) {
|
|
789
|
+
if (device.platform == "Android") {
|
|
790
|
+
|
|
791
|
+
// text as Array to androidMessages, since 1.1.0
|
|
792
|
+
if (Array.isArray(options.text)) {
|
|
793
|
+
options.androidMessages = options.text
|
|
794
|
+
console.log("Property 'text' as array is deprecated since version 1.1.0. Use 'androidMessages' instead.")
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// clock: boolean to androidShowWhen: boolean, since 1.1.0
|
|
798
|
+
if (typeof options.clock === 'boolean') {
|
|
799
|
+
options.androidShowWhen = options.clock
|
|
800
|
+
console.log("Property 'clock: boolean' is deprecated since version 1.1.0. Use 'androidShowWhen: boolean' instead.")
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// "clock: 'chronometer'" to androidUsesChronometer: true, since 1.1.0
|
|
804
|
+
if (options.clock == "chronometer") {
|
|
805
|
+
options.androidUsesChronometer = true
|
|
806
|
+
console.log("Property 'clock: 'chronometer'' is deprecated since version 1.1.0. Use 'androidUsesChronometer: true' instead.")
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
// led replaced by androidChannelEnableLights, since Android 8
|
|
810
|
+
if (options.led) options.androidChannelEnableLights = true
|
|
811
|
+
|
|
812
|
+
// priority changed to androidChannelImportance, androidAlarmType and androidAllowWhileIdle
|
|
813
|
+
this._androidHandleOldPropertyPriority(options)
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// sound: true changed to sound: "default", since 1.1.0
|
|
817
|
+
if (options.sound === true) {
|
|
818
|
+
options.sound = "default"
|
|
819
|
+
console.log(`Property "sound: true" is deprecated since version 1.1.0. Use "sound: 'default'" instead.`)
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
// sound: false changed to sound: null, since 1.1.0
|
|
823
|
+
if (options.sound === false) {
|
|
824
|
+
options.sound = null
|
|
825
|
+
console.log(`Property "sound: false" is deprecated since version 1.1.0. Use "sound: null" instead`)
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// Handle renamed and removed properties
|
|
829
|
+
// Log deprecated properties
|
|
830
|
+
for (const key in options) {
|
|
831
|
+
|
|
832
|
+
// Check if the property is deprecated
|
|
833
|
+
const deprecatedProperty = this._deprecatedProperties[key];
|
|
834
|
+
|
|
835
|
+
// Property not deprecated
|
|
836
|
+
if (!deprecatedProperty) continue
|
|
837
|
+
|
|
838
|
+
let message;
|
|
839
|
+
|
|
840
|
+
// Check if propert is renamed
|
|
841
|
+
if (deprecatedProperty.newPropertyKey) {
|
|
842
|
+
message = `Use "${deprecatedProperty.newPropertyKey}" instead.`
|
|
843
|
+
// Set deprecated property value to new property
|
|
844
|
+
options[deprecatedProperty.newPropertyKey] = options[key]
|
|
845
|
+
|
|
846
|
+
// Property was removed
|
|
847
|
+
} else if (deprecatedProperty.removed) {
|
|
848
|
+
message = `Property removed`
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
if (deprecatedProperty.additionalMessage) {
|
|
852
|
+
message += ` ${deprecatedProperty.additionalMessage}`
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
console.warn(`Property "${key}" is deprecated since version ${deprecatedProperty.since}. ${message}`)
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* Android: Backward compatibility for property priority.
|
|
861
|
+
* Replaced by androidChannelImportance, androidAlarmType and androidAllowWhileIdle
|
|
862
|
+
* Removed in plugin version 1.1.0
|
|
863
|
+
* If priority is present, it will set androidAlarmType and androidAllowWhileIdle, but not androidChannelImportance.
|
|
864
|
+
* @param {Object} options
|
|
865
|
+
*/
|
|
866
|
+
exports._androidHandleOldPropertyPriority = function (options) {
|
|
867
|
+
let priority = options.priority || options.prio;
|
|
868
|
+
|
|
869
|
+
// Old property not found
|
|
870
|
+
if (priority === undefined) return
|
|
871
|
+
|
|
872
|
+
if (typeof priority === 'string') {
|
|
873
|
+
priority = { min: -2, low: -1, high: 1, max: 2 }[priority] || 0;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
if (options.foreground === true) {
|
|
877
|
+
priority = Math.max(priority, 1);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
if (options.foreground === false) {
|
|
881
|
+
priority = Math.min(priority, 0);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// PRIORITY_MIN and PRIORITY_LOW
|
|
885
|
+
if (priority < 0) {
|
|
886
|
+
options.androidAlarmType = "RTC"
|
|
887
|
+
options.androidAllowWhileIdle = false
|
|
888
|
+
|
|
889
|
+
// PRIORITY_DEFAULT and PRIORITY_HIGH
|
|
890
|
+
} else if (priority < 2) {
|
|
891
|
+
options.androidAlarmType = "RTC_WAKEUP"
|
|
892
|
+
options.androidAllowWhileIdle = false
|
|
893
|
+
|
|
894
|
+
// PRIORITY_MAX
|
|
895
|
+
} else {
|
|
896
|
+
options.androidAlarmType = "RTC_WAKEUP"
|
|
897
|
+
options.androidAllowWhileIdle = true
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
options.priority = priority;
|
|
901
|
+
};
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* Convert the passed values to their required type, modifying them
|
|
905
|
+
* directly for Android and passing the converted list back for iOS.
|
|
906
|
+
*
|
|
907
|
+
* @param [ Map ] options Set of custom values.
|
|
908
|
+
*
|
|
909
|
+
* @return [ Map ] Interaction object with category & actions.
|
|
910
|
+
*/
|
|
911
|
+
exports._prepareActions = function (options) {
|
|
912
|
+
// options.actions is a string or not set
|
|
913
|
+
if (!options.actions || typeof options.actions === 'string') return options;
|
|
914
|
+
|
|
915
|
+
let actions = [];
|
|
916
|
+
|
|
917
|
+
for (const action of options.actions) {
|
|
918
|
+
if (!action.id) {
|
|
919
|
+
console.warn('Action with title ' + action.title + ' ' +
|
|
920
|
+
'has no id and will not be added.');
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
action.id = action.id.toString();
|
|
925
|
+
actions.push(action);
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
options.actions = actions;
|
|
929
|
+
|
|
930
|
+
return options;
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
/**
|
|
934
|
+
* Convert the passed values for the trigger to their required type.
|
|
935
|
+
* @param {Object} options
|
|
936
|
+
* @return {Object} Converted options
|
|
937
|
+
*/
|
|
938
|
+
exports._prepareTrigger = function (options) {
|
|
939
|
+
let trigger = options.trigger || {};
|
|
940
|
+
|
|
941
|
+
// Set trigger type
|
|
942
|
+
if (!trigger.type) trigger.type = trigger.center ? "location" : "calendar";
|
|
943
|
+
|
|
944
|
+
if (trigger.type == "calendar") {
|
|
945
|
+
// Set default trigger time at now if nothing is set
|
|
946
|
+
if (!trigger.at && !trigger.in && !trigger.every) trigger.at = new Date().getTime();
|
|
947
|
+
|
|
948
|
+
// Convert dates to numbers
|
|
949
|
+
if (trigger.at) trigger.at = exports._dateToNumber(trigger.at);
|
|
950
|
+
if (trigger.firstAt) trigger.firstAt = exports._dateToNumber(trigger.firstAt);
|
|
951
|
+
if (trigger.before) trigger.before = exports._dateToNumber(trigger.before);
|
|
952
|
+
if (trigger.after) trigger.after = exports._dateToNumber(trigger.after);
|
|
953
|
+
|
|
954
|
+
// On iOS notifications will be ignored if the trigger time is in the past
|
|
955
|
+
// Correct trigger.at if trigger time is maximum 5 seconds in the past
|
|
956
|
+
if (trigger.at) {
|
|
957
|
+
// Calculate the difference to now
|
|
958
|
+
const triggerAtDiff = trigger.at - new Date().getTime();
|
|
959
|
+
|
|
960
|
+
// Only correct if maximum 5 seconds in the past
|
|
961
|
+
if (triggerAtDiff > -5000 && triggerAtDiff <= 0) {
|
|
962
|
+
// Set it a little bit in the future so it will be definitely triggered
|
|
963
|
+
trigger.at = new Date().getTime() + 5000;
|
|
964
|
+
console.log("Correct trigger.at 5 seconds in the future because it was a bit in the past, new trigger.at=" + trigger.at);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// Warning that trigger.count is not supported on iOS
|
|
969
|
+
if (device.platform == 'iOS' && trigger.count) {
|
|
970
|
+
console.warn('trigger.count is not supported on iOS.');
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
// Location trigger, set defaults
|
|
974
|
+
} else {
|
|
975
|
+
trigger.notifyOnEntry = !!trigger.notifyOnEntry;
|
|
976
|
+
trigger.notifyOnExit = trigger.notifyOnExit === true;
|
|
977
|
+
trigger.radius = trigger.radius || 5;
|
|
978
|
+
trigger.single = !!trigger.single;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
options.trigger = trigger;
|
|
982
|
+
|
|
983
|
+
return options;
|
|
984
|
+
};
|
|
985
|
+
|
|
986
|
+
/**
|
|
987
|
+
* Convert the passed values for the progressBar to their required type.
|
|
988
|
+
* @param {Object} options
|
|
989
|
+
*/
|
|
990
|
+
exports._prepareAndroidProgressBar = function (options) {
|
|
991
|
+
if (!options.androidProgressBar) return
|
|
992
|
+
|
|
993
|
+
let progressBar = options.androidProgressBar
|
|
994
|
+
progressBar.value = progressBar.value || 0;
|
|
995
|
+
progressBar.maxValue = progressBar.maxValue || 100;
|
|
996
|
+
progressBar.indeterminate = progressBar.indeterminate || false;
|
|
997
|
+
|
|
998
|
+
// Show the Notification#when field as a stopwatch
|
|
999
|
+
if (options.androidShowWhen) options.androidUsesChronometer = true;
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1002
|
+
/**
|
|
1003
|
+
* On Android exists the bug, that when using JSONObject.optString("key", null),
|
|
1004
|
+
* it will return "NULL" as string and not plain null. This function removes
|
|
1005
|
+
* all null values, to workaround this. If this is also a problem on iOS, is not known.
|
|
1006
|
+
*
|
|
1007
|
+
* See: https://stackoverflow.com/questions/18226288/json-jsonobject-optstring-returns-string-null
|
|
1008
|
+
* @param {Object} options
|
|
1009
|
+
*/
|
|
1010
|
+
exports._removeNullValues = function (options) {
|
|
1011
|
+
for (const key in options) {
|
|
1012
|
+
if (options[key] === null) delete options[key];
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
/**
|
|
1017
|
+
* Warns about unknown properties in options
|
|
1018
|
+
* @param {Object} options
|
|
1019
|
+
*/
|
|
1020
|
+
exports._logUnknownProperties = function (options) {
|
|
1021
|
+
for (const key in options) {
|
|
1022
|
+
// Check if property is missing in defaults and is not a deprecated property
|
|
1023
|
+
if (this._defaults[key] === undefined && this._deprecatedProperties[key] === undefined) {
|
|
1024
|
+
console.warn('Unknown property: ' + key);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
/**
|
|
1030
|
+
* Create a callback function to get executed within a specific scope.
|
|
1031
|
+
*
|
|
1032
|
+
* @param {Function} callback The function to be exec as the callback.
|
|
1033
|
+
* @param {Object} scope The callback function's scope.
|
|
1034
|
+
* @return {Function} The callback function.
|
|
1035
|
+
*/
|
|
1036
|
+
exports._callbackWithScope = function (callback, scope) {
|
|
1037
|
+
if (typeof callback != 'function') return;
|
|
1038
|
+
|
|
1039
|
+
return function () {
|
|
1040
|
+
callback.apply(scope || this, arguments);
|
|
1041
|
+
};
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* Convert the IDs to numbers.
|
|
1046
|
+
* @param {Array|Object} ids Will be turned into an array, if it's not already.
|
|
1047
|
+
* @return {Array<Number>}
|
|
1048
|
+
*/
|
|
1049
|
+
exports._convertIdsToNumbers = function (ids) {
|
|
1050
|
+
return exports._toArray(ids).map((id) => Number(id))
|
|
1051
|
+
};
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* Execute the native counterpart.
|
|
1055
|
+
*
|
|
1056
|
+
* @param [ String ] action The name of the action.
|
|
1057
|
+
* @param [ Array ] args Array of arguments.
|
|
1058
|
+
* @param [ Function] callback The callback function.
|
|
1059
|
+
* @param [ Object ] scope The scope for the function.
|
|
1060
|
+
*
|
|
1061
|
+
* @return [ Void ]
|
|
1062
|
+
*/
|
|
1063
|
+
exports._exec = function (action, options, callback, scope) {
|
|
1064
|
+
exec(
|
|
1065
|
+
exports._callbackWithScope(callback, scope),
|
|
1066
|
+
null,
|
|
1067
|
+
'LocalNotification',
|
|
1068
|
+
action,
|
|
1069
|
+
// Convert options to array, if not already
|
|
1070
|
+
options === null ? [] : this._toArray(options)
|
|
1071
|
+
);
|
|
1072
|
+
};
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* First found value for the given keys.
|
|
1076
|
+
* @param {Object} options
|
|
1077
|
+
* @param {...string} findkeys Keys to find
|
|
1078
|
+
* @returns {*|void} The first found value or undefined
|
|
1079
|
+
*/
|
|
1080
|
+
exports._getValueFor = function (options, ...findKeys) {
|
|
1081
|
+
for (const findKey of findKeys) {
|
|
1082
|
+
if (options.hasOwnProperty(findKey)) return options[findKey];
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
return undefined;
|
|
1086
|
+
};
|
|
1087
|
+
|
|
1088
|
+
/**
|
|
1089
|
+
* Convert a value to an array, if it is not already an array.
|
|
1090
|
+
*
|
|
1091
|
+
* @param {Object|Array} object Any kind of object, or an array.
|
|
1092
|
+
* @return {Array} An array with the object as first item or the object itself, if it's already an array.
|
|
1093
|
+
*/
|
|
1094
|
+
exports._toArray = function (object) {
|
|
1095
|
+
return Array.isArray(object) ? object : [object];
|
|
1096
|
+
};
|
|
1097
|
+
|
|
1098
|
+
exports._deepCopy = function (object) {
|
|
1099
|
+
return JSON.parse(JSON.stringify(object));
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1102
|
+
exports._dateToNumber = function (date) {
|
|
1103
|
+
return date instanceof Date ? date.getTime() : date;
|
|
1104
|
+
};
|