local-notification.js 15 KB

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