diff --git a/src/index.ts b/src/index.ts index 73b7acd9..04c653e2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -34,6 +34,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 {GoogleAnalytics} from './plugins/googleanalytics'; import {Hotspot} from './plugins/hotspot'; import {ImagePicker} from './plugins/imagepicker'; @@ -41,6 +42,7 @@ import {InAppBrowser} from './plugins/inappbrowser'; import {Keyboard} from './plugins/keyboard'; import {LaunchNavigator} from './plugins/launchnavigator'; import {LocalNotifications} from './plugins/localnotifications'; +import {MediaPlugin} from './plugins/media'; import {Network, Connection} from './plugins/network'; import {Push} from './plugins/push'; import {Screenshot} from './plugins/screenshot'; @@ -48,6 +50,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'; @@ -85,6 +88,7 @@ export { Flashlight, Geolocation, Globalization, + GoogleMaps, GoogleAnalytics, Hotspot, ImagePicker, @@ -92,6 +96,7 @@ export { Keyboard, LaunchNavigator, LocalNotifications, + MediaPlugin, Network, Push, Screenshot, @@ -99,6 +104,7 @@ export { SocialSharing, SpinnerDialog, Splashscreen, + SQLite, StatusBar, Toast, TouchID, @@ -140,6 +146,7 @@ window['IonicNative'] = { Flashlight: Flashlight, Geolocation: Geolocation, Globalization: Globalization, + GoogleMaps : GoogleMaps, GoogleAnalytics: GoogleAnalytics, Hotspot: Hotspot, ImagePicker: ImagePicker, @@ -147,6 +154,7 @@ window['IonicNative'] = { Keyboard: Keyboard, LaunchNavigator: LaunchNavigator, LocalNotifications: LocalNotifications, + MediaPlugin: MediaPlugin, Network: Network, Push: Push, Screenshot: Screenshot, @@ -154,6 +162,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..05ac4da7 --- /dev/null +++ b/src/plugins/googlemaps.ts @@ -0,0 +1,37 @@ +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', + plugin: 'cordova-plugin-googlemaps', + repo: 'https://github.com/mapsplugin/cordova-plugin-googlemaps' +}) +export class GoogleMaps { + + private _objectInstance : any; + + constructor (elementId : string) { + 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 {} + +} diff --git a/src/plugins/media.ts b/src/plugins/media.ts new file mode 100644 index 00000000..5ebcc1b9 --- /dev/null +++ b/src/plugins/media.ts @@ -0,0 +1,168 @@ +import {CordovaInstance, Plugin} from './plugin'; +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', + plugin: 'cordova-plugin-media', + pluginRef: 'Media' +}) +export class MediaPlugin { + + // 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 diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index faa4a972..e4f931d4 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -54,26 +54,31 @@ 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 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); @@ -92,8 +97,6 @@ function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:an }; } - // console.log('Cordova calling', pluginObj.name, methodName, args); - // TODO: Illegal invocation needs window context return get(window, pluginObj.pluginRef)[methodName].apply(pluginInstance, args); } @@ -152,6 +155,38 @@ function wrapObservable(pluginObj:any, methodName:string, args:any[], opts:any = }); } +function callInstance(pluginObj:any, methodName : string, args:any[], opts:any = {}, resolve? : Function, reject? : Function){ + args = setIndex(args, opts, resolve, reject); + 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); + } 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); + } + } + }); + } else { + return getPromise((resolve, reject) => { + callInstance(pluginObj, methodName, args, opts, resolve, reject); + }); + } + } +} + /** * Wrap the event with an observable * @param event @@ -175,7 +210,7 @@ function wrapEventObservable (event : string) : Observable { 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) @@ -242,6 +277,21 @@ export function Cordova(opts:any = {}) { } } +/** + * @private + * + * 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); + } + } + } +} + /** * @private * @@ -252,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/plugins/sqlite.ts b/src/plugins/sqlite.ts new file mode 100644 index 00000000..0c89fb21 --- /dev/null +++ b/src/plugins/sqlite.ts @@ -0,0 +1,107 @@ +import {CordovaInstance, Plugin, Cordova} from './plugin'; +declare var sqlitePlugin; +/** + * @name SQLite + */ +@Plugin({ + pluginRef: 'sqlitePlugin', + plugin: 'cordova-sqlite-storage', + repo: 'https://github.com/litehelpers/Cordova-sqlite-storage' +}) +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