From 56fc0d3172826b5abee11da1822ef0d226beb052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Belli?= Date: Wed, 7 Jun 2017 15:58:36 +0200 Subject: [PATCH] Step 15.4: Implement getContactsFromAddressbook in the phone service --- src/services/phone.ts | 60 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/src/services/phone.ts b/src/services/phone.ts index 17ad6170e..3ffc140d9 100644 --- a/src/services/phone.ts +++ b/src/services/phone.ts @@ -3,6 +3,7 @@ import { Accounts } from 'meteor/accounts-base'; import { Meteor } from 'meteor/meteor'; import { Platform } from 'ionic-angular'; import { Sim } from '@ionic-native/sim'; +import { Contact, ContactFieldType, Contacts, IContactField, IContactFindOptions } from "@ionic-native/contacts"; import { SmsReceiver } from "../ionic/sms-receiver"; import * as Bluebird from "bluebird"; import { TWILIO_SMS_NUMBERS } from "api/models"; @@ -12,7 +13,8 @@ import { Observable } from "rxjs/Observable"; export class PhoneService { constructor(private platform: Platform, private sim: Sim, - private smsReceiver: SmsReceiver) { + private smsReceiver: SmsReceiver, + private contacts: Contacts) { Bluebird.promisifyAll(this.smsReceiver); } @@ -64,6 +66,62 @@ export class PhoneService { } } + getContactsFromAddressbook(): Promise { + const getContacts = (): Promise => { + if (!this.platform.is('cordova')) { + return Promise.reject(new Error('Cannot get contacts: not cordova.')); + } + + const fields: ContactFieldType[] = ["phoneNumbers"]; + const options: IContactFindOptions = { + filter: "", + multiple: true, + desiredFields: ["phoneNumbers"], + hasPhoneNumber: true + }; + return this.contacts.find(fields, options); + }; + + const cleanPhoneNumber = (phoneNumber: string): string => { + const phoneNumberNoSpaces: string = phoneNumber.replace(/ /g, ''); + + if (phoneNumberNoSpaces.charAt(0) === '+') { + return phoneNumberNoSpaces; + } else if (phoneNumberNoSpaces.substring(0, 2) === "00") { + return '+' + phoneNumberNoSpaces.slice(2); + } else { + // Use user's international prefix when absent + // FIXME: update meteor-accounts-phone typings + const prefix: string = (Meteor.user()).phone.number.substring(0, 3); + + return prefix + phoneNumberNoSpaces; + } + }; + + return new Promise((resolve, reject) => { + getContacts() + .then((contacts: Contact[]) => { + const arrayOfArrays: string[][] = contacts + .map((contact: Contact) => { + return contact.phoneNumbers + .filter((phoneNumber: IContactField) => { + return phoneNumber.type === "mobile"; + }).map((phoneNumber: IContactField) => { + return cleanPhoneNumber(phoneNumber.value); + }).filter((phoneNumber: string) => { + return phoneNumber.slice(1).match(/^[0-9]+$/) && phoneNumber.length >= 8; + }); + }); + const flattenedArray: string[] = [].concat(...arrayOfArrays); + const uniqueArray: string[] = [...new Set(flattenedArray)]; + resolve(uniqueArray); + }) + .catch((e: Error) => { + reject(e); + }); + }); + } + verify(phoneNumber: string): Promise { return new Promise((resolve, reject) => { Accounts.requestPhoneVerification(phoneNumber, (e: Error) => {