local-notification.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. /*
  2. Copyright 2013-2014 appPlant UG
  3. Licensed to the Apache Software Foundation (ASF) under one
  4. or more contributor license agreements. See the NOTICE file
  5. distributed with this work for additional information
  6. regarding copyright ownership. The ASF licenses this file
  7. to you under the Apache License, Version 2.0 (the
  8. "License"); you may not use this file except in compliance
  9. with the License. You may obtain a copy of the License at
  10. http://www.apache.org/licenses/LICENSE-2.0
  11. Unless required by applicable law or agreed to in writing,
  12. software distributed under the License is distributed on an
  13. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. KIND, either express or implied. See the License for the
  15. specific language governing permissions and limitations
  16. under the License.
  17. */
  18. var exec = require('cordova/exec'),
  19. channel = require('cordova/channel');
  20. // Called after 'deviceready' event
  21. channel.deviceready.subscribe( function () {
  22. // Device is ready now, the listeners are registered
  23. // and all queued events can be executed.
  24. exec(null, null, 'LocalNotification', 'deviceready', []);
  25. });
  26. // Called before 'deviceready' event
  27. channel.onCordovaReady.subscribe( function () {
  28. // The cordova device plugin is ready now
  29. channel.onCordovaInfoReady.subscribe( function () {
  30. if (device.platform == 'Android') {
  31. channel.onPause.subscribe( function () {
  32. // Necessary to set the state to `background`
  33. exec(null, null, 'LocalNotification', 'pause', []);
  34. });
  35. channel.onResume.subscribe( function () {
  36. // Necessary to set the state to `foreground`
  37. exec(null, null, 'LocalNotification', 'resume', []);
  38. });
  39. // Necessary to set the state to `foreground`
  40. exec(null, null, 'LocalNotification', 'resume', []);
  41. }
  42. // Merges the platform specific properties into the default properties
  43. exports.applyPlatformSpecificOptions();
  44. });
  45. });
  46. /**
  47. * @private
  48. *
  49. * Default values.
  50. */
  51. exports._defaults = {
  52. message: '',
  53. title: '',
  54. autoCancel: false,
  55. badge: -1,
  56. id: '0',
  57. json: '',
  58. repeat: ''
  59. };
  60. /**
  61. * Returns the default settings
  62. *
  63. * @return {Object}
  64. */
  65. exports.getDefaults = function () {
  66. return this._defaults;
  67. };
  68. /**
  69. * Overwrite default settings
  70. *
  71. * @param {Object} defaults
  72. */
  73. exports.setDefaults = function (newDefaults) {
  74. var defaults = this.getDefaults();
  75. for (var key in defaults) {
  76. if (newDefaults[key] !== undefined) {
  77. defaults[key] = newDefaults[key];
  78. }
  79. }
  80. };
  81. /**
  82. * Add a new entry to the registry
  83. *
  84. * @param {Object} props
  85. * The notification properties
  86. * @param {Function} callback
  87. * A function to be called after the notification has been canceled
  88. * @param {Object?} scope
  89. * The scope for the callback function
  90. */
  91. exports.add = function (props, callback, scope) {
  92. this.registerPermission(function(granted) {
  93. if (!granted)
  94. return;
  95. var notifications = Array.isArray(props) ? props : [props];
  96. for (var i = 0; i < notifications.length; i++) {
  97. var properties = notifications[i];
  98. this.mergeWithDefaults(properties);
  99. this.convertProperties(properties);
  100. }
  101. this.exec('add', notifications, callback, scope);
  102. }, this);
  103. };
  104. /**
  105. * Update existing notification specified by ID in options.
  106. *
  107. * @param {Object} options
  108. * The notification properties to update
  109. * @param {Function} callback
  110. * A function to be called after the notification has been updated
  111. * @param {Object?} scope
  112. * The scope for the callback function
  113. */
  114. exports.update = function (options, callback, scope) {
  115. this.exec('update', options, callback, scope);
  116. };
  117. /**
  118. * Clear the specified notification.
  119. *
  120. * @param {String} id
  121. * The ID of the notification
  122. * @param {Function} callback
  123. * A function to be called after the notification has been cleared
  124. * @param {Object?} scope
  125. * The scope for the callback function
  126. */
  127. exports.clear = function (ids, callback, scope) {
  128. ids = Array.isArray(ids) ? ids : [ids];
  129. ids = this.convertIds(ids);
  130. this.exec('clear', ids, callback, scope);
  131. };
  132. /**
  133. * Clear all previously sheduled notifications.
  134. *
  135. * @param {Function} callback
  136. * A function to be called after all notifications have been cleared
  137. * @param {Object?} scope
  138. * The scope for the callback function
  139. */
  140. exports.clearAll = function (callback, scope) {
  141. this.exec('clearAll', null, callback, scope);
  142. };
  143. /**
  144. * Cancel the specified notifications.
  145. *
  146. * @param {String[]} ids
  147. * The IDs of the notifications
  148. * @param {Function} callback
  149. * A function to be called after the notifications has been canceled
  150. * @param {Object?} scope
  151. * The scope for the callback function
  152. */
  153. exports.cancel = function (ids, callback, scope) {
  154. ids = Array.isArray(ids) ? ids : [ids];
  155. ids = this.convertIds(ids);
  156. this.exec('cancel', ids, callback, scope);
  157. };
  158. /**
  159. * Remove all previously registered notifications.
  160. *
  161. * @param {Function} callback
  162. * A function to be called after all notifications have been canceled
  163. * @param {Object?} scope
  164. * The scope for the callback function
  165. */
  166. exports.cancelAll = function (callback, scope) {
  167. this.exec('cancelAll', null, callback, scope);
  168. };
  169. /**
  170. * Check if a notification with an ID is scheduled.
  171. *
  172. * @param {String} id
  173. * The ID of the notification
  174. * @param {Function} callback
  175. * A callback function to be called with the list
  176. * @param {Object?} scope
  177. * The scope for the callback function
  178. */
  179. exports.isScheduled = function (id, callback, scope) {
  180. var notId = (id || '0').toString();
  181. this.exec('isScheduled', notId, callback, scope);
  182. };
  183. /**
  184. * Check if a notification with an ID was triggered.
  185. *
  186. * @param {String} id
  187. * The ID of the notification
  188. * @param {Function} callback
  189. * A callback function to be called with the list
  190. * @param {Object?} scope
  191. * The scope for the callback function
  192. */
  193. exports.isTriggered = function (id, callback, scope) {
  194. var notId = (id || '0').toString();
  195. this.exec('isTriggered', notId, callback, scope);
  196. };
  197. /**
  198. * List all currently pending notifications.
  199. *
  200. * @param {Function} callback
  201. * A callback function to be called with the list
  202. * @param {Object?} scope
  203. * The scope for the callback function
  204. */
  205. exports.getScheduledIds = function (callback, scope) {
  206. this.exec('getScheduledIds', null, callback, scope);
  207. };
  208. /**
  209. * List all triggered notifications.
  210. *
  211. * @param {Function} callback
  212. * A callback function to be called with the list
  213. * @param {Object?} scope
  214. * The scope for the callback function
  215. */
  216. exports.getTriggeredIds = function (callback, scope) {
  217. this.exec('getTriggeredIds', null, callback, scope);
  218. };
  219. /**
  220. * List all properties for given scheduled notifications.
  221. * If called without IDs, all notification will be returned.
  222. *
  223. * @param {Number[]?} ids
  224. * Set of notification IDs
  225. * @param {Function} callback
  226. * A callback function to be called with the list
  227. * @param {Object?} scope
  228. * The scope for the callback function
  229. */
  230. exports.getScheduled = function () {
  231. var args = Array.apply(null, arguments);
  232. if (typeof args[0] == 'function') {
  233. args.unshift([]);
  234. }
  235. var ids = args[0],
  236. callback = args[1],
  237. scope = args[2];
  238. if (!Array.isArray(ids)) {
  239. ids = [ids];
  240. }
  241. ids = this.convertIds(ids);
  242. this.exec('getScheduled', ids, callback, scope);
  243. };
  244. /**
  245. * Retrieve the properties for all scheduled notifications.
  246. *
  247. * @param {Function} callback
  248. * A callback function to be called with the list
  249. * @param {Object?} scope
  250. * The scope for the callback function
  251. */
  252. exports.getAllScheduled = function (callback, scope) {
  253. this.exec('getScheduled', null, callback, scope);
  254. };
  255. /**
  256. * List all properties for given triggered notifications.
  257. * If called without IDs, all notification will be returned.
  258. *
  259. * @param {Number[]?} ids
  260. * Set of notification IDs
  261. * @param {Function} callback
  262. * A callback function to be called with the list
  263. * @param {Object?} scope
  264. * The scope for the callback function
  265. */
  266. exports.getTriggered = function () {
  267. var args = Array.apply(null, arguments);
  268. if (typeof args[0] == 'function') {
  269. args.unshift([]);
  270. }
  271. var ids = args[0],
  272. callback = args[1],
  273. scope = args[2];
  274. if (!Array.isArray(ids)) {
  275. ids = [ids];
  276. }
  277. ids = this.convertIds(ids);
  278. this.exec('getTriggered', ids, callback, scope);
  279. };
  280. /**
  281. * Retrieve the properties for all triggered notifications.
  282. *
  283. * @param {Function} callback
  284. * A callback function to be called with the list
  285. * @param {Object?} scope
  286. * The scope for the callback function
  287. */
  288. exports.getAllTriggered = function (callback, scope) {
  289. this.exec('getTriggered', null, callback, scope);
  290. };
  291. /**
  292. * Informs if the app has the permission to show notifications.
  293. *
  294. * @param {Function} callback
  295. * The function to be exec as the callback
  296. * @param {Object?} scope
  297. * The callback function's scope
  298. */
  299. exports.hasPermission = function (callback, scope) {
  300. var fn = this.createCallbackFn(callback, scope);
  301. if (device.platform != 'iOS') {
  302. fn(true);
  303. return;
  304. }
  305. exec(fn, null, 'LocalNotification', 'hasPermission', []);
  306. };
  307. /**
  308. * Register permission to show notifications if not already granted.
  309. *
  310. * @param {Function} callback
  311. * The function to be exec as the callback
  312. * @param {Object?} scope
  313. * The callback function's scope
  314. */
  315. exports.registerPermission = function (callback, scope) {
  316. var fn = this.createCallbackFn(callback, scope);
  317. if (device.platform != 'iOS') {
  318. fn(true);
  319. return;
  320. }
  321. exec(fn, null, 'LocalNotification', 'registerPermission', []);
  322. };
  323. /**
  324. * @deprecated
  325. *
  326. * Register permission to show notifications if not already granted.
  327. *
  328. * @param {Function} callback
  329. * The function to be exec as the callback
  330. * @param {Object?} scope
  331. * The callback function's scope
  332. */
  333. exports.promptForPermission = function (callback, scope) {
  334. console.warn('Depreated: Please use `notification.local.registerPermission` instead.');
  335. exports.registerPermission.apply(this, arguments);
  336. };
  337. /**
  338. * Occurs when a notification was added.
  339. *
  340. * @param {String} id
  341. * The ID of the notification
  342. * @param {String} state
  343. * Either "foreground" or "background"
  344. * @param {String} json
  345. * A custom (JSON) string
  346. * @param {Object} data
  347. * The notification properties
  348. */
  349. exports.onadd = function (id, state, json, data) {};
  350. /**
  351. * Occurs when the notification is triggered.
  352. *
  353. * @param {String} id
  354. * The ID of the notification
  355. * @param {String} state
  356. * Either "foreground" or "background"
  357. * @param {String} json
  358. * A custom (JSON) string
  359. * @param {Object} data
  360. * The notification properties
  361. */
  362. exports.ontrigger = function (id, state, json, data) {};
  363. /**
  364. * Fires after the notification was clicked.
  365. *
  366. * @param {String} id
  367. * The ID of the notification
  368. * @param {String} state
  369. * Either "foreground" or "background"
  370. * @param {String} json
  371. * A custom (JSON) string
  372. * @param {Object} data
  373. * The notification properties
  374. */
  375. exports.onclick = function (id, state, json, data) {};
  376. /**
  377. * Fires if the notification was canceled.
  378. *
  379. * @param {String} id
  380. * The ID of the notification
  381. * @param {String} state
  382. * Either "foreground" or "background"
  383. * @param {String} json
  384. * A custom (JSON) string
  385. * @param {Object} data
  386. * The notification properties
  387. */
  388. exports.oncancel = function (id, state, json, data) {};
  389. /**
  390. * Get fired when the notification was cleared.
  391. *
  392. * @param {String} id
  393. * The ID of the notification
  394. * @param {String} state
  395. * Either "foreground" or "background"
  396. * @param {String} json
  397. * A custom (JSON) string
  398. * @param {Object} data
  399. * The notification properties
  400. */
  401. exports.onclear = function (id, state, json, data) {};
  402. /**
  403. * @private
  404. *
  405. * Merges custom properties with the default values.
  406. *
  407. * @param {Object} options
  408. * Set of custom values
  409. *
  410. * @retrun {Object}
  411. * The merged property list
  412. */
  413. exports.mergeWithDefaults = function (options) {
  414. var defaults = this.getDefaults();
  415. for (var key in defaults) {
  416. if (options[key] === undefined) {
  417. options[key] = defaults[key];
  418. }
  419. }
  420. return options;
  421. };
  422. /**
  423. * @private
  424. *
  425. * Convert the passed values to their required type.
  426. *
  427. * @param {Object} options
  428. * Set of custom values
  429. *
  430. * @retrun {Object}
  431. * The converted property list
  432. */
  433. exports.convertProperties = function (options) {
  434. if (options.id) {
  435. options.id = options.id.toString();
  436. }
  437. if (options.date === undefined) {
  438. options.date = new Date();
  439. }
  440. if (options.title) {
  441. options.title = options.title.toString();
  442. }
  443. if (options.message) {
  444. options.message = options.message.toString();
  445. }
  446. if (options.text) {
  447. options.message = options.text.toString();
  448. }
  449. if (typeof options.date == 'object') {
  450. options.date = Math.round(options.date.getTime()/1000);
  451. }
  452. if (typeof options.json == 'object') {
  453. options.json = JSON.stringify(options.json);
  454. }
  455. return options;
  456. };
  457. /**
  458. * @private
  459. *
  460. * Merges the platform specific properties into the default properties.
  461. *
  462. * @return {Object}
  463. * The default properties for the platform
  464. */
  465. exports.applyPlatformSpecificOptions = function () {
  466. var defaults = this._defaults;
  467. switch (device.platform) {
  468. case 'Android':
  469. defaults.icon = 'icon';
  470. defaults.smallIcon = null;
  471. defaults.ongoing = false;
  472. defaults.led = 'FFFFFF'; /*RRGGBB*/
  473. defaults.sound = 'TYPE_NOTIFICATION'; break;
  474. case 'iOS':
  475. defaults.sound = ''; break;
  476. case 'WinCE': case 'Win32NT':
  477. defaults.smallImage = null;
  478. defaults.image = null;
  479. defaults.wideImage = null;
  480. }
  481. return defaults;
  482. };
  483. /**
  484. * @private
  485. *
  486. * Creates a callback, which will be executed within a specific scope.
  487. *
  488. * @param {Function} callbackFn
  489. * The callback function
  490. * @param {Object} scope
  491. * The scope for the function
  492. *
  493. * @return {Function}
  494. * The new callback function
  495. */
  496. exports.createCallbackFn = function (callbackFn, scope) {
  497. if (typeof callbackFn != 'function')
  498. return;
  499. return function () {
  500. callbackFn.apply(scope || this, arguments);
  501. };
  502. };
  503. /**
  504. * @private
  505. *
  506. * Convert the IDs to Strings.
  507. *
  508. * @param {String/Number[]} ids
  509. *
  510. * @return Array of Strings
  511. */
  512. exports.convertIds = function (ids) {
  513. var convertedIds = [];
  514. for (var i = 0; i < ids.length; i++) {
  515. convertedIds.push(ids[i].toString());
  516. }
  517. return convertedIds;
  518. };
  519. /**
  520. * @private
  521. *
  522. * Executes the native counterpart.
  523. *
  524. * @param {String} action
  525. * The name of the action
  526. * @param args[]
  527. * Array of arguments
  528. * @param {Function} callback
  529. * The callback function
  530. * @param {Object} scope
  531. * The scope for the function
  532. */
  533. exports.exec = function (action, args, callback, scope) {
  534. var fn = this.createCallbackFn(callback, scope),
  535. params = [];
  536. if (Array.isArray(args)) {
  537. params = args;
  538. } else if (args) {
  539. params.push(args);
  540. }
  541. exec(fn, null, 'LocalNotification', action, params);
  542. };