html2apk 0.3.0 → 0.5.0

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.
@@ -0,0 +1,28 @@
1
+ package dev.html2apk.bridge;
2
+
3
+ import android.content.BroadcastReceiver;
4
+ import android.content.Context;
5
+ import android.content.Intent;
6
+
7
+ import androidx.core.app.NotificationManagerCompat;
8
+
9
+ import org.json.JSONObject;
10
+
11
+ public class NotificationClickReceiver extends BroadcastReceiver {
12
+ @Override
13
+ public void onReceive(Context context, Intent intent) {
14
+ if (intent == null || !intent.getBooleanExtra(Html2ApkBridge.EXTRA_NOTIFICATION_CLICKED, false)) {
15
+ return;
16
+ }
17
+
18
+ JSONObject detail;
19
+ try {
20
+ detail = new JSONObject(intent.getStringExtra(Html2ApkBridge.EXTRA_NOTIFICATION_DETAIL));
21
+ } catch (Exception ignored) {
22
+ detail = new JSONObject();
23
+ }
24
+
25
+ Html2ApkBridge.handleNotificationClickBroadcast(context, detail);
26
+ NotificationManagerCompat.from(context).cancel(detail.optInt("id", 0));
27
+ }
28
+ }
@@ -58,7 +58,7 @@ public class NotificationReceiver extends BroadcastReceiver {
58
58
  .setContentText(text)
59
59
  .setStyle(new NotificationCompat.BigTextStyle().bigText(text))
60
60
  .setAutoCancel(true)
61
- .setContentIntent(Html2ApkBridge.createContentIntent(context, id, detail))
61
+ .setContentIntent(Html2ApkBridge.createNotificationClickIntent(context, id, detail))
62
62
  .setPriority(NotificationCompat.PRIORITY_DEFAULT);
63
63
 
64
64
  Html2ApkBridge.addNotificationActions(builder, context, id, displayOptions);
@@ -1,12 +1,17 @@
1
1
  "use strict";
2
2
 
3
3
  var exec = require("cordova/exec");
4
+ var channel = require("cordova/channel");
4
5
 
5
6
  var notificationListeners = [];
6
7
  var eventListeners = {};
7
8
  var initialNotification = null;
8
9
  var initialLink = null;
9
10
  var scheduledNotificationCounter = 0;
11
+ var notificationActionCounter = 0;
12
+ var notificationActionCallbacks = {};
13
+ var deviceReady = typeof document === "undefined";
14
+ var deviceReadyCallbacks = [];
10
15
  var eventAliases = {
11
16
  "app:ready": "app:pronto",
12
17
  "app:paused": "app:pausado",
@@ -20,13 +25,212 @@ var eventAliases = {
20
25
  "notification:clicked": "notificacao:clicada"
21
26
  };
22
27
 
28
+ function markDeviceReady() {
29
+ if (deviceReady) {
30
+ return;
31
+ }
32
+
33
+ deviceReady = true;
34
+ deviceReadyCallbacks.splice(0).forEach(function (callback) {
35
+ callback();
36
+ });
37
+ }
38
+
39
+ function whenDeviceReady() {
40
+ if (deviceReady) {
41
+ return Promise.resolve();
42
+ }
43
+
44
+ return new Promise(function (resolve) {
45
+ deviceReadyCallbacks.push(resolve);
46
+ });
47
+ }
48
+
49
+ if (typeof document !== "undefined") {
50
+ document.addEventListener("deviceready", markDeviceReady, false);
51
+ }
52
+
23
53
  function call(action, args) {
54
+ return whenCordovaBridgeReady().then(function () {
55
+ return new Promise(function (resolve, reject) {
56
+ try {
57
+ exec(resolve, reject, "Html2ApkBridge", action, args || []);
58
+ } catch (error) {
59
+ reject(error);
60
+ }
61
+ });
62
+ });
63
+ }
64
+
65
+ function whenCordovaBridgeReady() {
66
+ var timer;
67
+
68
+ if (!channel || !channel.onCordovaReady || channel.onCordovaReady.state === 2) {
69
+ return Promise.resolve();
70
+ }
71
+
24
72
  return new Promise(function (resolve, reject) {
25
- exec(resolve, reject, "Html2ApkBridge", action, args || []);
73
+ timer = setTimeout(function () {
74
+ reject(new Error("html2apk native bridge is not ready. Make sure cordova.js finished loading."));
75
+ }, 10000);
76
+
77
+ channel.onCordovaReady.subscribe(function () {
78
+ clearTimeout(timer);
79
+ resolve();
80
+ });
81
+ });
82
+ }
83
+
84
+ function asyncThrow(error) {
85
+ setTimeout(function () {
86
+ throw error;
87
+ }, 0);
88
+ }
89
+
90
+ function cloneSerializable(value) {
91
+ var output;
92
+
93
+ if (typeof value === "function" || typeof value === "undefined") {
94
+ return undefined;
95
+ }
96
+ if (value === null || typeof value !== "object") {
97
+ return value;
98
+ }
99
+ if (Array.isArray(value)) {
100
+ output = [];
101
+ value.forEach(function (item) {
102
+ var cloned = cloneSerializable(item);
103
+ if (typeof cloned !== "undefined") {
104
+ output.push(cloned);
105
+ }
106
+ });
107
+ return output;
108
+ }
109
+ if (value instanceof Date) {
110
+ return value.toISOString();
111
+ }
112
+
113
+ output = {};
114
+ Object.keys(value).forEach(function (key) {
115
+ var cloned = cloneSerializable(value[key]);
116
+ if (typeof cloned !== "undefined") {
117
+ output[key] = cloned;
118
+ }
119
+ });
120
+ return output;
121
+ }
122
+
123
+ function registerNotificationAction(handler, source) {
124
+ var id = "html2apk-click-" + Date.now() + "-" + (++notificationActionCounter);
125
+ notificationActionCallbacks[id] = function (detail) {
126
+ return handler(detail, source || {});
127
+ };
128
+ return id;
129
+ }
130
+
131
+ function normalizeNotificationClick(click) {
132
+ var normalized;
133
+ var callbackId;
134
+ var actionHandler;
135
+ var functionName;
136
+
137
+ if (typeof click === "function") {
138
+ callbackId = registerNotificationAction(click);
139
+ return {
140
+ action: "run-function",
141
+ acao: "executar-funcao",
142
+ callbackId: callbackId
143
+ };
144
+ }
145
+
146
+ if (!click || typeof click !== "object") {
147
+ return {
148
+ action: "open-app",
149
+ acao: "abrir-app"
150
+ };
151
+ }
152
+
153
+ normalized = cloneSerializable(click) || {};
154
+ actionHandler = click.acao || click.action;
155
+ if (typeof actionHandler === "function") {
156
+ callbackId = registerNotificationAction(actionHandler, click);
157
+ normalized.callbackId = callbackId;
158
+ normalized.action = normalized.action || "run-function";
159
+ normalized.acao = normalized.acao || "executar-funcao";
160
+ }
161
+
162
+ functionName = normalized.funcao || normalized.functionName || normalized.function || normalized.fn || normalized.nomeFuncao;
163
+ if (typeof functionName === "string" && functionName.trim()) {
164
+ normalized.funcao = functionName.trim();
165
+ normalized.functionName = normalized.funcao;
166
+ normalized.action = normalized.action || "run-function";
167
+ normalized.acao = normalized.acao || "executar-funcao";
168
+ }
169
+
170
+ if (normalized.action && !normalized.acao) {
171
+ normalized.acao = normalized.action;
172
+ }
173
+ if (normalized.acao && !normalized.action) {
174
+ normalized.action = normalized.acao;
175
+ }
176
+
177
+ return normalized;
178
+ }
179
+
180
+ function notificationOpenValue(source) {
181
+ if (!source || typeof source !== "object") {
182
+ return undefined;
183
+ }
184
+ if (Object.prototype.hasOwnProperty.call(source, "open")) {
185
+ return source.open !== false;
186
+ }
187
+ if (Object.prototype.hasOwnProperty.call(source, "abrir")) {
188
+ return source.abrir !== false;
189
+ }
190
+ if (Object.prototype.hasOwnProperty.call(source, "abrirApp")) {
191
+ return source.abrirApp !== false;
192
+ }
193
+ if (Object.prototype.hasOwnProperty.call(source, "openApp")) {
194
+ return source.openApp !== false;
195
+ }
196
+ return undefined;
197
+ }
198
+
199
+ function normalizeNotificationActions(actions) {
200
+ if (!Array.isArray(actions)) {
201
+ return actions;
202
+ }
203
+
204
+ return actions.map(function (action) {
205
+ var normalized = cloneSerializable(action) || {};
206
+ var click = action && (action.aoClicar || action.onClick);
207
+ if (!click && action && (
208
+ typeof action.funcao === "string" ||
209
+ typeof action.functionName === "string" ||
210
+ typeof action.fn === "string"
211
+ )) {
212
+ click = action;
213
+ }
214
+ if (click) {
215
+ normalized.aoClicar = normalizeNotificationClick(click);
216
+ normalized.onClick = normalized.aoClicar;
217
+ }
218
+ if (typeof notificationOpenValue(action) !== "undefined") {
219
+ normalized.open = notificationOpenValue(action);
220
+ if (normalized.aoClicar && typeof normalized.aoClicar.open === "undefined") {
221
+ normalized.aoClicar.open = normalized.open;
222
+ normalized.onClick = normalized.aoClicar;
223
+ }
224
+ }
225
+ return normalized;
26
226
  });
27
227
  }
28
228
 
29
229
  function normalizeNotificationOptions(messageOrOptions) {
230
+ var options;
231
+ var click;
232
+ var actions;
233
+
30
234
  if (typeof messageOrOptions === "string") {
31
235
  return {
32
236
  title: "Notificacao",
@@ -37,12 +241,23 @@ function normalizeNotificationOptions(messageOrOptions) {
37
241
  };
38
242
  }
39
243
 
40
- var options = messageOrOptions || {};
41
- if (!options.onClick && !options.aoClicar) {
42
- options.onClick = {
43
- action: "open-app"
44
- };
244
+ options = cloneSerializable(messageOrOptions || {}) || {};
245
+ click = messageOrOptions && (messageOrOptions.aoClicar || messageOrOptions.onClick);
246
+ options.onClick = normalizeNotificationClick(click);
247
+ options.aoClicar = options.onClick;
248
+ if (typeof notificationOpenValue(messageOrOptions) !== "undefined") {
249
+ options.open = notificationOpenValue(messageOrOptions);
250
+ options.abrir = options.open;
251
+ options.onClick.open = options.open;
252
+ options.aoClicar.open = options.open;
253
+ }
254
+
255
+ actions = normalizeNotificationActions(messageOrOptions && (messageOrOptions.acoes || messageOrOptions.actions));
256
+ if (Array.isArray(actions)) {
257
+ options.acoes = actions;
258
+ options.actions = actions;
45
259
  }
260
+
46
261
  return options;
47
262
  }
48
263
 
@@ -154,17 +369,98 @@ function normalizeEventType(type) {
154
369
  }
155
370
 
156
371
  function emitNotificationClick(detail) {
372
+ var notification = detail || null;
157
373
  initialNotification = detail || null;
158
374
 
159
375
  notificationListeners.slice().forEach(function (listener) {
160
376
  try {
161
- listener(initialNotification);
377
+ listener(notification);
162
378
  } catch (error) {
163
- setTimeout(function () {
164
- throw error;
165
- }, 0);
379
+ asyncThrow(error);
166
380
  }
167
381
  });
382
+
383
+ executeNotificationClickAction(notification);
384
+ }
385
+
386
+ function notificationActionFromDetail(detail) {
387
+ var action;
388
+
389
+ if (!detail || typeof detail !== "object") {
390
+ return null;
391
+ }
392
+
393
+ action = detail.action || detail.acao;
394
+ if (action && typeof action === "object") {
395
+ if (action.callbackId || action.functionName || action.funcao || action.fn || action.nomeFuncao) {
396
+ return action;
397
+ }
398
+ if (action.aoClicar || action.onClick) {
399
+ return action.aoClicar || action.onClick;
400
+ }
401
+ }
402
+
403
+ return detail.aoClicar || detail.onClick || null;
404
+ }
405
+
406
+ function notificationActionArgs(action, detail) {
407
+ var args = action && (
408
+ action.argumentos ||
409
+ action.args ||
410
+ action.parametros ||
411
+ action.params ||
412
+ action.parameters
413
+ );
414
+
415
+ if (typeof args === "undefined") {
416
+ return action && (action.passarEvento === false || action.passEvent === false) ? [] : [detail];
417
+ }
418
+
419
+ return Array.isArray(args) ? args : [args];
420
+ }
421
+
422
+ function handleActionResult(result) {
423
+ if (result && typeof result.then === "function") {
424
+ result.catch(asyncThrow);
425
+ }
426
+ }
427
+
428
+ function executeNotificationClickAction(detail) {
429
+ var action = notificationActionFromDetail(detail);
430
+ var callbackId = action && (action.callbackId || action.idCallback || action.callback);
431
+ var functionName;
432
+ var handler;
433
+ var args;
434
+
435
+ if (!action || typeof action !== "object") {
436
+ return;
437
+ }
438
+ if (detail && detail.__html2apkActionHandled) {
439
+ return;
440
+ }
441
+
442
+ if (callbackId && notificationActionCallbacks[callbackId]) {
443
+ detail.__html2apkActionHandled = true;
444
+ handleActionResult(notificationActionCallbacks[callbackId](detail));
445
+ return;
446
+ }
447
+
448
+ functionName = action.funcao || action.functionName || action.function || action.fn || action.nomeFuncao;
449
+ if (!functionName) {
450
+ return;
451
+ }
452
+
453
+ handler = api && api[functionName];
454
+ if (typeof handler !== "function" && typeof window !== "undefined") {
455
+ handler = window[functionName];
456
+ }
457
+ if (typeof handler !== "function") {
458
+ return;
459
+ }
460
+
461
+ args = notificationActionArgs(action, detail);
462
+ detail.__html2apkActionHandled = true;
463
+ handleActionResult(handler.apply(typeof window === "undefined" ? null : window, args));
168
464
  }
169
465
 
170
466
  function emitEvent(type, detail) {