From 0ec737aa490b598b6d915c71a35f65788fdfbb15 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Tue, 29 Mar 2016 06:50:03 -0400 Subject: [PATCH 01/13] feat(ionicnative): add instance wrapper closes https://github.com/driftyco/ionic-native/issues/86 https://github.com/driftyco/ionic-native/issues/79 --- src/index.ts | 6 ++ src/plugins/googlemaps.ts | 35 +++++++++++ src/plugins/plugin.ts | 119 ++++++++++++++++++++++++++++---------- src/plugins/sqlite.ts | 106 +++++++++++++++++++++++++++++++++ test/app/index.html | 3 + 5 files changed, 237 insertions(+), 32 deletions(-) create mode 100644 src/plugins/googlemaps.ts create mode 100644 src/plugins/sqlite.ts diff --git a/src/index.ts b/src/index.ts index c2d8f139..e6b9444b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,7 @@ import {File} from './plugins/file'; import {Flashlight} from './plugins/flashlight'; import {Geolocation} from './plugins/geolocation'; import {Globalization} from './plugins/globalization'; +import {GoogleMaps} from './plugins/googlemaps'; import {Hotspot} from './plugins/hotspot'; import {ImagePicker} from './plugins/imagepicker'; import {InAppBrowser} from './plugins/inappbrowser'; @@ -41,6 +42,7 @@ import {SMS} from './plugins/sms'; import {SocialSharing} from './plugins/socialsharing'; import {SpinnerDialog} from './plugins/spinnerdialog'; import {Splashscreen} from './plugins/splashscreen'; +import {SQLite} from './plugins/sqlite'; import {StatusBar} from './plugins/statusbar'; import {Toast} from './plugins/toast'; import {TouchID} from './plugins/touchid'; @@ -72,6 +74,7 @@ export { Flashlight, Geolocation, Globalization, + GoogleMaps, Hotspot, ImagePicker, InAppBrowser, @@ -84,6 +87,7 @@ export { SocialSharing, SpinnerDialog, Splashscreen, + SQLite, StatusBar, Toast, TouchID, @@ -119,6 +123,7 @@ window['IonicNative'] = { Flashlight: Flashlight, Geolocation: Geolocation, Globalization: Globalization, + GoogleMaps : GoogleMaps, Hotspot: Hotspot, ImagePicker: ImagePicker, InAppBrowser: InAppBrowser, @@ -131,6 +136,7 @@ window['IonicNative'] = { SocialSharing: SocialSharing, SpinnerDialog: SpinnerDialog, Splashscreen: Splashscreen, + SQLite: SQLite, StatusBar: StatusBar, Toast: Toast, TouchID: TouchID, diff --git a/src/plugins/googlemaps.ts b/src/plugins/googlemaps.ts new file mode 100644 index 00000000..c9756268 --- /dev/null +++ b/src/plugins/googlemaps.ts @@ -0,0 +1,35 @@ +import {Cordova, Plugin} from "./plugin"; +import {Observable} from "rxjs/Observable"; +import {CordovaInstance} from "./plugin"; +/** + * Created by Ibrahim on 3/29/2016. + */ +declare var plugin : any; +/** + * @name Google Maps + */ +@Plugin({ + pluginRef: 'plugin.google.maps' +}) +export class GoogleMaps { + + private _objectInstance : any; + + constructor (elementId : string, public niggasIn = "paris") { + this._objectInstance = {};//plugin.google.maps.Map.getMap(document.getElementById(elementId)); + } + + @Cordova({ + eventObservable: true, + event: 'plugin.google.maps.event.MAP_READY' + }) + static onInit () : Observable {return} + + @CordovaInstance({ + sync: true + }) + setDebuggable (isDebuggable : boolean) : void {} + + setClickable (isClickable : boolean) : void {} + +} \ No newline at end of file diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index a06bb16d..bef02f36 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -54,45 +54,53 @@ export const cordovaWarn = function(pluginName: string, method: string) { console.warn('Native: tried accessing the ' + pluginName + ' plugin but Cordova is not available. Make sure to include cordova.js or run in a device/simulator'); } }; +function setIndex (args:any[], opts:any={}, resolve? : Function, reject?: Function) : any { + // If the plugin method expects myMethod(success, err, options) + if (opts.callbackOrder == 'reverse') { + // Get those arguments in the order [resolve, reject, ...restOfArgs] + args.unshift(reject); + args.unshift(resolve); + } else if(typeof opts.successIndex !== 'undefined' || typeof opts.errorIndex !== 'undefined') { + // If we've specified a success/error index + args.splice(opts.successIndex, 0, resolve); + args.splice(opts.errorIndex, 0, reject); + } else { + // Otherwise, let's tack them on to the end of the argument list + // which is 90% of cases + args.push(resolve); + args.push(reject); + } + return args; +} +function systemCheck (pluginInstance : any, pluginObj : any, methodName, resolve?: Function, reject?: Function) : boolean { + if(!pluginInstance) { + // Do this check in here in the case that the Web API for this plugin is available (for example, Geolocation). + if(!window.cordova) { + cordovaWarn(pluginObj.name, methodName); + reject && reject({ + error: 'cordova_not_available' + }); + return false; + } + + pluginWarn(pluginObj, methodName); + reject && reject({ + error: 'plugin_not_installed' + }); + return false; + } + return; +} function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:any={}, resolve?: Function, reject?: Function) { // Try to figure out where the success/error callbacks need to be bound // to our promise resolve/reject handlers. - // If the plugin method expects myMethod(success, err, options) - if (opts.callbackOrder == 'reverse') { - // Get those arguments in the order [resolve, reject, ...restOfArgs] - args.unshift(reject); - args.unshift(resolve); - } else if(typeof opts.successIndex !== 'undefined' || typeof opts.errorIndex !== 'undefined') { - // If we've specified a success/error index - args.splice(opts.successIndex, 0, resolve); - args.splice(opts.errorIndex, 0, reject); - } else { - // Otherwise, let's tack them on to the end of the argument list - // which is 90% of cases - args.push(resolve); - args.push(reject); - } + args = setIndex (args, opts, resolve, reject); let pluginInstance = getPlugin(pluginObj.pluginRef); - if(!pluginInstance) { - // Do this check in here in the case that the Web API for this plugin is available (for example, Geolocation). - if(!window.cordova) { - cordovaWarn(pluginObj.name, methodName); - reject && reject({ - error: 'cordova_not_available' - }); - return; - } - - pluginWarn(pluginObj, methodName); - reject && reject({ - error: 'plugin_not_installed' - }); - return; - } + if(!systemCheck(pluginInstance, pluginObj, methodName, resolve, reject)) return; // console.log('Cordova calling', pluginObj.name, methodName, args); @@ -141,6 +149,36 @@ function wrapObservable(pluginObj:any, methodName:string, args:any[], opts:any = }); } +function callInstance(pluginObj:any, methodName : string, args:any[], opts:any = {}, resolve? : Function, reject? : Function){ + console.log("C", methodName); + args = setIndex(args); + console.log("D", methodName, pluginObj, pluginObj._objectInstance); + + return pluginObj._objectInstance[methodName].apply(pluginObj._objectInstance, args); +} + +function wrapInstance (pluginObj:any, methodName:string, args:any[], opts:any = {}){ + + if (opts.sync) { + return callInstance(pluginObj, methodName, args, opts); + } else if (opts.observable) { + //console.log("It's an observable"); + return new Observable(observer => { + //args = setIndex(args); + callInstance(pluginObj, methodName,args, opts, observer.next.bind(observer), observer.error.bind(observer)); + return () => { + console.log("Observer cancelled."); + } + }); + } else { + console.log("B", methodName); + return getPromise((resolve, reject) => { + //args = setIndex(args); + callInstance(pluginObj, methodName, args, opts, resolve, reject); + }); + } +} + /** * Wrap the event with an observable * @param event @@ -164,7 +202,9 @@ function wrapEventObservable (event : string) : Observable { export const wrap = function(pluginObj:any, methodName:string, opts:any = {}) { return (...args) => { - if (opts.sync) + if(opts.instanceMethod) { + return wrapInstance(pluginObj, methodName, args, opts); + } else if (opts.sync) return callCordovaPlugin(pluginObj, methodName, args, opts); else if (opts.observable) @@ -231,6 +271,21 @@ export function Cordova(opts:any = {}) { } } + + +export function CordovaInstance(opts:any = {}) { + return (target: Object, methodName: string, descriptor: TypedPropertyDescriptor) => { + //let originalMethod = descriptor.value; + opts['instanceMethod'] = true; + return { + value: function(...args: any[]) { + console.log("A", methodName); + return wrap(this, methodName, opts).apply(this, args); + } + } + } +} + /** * @private * diff --git a/src/plugins/sqlite.ts b/src/plugins/sqlite.ts new file mode 100644 index 00000000..8c73c196 --- /dev/null +++ b/src/plugins/sqlite.ts @@ -0,0 +1,106 @@ +import {CordovaInstance, Plugin, Cordova} from './plugin'; +declare var sqlitePlugin; +/** + * @name SQLite + */ +@Plugin({ + pluginRef: 'sqlitePlugin' +}) +export class SQLite { + + private _objectInstance : any; + get databaseFeatures() : any { + return this._objectInstance.databaseFeatures; + } + + constructor (config : any) { + new Promise((resolve, reject) => { + sqlitePlugin.openDatabase(config, resolve, reject); + }).then( + db => this._objectInstance = db, + error => console.warn(error) + ); + } + + @CordovaInstance({ + sync: true + }) + addTransaction (transaction : any) : void {} + + @CordovaInstance() + transaction (fn : any) : Promise {return} + + @CordovaInstance() + readTransaction (fn : any) : Promise {return} + + @CordovaInstance({ + sync: true + }) + startNextTransaction () : void {} + + @CordovaInstance() + close () : Promise {return} + + @CordovaInstance({ + sync: true + }) + start () : void {} + + @CordovaInstance() + executeSql (statement : string, params : any) : Promise {return} + + @CordovaInstance() + addSatement (sql, values) : Promise {return} + + @CordovaInstance() + sqlBatch (sqlStatements : any) : Promise {return} + + @CordovaInstance({ + sync: true + }) + abortallPendingTransactions () : void {} + + @CordovaInstance({ + sync: true + }) + handleStatementSuccess (handler, response) : void {} + + + @CordovaInstance({ + sync: true + }) + handleStatementFailure (handler, response) : void {} + + + @CordovaInstance({ + sync: true + }) + run () : void {} + + + @CordovaInstance({ + sync: true + }) + abort (txFailure) : void {} + + + @CordovaInstance({ + sync: true + }) + finish () : void {} + + + + @CordovaInstance({ + sync: true + }) + abortFromQ (sqlerror) : void {} + + + @Cordova() + static echoTest () : Promise {return} + + @Cordova() + static deleteDatabase (first) : Promise {return} + +} \ No newline at end of file diff --git a/test/app/index.html b/test/app/index.html index 6efabc83..264b6e23 100644 --- a/test/app/index.html +++ b/test/app/index.html @@ -2,6 +2,7 @@ + @@ -10,5 +11,7 @@ + +
From 85e5522f403d2a93c061803727adc68cb1c5d66f Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Tue, 29 Mar 2016 06:56:21 -0400 Subject: [PATCH 02/13] remove test param --- src/plugins/googlemaps.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/googlemaps.ts b/src/plugins/googlemaps.ts index c9756268..bcb1f17b 100644 --- a/src/plugins/googlemaps.ts +++ b/src/plugins/googlemaps.ts @@ -15,7 +15,7 @@ export class GoogleMaps { private _objectInstance : any; - constructor (elementId : string, public niggasIn = "paris") { + constructor (elementId : string) { this._objectInstance = {};//plugin.google.maps.Map.getMap(document.getElementById(elementId)); } @@ -32,4 +32,4 @@ export class GoogleMaps { setClickable (isClickable : boolean) : void {} -} \ No newline at end of file +} From 5a8d48ea3620cf8ee48ab663d3d9a49f1044c084 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Tue, 29 Mar 2016 17:49:53 -0400 Subject: [PATCH 03/13] perf(ionicnative): instance wrapper cleanup and optimization --- src/plugins/plugin.ts | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index bef02f36..0059d535 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -7,6 +7,7 @@ declare var Promise; declare var $q; import {Observable} from 'rxjs/Observable'; +import sys = ts.sys; /** * @private @@ -150,30 +151,31 @@ function wrapObservable(pluginObj:any, methodName:string, args:any[], opts:any = } function callInstance(pluginObj:any, methodName : string, args:any[], opts:any = {}, resolve? : Function, reject? : Function){ - console.log("C", methodName); + if(!systemCheck(getPlugin(pluginObj), pluginObj, methodName, resolve, reject)) return; args = setIndex(args); - console.log("D", methodName, pluginObj, pluginObj._objectInstance); - return pluginObj._objectInstance[methodName].apply(pluginObj._objectInstance, args); } function wrapInstance (pluginObj:any, methodName:string, args:any[], opts:any = {}){ - if (opts.sync) { return callInstance(pluginObj, methodName, args, opts); } else if (opts.observable) { - //console.log("It's an observable"); return new Observable(observer => { - //args = setIndex(args); - callInstance(pluginObj, methodName,args, opts, observer.next.bind(observer), observer.error.bind(observer)); - return () => { - console.log("Observer cancelled."); + let pluginResult = callInstance(pluginObj, methodName,args, opts, observer.next.bind(observer), observer.error.bind(observer)); + return () => { + try { + if (opts.clearWithArgs){ + return pluginObj._objectInstance[opts.clearFunction].apply(pluginObj._objectInstance, args); + } + return pluginObj._objectInstance[opts.clearFunction].call(pluginObj, pluginResult); + } catch(e) { + console.warn('Unable to clear the previous observable watch for', pluginObj.name, methodName); + console.error(e); } + } }); } else { - console.log("B", methodName); return getPromise((resolve, reject) => { - //args = setIndex(args); callInstance(pluginObj, methodName, args, opts, resolve, reject); }); } @@ -202,9 +204,7 @@ function wrapEventObservable (event : string) : Observable { export const wrap = function(pluginObj:any, methodName:string, opts:any = {}) { return (...args) => { - if(opts.instanceMethod) { - return wrapInstance(pluginObj, methodName, args, opts); - } else if (opts.sync) + if (opts.sync) return callCordovaPlugin(pluginObj, methodName, args, opts); else if (opts.observable) @@ -271,16 +271,16 @@ export function Cordova(opts:any = {}) { } } - - +/** + * @private + * + * Wrap an instance method + */ export function CordovaInstance(opts:any = {}) { - return (target: Object, methodName: string, descriptor: TypedPropertyDescriptor) => { - //let originalMethod = descriptor.value; - opts['instanceMethod'] = true; + return (target: Object, methodName: string) => { return { value: function(...args: any[]) { - console.log("A", methodName); - return wrap(this, methodName, opts).apply(this, args); + return wrapInstance(this, methodName, opts).apply(this, args); } } } From eea70ffc0a1ed88f5a88ee123a92bfd516c07491 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Tue, 29 Mar 2016 17:53:51 -0400 Subject: [PATCH 04/13] style(plugin.ts): format/indent --- src/plugins/plugin.ts | 186 +++++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 93 deletions(-) diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index 0059d535..9c77762c 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -14,7 +14,7 @@ import sys = ts.sys; * @param pluginRef * @returns {null|*} */ -export const getPlugin = function(pluginRef: string): any { +export const getPlugin = function (pluginRef:string):any { return get(window, pluginRef); }; @@ -23,7 +23,7 @@ export const getPlugin = function(pluginRef: string): any { * @param pluginRef * @returns {boolean} */ -export const isInstalled = function(pluginRef: string): boolean { +export const isInstalled = function (pluginRef:string):boolean { return !!getPlugin(pluginRef); }; @@ -32,10 +32,10 @@ export const isInstalled = function(pluginRef: string): boolean { * @param pluginObj * @param method */ -export const pluginWarn = function(pluginObj: any, method: string) { +export const pluginWarn = function (pluginObj:any, method:string) { var pluginName = pluginObj.name; var plugin = pluginObj.plugin; - if(method) { + if (method) { console.warn('Native: tried calling ' + pluginName + '.' + method + ', but the ' + pluginName + ' plugin is not installed.'); } else { console.warn('Native: tried accessing the ' + pluginName + ' plugin but it\'s not installed.'); @@ -48,60 +48,60 @@ export const pluginWarn = function(pluginObj: any, method: string) { * @param pluginName * @param method */ -export const cordovaWarn = function(pluginName: string, method: string) { - if(method) { +export const cordovaWarn = function (pluginName:string, method:string) { + if (method) { console.warn('Native: tried calling ' + pluginName + '.' + method + ', but Cordova is not available. Make sure to include cordova.js or run in a device/simulator'); } else { console.warn('Native: tried accessing the ' + pluginName + ' plugin but Cordova is not available. Make sure to include cordova.js or run in a device/simulator'); } }; -function setIndex (args:any[], opts:any={}, resolve? : Function, reject?: Function) : any { - // If the plugin method expects myMethod(success, err, options) - if (opts.callbackOrder == 'reverse') { - // Get those arguments in the order [resolve, reject, ...restOfArgs] - args.unshift(reject); - args.unshift(resolve); - } else if(typeof opts.successIndex !== 'undefined' || typeof opts.errorIndex !== 'undefined') { - // If we've specified a success/error index - args.splice(opts.successIndex, 0, resolve); - args.splice(opts.errorIndex, 0, reject); - } else { - // Otherwise, let's tack them on to the end of the argument list - // which is 90% of cases - args.push(resolve); - args.push(reject); +function setIndex(args:any[], opts:any = {}, resolve?:Function, reject?:Function):any { + // If the plugin method expects myMethod(success, err, options) + if (opts.callbackOrder == 'reverse') { + // Get those arguments in the order [resolve, reject, ...restOfArgs] + args.unshift(reject); + args.unshift(resolve); + } else if (typeof opts.successIndex !== 'undefined' || typeof opts.errorIndex !== 'undefined') { + // If we've specified a success/error index + args.splice(opts.successIndex, 0, resolve); + args.splice(opts.errorIndex, 0, reject); + } else { + // Otherwise, let's tack them on to the end of the argument list + // which is 90% of cases + args.push(resolve); + args.push(reject); + } + + return args; +} +function systemCheck(pluginInstance:any, pluginObj:any, methodName, resolve?:Function, reject?:Function):boolean { + if (!pluginInstance) { + // Do this check in here in the case that the Web API for this plugin is available (for example, Geolocation). + if (!window.cordova) { + cordovaWarn(pluginObj.name, methodName); + reject && reject({ + error: 'cordova_not_available' + }); + return false; } - return args; + pluginWarn(pluginObj, methodName); + reject && reject({ + error: 'plugin_not_installed' + }); + return false; + } + return; } -function systemCheck (pluginInstance : any, pluginObj : any, methodName, resolve?: Function, reject?: Function) : boolean { - if(!pluginInstance) { - // Do this check in here in the case that the Web API for this plugin is available (for example, Geolocation). - if(!window.cordova) { - cordovaWarn(pluginObj.name, methodName); - reject && reject({ - error: 'cordova_not_available' - }); - return false; - } - - pluginWarn(pluginObj, methodName); - reject && reject({ - error: 'plugin_not_installed' - }); - return false; - } - return; -} -function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:any={}, resolve?: Function, reject?: Function) { +function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:any = {}, resolve?:Function, reject?:Function) { // Try to figure out where the success/error callbacks need to be bound // to our promise resolve/reject handlers. - args = setIndex (args, opts, resolve, reject); + args = setIndex(args, opts, resolve, reject); let pluginInstance = getPlugin(pluginObj.pluginRef); - if(!systemCheck(pluginInstance, pluginObj, methodName, resolve, reject)) return; + if (!systemCheck(pluginInstance, pluginObj, methodName, resolve, reject)) return; // console.log('Cordova calling', pluginObj.name, methodName, args); @@ -110,12 +110,12 @@ function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:an } function getPromise(cb) { - if(window.Promise) { + if (window.Promise) { // console.log('Native promises available...'); return new Promise((resolve, reject) => { cb(resolve, reject); }) - } else if(window.angular) { + } else if (window.angular) { let $q = window.angular.injector(['ng']).get('$q'); // console.log('Loaded $q', $q); return $q((resolve, reject) => { @@ -126,7 +126,7 @@ function getPromise(cb) { } } -function wrapPromise(pluginObj:any, methodName:string, args:any[], opts:any={}) { +function wrapPromise(pluginObj:any, methodName:string, args:any[], opts:any = {}) { return getPromise((resolve, reject) => { callCordovaPlugin(pluginObj, methodName, args, opts, resolve, reject); }) @@ -138,11 +138,11 @@ function wrapObservable(pluginObj:any, methodName:string, args:any[], opts:any = return () => { try { - if (opts.clearWithArgs){ + if (opts.clearWithArgs) { return get(window, pluginObj.pluginRef)[opts.clearFunction].apply(pluginObj, args); } return get(window, pluginObj.pluginRef)[opts.clearFunction].call(pluginObj, pluginResult); - } catch(e) { + } catch (e) { console.warn('Unable to clear the previous observable watch for', pluginObj.name, methodName); console.error(e); } @@ -150,35 +150,35 @@ function wrapObservable(pluginObj:any, methodName:string, args:any[], opts:any = }); } -function callInstance(pluginObj:any, methodName : string, args:any[], opts:any = {}, resolve? : Function, reject? : Function){ - if(!systemCheck(getPlugin(pluginObj), pluginObj, methodName, resolve, reject)) return; - args = setIndex(args); - return pluginObj._objectInstance[methodName].apply(pluginObj._objectInstance, args); +function callInstance(pluginObj:any, methodName:string, args:any[], opts:any = {}, resolve?:Function, reject?:Function) { + if (!systemCheck(getPlugin(pluginObj), pluginObj, methodName, resolve, reject)) return; + args = setIndex(args); + return pluginObj._objectInstance[methodName].apply(pluginObj._objectInstance, args); } -function wrapInstance (pluginObj:any, methodName:string, args:any[], opts:any = {}){ - if (opts.sync) { - return callInstance(pluginObj, methodName, args, opts); - } else if (opts.observable) { - return new Observable(observer => { - let pluginResult = callInstance(pluginObj, methodName,args, opts, observer.next.bind(observer), observer.error.bind(observer)); - return () => { - try { - if (opts.clearWithArgs){ - return pluginObj._objectInstance[opts.clearFunction].apply(pluginObj._objectInstance, args); - } - return pluginObj._objectInstance[opts.clearFunction].call(pluginObj, pluginResult); - } catch(e) { - console.warn('Unable to clear the previous observable watch for', pluginObj.name, methodName); - console.error(e); - } +function wrapInstance(pluginObj:any, methodName:string, args:any[], opts:any = {}) { + if (opts.sync) { + return callInstance(pluginObj, methodName, args, opts); + } else if (opts.observable) { + return new Observable(observer => { + let pluginResult = callInstance(pluginObj, methodName, args, opts, observer.next.bind(observer), observer.error.bind(observer)); + return () => { + try { + if (opts.clearWithArgs) { + return pluginObj._objectInstance[opts.clearFunction].apply(pluginObj._objectInstance, args); } - }); - } else { - return getPromise((resolve, reject) => { - callInstance(pluginObj, methodName, args, opts, resolve, reject); - }); - } + return pluginObj._objectInstance[opts.clearFunction].call(pluginObj, pluginResult); + } catch (e) { + console.warn('Unable to clear the previous observable watch for', pluginObj.name, methodName); + console.error(e); + } + } + }); + } else { + return getPromise((resolve, reject) => { + callInstance(pluginObj, methodName, args, opts, resolve, reject); + }); + } } /** @@ -186,9 +186,9 @@ function wrapInstance (pluginObj:any, methodName:string, args:any[], opts:any = * @param event * @returns {Observable} */ -function wrapEventObservable (event : string) : Observable { +function wrapEventObservable(event:string):Observable { return new Observable(observer => { - let callback = (status : any) => observer.next(status); + let callback = (status:any) => observer.next(status); window.addEventListener(event, callback, false); return () => window.removeEventListener(event, callback, false); }); @@ -201,10 +201,10 @@ function wrapEventObservable (event : string) : Observable { * @param opts * @returns {function(...[any]): (undefined|*|Observable|*|*)} */ -export const wrap = function(pluginObj:any, methodName:string, opts:any = {}) { +export const wrap = function (pluginObj:any, methodName:string, opts:any = {}) { return (...args) => { - if (opts.sync) + if (opts.sync) return callCordovaPlugin(pluginObj, methodName, args, opts); else if (opts.observable) @@ -238,14 +238,14 @@ export const wrap = function(pluginObj:any, methodName:string, opts:any = {}) { * ``` */ export function Plugin(config) { - return function(cls) { + return function (cls) { // Add these fields to the class for (let k in config) { cls[k] = config[k]; } - cls['installed'] = function() { + cls['installed'] = function () { return !!getPlugin(config.pluginRef); }; @@ -260,11 +260,11 @@ export function Plugin(config) { * and the required plugin are installed. */ export function Cordova(opts:any = {}) { - return (target: Object, methodName: string, descriptor: TypedPropertyDescriptor) => { + return (target:Object, methodName:string, descriptor:TypedPropertyDescriptor) => { let originalMethod = descriptor.value; return { - value: function(...args: any[]) { + value: function (...args:any[]) { return wrap(this, methodName, opts).apply(this, args); } } @@ -277,13 +277,13 @@ export function Cordova(opts:any = {}) { * Wrap an instance method */ export function CordovaInstance(opts:any = {}) { - return (target: Object, methodName: string) => { - return { - value: function(...args: any[]) { - return wrapInstance(this, methodName, opts).apply(this, args); - } - } + return (target:Object, methodName:string) => { + return { + value: function (...args:any[]) { + return wrapInstance(this, methodName, opts).apply(this, args); + } } + } } /** @@ -292,18 +292,18 @@ export function CordovaInstance(opts:any = {}) { * * Before calling the original method, ensure Cordova and the plugin are installed. */ -export function CordovaProperty(target: Function, key: string, descriptor: TypedPropertyDescriptor) { +export function CordovaProperty(target:Function, key:string, descriptor:TypedPropertyDescriptor) { let originalMethod = descriptor.get; - descriptor.get = function(...args: any[]) { + descriptor.get = function (...args:any[]) { // console.log('Calling', this); - if(!window.cordova) { + if (!window.cordova) { cordovaWarn(this.name, null); return {}; } let pluginInstance = getPlugin(this.pluginRef); - if(!pluginInstance) { + if (!pluginInstance) { pluginWarn(this, key); return {}; } From a37a0415383892bf7ceb024f2d3893f7d35c4196 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Mon, 25 Apr 2016 06:22:17 -0400 Subject: [PATCH 05/13] style(plugin): reverse previous commit, to keep track of changes easier --- src/plugins/plugin.ts | 186 +++++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 93 deletions(-) diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index 9c77762c..0059d535 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -14,7 +14,7 @@ import sys = ts.sys; * @param pluginRef * @returns {null|*} */ -export const getPlugin = function (pluginRef:string):any { +export const getPlugin = function(pluginRef: string): any { return get(window, pluginRef); }; @@ -23,7 +23,7 @@ export const getPlugin = function (pluginRef:string):any { * @param pluginRef * @returns {boolean} */ -export const isInstalled = function (pluginRef:string):boolean { +export const isInstalled = function(pluginRef: string): boolean { return !!getPlugin(pluginRef); }; @@ -32,10 +32,10 @@ export const isInstalled = function (pluginRef:string):boolean { * @param pluginObj * @param method */ -export const pluginWarn = function (pluginObj:any, method:string) { +export const pluginWarn = function(pluginObj: any, method: string) { var pluginName = pluginObj.name; var plugin = pluginObj.plugin; - if (method) { + if(method) { console.warn('Native: tried calling ' + pluginName + '.' + method + ', but the ' + pluginName + ' plugin is not installed.'); } else { console.warn('Native: tried accessing the ' + pluginName + ' plugin but it\'s not installed.'); @@ -48,60 +48,60 @@ export const pluginWarn = function (pluginObj:any, method:string) { * @param pluginName * @param method */ -export const cordovaWarn = function (pluginName:string, method:string) { - if (method) { +export const cordovaWarn = function(pluginName: string, method: string) { + if(method) { console.warn('Native: tried calling ' + pluginName + '.' + method + ', but Cordova is not available. Make sure to include cordova.js or run in a device/simulator'); } else { console.warn('Native: tried accessing the ' + pluginName + ' plugin but Cordova is not available. Make sure to include cordova.js or run in a device/simulator'); } }; -function setIndex(args:any[], opts:any = {}, resolve?:Function, reject?:Function):any { - // If the plugin method expects myMethod(success, err, options) - if (opts.callbackOrder == 'reverse') { - // Get those arguments in the order [resolve, reject, ...restOfArgs] - args.unshift(reject); - args.unshift(resolve); - } else if (typeof opts.successIndex !== 'undefined' || typeof opts.errorIndex !== 'undefined') { - // If we've specified a success/error index - args.splice(opts.successIndex, 0, resolve); - args.splice(opts.errorIndex, 0, reject); - } else { - // Otherwise, let's tack them on to the end of the argument list - // which is 90% of cases - args.push(resolve); - args.push(reject); - } - - return args; -} -function systemCheck(pluginInstance:any, pluginObj:any, methodName, resolve?:Function, reject?:Function):boolean { - if (!pluginInstance) { - // Do this check in here in the case that the Web API for this plugin is available (for example, Geolocation). - if (!window.cordova) { - cordovaWarn(pluginObj.name, methodName); - reject && reject({ - error: 'cordova_not_available' - }); - return false; +function setIndex (args:any[], opts:any={}, resolve? : Function, reject?: Function) : any { + // If the plugin method expects myMethod(success, err, options) + if (opts.callbackOrder == 'reverse') { + // Get those arguments in the order [resolve, reject, ...restOfArgs] + args.unshift(reject); + args.unshift(resolve); + } else if(typeof opts.successIndex !== 'undefined' || typeof opts.errorIndex !== 'undefined') { + // If we've specified a success/error index + args.splice(opts.successIndex, 0, resolve); + args.splice(opts.errorIndex, 0, reject); + } else { + // Otherwise, let's tack them on to the end of the argument list + // which is 90% of cases + args.push(resolve); + args.push(reject); } - pluginWarn(pluginObj, methodName); - reject && reject({ - error: 'plugin_not_installed' - }); - return false; - } - return; + return args; } -function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:any = {}, resolve?:Function, reject?:Function) { +function systemCheck (pluginInstance : any, pluginObj : any, methodName, resolve?: Function, reject?: Function) : boolean { + if(!pluginInstance) { + // Do this check in here in the case that the Web API for this plugin is available (for example, Geolocation). + if(!window.cordova) { + cordovaWarn(pluginObj.name, methodName); + reject && reject({ + error: 'cordova_not_available' + }); + return false; + } + + pluginWarn(pluginObj, methodName); + reject && reject({ + error: 'plugin_not_installed' + }); + return false; + } + return; +} +function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:any={}, resolve?: Function, reject?: Function) { // Try to figure out where the success/error callbacks need to be bound // to our promise resolve/reject handlers. - args = setIndex(args, opts, resolve, reject); + args = setIndex (args, opts, resolve, reject); let pluginInstance = getPlugin(pluginObj.pluginRef); - if (!systemCheck(pluginInstance, pluginObj, methodName, resolve, reject)) return; + if(!systemCheck(pluginInstance, pluginObj, methodName, resolve, reject)) return; // console.log('Cordova calling', pluginObj.name, methodName, args); @@ -110,12 +110,12 @@ function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:an } function getPromise(cb) { - if (window.Promise) { + if(window.Promise) { // console.log('Native promises available...'); return new Promise((resolve, reject) => { cb(resolve, reject); }) - } else if (window.angular) { + } else if(window.angular) { let $q = window.angular.injector(['ng']).get('$q'); // console.log('Loaded $q', $q); return $q((resolve, reject) => { @@ -126,7 +126,7 @@ function getPromise(cb) { } } -function wrapPromise(pluginObj:any, methodName:string, args:any[], opts:any = {}) { +function wrapPromise(pluginObj:any, methodName:string, args:any[], opts:any={}) { return getPromise((resolve, reject) => { callCordovaPlugin(pluginObj, methodName, args, opts, resolve, reject); }) @@ -138,11 +138,11 @@ function wrapObservable(pluginObj:any, methodName:string, args:any[], opts:any = return () => { try { - if (opts.clearWithArgs) { + if (opts.clearWithArgs){ return get(window, pluginObj.pluginRef)[opts.clearFunction].apply(pluginObj, args); } return get(window, pluginObj.pluginRef)[opts.clearFunction].call(pluginObj, pluginResult); - } catch (e) { + } catch(e) { console.warn('Unable to clear the previous observable watch for', pluginObj.name, methodName); console.error(e); } @@ -150,35 +150,35 @@ function wrapObservable(pluginObj:any, methodName:string, args:any[], opts:any = }); } -function callInstance(pluginObj:any, methodName:string, args:any[], opts:any = {}, resolve?:Function, reject?:Function) { - if (!systemCheck(getPlugin(pluginObj), pluginObj, methodName, resolve, reject)) return; - args = setIndex(args); - return pluginObj._objectInstance[methodName].apply(pluginObj._objectInstance, args); +function callInstance(pluginObj:any, methodName : string, args:any[], opts:any = {}, resolve? : Function, reject? : Function){ + if(!systemCheck(getPlugin(pluginObj), pluginObj, methodName, resolve, reject)) return; + args = setIndex(args); + return pluginObj._objectInstance[methodName].apply(pluginObj._objectInstance, args); } -function wrapInstance(pluginObj:any, methodName:string, args:any[], opts:any = {}) { - if (opts.sync) { - return callInstance(pluginObj, methodName, args, opts); - } else if (opts.observable) { - return new Observable(observer => { - let pluginResult = callInstance(pluginObj, methodName, args, opts, observer.next.bind(observer), observer.error.bind(observer)); - return () => { - try { - if (opts.clearWithArgs) { - return pluginObj._objectInstance[opts.clearFunction].apply(pluginObj._objectInstance, args); +function wrapInstance (pluginObj:any, methodName:string, args:any[], opts:any = {}){ + if (opts.sync) { + return callInstance(pluginObj, methodName, args, opts); + } else if (opts.observable) { + return new Observable(observer => { + let pluginResult = callInstance(pluginObj, methodName,args, opts, observer.next.bind(observer), observer.error.bind(observer)); + return () => { + try { + if (opts.clearWithArgs){ + return pluginObj._objectInstance[opts.clearFunction].apply(pluginObj._objectInstance, args); + } + return pluginObj._objectInstance[opts.clearFunction].call(pluginObj, pluginResult); + } catch(e) { + console.warn('Unable to clear the previous observable watch for', pluginObj.name, methodName); + console.error(e); + } } - return pluginObj._objectInstance[opts.clearFunction].call(pluginObj, pluginResult); - } catch (e) { - console.warn('Unable to clear the previous observable watch for', pluginObj.name, methodName); - console.error(e); - } - } - }); - } else { - return getPromise((resolve, reject) => { - callInstance(pluginObj, methodName, args, opts, resolve, reject); - }); - } + }); + } else { + return getPromise((resolve, reject) => { + callInstance(pluginObj, methodName, args, opts, resolve, reject); + }); + } } /** @@ -186,9 +186,9 @@ function wrapInstance(pluginObj:any, methodName:string, args:any[], opts:any = { * @param event * @returns {Observable} */ -function wrapEventObservable(event:string):Observable { +function wrapEventObservable (event : string) : Observable { return new Observable(observer => { - let callback = (status:any) => observer.next(status); + let callback = (status : any) => observer.next(status); window.addEventListener(event, callback, false); return () => window.removeEventListener(event, callback, false); }); @@ -201,10 +201,10 @@ function wrapEventObservable(event:string):Observable { * @param opts * @returns {function(...[any]): (undefined|*|Observable|*|*)} */ -export const wrap = function (pluginObj:any, methodName:string, opts:any = {}) { +export const wrap = function(pluginObj:any, methodName:string, opts:any = {}) { return (...args) => { - if (opts.sync) + if (opts.sync) return callCordovaPlugin(pluginObj, methodName, args, opts); else if (opts.observable) @@ -238,14 +238,14 @@ export const wrap = function (pluginObj:any, methodName:string, opts:any = {}) { * ``` */ export function Plugin(config) { - return function (cls) { + return function(cls) { // Add these fields to the class for (let k in config) { cls[k] = config[k]; } - cls['installed'] = function () { + cls['installed'] = function() { return !!getPlugin(config.pluginRef); }; @@ -260,11 +260,11 @@ export function Plugin(config) { * and the required plugin are installed. */ export function Cordova(opts:any = {}) { - return (target:Object, methodName:string, descriptor:TypedPropertyDescriptor) => { + return (target: Object, methodName: string, descriptor: TypedPropertyDescriptor) => { let originalMethod = descriptor.value; return { - value: function (...args:any[]) { + value: function(...args: any[]) { return wrap(this, methodName, opts).apply(this, args); } } @@ -277,13 +277,13 @@ export function Cordova(opts:any = {}) { * Wrap an instance method */ export function CordovaInstance(opts:any = {}) { - return (target:Object, methodName:string) => { - return { - value: function (...args:any[]) { - return wrapInstance(this, methodName, opts).apply(this, args); - } + return (target: Object, methodName: string) => { + return { + value: function(...args: any[]) { + return wrapInstance(this, methodName, opts).apply(this, args); + } + } } - } } /** @@ -292,18 +292,18 @@ export function CordovaInstance(opts:any = {}) { * * Before calling the original method, ensure Cordova and the plugin are installed. */ -export function CordovaProperty(target:Function, key:string, descriptor:TypedPropertyDescriptor) { +export function CordovaProperty(target: Function, key: string, descriptor: TypedPropertyDescriptor) { let originalMethod = descriptor.get; - descriptor.get = function (...args:any[]) { + descriptor.get = function(...args: any[]) { // console.log('Calling', this); - if (!window.cordova) { + if(!window.cordova) { cordovaWarn(this.name, null); return {}; } let pluginInstance = getPlugin(this.pluginRef); - if (!pluginInstance) { + if(!pluginInstance) { pluginWarn(this, key); return {}; } From 1105b5723bc9dd72ae4c276569e2fb068df863b6 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Mon, 25 Apr 2016 06:51:42 -0400 Subject: [PATCH 06/13] feat(media): add media plugin closes #88 --- src/plugins/media.ts | 140 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 src/plugins/media.ts diff --git a/src/plugins/media.ts b/src/plugins/media.ts new file mode 100644 index 00000000..8915f5e9 --- /dev/null +++ b/src/plugins/media.ts @@ -0,0 +1,140 @@ +import {CordovaInstance, Plugin} from './plugin'; + +/** + * @name Media + * @description + * @usage + */ +@Plugin({ + repo: 'https://github.com/apache/cordova-plugin-media', + plugin: 'cordova-plugin-media', + pluginRef: 'Media' +}) +export class Media { + + // Constants + + static MEDIA_NONE : number = 0; + static MEDIA_STARTING : number = 1; + static MEDIA_RUNNING : number = 2; + static MEDIA_PAUSED : number = 3; + static MEDIA_STOPPED : number = 4; + + // Properties + + private _objectInstance : any; + + // Methods + + /** + * Open a media file + * @param src {string} A URI containing the audio content. + */ + constructor (src : string) { + // TODO handle success, error, and status + this._objectInstance = new Media(src); + } + + /** + * Returns the current amplitude of the current recording. + */ + @CordovaInstance() + getCurrentAmplitude () : Promise {return} + + /** + * Returns the current position within an audio file. Also updates the Media object's position parameter. + */ + @CordovaInstance() + getCurrentPosition () : Promise {return} + + /** + * Returns the duration of an audio file in seconds. If the duration is unknown, it returns a value of -1. + */ + @CordovaInstance({ + sync: true + }) + getDuration () : number {return} + + /** + * Starts or resumes playing an audio file. + */ + @CordovaInstance({ + sync: true + }) + play (iosOptions? : { + numberOfLoops? : number, + playAudioWhenScreenIsLocked? : boolean + }) : void {} + + /** + * Pauses playing an audio file. + */ + @CordovaInstance({ + sync: true + }) + pause () : void {} + + /** + * Releases the underlying operating system's audio resources. This is particularly important for Android, since there are a finite amount of OpenCore instances for media playback. Applications should call the release function for any Media resource that is no longer needed. + */ + @CordovaInstance({ + sync: true + }) + release () : void {} + + /** + * Sets the current position within an audio file. + * @param milliseconds + */ + @CordovaInstance({ + sync: true + }) + seekTo (milliseconds : number) : void {} + + /** + * Set the volume for an audio file. + * @param volume The volume to set for playback. The value must be within the range of 0.0 to 1.0. + */ + @CordovaInstance({ + sync: true + }) + setVolume (volume : number) : void {} + + /** + * Starts recording an audio file. + */ + @CordovaInstance({ + sync: true + }) + startRecord () : void {} + + + /** + * Stops recording + */ + @CordovaInstance({ + sync: true + }) + stopRecord () : void {} + + + /** + * Stops playing an audio file. + */ + @CordovaInstance({ + sync: true + }) + stop () : void {} + + + +} + +export class MediaError { + static get MEDIA_ERR_ABORTED () {return 1;} + static get MEDIA_ERR_NETWORK () {return 2;} + static get MEDIA_ERR_DECODE () {return 3;} + static get MEDIA_ERR_NONE_SUPPORTED () {return 4;} + code : number; + message : string; +} \ No newline at end of file From 2afd415491546f66895cc8b1268ea3da21d68d58 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Mon, 25 Apr 2016 06:54:02 -0400 Subject: [PATCH 07/13] chore(index): update index --- src/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/index.ts b/src/index.ts index e6b9444b..3b2a564b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -36,6 +36,7 @@ import {InAppBrowser} from './plugins/inappbrowser'; import {Keyboard} from './plugins/keyboard'; import {LaunchNavigator} from './plugins/launchnavigator'; import {LocalNotifications} from './plugins/localnotifications'; +import {Media} from './plugins/media'; import {Network, Connection} from './plugins/network'; import {Push} from './plugins/push'; import {SMS} from './plugins/sms'; @@ -81,6 +82,7 @@ export { Keyboard, LaunchNavigator, LocalNotifications, + Media, Network, Push, SMS, @@ -130,6 +132,7 @@ window['IonicNative'] = { Keyboard: Keyboard, LaunchNavigator: LaunchNavigator, LocalNotifications: LocalNotifications, + Media: Media, Network: Network, Push: Push, SMS: SMS, From 4070991f677e31617f72c8f19ca3f72c73f63e31 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Mon, 25 Apr 2016 07:19:43 -0400 Subject: [PATCH 08/13] fix(plugin): remove unecessary code --- npm-debug.log | 40 ---------------------------------------- src/plugins/plugin.ts | 1 - 2 files changed, 41 deletions(-) delete mode 100644 npm-debug.log diff --git a/npm-debug.log b/npm-debug.log deleted file mode 100644 index 32e648ff..00000000 --- a/npm-debug.log +++ /dev/null @@ -1,40 +0,0 @@ -0 info it worked if it ends with ok -1 verbose cli [ 'C:\\Program Files\\nodejs\\node.exe', -1 verbose cli 'C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js', -1 verbose cli 'run', -1 verbose cli 'build_bundle' ] -2 info using npm@2.14.12 -3 info using node@v4.2.4 -4 verbose run-script [ 'prebuild_bundle', 'build_bundle', 'postbuild_bundle' ] -5 info prebuild_bundle ionic-native@1.1.0 -6 info build_bundle ionic-native@1.1.0 -7 verbose unsafe-perm in lifecycle true -8 info ionic-native@1.1.0 Failed to exec build_bundle script -9 verbose stack Error: ionic-native@1.1.0 build_bundle: `npm run-script build && browserify dist/index.js > dist/ionic.native.js` -9 verbose stack Exit status 1 -9 verbose stack at EventEmitter. (C:\Program Files\nodejs\node_modules\npm\lib\utils\lifecycle.js:214:16) -9 verbose stack at emitTwo (events.js:87:13) -9 verbose stack at EventEmitter.emit (events.js:172:7) -9 verbose stack at ChildProcess. (C:\Program Files\nodejs\node_modules\npm\lib\utils\spawn.js:24:14) -9 verbose stack at emitTwo (events.js:87:13) -9 verbose stack at ChildProcess.emit (events.js:172:7) -9 verbose stack at maybeClose (internal/child_process.js:818:16) -9 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5) -10 verbose pkgid ionic-native@1.1.0 -11 verbose cwd C:\Users\Ibrahim\WebstormProjects\ionic-native -12 error Windows_NT 10.0.10586 -13 error argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "run" "build_bundle" -14 error node v4.2.4 -15 error npm v2.14.12 -16 error code ELIFECYCLE -17 error ionic-native@1.1.0 build_bundle: `npm run-script build && browserify dist/index.js > dist/ionic.native.js` -17 error Exit status 1 -18 error Failed at the ionic-native@1.1.0 build_bundle script 'npm run-script build && browserify dist/index.js > dist/ionic.native.js'. -18 error This is most likely a problem with the ionic-native package, -18 error not with npm itself. -18 error Tell the author that this fails on your system: -18 error npm run-script build && browserify dist/index.js > dist/ionic.native.js -18 error You can get their info via: -18 error npm owner ls ionic-native -18 error There is likely additional logging output above. -19 verbose exit [ 1, true ] diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index 0059d535..fed7554d 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -7,7 +7,6 @@ declare var Promise; declare var $q; import {Observable} from 'rxjs/Observable'; -import sys = ts.sys; /** * @private From f89c2db86cccc5e8c6666f120014d346189b3288 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Wed, 27 Apr 2016 09:54:14 -0400 Subject: [PATCH 09/13] refactor(media): change plugin name to MediaPlugin to avoid conflicts --- src/index.ts | 6 +++--- src/plugins/media.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index 442d7be5..5ff171b3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -39,7 +39,7 @@ import {InAppBrowser} from './plugins/inappbrowser'; import {Keyboard} from './plugins/keyboard'; import {LaunchNavigator} from './plugins/launchnavigator'; import {LocalNotifications} from './plugins/localnotifications'; -import {Media} from './plugins/media'; +import {MediaPlugin} from './plugins/media'; import {Network, Connection} from './plugins/network'; import {Push} from './plugins/push'; import {SMS} from './plugins/sms'; @@ -89,7 +89,7 @@ export { Keyboard, LaunchNavigator, LocalNotifications, - Media, + MediaPlugin, Network, Push, SMS, @@ -143,7 +143,7 @@ window['IonicNative'] = { Keyboard: Keyboard, LaunchNavigator: LaunchNavigator, LocalNotifications: LocalNotifications, - Media: Media, + MediaPlugin: MediaPlugin, Network: Network, Push: Push, SMS: SMS, diff --git a/src/plugins/media.ts b/src/plugins/media.ts index 8915f5e9..406a9ce8 100644 --- a/src/plugins/media.ts +++ b/src/plugins/media.ts @@ -1,7 +1,7 @@ import {CordovaInstance, Plugin} from './plugin'; - +declare var Media:any; /** - * @name Media + * @name MediaPlugin * @description * @usage */ @@ -10,7 +10,7 @@ import {CordovaInstance, Plugin} from './plugin'; plugin: 'cordova-plugin-media', pluginRef: 'Media' }) -export class Media { +export class MediaPlugin { // Constants From 94a8a296c166e6fcad0454991f09986ee60aa047 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Fri, 29 Apr 2016 21:46:35 -0400 Subject: [PATCH 10/13] fix(instance-wrapper): --- src/plugins/media.ts | 34 ++++++++++++++++++-- src/plugins/plugin.ts | 74 +++++++++++++++++++++---------------------- src/util.ts | 1 + 3 files changed, 68 insertions(+), 41 deletions(-) diff --git a/src/plugins/media.ts b/src/plugins/media.ts index 406a9ce8..5ebcc1b9 100644 --- a/src/plugins/media.ts +++ b/src/plugins/media.ts @@ -4,6 +4,37 @@ declare var Media:any; * @name MediaPlugin * @description * @usage + * ```ts + * import {MediaPlugin} from 'ionic-native'; + * + * + * ... + * + * + * // Playing a file + * var file = new MediaPlugin("path/to/file.mp3"); + * + * // play the file + * file.play(); + * + * // skip to 10 seconds + * file.seekTo(10000); + * + * // stop plying the file + * file.stop(); + * + * + * ... + * + * // Recording to a file + * var newFile = new MediaPlugin("path/to/file.mp3"); + * newFile.startRecord(); + * + * newFile.stopRecord(); + * + * + * + * ``` */ @Plugin({ repo: 'https://github.com/apache/cordova-plugin-media', @@ -13,7 +44,6 @@ declare var Media:any; export class MediaPlugin { // Constants - static MEDIA_NONE : number = 0; static MEDIA_STARTING : number = 1; static MEDIA_RUNNING : number = 2; @@ -21,11 +51,9 @@ export class MediaPlugin { static MEDIA_STOPPED : number = 4; // Properties - private _objectInstance : any; // Methods - /** * Open a media file * @param src {string} A URI containing the audio content. diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index a853cb30..aadb8329 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -73,25 +73,7 @@ function setIndex (args:any[], opts:any={}, resolve? : Function, reject?: Functi return args; } -function systemCheck (pluginInstance : any, pluginObj : any, methodName, resolve?: Function, reject?: Function) : boolean { - if(!pluginInstance) { - // Do this check in here in the case that the Web API for this plugin is available (for example, Geolocation). - if(!window.cordova) { - cordovaWarn(pluginObj.name, methodName); - reject && reject({ - error: 'cordova_not_available' - }); - return false; - } - pluginWarn(pluginObj, methodName); - reject && reject({ - error: 'plugin_not_installed' - }); - return false; - } - return; -} function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:any={}, resolve?: Function, reject?: Function) { // Try to figure out where the success/error callbacks need to be bound // to our promise resolve/reject handlers. @@ -100,9 +82,20 @@ function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:an let pluginInstance = getPlugin(pluginObj.pluginRef); - if(!systemCheck(pluginInstance, pluginObj, methodName, resolve, reject)) return; + if(!pluginInstance) { + // Do this check in here in the case that the Web API for this plugin is available (for example, Geolocation). + if(!window.cordova) { + cordovaWarn(pluginObj.name, methodName); + return { + error: 'cordova_not_available' + } + } - // console.log('Cordova calling', pluginObj.name, methodName, args); + pluginWarn(pluginObj, methodName); + return { + error: 'plugin_not_installed' + }; + } // TODO: Illegal invocation needs window context return get(window, pluginObj.pluginRef)[methodName].apply(pluginInstance, args); @@ -163,34 +156,37 @@ function wrapObservable(pluginObj:any, methodName:string, args:any[], opts:any = } function callInstance(pluginObj:any, methodName : string, args:any[], opts:any = {}, resolve? : Function, reject? : Function){ - if(!systemCheck(getPlugin(pluginObj), pluginObj, methodName, resolve, reject)) return; - args = setIndex(args); + //if(!systemCheck(null, pluginObj, methodName, resolve, reject)) return; + args = setIndex(args, opts, resolve, reject); + console.log("!====!", pluginObj, methodName, args); return pluginObj._objectInstance[methodName].apply(pluginObj._objectInstance, args); } function wrapInstance (pluginObj:any, methodName:string, args:any[], opts:any = {}){ + return (...args) => { if (opts.sync) { - return callInstance(pluginObj, methodName, args, opts); + return callInstance(pluginObj, methodName, args, opts); } else if (opts.observable) { - return new Observable(observer => { - let pluginResult = callInstance(pluginObj, methodName,args, opts, observer.next.bind(observer), observer.error.bind(observer)); - return () => { - try { - if (opts.clearWithArgs){ - return pluginObj._objectInstance[opts.clearFunction].apply(pluginObj._objectInstance, args); - } - return pluginObj._objectInstance[opts.clearFunction].call(pluginObj, pluginResult); - } catch(e) { - console.warn('Unable to clear the previous observable watch for', pluginObj.name, methodName); - console.error(e); + return new Observable(observer => { + let pluginResult = callInstance(pluginObj, methodName,args, opts, observer.next.bind(observer), observer.error.bind(observer)); + return () => { + try { + if (opts.clearWithArgs){ + return pluginObj._objectInstance[opts.clearFunction].apply(pluginObj._objectInstance, args); } + return pluginObj._objectInstance[opts.clearFunction].call(pluginObj, pluginResult); + } catch(e) { + console.warn('Unable to clear the previous observable watch for', pluginObj.name, methodName); + console.error(e); } - }); + } + }); } else { - return getPromise((resolve, reject) => { - callInstance(pluginObj, methodName, args, opts, resolve, reject); - }); + return getPromise((resolve, reject) => { + callInstance(pluginObj, methodName, args, opts, resolve, reject); + }); } + } } /** @@ -290,8 +286,10 @@ export function Cordova(opts:any = {}) { */ export function CordovaInstance(opts:any = {}) { return (target: Object, methodName: string) => { + console.log("P-A", target, methodName, opts); return { value: function(...args: any[]) { + console.log("P-B", ...args); return wrapInstance(this, methodName, opts).apply(this, args); } } diff --git a/src/util.ts b/src/util.ts index c4bca9be..ff3fce6d 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,4 +1,5 @@ export function get(obj, path) { + console.log(obj, path); for(var i = 0, path = path.split('.'), len = path.length; i < len; i++) { if(!obj) { return null; } obj = obj[path[i]]; From 2efce5dcb70117c5158f98d8f6ec34335d37529b Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Fri, 29 Apr 2016 21:50:09 -0400 Subject: [PATCH 11/13] refactor(-): cleanup --- src/plugins/plugin.ts | 5 ----- src/util.ts | 1 - test/app/index.html | 3 --- 3 files changed, 9 deletions(-) diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index aadb8329..e4f931d4 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -156,9 +156,7 @@ function wrapObservable(pluginObj:any, methodName:string, args:any[], opts:any = } function callInstance(pluginObj:any, methodName : string, args:any[], opts:any = {}, resolve? : Function, reject? : Function){ - //if(!systemCheck(null, pluginObj, methodName, resolve, reject)) return; args = setIndex(args, opts, resolve, reject); - console.log("!====!", pluginObj, methodName, args); return pluginObj._objectInstance[methodName].apply(pluginObj._objectInstance, args); } @@ -286,10 +284,8 @@ export function Cordova(opts:any = {}) { */ export function CordovaInstance(opts:any = {}) { return (target: Object, methodName: string) => { - console.log("P-A", target, methodName, opts); return { value: function(...args: any[]) { - console.log("P-B", ...args); return wrapInstance(this, methodName, opts).apply(this, args); } } @@ -306,7 +302,6 @@ export function CordovaProperty(target: Function, key: string, descriptor: Typed let originalMethod = descriptor.get; descriptor.get = function(...args: any[]) { - // console.log('Calling', this); if(!window.cordova) { cordovaWarn(this.name, null); return {}; diff --git a/src/util.ts b/src/util.ts index ff3fce6d..c4bca9be 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,5 +1,4 @@ export function get(obj, path) { - console.log(obj, path); for(var i = 0, path = path.split('.'), len = path.length; i < len; i++) { if(!obj) { return null; } obj = obj[path[i]]; diff --git a/test/app/index.html b/test/app/index.html index 264b6e23..6efabc83 100644 --- a/test/app/index.html +++ b/test/app/index.html @@ -2,7 +2,6 @@ - @@ -11,7 +10,5 @@ - -
From a1946442d132fe78e79017a619ef7aeff889368d Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Fri, 29 Apr 2016 22:47:01 -0400 Subject: [PATCH 12/13] refactor(plugins): clean up --- src/plugins/googlemaps.ts | 2 +- src/plugins/sqlite.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/googlemaps.ts b/src/plugins/googlemaps.ts index bcb1f17b..7c51b5ce 100644 --- a/src/plugins/googlemaps.ts +++ b/src/plugins/googlemaps.ts @@ -16,7 +16,7 @@ export class GoogleMaps { private _objectInstance : any; constructor (elementId : string) { - this._objectInstance = {};//plugin.google.maps.Map.getMap(document.getElementById(elementId)); + this._objectInstance = plugin.google.maps.Map.getMap(document.getElementById(elementId)); } @Cordova({ diff --git a/src/plugins/sqlite.ts b/src/plugins/sqlite.ts index 8c73c196..0c89fb21 100644 --- a/src/plugins/sqlite.ts +++ b/src/plugins/sqlite.ts @@ -4,7 +4,9 @@ declare var sqlitePlugin; * @name SQLite */ @Plugin({ - pluginRef: 'sqlitePlugin' + pluginRef: 'sqlitePlugin', + plugin: 'cordova-sqlite-storage', + repo: 'https://github.com/litehelpers/Cordova-sqlite-storage' }) export class SQLite { @@ -90,7 +92,6 @@ export class SQLite { finish () : void {} - @CordovaInstance({ sync: true }) From fd3fa5b1b9ebbf69b8deb677ce1616b581e57d40 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Fri, 29 Apr 2016 22:47:45 -0400 Subject: [PATCH 13/13] refactor(googlemaps): add plugin meta --- src/plugins/googlemaps.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/googlemaps.ts b/src/plugins/googlemaps.ts index 7c51b5ce..05ac4da7 100644 --- a/src/plugins/googlemaps.ts +++ b/src/plugins/googlemaps.ts @@ -9,7 +9,9 @@ declare var plugin : any; * @name Google Maps */ @Plugin({ - pluginRef: 'plugin.google.maps' + pluginRef: 'plugin.google.maps', + plugin: 'cordova-plugin-googlemaps', + repo: 'https://github.com/mapsplugin/cordova-plugin-googlemaps' }) export class GoogleMaps {