From aada893f09557e94c72d89167460d10742bb8586 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Sat, 30 Apr 2016 12:56:30 -0400 Subject: [PATCH 01/16] fix(contacts): plugin rewrite --- src/plugins/contacts.ts | 174 +++++++++++++++++++++++++++++++--------- 1 file changed, 136 insertions(+), 38 deletions(-) diff --git a/src/plugins/contacts.ts b/src/plugins/contacts.ts index 16299330..049314ff 100644 --- a/src/plugins/contacts.ts +++ b/src/plugins/contacts.ts @@ -31,27 +31,80 @@ export interface ContactProperties { urls?: ContactField[]; } -export interface Contact extends ContactProperties { - /** - * Returns a new Contact object that is a deep copy of the calling object, with the id property set to null - */ - clone(): Contact; - /** - * Removes the contact from the device contacts database, otherwise executes an error callback with a ContactError object. - * @param onSuccess Success callback function invoked on success operation. - * @param onError Error callback function, invoked when an error occurs. - */ - remove( - onSuccess?: () => void, - onError?: (error: Error) => void): void; - /** - * Saves a new contact to the device contacts database, or updates an existing contact if a contact with the same id already exists. - * @param onSuccess Success callback function invoked on success operation with che Contact object. - * @param onError Error callback function, invoked when an error occurs. - */ - save( - onSuccess?: (contact: Contact) => void, - onError?: (error: Error) => void): void; +// export interface Contact extends ContactProperties { +// /** +// * Returns a new Contact object that is a deep copy of the calling object, with the id property set to null +// */ +// clone(): Contact; +// /** +// * Removes the contact from the device contacts database, otherwise executes an error callback with a ContactError object. +// * @param onSuccess Success callback function invoked on success operation. +// * @param onError Error callback function, invoked when an error occurs. +// */ +// remove( +// onSuccess?: () => void, +// onError?: (error: Error) => void): void; +// /** +// * Saves a new contact to the device contacts database, or updates an existing contact if a contact with the same id already exists. +// * @param onSuccess Success callback function invoked on success operation with che Contact object. +// * @param onError Error callback function, invoked when an error occurs. +// */ +// save( +// onSuccess?: (contact: Contact) => void, +// onError?: (error: Error) => void): void; +// } + +export class Contact { + + private _objectInstance: any; + + get id(): string { + return this._objectInstance.id; + } + set id(val: string) { + this._objectInstance.id = val; + } + get displayName(): string { + return this._objectInstance.displayName; + } + set displayName(val: string){ + this._objectInstance.displayName = val; + } + get name(): ContactName { + return this._objectInstance.name; + } + set name(val: ContactName){ + this._objectInstance.name = val; + } + get nickname(): string { + return this._objectInstance.nickname; + } + set nickname(val: string){ + this._objectInstance.nickname = val; + } + get phoneNumbers(): ContactField[] { + return this._objectInstance.phoneNumbers; + } + set phoneNumbers(val: ContactField[]){ + this._objectInstance.phoneNumbers = val; + } + get emails(): ContactField[] { + return this._objectInstance.emails; + } + set emails(val: ContactField[]){ + this._objectInstance.emails = val; + } + get addresses(): ContactAddress[] { + return this._objectInstance.addresses; + } + set addresses(val: ContactAddress[]){ + this._objectInstance.addresses = val; + } + + constructor () { + // creat eobj + } + } interface ContactError { @@ -87,15 +140,30 @@ export interface ContactName { honorificSuffix?: string; } -declare var ContactName: { - /** Constructor for ContactName object */ - new(formatted?: string, - familyName?: string, - givenName?: string, - middleName?: string, - honorificPrefix?: string, - honorificSuffix?: string): ContactName -}; +// declare var ContactName: { +// /** Constructor for ContactName object */ +// new(formatted?: string, +// familyName?: string, +// givenName?: string, +// middleName?: string, +// honorificPrefix?: string, +// honorificSuffix?: string): ContactName +// }; + +export class ContactName { + private _objectInstance: any; + + constructor() { } + + public set givenName(val: string) { + this._objectInstance.givenName = val; + } + public set familyName(val: string) { + this._objectInstance.familyName = val; + } + public get givenName(): string {return this._objectInstance.givenName; } + public get familyName(): string {return this._objectInstance.familyName; } +} export interface ContactField { /** A string that indicates what type of field this is, home for example. */ @@ -183,9 +251,28 @@ declare var ContactFindOptions: { desiredFields?: string[]): ContactFindOptions }; -declare var Contact: { - new(): Contact -}; +export class ContactFindOptions { + private _objectInstance: any; + public set filter(val: string) { + this._objectInstance.filter = val; + } + + public set multiple(val: boolean) { + this._objectInstance.multiple = val; + } + + public set desiredFields(val) { + this._objectInstance.desiredFields = val; + } + + public set hasPhoneNumber(val: boolean) { + this._objectInstance.hasPhoneNumber = val; + } +} + +// declare var Contact: { +// new(): Contact +// }; /** * @name Contacts @@ -215,17 +302,28 @@ declare var Contact: { repo: 'https://github.com/apache/cordova-plugin-contacts' }) export class Contacts { + + private _objectInstance: any; + + public set displayName(val: string) { + this._objectInstance.displayName = val; + } + + public set nickname(val: boolean) { + this._objectInstance.nickname = val; + } + + get displayName() {return this._objectInstance.displayName; } + get nickname() {return this._objectInstance.nickname; } + /** * Create a new Contact object. * * @param options {Object} Object whose properties the created Contact should have. * @return {Contact} Returns the created contact */ - @Cordova({ - sync: true - }) - static create(options: ContactProperties) { - return new Contact(); + constructor (options?: ContactProperties) { + this._objectInstance = navigator.contacts(options); }; /** From 937138378bda330d5d2408b11935d97919c3d41f Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Sat, 30 Apr 2016 13:43:47 -0400 Subject: [PATCH 02/16] update the new plugin rewrite --- src/plugins/contacts.ts | 96 ++++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/src/plugins/contacts.ts b/src/plugins/contacts.ts index 049314ff..afaa603c 100644 --- a/src/plugins/contacts.ts +++ b/src/plugins/contacts.ts @@ -1,4 +1,4 @@ -import {Plugin, Cordova} from './plugin'; +import {Plugin, Cordova, InstanceProperty, CordovaInstance} from './plugin'; export interface ContactProperties { /** A globally unique identifier. */ @@ -58,53 +58,61 @@ export class Contact { private _objectInstance: any; - get id(): string { - return this._objectInstance.id; - } - set id(val: string) { - this._objectInstance.id = val; - } - get displayName(): string { - return this._objectInstance.displayName; - } - set displayName(val: string){ - this._objectInstance.displayName = val; - } - get name(): ContactName { - return this._objectInstance.name; - } - set name(val: ContactName){ - this._objectInstance.name = val; - } - get nickname(): string { - return this._objectInstance.nickname; - } - set nickname(val: string){ - this._objectInstance.nickname = val; - } - get phoneNumbers(): ContactField[] { - return this._objectInstance.phoneNumbers; - } - set phoneNumbers(val: ContactField[]){ - this._objectInstance.phoneNumbers = val; - } - get emails(): ContactField[] { - return this._objectInstance.emails; - } - set emails(val: ContactField[]){ - this._objectInstance.emails = val; - } - get addresses(): ContactAddress[] { - return this._objectInstance.addresses; - } - set addresses(val: ContactAddress[]){ - this._objectInstance.addresses = val; - } + @InstanceProperty + get id() {return; } + + @InstanceProperty + get displayName() {return; } + + @InstanceProperty + get nickname() {return; } + + @InstanceProperty + get phoneNumbers() {return; } + + @InstanceProperty + get emails() {return; } + + @InstanceProperty + get addresses() {return; } + + @InstanceProperty + get ims() {return; } + + @InstanceProperty + get organizations() {return; } + + @InstanceProperty + get birthday() {return; } + + @InstanceProperty + get note() {return; } + + @InstanceProperty + get photos() {return; } + + @InstanceProperty + get categories() {return; } + + @InstanceProperty + get urls() {return; } + constructor () { - // creat eobj + this._objectInstance = navigator.contacts.create(); } + clone(): Contact { + // TODO manually clone the object + return; + } + + @CordovaInstance() + remove(): Promise {return; } + + @CordovaInstance() + save(): Promise {return; } + } interface ContactError { From ab9af2bdc41b41cb1201c99d7469edd44aa7728f Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Sat, 30 Apr 2016 17:50:08 -0400 Subject: [PATCH 03/16] pre-final plugin rewrite --- src/plugins/contacts.ts | 248 ++++++++++++++++++++-------------------- 1 file changed, 122 insertions(+), 126 deletions(-) diff --git a/src/plugins/contacts.ts b/src/plugins/contacts.ts index afaa603c..e280aa12 100644 --- a/src/plugins/contacts.ts +++ b/src/plugins/contacts.ts @@ -1,6 +1,13 @@ import {Plugin, Cordova, InstanceProperty, CordovaInstance} from './plugin'; - -export interface ContactProperties { +declare var window: any = { + ContactAddress: (...args) => {}, + ContactProperties: (...args) => {}, + ContactOrganization: (...args) => {}, + ContactName: (...args) => {}, + ContactField: (...args) => {}, + ContactFindOptions: (...args) => {} +}; +export interface IContactProperties { /** A globally unique identifier. */ id?: string; /** The name of this Contact, suitable for display to end users. */ @@ -10,13 +17,13 @@ export interface ContactProperties { /** A casual name by which to address the contact. */ nickname?: string; /** An array of all the contact's phone numbers. */ - phoneNumbers?: ContactField[]; + phoneNumbers?: IContactField[]; /** An array of all the contact's email addresses. */ - emails?: ContactField[]; + emails?: IContactField[]; /** An array of all the contact's addresses. */ addresses?: ContactAddress[]; /** An array of all the contact's IM addresses. */ - ims?: ContactField[]; + ims?: IContactField[]; /** An array of all the contact's organizations. */ organizations?: ContactOrganization[]; /** The birthday of the contact. */ @@ -24,36 +31,13 @@ export interface ContactProperties { /** A note about the contact. */ note?: string; /** An array of the contact's photos. */ - photos?: ContactField[]; + photos?: IContactField[]; /** An array of all the user-defined categories associated with the contact. */ - categories?: ContactField[]; + categories?: IContactField[]; /** An array of web pages associated with the contact. */ - urls?: ContactField[]; + urls?: IContactField[]; } -// export interface Contact extends ContactProperties { -// /** -// * Returns a new Contact object that is a deep copy of the calling object, with the id property set to null -// */ -// clone(): Contact; -// /** -// * Removes the contact from the device contacts database, otherwise executes an error callback with a ContactError object. -// * @param onSuccess Success callback function invoked on success operation. -// * @param onError Error callback function, invoked when an error occurs. -// */ -// remove( -// onSuccess?: () => void, -// onError?: (error: Error) => void): void; -// /** -// * Saves a new contact to the device contacts database, or updates an existing contact if a contact with the same id already exists. -// * @param onSuccess Success callback function invoked on success operation with che Contact object. -// * @param onError Error callback function, invoked when an error occurs. -// */ -// save( -// onSuccess?: (contact: Contact) => void, -// onError?: (error: Error) => void): void; -// } - export class Contact { private _objectInstance: any; @@ -115,7 +99,7 @@ export class Contact { } -interface ContactError { +interface IContactError { /** Error code */ code: number; /** Error message */ @@ -123,7 +107,7 @@ interface ContactError { } declare var ContactError: { - new(code: number): ContactError; + new(code: number): IContactError; UNKNOWN_ERROR: number; INVALID_ARGUMENT_ERROR: number; TIMEOUT_ERROR: number; @@ -133,7 +117,7 @@ declare var ContactError: { PERMISSION_DENIED_ERROR: number }; -export interface ContactName { +export interface IContactName { /** The complete name of the contact. */ formatted?: string; /** The contact's family name. */ @@ -148,32 +132,28 @@ export interface ContactName { honorificSuffix?: string; } -// declare var ContactName: { -// /** Constructor for ContactName object */ -// new(formatted?: string, -// familyName?: string, -// givenName?: string, -// middleName?: string, -// honorificPrefix?: string, -// honorificSuffix?: string): ContactName -// }; - -export class ContactName { +export class ContactName implements IContactName { private _objectInstance: any; - constructor() { } + constructor(formatted?: string, familyName?: string, givenName?: string, middleName?: string, honorificPrefix?: string, honorificSuffix?: string) { + this._objectInstance = new window.ContactName(formatted, familyName, givenName, middleName, honorificPrefix, honorificSuffix); + } - public set givenName(val: string) { - this._objectInstance.givenName = val; - } - public set familyName(val: string) { - this._objectInstance.familyName = val; - } - public get givenName(): string {return this._objectInstance.givenName; } - public get familyName(): string {return this._objectInstance.familyName; } + @InstanceProperty + get formatted(): string {return; } + @InstanceProperty + get familyName(): string {return; } + @InstanceProperty + get givenName(): string {return; } + @InstanceProperty + get middleName(): string {return; } + @InstanceProperty + get honorificPrefix(): string {return; } + @InstanceProperty + get honorificSuffix(): string {return; } } -export interface ContactField { +export interface IContactField { /** A string that indicates what type of field this is, home for example. */ type: string; /** The value of the field, such as a phone number or email address. */ @@ -182,14 +162,20 @@ export interface ContactField { pref: boolean; } -declare var ContactField: { - /** Constructor for ContactField object */ - new(type?: string, - value?: string, - pref?: boolean): ContactField -}; +export class ContactField implements IContactField { + private _objectInstance: any; + constructor(type?: string, value?: string, pref?: boolean) { + this._objectInstance = new window.ContactField(type, value, pref); + } + @InstanceProperty + get type(): string {return; } + @InstanceProperty + get value(): string {return; } + @InstanceProperty + get pref(): boolean {return; } +} -export interface ContactAddress { +export interface IContactAddress { /** Set to true if this ContactAddress contains the user's preferred value. */ pref?: boolean; /** A string indicating what type of field this is, home for example. */ @@ -208,19 +194,46 @@ export interface ContactAddress { country?: string; } -declare var ContactAddress: { - /** Constructor of ContactAddress object */ - new(pref?: boolean, - type?: string, - formatted?: string, - streetAddress?: string, - locality?: string, - region?: string, - postalCode?: string, - country?: string): ContactAddress -}; +export class ContactAddress implements IContactAddress { + private _objectInstance: any; -export interface ContactOrganization { + constructor (pref?: boolean, + type?: string, + formatted?: string, + streetAddress?: string, + locality?: string, + region?: string, + postalCode?: string, + country?: string) { + this._objectInstance = new window.ContactAddress(pref, type, formatted, streetAddress, locality, region, postalCode, country); + } + + @InstanceProperty + get pref(): boolean {return; } + + @InstanceProperty + get type(): string {return; } + + @InstanceProperty + get formatted(): string {return; } + + @InstanceProperty + get streetAddress(): string {return; } + + @InstanceProperty + get locality(): string {return; } + + @InstanceProperty + get region(): string {return; } + + @InstanceProperty + get postalCode(): string {return; } + + @InstanceProperty + get country(): string {return; } +} + +export interface IContactOrganization { /** Set to true if this ContactOrganization contains the user's preferred value. */ pref?: boolean; /** A string that indicates what type of field this is, home for example. */ @@ -233,17 +246,29 @@ export interface ContactOrganization { title?: string; } -declare var ContactOrganization: { - /** Constructor for ContactOrganization object */ - new(pref?: boolean, - type?: string, - name?: string, - department?: string, - title?: string): ContactOrganization -}; +export class ContactOrganization implements IContactOrganization { + private _objectInstance: any; + constructor () { + this._objectInstance = new window.ContactOrganization(); + } + @InstanceProperty + get pref(): boolean {return; } + + @InstanceProperty + get type(): string {return; } + + @InstanceProperty + get name(): string {return; } + + @InstanceProperty + get department(): string {return; } + + @InstanceProperty + get title(): string {return; } +} /** Search options to filter navigator.contacts. */ -interface ContactFindOptions { +interface IContactFindOptions { /** The search string used to find navigator.contacts. */ filter?: string; /** Determines if the find operation returns multiple navigator.contacts. */ @@ -252,36 +277,24 @@ interface ContactFindOptions { desiredFields?: string[]; } -declare var ContactFindOptions: { - /** Constructor for ContactFindOptions object */ - new(filter?: string, - multiple?: boolean, - desiredFields?: string[]): ContactFindOptions -}; - -export class ContactFindOptions { +export class ContactFindOptions implements IContactFindOptions { private _objectInstance: any; - public set filter(val: string) { - this._objectInstance.filter = val; + constructor () { + this._objectInstance = new window.ContactFindOptions(); } + @InstanceProperty + public get filter(): string {return; } - public set multiple(val: boolean) { - this._objectInstance.multiple = val; - } + @InstanceProperty + public get multiple(): boolean {return; } - public set desiredFields(val) { - this._objectInstance.desiredFields = val; - } + @InstanceProperty + public get desiredFields(): any {return; } - public set hasPhoneNumber(val: boolean) { - this._objectInstance.hasPhoneNumber = val; - } + @InstanceProperty + public get hasPhoneNumber(): boolean {return; } } -// declare var Contact: { -// new(): Contact -// }; - /** * @name Contacts * @description @@ -311,28 +324,11 @@ export class ContactFindOptions { }) export class Contacts { - private _objectInstance: any; - - public set displayName(val: string) { - this._objectInstance.displayName = val; + static create(): Contact { + return new Contact(); } - public set nickname(val: boolean) { - this._objectInstance.nickname = val; - } - - get displayName() {return this._objectInstance.displayName; } - get nickname() {return this._objectInstance.nickname; } - - /** - * Create a new Contact object. - * - * @param options {Object} Object whose properties the created Contact should have. - * @return {Contact} Returns the created contact - */ - constructor (options?: ContactProperties) { - this._objectInstance = navigator.contacts(options); - }; + // TODO add fieldType options /** * Search for contacts in the Contacts list. From dfdd476ac9aed092e600537bc77af25aec25a974 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Sat, 30 Apr 2016 17:52:14 -0400 Subject: [PATCH 04/16] pre-final plugin rewrite --- src/plugins/contacts.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/contacts.ts b/src/plugins/contacts.ts index e280aa12..869bf74e 100644 --- a/src/plugins/contacts.ts +++ b/src/plugins/contacts.ts @@ -1,7 +1,6 @@ import {Plugin, Cordova, InstanceProperty, CordovaInstance} from './plugin'; declare var window: any = { ContactAddress: (...args) => {}, - ContactProperties: (...args) => {}, ContactOrganization: (...args) => {}, ContactName: (...args) => {}, ContactField: (...args) => {}, @@ -38,7 +37,7 @@ export interface IContactProperties { urls?: IContactField[]; } -export class Contact { +export class Contact implements IContactProperties { private _objectInstance: any; From 5df447a02fe7b079b67e3a152638c69e5ada0e46 Mon Sep 17 00:00:00 2001 From: Gaven Henry Date: Fri, 3 Jun 2016 15:09:55 +0800 Subject: [PATCH 05/16] add success, error, status handlers fixes #186 --- src/plugins/media.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/plugins/media.ts b/src/plugins/media.ts index 37c7d471..eb961a38 100644 --- a/src/plugins/media.ts +++ b/src/plugins/media.ts @@ -1,4 +1,5 @@ import {CordovaInstance, Plugin} from './plugin'; +import {Observable} from 'rxjs/Rx'; declare var Media: any; /** * @name MediaPlugin @@ -14,6 +15,13 @@ declare var Media: any; * // Playing a file * var file = new MediaPlugin("path/to/file.mp3"); * + * // Catch the Success & Error Output + * file.init.then(() => { + * console.log("Playback Finished"); + * }, (err) => { + * console.log("somthing went wrong! error code: "+err.code+" message: "+err.message); + * }); + * * // play the file * file.play(); * @@ -52,6 +60,8 @@ export class MediaPlugin { // Properties private _objectInstance: any; + status: Observable; + init: Promise; // Methods /** @@ -59,8 +69,10 @@ export class MediaPlugin { * @param src {string} A URI containing the audio content. */ constructor (src: string) { - // TODO handle success, error, and status - this._objectInstance = new Media(src); + let res, rej, next; + this.init = new Promise((resolve, reject) => {res = resolve; rej = reject;}); + this.status = new Observable((observer) => {next = observer.next;}); + this._objectInstance = new Media(src, res, rej, next); } /** From 6e426074235b8506578296f2d995502a51db7784 Mon Sep 17 00:00:00 2001 From: Gaven Henry Date: Sat, 4 Jun 2016 11:01:06 +0800 Subject: [PATCH 06/16] update status method --- src/plugins/media.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/media.ts b/src/plugins/media.ts index eb961a38..5e664802 100644 --- a/src/plugins/media.ts +++ b/src/plugins/media.ts @@ -1,5 +1,5 @@ import {CordovaInstance, Plugin} from './plugin'; -import {Observable} from 'rxjs/Rx'; +import {Observable} from 'rxjs/Observable'; declare var Media: any; /** * @name MediaPlugin @@ -71,7 +71,9 @@ export class MediaPlugin { constructor (src: string) { let res, rej, next; this.init = new Promise((resolve, reject) => {res = resolve; rej = reject;}); - this.status = new Observable((observer) => {next = observer.next;}); + this.status = new Observable((observer) => { + next = data => observer.next(data); + }); this._objectInstance = new Media(src, res, rej, next); } From 6d94c1dfa26b2992c550b6258f1aeb33e1a0240e Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Thu, 9 Jun 2016 23:11:51 -0400 Subject: [PATCH 07/16] Fixes --- src/plugins/contacts.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/plugins/contacts.ts b/src/plugins/contacts.ts index 869bf74e..31cce2f7 100644 --- a/src/plugins/contacts.ts +++ b/src/plugins/contacts.ts @@ -1,11 +1,5 @@ import {Plugin, Cordova, InstanceProperty, CordovaInstance} from './plugin'; -declare var window: any = { - ContactAddress: (...args) => {}, - ContactOrganization: (...args) => {}, - ContactName: (...args) => {}, - ContactField: (...args) => {}, - ContactFindOptions: (...args) => {} -}; +declare var window: any; export interface IContactProperties { /** A globally unique identifier. */ id?: string; @@ -37,7 +31,7 @@ export interface IContactProperties { urls?: IContactField[]; } -export class Contact implements IContactProperties { +export class Contact { private _objectInstance: any; From 75dfdd236c2673afa48ad82345fd68fd9cf7b0bf Mon Sep 17 00:00:00 2001 From: Gaven Henry Date: Fri, 10 Jun 2016 12:00:06 +0800 Subject: [PATCH 08/16] update doc --- src/plugins/media.ts | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/plugins/media.ts b/src/plugins/media.ts index 5e664802..f7ab6a21 100644 --- a/src/plugins/media.ts +++ b/src/plugins/media.ts @@ -9,13 +9,14 @@ declare var Media: any; * import {MediaPlugin} from 'ionic-native'; * * - * ... * - * - * // Playing a file + * // Create a MediaPlugin instance. Expects path to file or url as argument * var file = new MediaPlugin("path/to/file.mp3"); * * // Catch the Success & Error Output + * // Platform Quirks + * // iOS calls success on completion of playback only + * // Android calls success on completion of playback AND on release() * file.init.then(() => { * console.log("Playback Finished"); * }, (err) => { @@ -25,14 +26,30 @@ declare var Media: any; * // play the file * file.play(); * - * // skip to 10 seconds + * // pause the file + * file.pause(); + * + * // get current playback position + * file.getCurrentPosition().then((position) => { + * console.log(position); + * }); + * + * // get file duration + * file.getDuration().then((duration) => { + * console.log(position); + * }); + * + * // skip to 10 seconds (expects int value in ms) * file.seekTo(10000); * - * // stop plying the file + * // stop playing the file * file.stop(); * - * - * ... + * // release the native audio resource + * // Platform Quirks: + * // iOS simply create a new instance and the old one will be overwritten + * // Android you must call release() to destroy instances of media when you are done + * file.release(); * * // Recording to a file * var newFile = new MediaPlugin("path/to/file.mp3"); From 411e6fc2a161a84edb3a22dd89bf55078c804f98 Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Fri, 10 Jun 2016 01:10:50 -0400 Subject: [PATCH 09/16] tweaks to make contact plugin work better --- src/index.ts | 1 + src/plugins/contacts.ts | 198 ++++++++++++---------------------------- src/plugins/plugin.ts | 4 +- 3 files changed, 60 insertions(+), 143 deletions(-) diff --git a/src/index.ts b/src/index.ts index e7546147..d104d99d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -66,6 +66,7 @@ import {Vibration} from './plugins/vibration'; import {WebIntent} from './plugins/webintent'; export * from './plugins/googlemaps'; export * from './plugins/3dtouch'; +export * from './plugins/contacts'; export { ActionSheet, AdMob, diff --git a/src/plugins/contacts.ts b/src/plugins/contacts.ts index 31cce2f7..7b79efae 100644 --- a/src/plugins/contacts.ts +++ b/src/plugins/contacts.ts @@ -1,5 +1,6 @@ import {Plugin, Cordova, InstanceProperty, CordovaInstance} from './plugin'; -declare var window: any; +declare var window: any, + navigator: any; export interface IContactProperties { /** A globally unique identifier. */ id?: string; @@ -30,75 +31,43 @@ export interface IContactProperties { /** An array of web pages associated with the contact. */ urls?: IContactField[]; } - export class Contact { - private _objectInstance: any; - - @InstanceProperty - get id() {return; } - - @InstanceProperty - get displayName() {return; } - - @InstanceProperty - get nickname() {return; } - - @InstanceProperty - get phoneNumbers() {return; } - - @InstanceProperty - get emails() {return; } - - @InstanceProperty - get addresses() {return; } - - @InstanceProperty - get ims() {return; } - - @InstanceProperty - get organizations() {return; } - - @InstanceProperty - get birthday() {return; } - - @InstanceProperty - get note() {return; } - - @InstanceProperty - get photos() {return; } - - @InstanceProperty - get categories() {return; } - - @InstanceProperty - get urls() {return; } - - + @InstanceProperty get id() {return; } + @InstanceProperty get displayName() {return; } + @InstanceProperty get nickname() {return; } + @InstanceProperty get phoneNumbers() {return; } + @InstanceProperty get emails() {return; } + @InstanceProperty get addresses() {return; } + @InstanceProperty get ims() {return; } + @InstanceProperty get organizations() {return; } + @InstanceProperty get birthday() {return; } + @InstanceProperty get note() {return; } + @InstanceProperty get photos() {return; } + @InstanceProperty get categories() {return; } + @InstanceProperty get urls() {return; } constructor () { this._objectInstance = navigator.contacts.create(); } - clone(): Contact { - // TODO manually clone the object - return; + let newContact = new Contact(); + for (let prop in this) { + if (prop === 'id') return; + newContact[prop] = this[prop]; + } + return newContact; } - @CordovaInstance() remove(): Promise {return; } - @CordovaInstance() save(): Promise {return; } - } - interface IContactError { /** Error code */ code: number; /** Error message */ message: string; } - declare var ContactError: { new(code: number): IContactError; UNKNOWN_ERROR: number; @@ -109,7 +78,6 @@ declare var ContactError: { NOT_SUPPORTED_ERROR: number; PERMISSION_DENIED_ERROR: number }; - export interface IContactName { /** The complete name of the contact. */ formatted?: string; @@ -124,26 +92,17 @@ export interface IContactName { /** The contact's suffix (example Esq.). */ honorificSuffix?: string; } - export class ContactName implements IContactName { private _objectInstance: any; - constructor(formatted?: string, familyName?: string, givenName?: string, middleName?: string, honorificPrefix?: string, honorificSuffix?: string) { this._objectInstance = new window.ContactName(formatted, familyName, givenName, middleName, honorificPrefix, honorificSuffix); } - - @InstanceProperty - get formatted(): string {return; } - @InstanceProperty - get familyName(): string {return; } - @InstanceProperty - get givenName(): string {return; } - @InstanceProperty - get middleName(): string {return; } - @InstanceProperty - get honorificPrefix(): string {return; } - @InstanceProperty - get honorificSuffix(): string {return; } + @InstanceProperty get formatted(): string {return; } + @InstanceProperty get familyName(): string {return; } + @InstanceProperty get givenName(): string {return; } + @InstanceProperty get middleName(): string {return; } + @InstanceProperty get honorificPrefix(): string {return; } + @InstanceProperty get honorificSuffix(): string {return; } } export interface IContactField { @@ -160,12 +119,9 @@ export class ContactField implements IContactField { constructor(type?: string, value?: string, pref?: boolean) { this._objectInstance = new window.ContactField(type, value, pref); } - @InstanceProperty - get type(): string {return; } - @InstanceProperty - get value(): string {return; } - @InstanceProperty - get pref(): boolean {return; } + @InstanceProperty get type(): string {return; } + @InstanceProperty get value(): string {return; } + @InstanceProperty get pref(): boolean {return; } } export interface IContactAddress { @@ -189,7 +145,6 @@ export interface IContactAddress { export class ContactAddress implements IContactAddress { private _objectInstance: any; - constructor (pref?: boolean, type?: string, formatted?: string, @@ -200,30 +155,14 @@ export class ContactAddress implements IContactAddress { country?: string) { this._objectInstance = new window.ContactAddress(pref, type, formatted, streetAddress, locality, region, postalCode, country); } - - @InstanceProperty - get pref(): boolean {return; } - - @InstanceProperty - get type(): string {return; } - - @InstanceProperty - get formatted(): string {return; } - - @InstanceProperty - get streetAddress(): string {return; } - - @InstanceProperty - get locality(): string {return; } - - @InstanceProperty - get region(): string {return; } - - @InstanceProperty - get postalCode(): string {return; } - - @InstanceProperty - get country(): string {return; } + @InstanceProperty get pref(): boolean {return; } + @InstanceProperty get type(): string {return; } + @InstanceProperty get formatted(): string {return; } + @InstanceProperty get streetAddress(): string {return; } + @InstanceProperty get locality(): string {return; } + @InstanceProperty get region(): string {return; } + @InstanceProperty get postalCode(): string {return; } + @InstanceProperty get country(): string {return; } } export interface IContactOrganization { @@ -244,24 +183,15 @@ export class ContactOrganization implements IContactOrganization { constructor () { this._objectInstance = new window.ContactOrganization(); } - @InstanceProperty - get pref(): boolean {return; } - - @InstanceProperty - get type(): string {return; } - - @InstanceProperty - get name(): string {return; } - - @InstanceProperty - get department(): string {return; } - - @InstanceProperty - get title(): string {return; } + @InstanceProperty get pref(): boolean {return; } + @InstanceProperty get type(): string {return; } + @InstanceProperty get name(): string {return; } + @InstanceProperty get department(): string {return; } + @InstanceProperty get title(): string {return; } } /** Search options to filter navigator.contacts. */ -interface IContactFindOptions { +export interface IContactFindOptions { /** The search string used to find navigator.contacts. */ filter?: string; /** Determines if the find operation returns multiple navigator.contacts. */ @@ -275,37 +205,29 @@ export class ContactFindOptions implements IContactFindOptions { constructor () { this._objectInstance = new window.ContactFindOptions(); } - @InstanceProperty - public get filter(): string {return; } - - @InstanceProperty - public get multiple(): boolean {return; } - - @InstanceProperty - public get desiredFields(): any {return; } - - @InstanceProperty - public get hasPhoneNumber(): boolean {return; } + @InstanceProperty get filter(): string {return; } + @InstanceProperty get multiple(): boolean {return; } + @InstanceProperty get desiredFields(): any {return; } + @InstanceProperty get hasPhoneNumber(): boolean {return; } } - /** * @name Contacts * @description * Access and manage Contacts on the device. * - * Requires plugin: `cordova-plugin-contacts` - * For full info, please see the [Cordova Contacts plugin docs](https://github.com/apache/cordova-plugin-contacts) - * * @usage * * ```js - * import {Contacts} from 'ionic-native'; + * import {Contact} from 'ionic-native'; * * * - * Contacts.create({ - * displayName: "Mr. Ionitron" - * }).then((contact) => {}, (err) => {}) + * let contact = new Contact(); + * contact.displayName = "Mr. Ionitron"; + * contact.save().then( + * () => console.log("Contact saved!", contact), + * (error: any) => console.error("Error saving contact.", error) + * ); * ``` * * @@ -316,13 +238,9 @@ export class ContactFindOptions implements IContactFindOptions { repo: 'https://github.com/apache/cordova-plugin-contacts' }) export class Contacts { - static create(): Contact { return new Contact(); } - - // TODO add fieldType options - /** * Search for contacts in the Contacts list. * @@ -345,12 +263,10 @@ export class Contacts { errorIndex: 2 }) static find(fields: string[], options?: any): Promise { return; } - - /** * Select a single Contact. * @return Returns a Promise that resolves with the selected Contact */ @Cordova() - static pickContact(): Promise { return; } -} + static pickContact(): Promise {return; } +} \ No newline at end of file diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index f5b38569..1e64fa9e 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -323,13 +323,13 @@ export function CordovaProperty(target: Function, key: string, descriptor: Typed * @param descriptor * @constructor */ -export function InstanceProperty(target: Function, key: string, descriptor: TypedPropertyDescriptor) { +export function InstanceProperty(target: any, key: string, descriptor: TypedPropertyDescriptor) { descriptor.get = function() { return this._objectInstance[key]; }; descriptor.set = function(...args: any[]) { - return this._objectInstance[key] = args[0]; + this._objectInstance[key] = args[0]; }; return descriptor; From b9ae123d030a15dfe933c7a8546e6b2f41f4923c Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Fri, 10 Jun 2016 02:03:21 -0400 Subject: [PATCH 10/16] add missing types --- src/plugins/contacts.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/plugins/contacts.ts b/src/plugins/contacts.ts index 7b79efae..17c8cb67 100644 --- a/src/plugins/contacts.ts +++ b/src/plugins/contacts.ts @@ -33,19 +33,19 @@ export interface IContactProperties { } export class Contact { private _objectInstance: any; - @InstanceProperty get id() {return; } - @InstanceProperty get displayName() {return; } - @InstanceProperty get nickname() {return; } - @InstanceProperty get phoneNumbers() {return; } - @InstanceProperty get emails() {return; } - @InstanceProperty get addresses() {return; } - @InstanceProperty get ims() {return; } - @InstanceProperty get organizations() {return; } - @InstanceProperty get birthday() {return; } - @InstanceProperty get note() {return; } - @InstanceProperty get photos() {return; } - @InstanceProperty get categories() {return; } - @InstanceProperty get urls() {return; } + @InstanceProperty get id(): string {return; } + @InstanceProperty get displayName(): string {return; } + @InstanceProperty get nickname(): ContactName {return; } + @InstanceProperty get phoneNumbers(): string {return; } + @InstanceProperty get emails(): IContactField[] {return; } + @InstanceProperty get addresses(): ContactAddress[] {return; } + @InstanceProperty get ims(): IContactField[] {return; } + @InstanceProperty get organizations(): ContactOrganization[] {return; } + @InstanceProperty get birthday(): Date {return; } + @InstanceProperty get note(): string {return; } + @InstanceProperty get photos(): IContactField[] {return; } + @InstanceProperty get categories(): IContactField[] {return; } + @InstanceProperty get urls(): IContactField[] {return; } constructor () { this._objectInstance = navigator.contacts.create(); } From 8587d47ae883f3b13a7be35e2aeb9bf81b23b4eb Mon Sep 17 00:00:00 2001 From: Ibrahim Hadeed Date: Fri, 10 Jun 2016 06:17:17 -0400 Subject: [PATCH 11/16] add tslint instructions to dev guide --- DEVELOPER.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DEVELOPER.md b/DEVELOPER.md index fcd2cfc3..a71660f6 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -96,6 +96,10 @@ The `@Cordova` decorator has a few more options now. You need to run `npm run build_bundle` in the `ionic-native` project, this will create a `dist` directory. Then, you must go to your ionic application folder and replace your current `node_modules/ionic-native/dist/` with the newly generated one. +### Cleaning the code + +You need to run `gulp tslint` to analyze the code and ensure it's consitency with the repository style. Fix any errors before submitting a PR. + ### 'Wrapping' Up That's it! The only thing left to do is rigorously document the plugin and it's usage. Take a look at some of the other plugins for good documentation styles. From b19567ca19e0638e00f870414bcbf007ba1e130c Mon Sep 17 00:00:00 2001 From: Guille Date: Fri, 10 Jun 2016 14:09:22 +0200 Subject: [PATCH 12/16] Fix tslint --- src/plugins/media.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/media.ts b/src/plugins/media.ts index f7ab6a21..20898718 100644 --- a/src/plugins/media.ts +++ b/src/plugins/media.ts @@ -87,7 +87,7 @@ export class MediaPlugin { */ constructor (src: string) { let res, rej, next; - this.init = new Promise((resolve, reject) => {res = resolve; rej = reject;}); + this.init = new Promise((resolve, reject) => {res = resolve; rej = reject; }); this.status = new Observable((observer) => { next = data => observer.next(data); }); From 97ad1bc92faf14179029e68f80224b4d5ff101f6 Mon Sep 17 00:00:00 2001 From: perry Date: Fri, 10 Jun 2016 11:30:58 -0500 Subject: [PATCH 13/16] docs: differentiate between member properties and methods --- scripts/docs/dgeni-config.js | 1 + .../docs/processors/collect-inputs-outputs.js | 62 +++++++++++++++++++ scripts/docs/templates/common.template.html | 12 ++-- 3 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 scripts/docs/processors/collect-inputs-outputs.js diff --git a/scripts/docs/dgeni-config.js b/scripts/docs/dgeni-config.js index 2281a052..a0cf4217 100644 --- a/scripts/docs/dgeni-config.js +++ b/scripts/docs/dgeni-config.js @@ -22,6 +22,7 @@ module.exports = function(currentVersion) { .processor(require('./processors/jekyll')) .processor(require('./processors/remove-private-members')) .processor(require('./processors/hide-private-api')) +.processor(require('./processors/collect-inputs-outputs')) // for debugging docs // .processor(function test(){ diff --git a/scripts/docs/processors/collect-inputs-outputs.js b/scripts/docs/processors/collect-inputs-outputs.js new file mode 100644 index 00000000..c8b382e6 --- /dev/null +++ b/scripts/docs/processors/collect-inputs-outputs.js @@ -0,0 +1,62 @@ +module.exports = function collectInputsOutputs() { + return { + + $runBefore: ['rendering-docs'], + $process: function(docs) { + docs.forEach(function(doc) { + + if (doc.members && doc.members.length) { + var members = []; + var inputs = []; + var outputs = []; + + memberLoop: + for (var i in doc.members) { + + // identify properties to differentiate from methods + if (typeof doc.members[i].parameters == 'undefined') { + doc.members[i].isProperty = true; + } + + if (doc.members[i].decorators && doc.members[i].decorators.length) { + + decoratorLoop: + for (var ii in doc.members[i].decorators) { + + if (doc.members[i].decorators[ii].name == 'Input') { + inputs.push(parseMember(doc.members[i])); + continue memberLoop; + } + if (doc.members[i].decorators[ii].name == 'Output') { + outputs.push(parseMember(doc.members[i])); + continue memberLoop; + } + } + // not an input or output, must be a plain member + members.push(doc.members[i]); + } else { + members.push(doc.members[i]); + }; + } + + // update doc with pruned members list and add inputs and outputs + doc.members = members; + doc.inputs = inputs; + doc.outputs = outputs; + } + + function parseMember(member) { + member.type = member.content.substring( + member.content.indexOf('{') + 1, + member.content.indexOf('}') + ); + member.description = member.content.substring( + member.content.indexOf('}') + 1, + member.content.length + ); + return member; + } + }); + } + }; +}; diff --git a/scripts/docs/templates/common.template.html b/scripts/docs/templates/common.template.html index 4354f8c1..886f8487 100644 --- a/scripts/docs/templates/common.template.html +++ b/scripts/docs/templates/common.template.html @@ -55,13 +55,13 @@ docType: "<$ doc.docType $>" <@- macro functionSyntax(fn) @> -<@- set sep = joiner(', ') -@> -<$ fn.name $>(<@- for param in fn.params @><$ sep() $> + <@- set sep = joiner(', ') -@> + <$ fn.name $><@- if not fn.isProperty @>(<@ endif -@><@- for param in fn.params @><$ sep() $> <@- if param.type.optional @>[<@ endif -@> <$ param.name $> <@- if param.type.optional @>]<@ endif -@> - <@ endfor @>) -<@ if fn.alias @>(alias: <$ fn.alias $>)<@ endif @> + <@ endfor @><@- if not fn.isProperty @>)<@ endif -@> + <@ if fn.alias @>(alias: <$ fn.alias $>)<@ endif @> <@ endmacro -@> <@ macro typeList(types) -@> @@ -203,7 +203,7 @@ docType: "<$ doc.docType $>" <@ endif @> <@- if doc.statics.length -@> -

Static Methods

+

Static Members

<@- for method in doc.statics @><@ if not method.internal @>

<$ functionSyntax(method) $>

@@ -244,7 +244,7 @@ docType: "<$ doc.docType $>" <@- if doc.members and doc.members.length @> -

Instance Methods

+

Instance Members

<@- for method in doc.members @>
From 3a2c8f3e267b7ac4e12137704a39cf82ecbbf036 Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Fri, 10 Jun 2016 13:59:51 -0500 Subject: [PATCH 14/16] Update README.md Incorrect usage of watchPosition().subscribe and then unsubscribe --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 3fcc8b0e..2da5cf8e 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,7 @@ Geolocation.getCurrentPosition().then(pos => { console.log('lat: ' + pos.coords.latitude + ', lon: ' + pos.coords.longitude); }); -let watch = Geolocation.watchPosition(); -watch.subscribe(pos => { +let watch = Geolocation.watchPosition().subscribe(pos => { console.log('lat: ' + pos.coords.latitude + ', lon: ' + pos.coords.longitude); }); From 11226d7d51c2e4497985a57854b191fca6bf2da6 Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Fri, 10 Jun 2016 13:32:42 -0500 Subject: [PATCH 15/16] fix(deeplinks): new result type --- src/plugins/deeplinks.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/plugins/deeplinks.ts b/src/plugins/deeplinks.ts index 5bb060f6..d27d7da6 100644 --- a/src/plugins/deeplinks.ts +++ b/src/plugins/deeplinks.ts @@ -5,14 +5,19 @@ export interface DeeplinkMatch { /** * The route info for the matched route */ - routeInfo: any; + $route: any; /** - * The arguments passed to the route through GET params along with + * Any arguments passed either through route parameters or GET parameters + */ + $args: any; + + /** + * The deeplink object processed from the plugin, along with any * any internal native data available as "extras" at the time * the route was matched (for example, Facebook sometimes adds extra data) */ - args: any; + $link: any; } /** From 28e2f731f76673af55fa6a39b435a33ac7314c0c Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Fri, 10 Jun 2016 14:00:35 -0500 Subject: [PATCH 16/16] fix(plugin) only call clearFunction if defined. Fixes #210 --- src/plugins/plugin.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index f5b38569..a3730277 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -141,10 +141,12 @@ function wrapObservable(pluginObj: any, methodName: string, args: any[], opts: a return () => { try { - if (opts.clearWithArgs) { - return get(window, pluginObj.pluginRef)[opts.clearFunction].apply(pluginObj, args); + if (opts.clearFunction) { + if (opts.clearWithArgs) { + return get(window, pluginObj.pluginRef)[opts.clearFunction].apply(pluginObj, args); + } + return get(window, pluginObj.pluginRef)[opts.clearFunction].call(pluginObj, pluginResult); } - return get(window, pluginObj.pluginRef)[opts.clearFunction].call(pluginObj, pluginResult); } catch (e) { console.warn('Unable to clear the previous observable watch for', pluginObj.name, methodName); console.error(e);