├── index.js ├── app ├── initializers │ ├── cordova.js │ ├── contacts.js │ ├── device.js │ └── dialogs.js └── services │ ├── device.js │ ├── contacts.js │ └── dialogs.js ├── package.json └── README.md /index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | name: 'Ember CLI Cordova Utils' 3 | }; 4 | -------------------------------------------------------------------------------- /app/initializers/cordova.js: -------------------------------------------------------------------------------- 1 | import Contacts from '../services/contacts'; 2 | 3 | // Defers readiness of applicatoin until plugins are ready. 4 | export default { 5 | name: 'cordova', 6 | 7 | initialize: function(container, application) { 8 | if(typeof cordova !== 'undefined') { 9 | application.deferReadiness(); 10 | document.addEventListener('deviceready', function() { 11 | application.advanceReadiness(); 12 | }, false); 13 | } 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /app/initializers/contacts.js: -------------------------------------------------------------------------------- 1 | import Contacts from '../services/contacts'; 2 | 3 | export default { 4 | name: 'contacts', 5 | after: 'cordova', 6 | 7 | initialize: function(container, application) { 8 | container.register('cordova:contacts', Contacts); 9 | 10 | application.inject('route', 'contacts', 'cordova:contacts'); 11 | application.inject('controller', 'contacts', 'cordova:contacts'); 12 | application.inject('view', 'contacts', 'cordova:contacts'); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /app/initializers/device.js: -------------------------------------------------------------------------------- 1 | import Device from '../services/device'; 2 | 3 | export default { 4 | name: 'device', 5 | after: 'cordova', 6 | 7 | initialize: function(container, application) { 8 | container.register('cordova:device', Device); 9 | 10 | application.inject('route', 'device', 'cordova:device'); 11 | application.inject('controller', 'device', 'cordova:device'); 12 | application.inject('component', 'device', 'cordova:device'); 13 | application.inject('view', 'device', 'cordova:device'); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /app/initializers/dialogs.js: -------------------------------------------------------------------------------- 1 | import Dialogs from '../services/dialogs'; 2 | 3 | export default { 4 | name: 'dialogs', 5 | after: 'cordova', 6 | 7 | initialize: function(container, application) { 8 | container.register('cordova:dialogs', Dialogs); 9 | 10 | application.inject('route', 'dialogs', 'cordova:dialogs'); 11 | application.inject('controller', 'dialogs', 'cordova:dialogs'); 12 | application.inject('view', 'dialogs', 'cordova:dialogs'); 13 | application.inject('component', 'dialogs', 'cordova:dialogs'); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /app/services/device.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | var hasDevice = function() { 4 | return typeof device !== 'undefined'; 5 | }; 6 | 7 | var verifyDevice = function() { 8 | if(!hasDevice()) { 9 | window.device = { 10 | platform: 'browser' 11 | }; 12 | } 13 | }; 14 | 15 | export default Ember.Object.extend({ 16 | isAndroid: function() { 17 | verifyDevice(); 18 | return device.platform === 'Android'; 19 | }.property(), 20 | 21 | isiOS: function() { 22 | verifyDevice(); 23 | return device.platform === 'iOS'; 24 | }.property() 25 | }); 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-cli-cordova-utils", 3 | "version": "0.0.0", 4 | "description": "Utilities for cordova apps made with ember-cli-corodva", 5 | "main": "index.js", 6 | "scripts": { }, 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/poetic/ember-cli-cordova-utils" 10 | }, 11 | "keywords": [ 12 | "ember-addon", 13 | "emberjs", 14 | "cordova", 15 | "phonegap" 16 | ], 17 | "ember-addon": { 18 | "main": "index.js" 19 | }, 20 | "author": "Jake Craige ", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/poetic/ember-cli-cordova-utils/issues" 24 | }, 25 | "homepage": "https://github.com/poetic/ember-cli-cordova-utils" 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ember-cli-cordova-utils 2 | 3 | A utility library for wrapping various cordova plugins to provide a unified 4 | interface whether or not you are running in the browser or app. This also 5 | includes removing the callbacks and returning promises instead. 6 | 7 | The general idea is to ease the development of these type of apps. 8 | 9 | ### Installation 10 | 11 | This is made as an ember-cli addon. You can add it to your project by simply 12 | running this command below 13 | 14 | ``` 15 | npm install --save-dev poetic/ember-cli-cordova-utils 16 | ``` 17 | 18 | ### supported plugins 19 | 20 | + [org.apache.cordova.dialogs](https://github.com/apache/cordova-plugin-dialogs/blob/master/doc/index.md) 21 | + [org.apache.cordova.contacts](https://github.com/apache/cordova-plugin-contacts/blob/master/doc/index.md) 22 | -------------------------------------------------------------------------------- /app/services/contacts.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | var hasContacts = function(){ 4 | return typeof navigator.contacts !== 'undefined'; 5 | }; 6 | 7 | export default Ember.Object.extend({ 8 | create: function(options) { 9 | if(!hasContacts()) { 10 | throw new Error('contacts not available from outside app'); 11 | } 12 | 13 | return navigator.contacts.create(options); 14 | }, 15 | 16 | find: function(fields, options){ 17 | return new Ember.RSVP.Promise(function(resolve, reject){ 18 | if(hasContacts()) { 19 | navigator.contacts.find(fields, resolve, reject, options); 20 | } else { 21 | reject('contacts not available from outside app'); 22 | } 23 | }); 24 | }, 25 | 26 | pickContact: function() { 27 | return new Ember.RSVP.Promise(function(resolve, reject){ 28 | if(hasContacts()) { 29 | navigator.contacts.pickContact(resolve, reject); 30 | } else { 31 | reject('contacts not available from outside app'); 32 | } 33 | }); 34 | } 35 | }); 36 | -------------------------------------------------------------------------------- /app/services/dialogs.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | var hasNotificationType = function(type){ 4 | return typeof navigator.notification !== 'undefined' && navigator.notification[type]; 5 | }; 6 | 7 | export default Ember.Object.extend({ 8 | 9 | // The promise returned will never reject since the callback has to 10 | // success/failure scenario 11 | alert: function(msg, title){ 12 | if(Ember.isBlank(title)) { 13 | title = 'Alert'; 14 | } 15 | 16 | return new Ember.RSVP.Promise(function(resolve){ 17 | if (hasNotificationType('alert')) { 18 | navigator.notification.alert(msg, resolve, title); 19 | } else { 20 | alert(msg); 21 | resolve(); 22 | } 23 | }); 24 | }, 25 | 26 | // Returns a promise that will be resolved when the first button is pressed. 27 | // It will reject when the alternate is 28 | confirm: function(msg, title, buttonLabels){ 29 | if(Ember.isBlank(title)) { 30 | title = 'Confirm'; 31 | } 32 | 33 | if(Ember.isBlank(buttonLabels)) { 34 | buttonLabels = ['Yes', 'No']; 35 | } 36 | 37 | return new Ember.RSVP.Promise(function(resolve, reject){ 38 | if (hasNotificationType('confirm')) { 39 | navigator.notification.confirm(msg, function(index) { 40 | // We're going to assume it's a 2 button confirm. If not, then just 41 | // use the navigator.notification.confirm directly 42 | if(index === 1 || index === true) { 43 | resolve(index); 44 | } else { 45 | reject(index); 46 | } 47 | }, title, buttonLabels); 48 | } else { 49 | if(confirm(msg)) { 50 | resolve(); 51 | } else { 52 | reject(); 53 | } 54 | } 55 | }); 56 | }, 57 | 58 | // Convenience destroy method to call destroyRecord on an ember-data model 59 | // after a deletion has been confirmed in a dialog. 60 | confirmDestroy: function(msg, title, model) { 61 | var confirmObject = this; 62 | if(Ember.isBlank(title)) { 63 | title = 'Delete'; 64 | } 65 | 66 | return this.confirm(msg, title).then(function() { 67 | return model.destroyRecord().catch(function(){ 68 | confirmObject.alert('We are unable to remove this right now. Please try again later.'); 69 | }); 70 | }); 71 | } 72 | }); 73 | --------------------------------------------------------------------------------