local-notification.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  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: 0,
  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. * @return {Number}
  92. * The notification's ID
  93. */
  94. exports.add = function (props, callback, scope) {
  95. var options = this.mergeWithDefaults(props),
  96. fn = this.createCallbackFn(callback, scope);
  97. if (options.id) {
  98. options.id = options.id.toString();
  99. }
  100. if (options.date === undefined) {
  101. options.date = new Date();
  102. }
  103. if (options.title) {
  104. options.title = options.title.toString();
  105. }
  106. if (options.message) {
  107. options.message = options.message.toString();
  108. }
  109. if (typeof options.date == 'object') {
  110. options.date = Math.round(options.date.getTime()/1000);
  111. }
  112. if (typeof options.json == 'object') {
  113. options.json = JSON.stringify(options.json);
  114. }
  115. if (['WinCE', 'Win32NT'].indexOf(device.platform) > -1) {
  116. fn = function (cmd) {
  117. eval(cmd);
  118. };
  119. }
  120. exec(fn, null, 'LocalNotification', 'add', [options]);
  121. return options.id;
  122. };
  123. /**
  124. * Add new entries to the registry (more than one)
  125. *
  126. * @param {Object} options
  127. * The notification properties
  128. * @param {Function} callback
  129. * A function to be called after the notification has been added
  130. * @param {Object} scope
  131. * The scope for the callback function
  132. *
  133. * @return {Number}
  134. * The notification's ID
  135. */
  136. exports.addMultiple = function (notifications, callback, scope) {
  137. var length = notifications.length;
  138. var notificationsMerged = new Array(),
  139. callbackFn = this.createCallbackFn(callback, scope);
  140. for (var i=0;i<length;i++){
  141. var options = this.mergeWithDefaults(notifications[i]);
  142. if (options.id) {
  143. options.id = options.id.toString();
  144. }
  145. if (options.date === undefined) {
  146. options.date = new Date();
  147. }
  148. if (options.title) {
  149. options.title = options.title.toString();
  150. }
  151. if (options.message) {
  152. options.message = options.message.toString();
  153. }
  154. if (typeof options.date == 'object') {
  155. options.date = Math.round(options.date.getTime()/1000);
  156. }
  157. if (['WinCE', 'Win32NT'].indexOf(device.platform) > -1) {
  158. callbackFn = function (cmd) {
  159. eval(cmd);
  160. };
  161. }
  162. notificationsMerged.push(options);
  163. }
  164. cordova.exec(callbackFn, null, 'LocalNotification', 'addMultiple', notificationsMerged);
  165. return options.id;
  166. };
  167. /**
  168. * Update existing notification (currently android only)
  169. *
  170. * @param {Object} options
  171. * The notification properties to update
  172. * @param {Function} callback
  173. * A function to be called after the notification has been updated
  174. * @param {Object} scope
  175. * The scope for the callback function
  176. *
  177. * @return {Number}
  178. * The notification's ID
  179. */
  180. exports.update = function (updates, callback, scope) {
  181. callbackFn = this.createCallbackFn(callback, scope);
  182. cordova.exec(callbackFn, null, 'LocalNotification', 'update', [updates]);
  183. };
  184. /**
  185. * Clears the specified notification.
  186. *
  187. * @param {String} id
  188. * The ID of the notification
  189. * @param {Function} callback
  190. * A function to be called after the notification has been cleared
  191. * @param {Object} scope
  192. * The scope for the callback function
  193. */
  194. exports.clear = function (id, callback, scope) {
  195. var id = id.toString(),
  196. callbackFn = this.createCallbackFn(callback, scope);
  197. cordova.exec(callbackFn, null, 'LocalNotification', 'clear', [id]);
  198. };
  199. /**
  200. * Clear the specified notifications (more than one).
  201. *
  202. * @param {String} id
  203. * The ID of the notification
  204. * @param {Function} callback
  205. * A function to be called after the notifications has been cleared.
  206. * @param {Object} scope
  207. * The scope for the callback function
  208. */
  209. exports.clearMultiple = function (ids, callback, scope) {
  210. var length = ids.length;
  211. var idArray = new Array(),
  212. callbackFn = this.createCallbackFn(callback, scope);
  213. for (var i=0;i<length;i++){
  214. var id = ids[i].toString();
  215. idArray.push(id);
  216. }
  217. var callbackFn = this.createCallbackFn(callback, scope);
  218. cordova.exec(callbackFn, null, 'LocalNotification', 'clearMultiple', [ids]);
  219. };
  220. /**
  221. * Clears all previously sheduled notifications.
  222. *
  223. * @param {Function} callback
  224. * A function to be called after all notifications have been cleared
  225. * @param {Object} scope
  226. * The scope for the callback function
  227. */
  228. exports.clearAll = function (callback, scope) {
  229. var callbackFn = this.createCallbackFn(callback, scope);
  230. cordova.exec(callbackFn, null, 'LocalNotification', 'clearAll', []);
  231. };
  232. /**
  233. * Cancels the specified notification.
  234. *
  235. * @param {String} id
  236. * The ID of the notification
  237. * @param {Function} callback
  238. * A function to be called after the notification has been canceled
  239. * @param {Object} scope
  240. * The scope for the callback function
  241. */
  242. exports.cancel = function (id, callback, scope) {
  243. var fn = this.createCallbackFn(callback, scope);
  244. exec(fn, null, 'LocalNotification', 'cancel', [(id || '0').toString()]);
  245. };
  246. /**
  247. * Cancel the specified notifications (more than one).
  248. *
  249. * @param {String} id
  250. * The ID of the notification
  251. * @param {Function} callback
  252. * A function to be called after the notifications has been canceled
  253. * @param {Object} scope
  254. * The scope for the callback function
  255. */
  256. exports.cancelMultiple = function (ids, callback, scope) {
  257. var length = ids.length;
  258. var idArray = new Array(),
  259. callbackFn = this.createCallbackFn(callback, scope);
  260. for (var i=0;i<length;i++){
  261. var id = ids[i].toString();
  262. idArray.push(id);
  263. }
  264. var callbackFn = this.createCallbackFn(callback, scope);
  265. cordova.exec(callbackFn, null, 'LocalNotification', 'cancelMultiple', [ids]);
  266. };
  267. /**
  268. * Removes all previously registered notifications.
  269. *
  270. * @param {Function} callback
  271. * A function to be called after all notifications have been canceled
  272. * @param {Object} scope
  273. * The scope for the callback function
  274. */
  275. exports.cancelAll = function (callback, scope) {
  276. var fn = this.createCallbackFn(callback, scope);
  277. exec(fn, null, 'LocalNotification', 'cancelAll', []);
  278. };
  279. /**
  280. * Retrieves a list with all currently pending notifications.
  281. *
  282. * @param {Function} callback
  283. * A callback function to be called with the list
  284. * @param {Object} scope
  285. * The scope for the callback function
  286. */
  287. exports.getScheduledIds = function (callback, scope) {
  288. var fn = this.createCallbackFn(callback, scope);
  289. exec(fn, null, 'LocalNotification', 'getScheduledIds', []);
  290. };
  291. /**
  292. * Checks wether a notification with an ID is scheduled.
  293. *
  294. * @param {String} id
  295. * The ID of the notification
  296. * @param {Function} callback
  297. * A callback function to be called with the list
  298. * @param {Object} scope
  299. * The scope for the callback function
  300. */
  301. exports.isScheduled = function (id, callback, scope) {
  302. var fn = this.createCallbackFn(callback, scope);
  303. exec(fn, null, 'LocalNotification', 'isScheduled', [id.toString()]);
  304. };
  305. /**
  306. * Retrieves a list with all triggered notifications.
  307. *
  308. * @param {Function} callback
  309. * A callback function to be called with the list
  310. * @param {Object} scope
  311. * The scope for the callback function
  312. */
  313. exports.getTriggeredIds = function (callback, scope) {
  314. var fn = this.createCallbackFn(callback, scope);
  315. exec(fn, null, 'LocalNotification', 'getTriggeredIds', []);
  316. };
  317. /**
  318. * Checks wether a notification with an ID was triggered.
  319. *
  320. * @param {String} id
  321. * The ID of the notification
  322. * @param {Function} callback
  323. * A callback function to be called with the list
  324. * @param {Object} scope
  325. * The scope for the callback function
  326. */
  327. exports.isTriggered = function (id, callback, scope) {
  328. var fn = this.createCallbackFn(callback, scope);
  329. exec(fn, null, 'LocalNotification', 'isTriggered', [id.toString()]);
  330. };
  331. /**
  332. * Informs if the app has the permission to show notifications.
  333. *
  334. * @param {Function} callback
  335. * The function to be exec as the callback
  336. * @param {Object?} scope
  337. * The callback function's scope
  338. */
  339. exports.hasPermission = function (callback, scope) {
  340. var fn = this.createCallbackFn(callback, scope);
  341. if (device.platform != 'iOS') {
  342. fn(true);
  343. return;
  344. }
  345. exec(fn, null, 'LocalNotification', 'hasPermission', []);
  346. };
  347. /**
  348. * Register permission to show notifications if not already granted.
  349. *
  350. * @param {Function} callback
  351. * The function to be exec as the callback
  352. * @param {Object?} scope
  353. * The callback function's scope
  354. */
  355. exports.registerPermission = function (callback, scope) {
  356. var fn = this.createCallbackFn(callback, scope);
  357. if (device.platform != 'iOS') {
  358. fn(true);
  359. return;
  360. }
  361. exec(fn, null, 'LocalNotification', 'registerPermission', []);
  362. };
  363. exports.promptForPermission = function (callback, scope) {
  364. console.warn('Depreated: Please use `notification.local.registerPermission` instead.');
  365. exports.registerPermission.apply(this, arguments);
  366. };
  367. /**
  368. * Occurs when a notification was added.
  369. *
  370. * @param {String} id
  371. * The ID of the notification
  372. * @param {String} state
  373. * Either "foreground" or "background"
  374. * @param {String} json
  375. * A custom (JSON) string
  376. */
  377. exports.onadd = function (id, state, json) {};
  378. /**
  379. * Occurs when the notification is triggered.
  380. *
  381. * @param {String} id
  382. * The ID of the notification
  383. * @param {String} state
  384. * Either "foreground" or "background"
  385. * @param {String} json
  386. * A custom (JSON) string
  387. */
  388. exports.ontrigger = function (id, state, json) {};
  389. /**
  390. * Fires after the notification was clicked.
  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. */
  399. exports.onclick = function (id, state, json) {};
  400. /**
  401. * Fires if the notification was canceled.
  402. *
  403. * @param {String} id
  404. * The ID of the notification
  405. * @param {String} state
  406. * Either "foreground" or "background"
  407. * @param {String} json
  408. * A custom (JSON) string
  409. */
  410. exports.oncancel = function (id, state, json) {};
  411. /**
  412. * Get fired when the notification was cleared.
  413. *
  414. * @param {String} id
  415. * The ID of the notification
  416. * @param {String} state
  417. * Either "foreground" or "background"
  418. * @param {String} json
  419. * A custom (JSON) string
  420. */
  421. exports.onclear = function (id, state, json) {};
  422. /**
  423. * @private
  424. *
  425. * Merges custom properties with the default values.
  426. *
  427. * @param {Object} options
  428. * Set of custom values
  429. *
  430. * @retrun {Object}
  431. * The merged property list
  432. */
  433. exports.mergeWithDefaults = function (options) {
  434. var defaults = this.getDefaults();
  435. for (var key in defaults) {
  436. if (options[key] === undefined) {
  437. options[key] = defaults[key];
  438. }
  439. }
  440. return options;
  441. };
  442. /**
  443. * @private
  444. *
  445. * Merges the platform specific properties into the default properties.
  446. *
  447. * @return {Object}
  448. * The default properties for the platform
  449. */
  450. exports.applyPlatformSpecificOptions = function () {
  451. var defaults = this._defaults;
  452. switch (device.platform) {
  453. case 'Android':
  454. defaults.icon = 'icon';
  455. defaults.smallIcon = null;
  456. defaults.ongoing = false;
  457. defaults.led = 'FFFFFF'; /*RRGGBB*/
  458. defaults.sound = 'TYPE_NOTIFICATION'; break;
  459. case 'iOS':
  460. defaults.sound = ''; break;
  461. case 'WinCE': case 'Win32NT':
  462. defaults.smallImage = null;
  463. defaults.image = null;
  464. defaults.wideImage = null;
  465. }
  466. return defaults;
  467. };
  468. /**
  469. * @private
  470. *
  471. * Creates a callback, which will be executed within a specific scope.
  472. *
  473. * @param {Function} callbackFn
  474. * The callback function
  475. * @param {Object} scope
  476. * The scope for the function
  477. *
  478. * @return {Function}
  479. * The new callback function
  480. */
  481. exports.createCallbackFn = function (callbackFn, scope) {
  482. if (typeof callbackFn != 'function')
  483. return;
  484. return function () {
  485. callbackFn.apply(scope || this, arguments);
  486. };
  487. };