diff options
| author | Arjun Roychowdhury <pliablepixels@gmail.com> | 2015-10-10 11:28:44 -0400 |
|---|---|---|
| committer | Arjun Roychowdhury <pliablepixels@gmail.com> | 2015-10-10 11:28:44 -0400 |
| commit | d0d3aaf7af63afa041e9af145267b0bb04ee729f (patch) | |
| tree | be718a451ed33afeead4d87c186fe231fe09a444 /plugins/de.appplant.cordova.plugin.badge | |
| parent | 7b0d282994db52cc4bc6b62b33ce05efbb522fae (diff) | |
Notifications now have a blop sound, also handling application badges
Diffstat (limited to 'plugins/de.appplant.cordova.plugin.badge')
20 files changed, 2424 insertions, 0 deletions
diff --git a/plugins/de.appplant.cordova.plugin.badge/CHANGELOG.md b/plugins/de.appplant.cordova.plugin.badge/CHANGELOG.md new file mode 100644 index 00000000..b2aba530 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/CHANGELOG.md @@ -0,0 +1,83 @@ +## ChangeLog +#### Version 0.7.1 (30.07.2015) +- Support for app icon badges on selective Android platforms thanks to [ShortcutBadger](https://github.com/leolin310148/ShortcutBadger) + - Sony + - Samsung + - LG + - HTC + - Xiaomi + - ASUS + - ADW, APEX, NOVA + +#### Version 0.7.0 (18.07.2015) +- New platform support: + - Amazon FireOS + - Browser + - Windows +- `get`, `set` and `clear` support callbacks. +- Support for [Glyphs](https://msdn.microsoft.com/de-de/library/windows/apps/hh779719#phone_badge) on _Windows_ platform. +- Added tests + +#### Version 0.6.4 (02.05.2015) +- Upgrade cordova dependency from 3.0 to 3.6 +- Fix incompatibility with local-notification plugin and PGB caused by the usage of hooks. + +#### Version 0.6.3 (22.03.2015) +- New interfaces to increase or decrease the badge number. +- Fix incompatibility with local-notification plugin. +- Add instead of replace permissions on iOS. +- Refreshed layout of the example app. + +#### Version 0.6.2 (01.03.2015) +- [change:] Renamed `promptForPermission` to `registerPermission`. Older one is still supported. +- [enhancement:] Support iOS8 and older SDK versions from a single binary. +- [enhancement:] `registerPermission` returns result of registration. +- [enhancement:] No need anymore to call `registerPermission` explicit before trying to set the badge number. + +#### Version 0.6.1 (03.10.2014) +- [bugfix:] `hasPermission` and `promptForPermission` let the app crash on iOS7 and older. + +#### Version 0.6.0 (29.09.2014) +- [enhancement:] iOS 8 support +- [enhancement:] All methods are asynchron now and do not block the main thread anymore. +- [feature:] New method `hasPermission` to ask if the user has granted to display badge notifications. +- [feature:] New method `promptForPermission` to promt the user to grant permission to display badge notifications. +- [feature:] New method `configure` to configure badge properties. +- [feature:] The small icon on Android can be changed through `configure`. +- [**change**:] The namespace `plugin.notification.badge` will be removed with v0.6.1 +- [**change**:] `setTitle` is deprecated, please use `configure({ title: 'title' })`. +- [**change**:] `clearOnTap` is deprecated, please use `configure({ autoClear: true })`. +- [bugfix:] `getBadge` still returned the number when autoClear: was set and the notification was already cleared by the system (Android). +- [bugfix:] `clean` was not working on Windows Phone. + +#### Version 0.5.3 (23.05.2014) +- Added new namespace `cordova.plugins.notification.badge`<br> + **Note:** The former `plugin.notification.badge` namespace is deprecated now and will be removed in the next major release. + +- [bugfix:] `get` returned the old value even after `clear` was called on Android. + +#### Version 0.5.2 (12.04.2014) +- [enhancement:] Badge can be cleared automatically through `setClearOnTap` +- [enhancement:] Badge can be retrieved through `get` + +#### Version 0.5.1 (25.01.2014) +- [enhancement:] Specify custom notification title on Android can be set through JS interface. +- [enhancement:] Setting launchMode to *singleInstance* isn't necessary anymore. App does not restart on click anymore. + +#### Version 0.5.0 (04.01.2014) +- Added Android support + +#### Version 0.4.1 (04.12.2013) +- Release under the Apache 2.0 license. + +#### Version 0.4.0 (07.10.2013) +- Added WP8 support +- **Note:** The former `plugin.badge` namespace is not longer available. + +#### Version 0.2.1 (15.08.2013) +- Added new namespace `plugin.notification.badge`<br> + **Note:** The former `plugin.badge` namespace is deprecated now and will be removed in the next major release. + +#### Version 0.2.0 (11.08.2013) +- Added iOS support<br> + *Based on the Badge iOS plugin made by* ***Joseph Stuhr*** diff --git a/plugins/de.appplant.cordova.plugin.badge/LICENSE b/plugins/de.appplant.cordova.plugin.badge/LICENSE new file mode 100644 index 00000000..7a4a3ea2 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
\ No newline at end of file diff --git a/plugins/de.appplant.cordova.plugin.badge/README.md b/plugins/de.appplant.cordova.plugin.badge/README.md new file mode 100644 index 00000000..e7f44ba9 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/README.md @@ -0,0 +1,113 @@ + +[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FF6GG425KEQ3E "Donate once-off to this project using Paypal") +[](http://badge.fury.io/js/de.appplant.cordova.plugin.badge) +[](https://codeclimate.com/github/katzer/cordova-plugin-badge) + +Cordova Badge Plugin +==================== + +The essential purpose of badge numbers is to enable an application to inform its users that it has something for them — for example, unread messages — when the application isn’t running in the foreground. + +<img height="150px" align="right" hspace="19" vspace="12" src="http://4.bp.blogspot.com/-GBwBSN92DvU/UB8Kut7Oz0I/AAAAAAAAJKs/mJgBmj1RKqU/s1600/whatsapp+wp8+10.png"></img> + +### How they appear to the user +Users see notifications in the following ways: +- Badging the app’s icon + + +## Supported Platforms +The current 0.7 branch does support the following platforms: +- __Amazon FireOS__ +- __Android__ +- __Browser__ +- __iOS__ +- __Windows__ +- __WP8__ and __WP8.1 Silverlight__ + +Find out more informations [here][wiki_platforms] in our wiki. + + +## Installation +The plugin is installable from source and available on Cordova Plugin Registry and PhoneGap Build. + +Find out more informations [here][wiki_installation] in our wiki. + + +## I want to get a quick overview +All wiki pages contain samples, but for a quick overview the sample section may be the fastest way. + +Find out more informations [here][wiki_samples] in our wiki. + + +## I want to get a deep overview +The plugin allows you to set, get, clear, increase and decrease the badge number. For Android the plugin offers additional configuration flags. + +Find out more about how to set, increase or decrease the badge [here][wiki_set]. + +To get a deep overview we recommend to read about all the topics in this wiki and try out the [Kitchen Sink App][wiki_kitchensink] + + +## I want to see the plugin in action +The plugin offers a kitchen sink sample app. Check out the cordova project and run the app directly from your command line or preferred IDE. + +Find out more informations [here][wiki_kitchensink] in our wiki. + + +## What's new +We are proud to announce our newest release version 0.7.x. Beside the hard work at the office and at the weekends it contains a lot of goodies, new features and easy to use APIs. + +Find out more informations [here][wiki_changelog] in our wiki. + + +## Sample +The sample demonstrates how to set a fix badge number and how to increase the current badge number. + +```javascript +// Set 10 on device ready +document.addEventListener('deviceready', function () { + cordova.plugins.notification.badge.set(10); +}, false); +``` +```javascript +// Increase the badge each time on pause +document.addEventListener('pause', function () { + cordova.plugins.notification.badge.increase(); +}, false); +``` + +Find out more informations [here][wiki_samples] in our wiki. + + +## Supporting +Your support is needed. If you use the plugin please support us in order to ensure further development and send us a drop through the donation button. + +Thank you! + +[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FF6GG425KEQ3E "Donate once-off to this project using Paypal") + + +## Contributing + +1. Fork it +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create new Pull Request + + +## License + +This software is released under the [Apache 2.0 License][apache2_license]. + +© 2013-2015 appPlant UG, Inc. All rights reserved + + +[cordova]: https://cordova.apache.org +[wiki]: https://github.com/katzer/cordova-plugin-badge/wiki +[wiki_platforms]: https://github.com/katzer/cordova-plugin-badge/wiki/01.-Platforms +[wiki_installation]: https://github.com/katzer/cordova-plugin-badge/wiki/02.-Installation +[wiki_kitchensink]: https://github.com/katzer/cordova-plugin-badge/tree/example +[wiki_set]: https://github.com/katzer/cordova-plugin-badge/wiki/03.-Set-Badge +[wiki_samples]: https://github.com/katzer/cordova-plugin-badge/wiki/07.-Samples +[wiki_changelog]: https://github.com/katzer/cordova-plugin-badge/wiki/08.-Changelog +[apache2_license]: http://opensource.org/licenses/Apache-2.0 diff --git a/plugins/de.appplant.cordova.plugin.badge/package.json b/plugins/de.appplant.cordova.plugin.badge/package.json new file mode 100644 index 00000000..391794a7 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/package.json @@ -0,0 +1,40 @@ +{ + "version": "0.7.1", + "name": "de.appplant.cordova.plugin.badge", + "cordova_name": "Cordova Badge Plugin", + "description": "Cordova plugin to access and modify the badge number of the app icon", + "author": "Sebastián Katzer", + "license": "Apache 2.0", + "repo": "https://github.com/katzer/cordova-plugin-badge.git", + "issue": "https://github.com/katzer/cordova-plugin-badge/issues", + "keywords": [ + "appplant", + "badge", + "cordova", + "ecosystem:cordova", + "cordova-android", + "cordova-amazon-fireos", + "cordova-ios", + "cordova-wp8", + "cordova-windows", + "cordova-browser" + ], + "platforms": [ + "ios", + "wp8", + "android", + "amazon-fireos", + "browser", + "windows" + ], + "engines": [ + { + "name": "cordova", + "version": ">=3.0.0" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/katzer/cordova-plugin-badge.git" + } +} diff --git a/plugins/de.appplant.cordova.plugin.badge/plugin.xml b/plugins/de.appplant.cordova.plugin.badge/plugin.xml new file mode 100644 index 00000000..46bae990 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/plugin.xml @@ -0,0 +1,201 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ +--> + +<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" + xmlns:android="http://schemas.android.com/apk/res/android" + id="de.appplant.cordova.plugin.badge" + version="0.7.1"> + + <name>Cordova Badge Plugin</name> + + <description> + Cordova plugin to access and modify the badge number of the app icon + </description> + + <repo>https://github.com/katzer/cordova-plugin-badge.git</repo> + + <issue>https://github.com/katzer/cordova-plugin-badge/issues</issue> + + <keywords>appplant, badge</keywords> + + <license>Apache 2.0</license> + + <author>Sebastián Katzer</author> + + <!-- cordova --> + <engines> + <engine name="cordova" version=">=3.0.0" /> + <engine name="cordova-android" version=">=4"/> + <engine name="cordova-plugman" version=">=4.2.0"/><!-- needed for gradleReference support --> + </engines> + + <!-- js --> + <js-module src="www/badge.js" name="Badge"> + <clobbers target="plugin.notification.badge" /> + <clobbers target="cordova.plugins.notification.badge" /> + </js-module> + + <!-- info --> + <info> + Your support is needed. If you use the badge plugin please support us in order to ensure further development. + https://github.com/katzer/cordova-plugin-badge#supporting + + Thank you! + </info> + + <!-- ios --> + <platform name="ios"> + + <dependency id="de.appplant.cordova.common.registerusernotificationsettings" /> + + <config-file target="config.xml" parent="/*"> + <feature name="Badge"> + <param name="ios-package" value="APPBadge"/> + </feature> + </config-file> + + <header-file src="src/ios/APPBadge.h" /> + <source-file src="src/ios/APPBadge.m" /> + + <header-file src="src/ios/UIApplication+APPBadge.h" /> + <source-file src="src/ios/UIApplication+APPBadge.m" /> + + </platform> + + <!-- wp8 --> + <platform name="wp8"> + + <config-file target="config.xml" parent="/*"> + <feature name="Badge"> + <param name="wp-package" value="Badge"/> + </feature> + </config-file> + + <source-file src="src/wp8/Badge.cs" /> + + </platform> + + <!-- android --> + <platform name="android"> + + <config-file target="res/xml/config.xml" parent="/*"> + <feature name="Badge"> + <param name="android-package" value="de.appplant.cordova.plugin.badge.Badge"/> + </feature> + </config-file> + + <config-file target="AndroidManifest.xml" parent="/manifest/application"> + <!-- + * The launch activity is triggered when a notification is clicked by a user. + * The activity launches the main activity. + --> + <activity + android:name="de.appplant.cordova.plugin.badge.LaunchActivity" + android:theme="@android:style/Theme.Black.NoTitleBar" + android:launchMode="singleInstance" + android:exported="false" /> + </config-file> + + <framework src="src/android/badge.gradle" custom="true" type="gradleReference"/> + + <source-file + src="src/android/Badge.java" + target-dir="src/de/appplant/cordova/plugin/badge" /> + + <source-file + src="src/android/BadgeImpl.java" + target-dir="src/de/appplant/cordova/plugin/badge" /> + + <source-file + src="src/android/LaunchActivity.java" + target-dir="src/de/appplant/cordova/plugin/badge" /> + + </platform> + + <!-- amazon-fireos --> + <platform name="amazon-fireos"> + + <config-file target="res/xml/config.xml" parent="/*"> + <feature name="Badge"> + <param name="android-package" value="de.appplant.cordova.plugin.badge.Badge"/> + </feature> + </config-file> + + <config-file target="AndroidManifest.xml" parent="/manifest/application"> + <!-- + * The launch activity is triggered when a notification is clicked by a user. + * The activity launches the main activity. + --> + <activity + android:name="de.appplant.cordova.plugin.badge.LaunchActivity" + android:theme="@android:style/Theme.Black.NoTitleBar" + android:launchMode="singleInstance" + android:exported="false" /> + </config-file> + + <framework src="src/android/badge.gradle" custom="true" type="gradleReference"/> + + <source-file + src="src/android/Badge.java" + target-dir="src/de/appplant/cordova/plugin/badge" /> + + <source-file + src="src/android/BadgeImpl.java" + target-dir="src/de/appplant/cordova/plugin/badge" /> + + <source-file + src="src/android/LaunchActivity.java" + target-dir="src/de/appplant/cordova/plugin/badge" /> + + </platform> + + <!-- browser --> + <platform name="browser"> + + <config-file target="config.xml" parent="/*"> + <feature name="Badge"> + <param name="browser-package" value="Badge"/> + </feature> + </config-file> + + <js-module src="src/browser/favico.min.js" name="Badge.Favico"> + <clobbers target="cordova.plugins.notification.badge.Favico" /> + </js-module> + + <js-module src="src/browser/BadgeProxy.js" name="Badge.Proxy"> + <runs /> + </js-module> + + </platform> + + <!-- windows --> + <platform name="windows"> + + <js-module src="src/windows/BadgeProxy.js" name="Badge.Proxy" > + <runs /> + </js-module> + + </platform> + +</plugin> diff --git a/plugins/de.appplant.cordova.plugin.badge/src/android/Badge.java b/plugins/de.appplant.cordova.plugin.badge/src/android/Badge.java new file mode 100644 index 00000000..97f710e6 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/android/Badge.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.badge; + +import android.content.Context; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaPlugin; +import org.json.JSONArray; +import org.json.JSONException; + + +public class Badge extends CordovaPlugin { + + /** + * Implementation of the badge interface methods. + */ + private final BadgeImpl badgeImpl = new BadgeImpl(); + + /** + * Executes the request. + * + * @param action The action to execute. + * @param args The exec() arguments. + * @param callback The callback context used when + * calling back into JavaScript. + * + * @return + * Returning false results in a "MethodNotFound" error. + * + * @throws JSONException + */ + @Override + public boolean execute (String action, JSONArray args, CallbackContext callback) + throws JSONException { + + if (action.equalsIgnoreCase("clearBadge")) { + clearBadge(callback); + return true; + } + + if (action.equalsIgnoreCase("getBadge")) { + getBadge(callback); + return true; + } + + if (action.equalsIgnoreCase("hasPermission")) { + hasPermission(callback); + return true; + } + + if (action.equalsIgnoreCase("registerPermission")) { + hasPermission(callback); + return true; + } + + if (action.equalsIgnoreCase("setBadge")) { + setBadge(args, callback); + return true; + } + + return false; + } + + /** + * Clears the badge of the app icon. + * + * @param callback + * The function to be exec as the callback + */ + private void clearBadge (final CallbackContext callback) { + cordova.getThreadPool().execute(new Runnable() { + @Override + public void run() { + badgeImpl.clearBadge(getContext()); + badgeImpl.getBadge(callback, getContext()); + } + }); + } + + /** + * Retrieves the badge of the app icon. + * + * @param callback + * The function to be exec as the callback + */ + private void getBadge (final CallbackContext callback) { + cordova.getThreadPool().execute(new Runnable() { + @Override + public void run() { + badgeImpl.getBadge(callback, getContext()); + } + }); + } + + /** + * Informs if the app has the permission to show badges. + * + * @param callback + * The function to be exec as the callback + */ + private void hasPermission (final CallbackContext callback) { + cordova.getThreadPool().execute(new Runnable() { + @Override + public void run() { + badgeImpl.hasPermission(callback); + } + }); + } + + /** + * Sets the badge of the app icon. + * + * @param args + * The new badge number + * @param callback + * The function to be exec as the callback + */ + private void setBadge (final JSONArray args, + final CallbackContext callback) { + + cordova.getThreadPool().execute(new Runnable() { + @Override + public void run() { + badgeImpl.clearBadge(getContext()); + badgeImpl.setBadge(args, getContext()); + badgeImpl.getBadge(callback, getContext()); + } + }); + } + + /** + * Returns the context of the activity. + */ + private Context getContext () { + return cordova.getActivity(); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.badge/src/android/BadgeImpl.java b/plugins/de.appplant.cordova.plugin.badge/src/android/BadgeImpl.java new file mode 100644 index 00000000..9f55c920 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/android/BadgeImpl.java @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2014-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.badge; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Build; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.PluginResult; +import org.json.JSONArray; + +import me.leolin.shortcutbadger.ShortcutBadger; +import me.leolin.shortcutbadger.impl.DefaultBadger; + +/** + * Implementation of the badge interface methods. + */ +class BadgeImpl { + + /** + * The ID for the notification + */ + private final int ID = -450793490; + + /** + * The name for the shared preferences key + */ + protected static final String KEY = "badge"; + + /** + * Bundle identifier for the autoCancel value + */ + protected static final String EXTRA_AUTO_CANCEL = "EXTRA_AUTO_CANCEL"; + + /** + * Finds out if badgeing the app icon is possible on that device. + * + * @param ctx + * The application context. + * @return + * true if its supported. + */ + private boolean canBadgeAppIcon (Context ctx) { + ShortcutBadger badger = ShortcutBadger.with(ctx); + + return !(badger instanceof DefaultBadger); + } + + /** + * Clears the badge of the app icon. + * + * @param ctx + * The application context. + */ + protected void clearBadge (Context ctx) { + saveBadge(0, ctx); + getNotificationManager(ctx).cancel(ID); + ShortcutBadger.with(ctx).remove(); + } + + /** + * Retrieves the badge of the app icon. + * + * @param ctx + * The application context. + * @param callback + * The function to be exec as the callback. + */ + protected void getBadge (CallbackContext callback, Context ctx) { + SharedPreferences settings = getSharedPreferences(ctx); + int badge = settings.getInt(KEY, 0); + PluginResult result; + + result = new PluginResult(PluginResult.Status.OK, badge); + + callback.sendPluginResult(result); + } + + /** + * Sets the badge of the app icon. + * + * @param args + * The new badge number + * @param ctx + * The application context + */ + protected void setBadge (JSONArray args, Context ctx) { + int badge = args.optInt(0); + + saveBadge(badge, ctx); + + if (canBadgeAppIcon(ctx)) { + ShortcutBadger.with(ctx).count(badge); + } else { + setBadgeNotification(badge, args, ctx); + } + } + + /** + * Sets the badge of the app icon. + * + * @param args + * The new badge number + * @param ctx + * The application context + */ + @SuppressWarnings("deprecation") + private void setBadgeNotification (int badge, JSONArray args, Context ctx) { + String title = args.optString(1, "%d new messages"); + String icon = args.optString(2); + boolean autoCancel = args.optBoolean(3, false); + + Resources res = ctx.getResources(); + Bitmap appIcon = BitmapFactory.decodeResource( + res, getDrawableIcon(ctx)); + + Intent intent = new Intent(ctx, LaunchActivity.class) + .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); + + intent.putExtra(EXTRA_AUTO_CANCEL, autoCancel); + + PendingIntent contentIntent = PendingIntent.getActivity( + ctx, ID, intent, PendingIntent.FLAG_CANCEL_CURRENT); + + String title_ = String.format(title, badge); + + Notification.Builder notification = new Notification.Builder(ctx) + .setContentTitle(title_) + .setNumber(badge) + .setTicker(title_) + .setAutoCancel(autoCancel) + .setSmallIcon(getResIdForSmallIcon(icon, ctx)) + .setLargeIcon(appIcon) + .setContentIntent(contentIntent); + + if (Build.VERSION.SDK_INT<16) { + // Build notification for HoneyComb to ICS + getNotificationManager(ctx).notify(ID, notification.getNotification()); + } else if (Build.VERSION.SDK_INT>15) { + // Notification for Jellybean and above + getNotificationManager(ctx).notify(ID, notification.build()); + } + } + + /** + * Persist the badge of the app icon so that `getBadge` is able to return + * the badge number back to the client. + * + * @param badge + * The badge of the app icon. + * @param ctx + * The application context. + */ + protected void saveBadge (int badge, Context ctx) { + SharedPreferences.Editor editor = getSharedPreferences(ctx).edit(); + + editor.putInt(KEY, badge); + editor.apply(); + } + + /** + * Informs if the app has the permission to show badges. + * + * @param callback + * The function to be exec as the callback + */ + protected void hasPermission (final CallbackContext callback) { + PluginResult result = new PluginResult(PluginResult.Status.OK, true); + + callback.sendPluginResult(result); + } + + /** + * The Local storage for the application. + */ + private SharedPreferences getSharedPreferences (Context context) { + return context.getSharedPreferences(KEY, Context.MODE_PRIVATE); + } + + /** + * The NotificationManager for the app. + */ + private NotificationManager getNotificationManager (Context context) { + return (NotificationManager) context.getSystemService( + Context.NOTIFICATION_SERVICE); + } + + /** + * Returns the ID for the given resource. + * + * @return + * The resource ID of the app icon + */ + private int getDrawableIcon (Context ctx) { + Resources res = ctx.getResources(); + String pkgName = ctx.getPackageName(); + + int resId; + resId = res.getIdentifier("icon", "drawable", pkgName); + + return resId; + } + + /** + * Returns the ID for the given resource. + * + * @return + * The resource ID for the small icon. + */ + private int getResIdForSmallIcon (String smallIcon, Context ctx) { + int resId; + + String pkgName = ctx.getPackageName(); + + resId = getResId(pkgName, smallIcon); + + if (resId == 0) { + resId = getResId("android", smallIcon); + } + + if (resId == 0) { + resId = getResId("android", "ic_dialog_email"); + } + + return resId; + } + + /** + * Returns numerical icon Value. + * + * @param className + * The class name prefix either from Android or the app. + * @param iconName + * The resource name. + */ + private int getResId (String className, String iconName) { + int icon = 0; + + try { + Class<?> klass = Class.forName(className + ".R$drawable"); + + icon = (Integer) klass.getDeclaredField(iconName).get(Integer.class); + } catch (Exception ignored) {} + + return icon; + } + +} diff --git a/plugins/de.appplant.cordova.plugin.badge/src/android/LaunchActivity.java b/plugins/de.appplant.cordova.plugin.badge/src/android/LaunchActivity.java new file mode 100644 index 00000000..8e2227fb --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/android/LaunchActivity.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.badge; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; + +public class LaunchActivity extends Activity { + + /** + * Clears the badge and moves the launch intent + * (web view) back to front. + */ + @Override + public void onCreate (Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent intent = getIntent(); + boolean cancel = intent.getBooleanExtra( + BadgeImpl.EXTRA_AUTO_CANCEL, false); + + if (cancel) { + clearBagde(); + } + + launchMainIntent(); + } + + /** + * Launch main intent for package. + */ + private void launchMainIntent () { + Context context = getApplicationContext(); + String pkgName = context.getPackageName(); + Intent intent = context.getPackageManager() + .getLaunchIntentForPackage(pkgName); + + intent.addFlags( + Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); + + context.startActivity(intent); + } + + /** + * Removes the badge of the app icon so that `getBadge` + * will return 0 back to the client. + */ + private void clearBagde () { + SharedPreferences.Editor editor = getSharedPreferences().edit(); + + editor.putInt(BadgeImpl.KEY, 0); + editor.apply(); + } + + /** + * The Local storage for the application. + */ + private SharedPreferences getSharedPreferences () { + Context context = getApplicationContext(); + + return context.getSharedPreferences(BadgeImpl.KEY, Context.MODE_PRIVATE); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.badge/src/android/badge.gradle b/plugins/de.appplant.cordova.plugin.badge/src/android/badge.gradle new file mode 100644 index 00000000..b2a7b07d --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/android/badge.gradle @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +repositories { + mavenCentral() +} + +dependencies { + compile 'me.leolin:ShortcutBadger:1.1.2@aar' +} diff --git a/plugins/de.appplant.cordova.plugin.badge/src/browser/BadgeProxy.js b/plugins/de.appplant.cordova.plugin.badge/src/browser/BadgeProxy.js new file mode 100644 index 00000000..44edd023 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/browser/BadgeProxy.js @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + + +/** + * Instance of the Favico.js libary. + * @type {Favico} + */ +exports.favico = new cordova.plugins.notification.badge.Favico({ + animation: 'none' +}); + +/** + * Holds the current badge number value. + * @type {Number} + */ +exports.badgeNumber = 0; + + +/** + * Clears the badge of the app icon. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.clearBadge = function (success, error) { + exports.setBadge(success, error, [0]); +}; + +/** + * Sets the badge of the app icon. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {Number} badge + * The new badge number + */ +exports.setBadge = function (success, error, args) { + var badge = args[0]; + + exports.badgeNumber = badge; + + exports.favico.badge(badge); + success(badge); +}; + +/** + * Gets the badge of the app icon. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.getBadge = function (success, error) { + success(exports.badgeNumber); +}; + +/** + * Informs if the app has the permission to show badges. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.hasPermission = function (success, error) { + success(true); +}; + +/** + * Register permission to show badges if not already granted. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.registerPermission = function (success, error) { + success(true); +}; + + +cordova.commandProxy.add('Badge', exports); diff --git a/plugins/de.appplant.cordova.plugin.badge/src/browser/favico.min.js b/plugins/de.appplant.cordova.plugin.badge/src/browser/favico.min.js new file mode 100644 index 00000000..de0de6bc --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/browser/favico.min.js @@ -0,0 +1,7 @@ +/** + * @license MIT + * @fileOverview Favico animations + * @author Miroslav Magda, http://blog.ejci.net + * @version 0.3.9 + */ +!function(){var e=function(e){"use strict";function t(e){if(e.paused||e.ended||g)return!1;try{f.clearRect(0,0,s,l),f.drawImage(e,0,0,s,l)}catch(o){}p=setTimeout(t,S.duration,e),O.setIcon(h)}function o(e){var t=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;e=e.replace(t,function(e,t,o,n){return t+t+o+o+n+n});var o=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return o?{r:parseInt(o[1],16),g:parseInt(o[2],16),b:parseInt(o[3],16)}:!1}function n(e,t){var o,n={};for(o in e)n[o]=e[o];for(o in t)n[o]=t[o];return n}function r(){return b.hidden||b.msHidden||b.webkitHidden||b.mozHidden}e=e?e:{};var i,a,l,s,h,f,c,d,u,y,w,g,x,m,p,b,v={bgColor:"#d00",textColor:"#fff",fontFamily:"sans-serif",fontStyle:"bold",type:"circle",position:"down",animation:"slide",elementId:!1,dataUrl:!1,win:window};x={},x.ff="undefined"!=typeof InstallTrigger,x.chrome=!!window.chrome,x.opera=!!window.opera||navigator.userAgent.indexOf("Opera")>=0,x.ie=/*@cc_on!@*/!1,x.safari=Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0,x.supported=x.chrome||x.ff||x.opera;var C=[];w=function(){},d=g=!1;var E=function(){i=n(v,e),i.bgColor=o(i.bgColor),i.textColor=o(i.textColor),i.position=i.position.toLowerCase(),i.animation=S.types[""+i.animation]?i.animation:v.animation,b=i.win.document;var t=i.position.indexOf("up")>-1,r=i.position.indexOf("left")>-1;if(t||r)for(var d=0;d<S.types[""+i.animation].length;d++){var u=S.types[""+i.animation][d];t&&(u.y=u.y<.6?u.y-.4:u.y-2*u.y+(1-u.w)),r&&(u.x=u.x<.6?u.x-.4:u.x-2*u.x+(1-u.h)),S.types[""+i.animation][d]=u}i.type=A[""+i.type]?i.type:v.type,a=O.getIcon(),h=document.createElement("canvas"),c=document.createElement("img"),a.hasAttribute("href")?(c.setAttribute("crossOrigin","anonymous"),c.setAttribute("src",a.getAttribute("href")),c.onload=function(){l=c.height>0?c.height:32,s=c.width>0?c.width:32,h.height=l,h.width=s,f=h.getContext("2d"),M.ready()}):(c.setAttribute("src",""),l=32,s=32,c.height=l,c.width=s,h.height=l,h.width=s,f=h.getContext("2d"),M.ready())},M={};M.ready=function(){d=!0,M.reset(),w()},M.reset=function(){d&&(C=[],u=!1,y=!1,f.clearRect(0,0,s,l),f.drawImage(c,0,0,s,l),O.setIcon(h),window.clearTimeout(m),window.clearTimeout(p))},M.start=function(){if(d&&!y){var e=function(){u=C[0],y=!1,C.length>0&&(C.shift(),M.start())};if(C.length>0){y=!0;var t=function(){["type","animation","bgColor","textColor","fontFamily","fontStyle"].forEach(function(e){e in C[0].options&&(i[e]=C[0].options[e])}),S.run(C[0].options,function(){e()},!1)};u?S.run(u.options,function(){t()},!0):t()}}};var A={},I=function(e){return e.n="number"==typeof e.n?Math.abs(0|e.n):e.n,e.x=s*e.x,e.y=l*e.y,e.w=s*e.w,e.h=l*e.h,e.len=(""+e.n).length,e};A.circle=function(e){e=I(e);var t=!1;2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w,t=!0):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w,t=!0),f.clearRect(0,0,s,l),f.drawImage(c,0,0,s,l),f.beginPath(),f.font=i.fontStyle+" "+Math.floor(e.h*(e.n>99?.85:1))+"px "+i.fontFamily,f.textAlign="center",t?(f.moveTo(e.x+e.w/2,e.y),f.lineTo(e.x+e.w-e.h/2,e.y),f.quadraticCurveTo(e.x+e.w,e.y,e.x+e.w,e.y+e.h/2),f.lineTo(e.x+e.w,e.y+e.h-e.h/2),f.quadraticCurveTo(e.x+e.w,e.y+e.h,e.x+e.w-e.h/2,e.y+e.h),f.lineTo(e.x+e.h/2,e.y+e.h),f.quadraticCurveTo(e.x,e.y+e.h,e.x,e.y+e.h-e.h/2),f.lineTo(e.x,e.y+e.h/2),f.quadraticCurveTo(e.x,e.y,e.x+e.h/2,e.y)):f.arc(e.x+e.w/2,e.y+e.h/2,e.h/2,0,2*Math.PI),f.fillStyle="rgba("+i.bgColor.r+","+i.bgColor.g+","+i.bgColor.b+","+e.o+")",f.fill(),f.closePath(),f.beginPath(),f.stroke(),f.fillStyle="rgba("+i.textColor.r+","+i.textColor.g+","+i.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?f.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):f.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),f.closePath()},A.rectangle=function(e){e=I(e);var t=!1;2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w,t=!0):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w,t=!0),f.clearRect(0,0,s,l),f.drawImage(c,0,0,s,l),f.beginPath(),f.font=i.fontStyle+" "+Math.floor(e.h*(e.n>99?.9:1))+"px "+i.fontFamily,f.textAlign="center",f.fillStyle="rgba("+i.bgColor.r+","+i.bgColor.g+","+i.bgColor.b+","+e.o+")",f.fillRect(e.x,e.y,e.w,e.h),f.fillStyle="rgba("+i.textColor.r+","+i.textColor.g+","+i.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?f.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):f.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),f.closePath()};var T=function(e,t){t=("string"==typeof t?{animation:t}:t)||{},w=function(){try{if("number"==typeof e?e>0:""!==e){var n={type:"badge",options:{n:e}};if("animation"in t&&S.types[""+t.animation]&&(n.options.animation=""+t.animation),"type"in t&&A[""+t.type]&&(n.options.type=""+t.type),["bgColor","textColor"].forEach(function(e){e in t&&(n.options[e]=o(t[e]))}),["fontStyle","fontFamily"].forEach(function(e){e in t&&(n.options[e]=t[e])}),C.push(n),C.length>100)throw new Error("Too many badges requests in queue.");M.start()}else M.reset()}catch(r){throw new Error("Error setting badge. Message: "+r.message)}},d&&w()},U=function(e){w=function(){try{var t=e.width,o=e.height,n=document.createElement("img"),r=o/l>t/s?t/s:o/l;n.setAttribute("crossOrigin","anonymous"),n.setAttribute("src",e.getAttribute("src")),n.height=o/r,n.width=t/r,f.clearRect(0,0,s,l),f.drawImage(n,0,0,s,l),O.setIcon(h)}catch(i){throw new Error("Error setting image. Message: "+i.message)}},d&&w()},R=function(e){w=function(){try{if("stop"===e)return g=!0,M.reset(),void(g=!1);e.addEventListener("play",function(){t(this)},!1)}catch(o){throw new Error("Error setting video. Message: "+o.message)}},d&&w()},L=function(e){if(window.URL&&window.URL.createObjectURL||(window.URL=window.URL||{},window.URL.createObjectURL=function(e){return e}),x.supported){var o=!1;navigator.getUserMedia=navigator.getUserMedia||navigator.oGetUserMedia||navigator.msGetUserMedia||navigator.mozGetUserMedia||navigator.webkitGetUserMedia,w=function(){try{if("stop"===e)return g=!0,M.reset(),void(g=!1);o=document.createElement("video"),o.width=s,o.height=l,navigator.getUserMedia({video:!0,audio:!1},function(e){o.src=URL.createObjectURL(e),o.play(),t(o)},function(){})}catch(n){throw new Error("Error setting webcam. Message: "+n.message)}},d&&w()}},O={};O.getIcon=function(){var e=!1,t=function(){for(var e=b.getElementsByTagName("head")[0].getElementsByTagName("link"),t=e.length,o=t-1;o>=0;o--)if(/(^|\s)icon(\s|$)/i.test(e[o].getAttribute("rel")))return e[o];return!1};return i.element?e=i.element:i.elementId?(e=b.getElementById(i.elementId),e.setAttribute("href",e.getAttribute("src"))):(e=t(),e===!1&&(e=b.createElement("link"),e.setAttribute("rel","icon"),b.getElementsByTagName("head")[0].appendChild(e))),e.setAttribute("type","image/png"),e},O.setIcon=function(e){var t=e.toDataURL("image/png");if(i.dataUrl&&i.dataUrl(t),i.element)i.element.setAttribute("href",t),i.element.setAttribute("src",t);else if(i.elementId){var o=b.getElementById(i.elementId);o.setAttribute("href",t),o.setAttribute("src",t)}else if(x.ff||x.opera){var n=a;a=b.createElement("link"),x.opera&&a.setAttribute("rel","icon"),a.setAttribute("rel","icon"),a.setAttribute("type","image/png"),b.getElementsByTagName("head")[0].appendChild(a),a.setAttribute("href",t),n.parentNode&&n.parentNode.removeChild(n)}else a.setAttribute("href",t)};var S={};return S.duration=40,S.types={},S.types.fade=[{x:.4,y:.4,w:.6,h:.6,o:0},{x:.4,y:.4,w:.6,h:.6,o:.1},{x:.4,y:.4,w:.6,h:.6,o:.2},{x:.4,y:.4,w:.6,h:.6,o:.3},{x:.4,y:.4,w:.6,h:.6,o:.4},{x:.4,y:.4,w:.6,h:.6,o:.5},{x:.4,y:.4,w:.6,h:.6,o:.6},{x:.4,y:.4,w:.6,h:.6,o:.7},{x:.4,y:.4,w:.6,h:.6,o:.8},{x:.4,y:.4,w:.6,h:.6,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],S.types.none=[{x:.4,y:.4,w:.6,h:.6,o:1}],S.types.pop=[{x:1,y:1,w:0,h:0,o:1},{x:.9,y:.9,w:.1,h:.1,o:1},{x:.8,y:.8,w:.2,h:.2,o:1},{x:.7,y:.7,w:.3,h:.3,o:1},{x:.6,y:.6,w:.4,h:.4,o:1},{x:.5,y:.5,w:.5,h:.5,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],S.types.popFade=[{x:.75,y:.75,w:0,h:0,o:0},{x:.65,y:.65,w:.1,h:.1,o:.2},{x:.6,y:.6,w:.2,h:.2,o:.4},{x:.55,y:.55,w:.3,h:.3,o:.6},{x:.5,y:.5,w:.4,h:.4,o:.8},{x:.45,y:.45,w:.5,h:.5,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],S.types.slide=[{x:.4,y:1,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.8,w:.6,h:.6,o:1},{x:.4,y:.7,w:.6,h:.6,o:1},{x:.4,y:.6,w:.6,h:.6,o:1},{x:.4,y:.5,w:.6,h:.6,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],S.run=function(e,t,o,a){var l=S.types[r()?"none":i.animation];return a=o===!0?"undefined"!=typeof a?a:l.length-1:"undefined"!=typeof a?a:0,t=t?t:function(){},a<l.length&&a>=0?(A[i.type](n(e,l[a])),m=setTimeout(function(){o?a-=1:a+=1,S.run(e,t,o,a)},S.duration),O.setIcon(h),void 0):void t()},E(),{badge:T,video:R,image:U,webcam:L,reset:M.reset,browser:{supported:x.supported}}};"undefined"!=typeof define&&define.amd?define([],function(){return e}):"undefined"!=typeof module&&module.exports?module.exports=e:this.Favico=e}(); diff --git a/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.h b/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.h new file mode 100644 index 00000000..bf9a1e58 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import <Foundation/Foundation.h> +#import <Cordova/CDVPlugin.h> + +@interface APPBadge : CDVPlugin + +// Clears the badge of the app icon +- (void) clearBadge:(CDVInvokedUrlCommand *)command; +// Sets the badge of the app icon +- (void) setBadge:(CDVInvokedUrlCommand *)command; +// Gets the badge of the app icon +- (void) getBadge:(CDVInvokedUrlCommand *)command; +// Informs if the app has the permission to show badges +- (void) hasPermission:(CDVInvokedUrlCommand *)command; +// Register permission to show badges +- (void) registerPermission:(CDVInvokedUrlCommand *)command; + +@end diff --git a/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.m b/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.m new file mode 100644 index 00000000..e7db643f --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.m @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "APPBadge.h" +#import "UIApplication+APPBadge.h" +#import "AppDelegate+APPRegisterUserNotificationSettings.h" + +@interface APPBadge () + +// Needed when calling `registerPermission` +@property (nonatomic, retain) CDVInvokedUrlCommand* command; + +@end + +@implementation APPBadge + +#pragma mark - +#pragma mark Interface + +/** + * Clears the badge of the app icon. + * + */ +- (void) clearBadge:(CDVInvokedUrlCommand *)command +{ + [self.commandDelegate runInBackground:^{ + [self.app setApplicationIconBadgeNumber:0]; + + [self sendPluginResult:CDVCommandStatus_OK + messageAsLong:0 + callbackId:command.callbackId]; + }]; +} + +/** + * Sets the badge of the app icon. + * + * @param badge + * The badge to be set + */ +- (void) setBadge:(CDVInvokedUrlCommand *)command +{ + NSArray* args = [command arguments]; + int number = [[args objectAtIndex:0] intValue]; + + [self.commandDelegate runInBackground:^{ + [self.app setApplicationIconBadgeNumber:number]; + + [self sendPluginResult:CDVCommandStatus_OK + messageAsLong:number + callbackId:command.callbackId]; + }]; +} + +/** + * Gets the badge of the app icon. + * + * @param callback + * The function to be exec as the callback + */ +- (void) getBadge:(CDVInvokedUrlCommand *)command +{ + [self.commandDelegate runInBackground:^{ + long badge = [self.app applicationIconBadgeNumber]; + + [self sendPluginResult:CDVCommandStatus_OK + messageAsLong:badge + callbackId:command.callbackId]; + }]; +} + +/** + * Informs if the app has the permission to show badges. + * + * @param callback + * The function to be exec as the callback + */ +- (void) hasPermission:(CDVInvokedUrlCommand *)command +{ + [self.commandDelegate runInBackground:^{ + BOOL hasPermission = [self.app hasPermissionToDisplayBadges]; + + [self sendPluginResult:CDVCommandStatus_OK + messageAsBool:hasPermission + callbackId:command.callbackId]; + }]; +} + +/** + * Register permission to show badges. + * + * @param callback + * The function to be exec as the callback + */ +- (void) registerPermission:(CDVInvokedUrlCommand *)command +{ + if (![[UIApplication sharedApplication] + respondsToSelector:@selector(registerUserNotificationSettings:)]) + { + return [self hasPermission:command]; + } + + _command = command; + + [self.commandDelegate runInBackground:^{ + [self.app registerPermissionToDisplayBadges]; + }]; +} + +#pragma mark - +#pragma mark Delegates + +/** + * Called on otification settings registration is completed. + */ +- (void) didRegisterUserNotificationSettings:(UIUserNotificationSettings*)settings +{ + if (_command) + { + [self hasPermission:_command]; + _command = NULL; + } +} + +#pragma mark - +#pragma mark Life Cycle + +/** + * Registers obervers after plugin was initialized. + */ +- (void) pluginInitialize +{ + NSNotificationCenter* center = [NSNotificationCenter + defaultCenter]; + + [center addObserver:self + selector:@selector(didRegisterUserNotificationSettings:) + name:UIApplicationRegisterUserNotificationSettings + object:nil]; +} + +#pragma mark - +#pragma mark Helper + +/** + * Short hand for shared application instance. + */ +- (UIApplication*) app +{ + return [UIApplication sharedApplication]; +} + +/** + * Sends a plugin result with the specified status and message. + */ +- (void) sendPluginResult:(CDVCommandStatus)status + messageAsBool:(BOOL)msg + callbackId:(NSString*)callbackId +{ + CDVPluginResult* result; + + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK + messageAsBool:msg]; + + [self.commandDelegate sendPluginResult:result + callbackId:callbackId]; +} + +/** + * Sends a plugin result with the specified status and message. + */ +- (void) sendPluginResult:(CDVCommandStatus)status + messageAsLong:(long)msg + callbackId:(NSString*)callbackId +{ + CDVPluginResult* result; + + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK + messageAsDouble:msg]; + + [self.commandDelegate sendPluginResult:result + callbackId:callbackId]; +} + +@end diff --git a/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.h b/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.h new file mode 100644 index 00000000..9ce7f7e5 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +@interface UIApplication (APPBadge) + +// If the app has the permission to display badges +- (BOOL) hasPermissionToDisplayBadges; +// Ask for permission to display badges +- (void) registerPermissionToDisplayBadges; + +@end diff --git a/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.m b/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.m new file mode 100644 index 00000000..3e4cd99b --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.m @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "UIApplication+APPBadge.h" + +@implementation UIApplication (APPBadge) + +#pragma mark - +#pragma mark Permissions + +/** + * If the app has the permission to display badges. + */ +- (BOOL) hasPermissionToDisplayBadges +{ + if (![self respondsToRegisterUserNotificationSettings]) + return YES; + + UIUserNotificationSettings *settings; + + settings = [[UIApplication sharedApplication] + currentUserNotificationSettings]; + + return (settings.types & UIUserNotificationTypeBadge); +} + +/** + * Register permission to display badges. + */ +- (void) registerPermissionToDisplayBadges +{ + if (![self respondsToRegisterUserNotificationSettings]) + return; + + UIUserNotificationType types; + UIUserNotificationSettings *settings; + + settings = [[UIApplication sharedApplication] + currentUserNotificationSettings]; + + types = settings.types | UIUserNotificationTypeBadge; + + settings = [UIUserNotificationSettings settingsForTypes:types + categories:nil]; + + [[UIApplication sharedApplication] + registerUserNotificationSettings:settings]; +} + +#pragma mark - +#pragma mark Helper methods + +/** + * If UIApplication responds to seelctor registerUserNotificationSettings: + * + * @return + * true for iOS8 and above + */ +- (BOOL) respondsToRegisterUserNotificationSettings +{ + return [[UIApplication sharedApplication] + respondsToSelector:@selector(registerUserNotificationSettings:)]; +} + +@end diff --git a/plugins/de.appplant.cordova.plugin.badge/src/windows/BadgeProxy.js b/plugins/de.appplant.cordova.plugin.badge/src/windows/BadgeProxy.js new file mode 100644 index 00000000..33029f2c --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/windows/BadgeProxy.js @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + + +/** + * Clears the badge of the app icon. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.clearBadge = function (success, error) { + exports.setBadge(success, error, [0]); +}; + +/** + * Gets the badge of the app icon. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.getBadge = function (success, error) { + var app = WinJS.Application, + file = exports._cordova_badge_number; + + app.local.exists(file).then(function (exists) { + if (exists) { + app.local.readText(file).then(function (badge) { + success(isNaN(badge) ? badge : Number(badge)); + }); + } else { + success(0); + } + }); +}; + +/** + * Informs if the app has the permission to show badges. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.hasPermission = function (success, error) { + success(true); +}; + +/** + * Register permission to show badges if not already granted. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.registerPermission = function (success, error) { + exports.hasPermission(success, error); +}; + +/** + * Sets the badge of the app icon. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {Number} badge + * The new badge number + */ +exports.setBadge = function (success, error, args) { + var notifications = Windows.UI.Notifications, + badge = args[0], + type = notifications.BadgeTemplateType.badgeNumber, + xml = notifications.BadgeUpdateManager.getTemplateContent(type), + attrs = xml.getElementsByTagName('badge'), + notification = new notifications.BadgeNotification(xml); + + attrs[0].setAttribute('value', badge); + + notifications.BadgeUpdateManager + .createBadgeUpdaterForApplication() + .update(notification); + + exports._saveBadge(badge); + + success(badge); +}; + + +/******** + * UTIL * + ********/ + +/** + * Path to file that containes the badge number. + * @type {String} + */ +exports._cordova_badge_number = 'cordova_badge_number'; + +/** + * Persist the badge of the app icon so that `getBadge` is able to return the + * badge number back to the client. + * + * @param {Number|String} badge + * The badge number to save for. + * + * @return void + */ +exports._saveBadge = function (badge) { + WinJS.Application.local.writeText(exports._cordova_badge_number, badge); +}; + + +cordova.commandProxy.add('Badge', exports); diff --git a/plugins/de.appplant.cordova.plugin.badge/src/wp8/Badge.cs b/plugins/de.appplant.cordova.plugin.badge/src/wp8/Badge.cs new file mode 100644 index 00000000..eb384c38 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/src/wp8/Badge.cs @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +using System; +using System.Linq; + +using Microsoft.Phone.Shell; + +using WPCordovaClassLib.Cordova; +using WPCordovaClassLib.Cordova.Commands; +using WPCordovaClassLib.Cordova.JSON; +using System.IO.IsolatedStorage; + +namespace Cordova.Extension.Commands +{ + public class Badge : BaseCommand + { + + /// <summary> + /// Name for the shared preferences + /// <summary> + private const string KEY = "badge"; + + /// <summary> + /// Clears the count property of the live tile + /// </summary> + public void clearBadge (string args) + { + setBadge(args); + getBadge(args); + } + + /// <summary> + /// Sets the count property of the live tile + /// </summary> + public void setBadge (string args) + { + // Application Tile is always the first Tile, even if it is not pinned to Start. + ShellTile tile = ShellTile.ActiveTiles.First(); + + // Application should always be found + if (tile != null) + { + string[] ary = JsonHelper.Deserialize<string[]>(args); + int count = 0; + string title = ""; + + try { + count = int.Parse(ary[0]); + } + catch (FormatException) { }; + + if (ary.Length > 1) + { + title = ary[1].Replace("%d", "{0}"); + title = String.Format(title, count); + } + + StandardTileData TileData = new StandardTileData + { + Count = count, + BackTitle = title + }; + + SaveBadge(count); + + tile.Update(TileData); + } + + getBadge(args); + } + + /// <summary> + /// Gets the count property of the live tile + /// </summary> + public void getBadge (string args) + { + // Application Tile is always the first Tile, even if it is not pinned to Start. + ShellTile tile = ShellTile.ActiveTiles.First(); + + // Application should always be found + if (tile != null) + { + IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings; + int badge = 0; + PluginResult result; + + if (settings.Contains(KEY)) { + badge = (int)settings[KEY]; + } + + result = new PluginResult(PluginResult.Status.OK, badge); + + DispatchCommandResult(result); + } + } + + /// <summery> + /// Informs if the app has the permission to show badges. + /// </summery> + public void hasPermission (string args) + { + PluginResult result; + + result = new PluginResult(PluginResult.Status.OK, true); + + DispatchCommandResult(result); + } + + /// <summery> + /// Ask for permission to show badges. + /// </summery> + public void registerPermission (string args) + { + hasPermission(args); + } + + /// <summary> + /// Persist the badge of the app icon so that `getBadge` is able to return + /// the badge number back to the client. + /// </summary> + private void SaveBadge (int badge) + { + IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings; + + if (settings.Contains(KEY)) { + settings[KEY] = badge; + } + else { + settings.Add(KEY, badge); + } + } + + } +} diff --git a/plugins/de.appplant.cordova.plugin.badge/tests/plugin.xml b/plugins/de.appplant.cordova.plugin.badge/tests/plugin.xml new file mode 100644 index 00000000..f8d815bf --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/tests/plugin.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ +--> + +<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" + xmlns:android="http://schemas.android.com/apk/res/android" + id="de.appplant.cordova.plugin.badge-tests" + version="0.7.0dev"> + + <name>Cordova Badge Plugin Tests</name> + <license>Apache 2.0</license> + + <js-module src="tests.js" name="tests" /> +</plugin> diff --git a/plugins/de.appplant.cordova.plugin.badge/tests/tests.js b/plugins/de.appplant.cordova.plugin.badge/tests/tests.js new file mode 100644 index 00000000..473cd02a --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/tests/tests.js @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + + +exports.defineAutoTests = function() { + + describe('Badge Plugin (cordova.plugins.notification.badge)', function () { + + describe('Plugin availability', function () { + + it("should exist", function() { + expect(cordova.plugins.notification.badge).toBeDefined(); + }); + + it("should define clear", function() { + expect(cordova.plugins.notification.badge.clear).toBeDefined(); + }); + + it("should define get", function() { + expect(cordova.plugins.notification.badge.get).toBeDefined(); + }); + + it("should define set", function() { + expect(cordova.plugins.notification.badge.set).toBeDefined(); + }); + + it("should define increase", function() { + expect(cordova.plugins.notification.badge.increase).toBeDefined(); + }); + + it("should define decrease", function() { + expect(cordova.plugins.notification.badge.decrease).toBeDefined(); + }); + + it("should define hasPermission", function() { + expect(cordova.plugins.notification.badge.hasPermission).toBeDefined(); + }); + + it("should define registerPermission", function() { + expect(cordova.plugins.notification.badge.registerPermission).toBeDefined(); + }); + + it("should define configure", function() { + expect(cordova.plugins.notification.badge.configure).toBeDefined(); + }); + + }); + + describe('API callbacks', function () { + + it("clear should invoke callback", function(done) { + cordova.plugins.notification.badge.clear(done); + }); + + it("get should invoke callback", function(done) { + cordova.plugins.notification.badge.get(done); + }); + + it("set should invoke callback", function(done) { + cordova.plugins.notification.badge.set(done); + }); + + it("increase should invoke callback", function(done) { + cordova.plugins.notification.badge.increase(done); + }); + + it("decrease should invoke callback", function(done) { + cordova.plugins.notification.badge.decrease(done); + }); + + it("hasPermission should invoke callback", function(done) { + cordova.plugins.notification.badge.hasPermission(done); + }); + + it("registerPermission should invoke callback", function(done) { + cordova.plugins.notification.badge.registerPermission(done); + }); + + }); + + describe('API functions', function () { + + it("clear should set badge to 0", function(done) { + cordova.plugins.notification.badge.clear(function (badge) { + expect(badge).toBe(0); + done(); + }); + }); + + it("should return badge", function(done) { + cordova.plugins.notification.badge.set(10, function (badge) { + expect(badge).toBe(10); + + cordova.plugins.notification.badge.get(function (badge2) { + expect(badge).toBe(badge2); + done(); + }); + }); + }); + + it("should increase badge", function(done) { + cordova.plugins.notification.badge.set(10, function () { + cordova.plugins.notification.badge.increase(1, function (badge) { + expect(badge).toBe(11); + done(); + }); + }); + }); + + it("should decrease badge", function(done) { + cordova.plugins.notification.badge.set(10, function () { + cordova.plugins.notification.badge.decrease(1, function (badge) { + expect(badge).toBe(9); + done(); + }); + }); + }); + + it("hasPermission should return boolean", function(done) { + cordova.plugins.notification.badge.hasPermission(function (has) { + expect(has === true || has === false).toBe(true); + done(); + }); + }); + + it("registerPermission should return boolean", function(done) { + cordova.plugins.notification.badge.registerPermission(function (has) { + expect(has === true || has === false).toBe(true); + done(); + }); + }); + + }); + + }); +}; diff --git a/plugins/de.appplant.cordova.plugin.badge/www/badge.js b/plugins/de.appplant.cordova.plugin.badge/www/badge.js new file mode 100644 index 00000000..ab6177cc --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.badge/www/badge.js @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +var exec = require('cordova/exec'), + channel = require('cordova/channel'); + + +/************* + * INTERFACE * + *************/ + +/** + * Clears the badge of the app icon. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.clear = function (callback, scope) { + this.exec('clearBadge', null, callback, scope); +}; + +/** + * Sets the badge of the app icon. + * + * @param {Number} badge + * The new badge number + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.set = function (badge, callback, scope) { + var args = [ + parseInt(badge) || 0, + this._config.title, + this._config.smallIcon, + this._config.autoClear + ]; + + this.registerPermission(function (granted) { + if (granted) { + this.exec('setBadge', args, callback, scope); + } + }, this); +}; + +/** + * Gets the badge of the app icon. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.get = function (callback, scope) { + this.exec('getBadge', null, callback, scope); +}; + +/** + * Increases the badge number. + * + * @param {Number} count + * Count to add to the current badge number + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.increase = function (count, callback, scope) { + this.get(function (badge) { + this.set(badge + (count || 1), callback, scope); + }, this); +}; + +/** + * Decreases the badge number. + * + * @param {Number} count + * Count to subtract from the current badge number + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.decrease = function (count, callback, scope) { + this.get(function (badge) { + this.set(Math.max(0, badge - (count || 1)), callback, scope); + }, this); +}; + +/** + * Informs if the app has the permission to show badges. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.hasPermission = function (callback, scope) { + this.exec('hasPermission', null, callback, scope); +}; + +/** + * Register permission to show badges if not already granted. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.registerPermission = function (callback, scope) { + this.exec('registerPermission', null, callback, scope); +}; + +/** + * Configures the plugin's platform options. + * + * @param {Hash?} object + * The new configuration settings + * + * @return {Hash} + * The current configuration settings + */ +exports.configure = function (config) { + for (var key in config) { + if (this._config.hasOwnProperty(key)) { + this._config[key] = config[key]; + } + } + + return this._config; +}; + + +/**************** + * DEPRECATIONS * + ****************/ + +/** + * Sets the custom notification title for Android. + * + * @param {String} title + * The title of the notification + */ +exports.setTitle = function (title) { + console.warn('badge.setTitle(title) is deprecated! Please use badge.configure({ title:title }) instead.'); + + this._config.title = title; +}; + +/** + * Tells the plugin if the badge needs to be cleared when the user taps + * the icon. + * + * @param {Boolean} clearOnTap + * Either true or false + */ +exports.setClearOnTap = function (clearOnTap) { + console.warn('badge.clearOnTap(bool) is deprecated! Please use badge.configure({ autoClear:bool }) instead.'); + + this._config.autoClear = clearOnTap; +}; + +/** + * Register permission to show notifications + * if not already granted. + */ +exports.promptForPermission = function () { + console.warn('Depreated: Please use `notification.badge.registerPermission` instead.'); + + this.registerPermission.apply(this, arguments); +}; + + +/*********** + * MEMBERS * + ***********/ + +exports._config = { + // Titel der Meldung für Android + title: '%d new messages', + // Ob die Badge Zahl automatisch beim Öffnen der App gelöscht werden soll + autoClear: false, + // Ob und welches Icon für Android verwendet werden soll + smallIcon: 'ic_dialog_email' +}; + + +/******** + * UTIL * + ********/ + +/** + * Create callback, which will be executed within a specific scope. + * + * @param {Function} callbackFn + * The callback function + * @param {Object} scope + * The scope for the function + * + * @return {Function} + * The new callback function + */ +exports.createCallbackFn = function (callbackFn, scope) { + if (typeof callbackFn != 'function') + return; + + return function () { + callbackFn.apply(scope || this, arguments); + }; +}; + +/** + * Execute the native counterpart. + * + * @param {String} action + * The name of the action + * @param args[] + * Array of arguments + * @param {Function} callback + * The callback function + * @param {Object} scope + * The scope for the function + */ +exports.exec = function (action, args, callback, scope) { + var fn = this.createCallbackFn(callback, scope), + params = []; + + if (Array.isArray(args)) { + params = args; + } else if (args) { + params.push(args); + } + + exec(fn, null, 'Badge', action, params); +}; + + +/********* + * HOOKS * + *********/ + +channel.onCordovaReady.subscribe(function () { + if (exports._config.autoClear) { exports.clear(); } +}); + +channel.onResume.subscribe(function () { + if (exports._config.autoClear) { exports.clear(); } +}); |
