From 61b24df5d6bcc349d885a443d6c39992260a41ae Mon Sep 17 00:00:00 2001 From: chen834921478 Date: Mon, 26 Aug 2024 15:10:57 +0800 Subject: [PATCH 01/11] Update SelectContactModule.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit android 9以上不再需要获取权限 --- .../selectcontact/SelectContactModule.java | 69 +++++++------------ 1 file changed, 26 insertions(+), 43 deletions(-) diff --git a/android/src/main/java/com/streem/selectcontact/SelectContactModule.java b/android/src/main/java/com/streem/selectcontact/SelectContactModule.java index f708890..f2af0fb 100644 --- a/android/src/main/java/com/streem/selectcontact/SelectContactModule.java +++ b/android/src/main/java/com/streem/selectcontact/SelectContactModule.java @@ -5,6 +5,7 @@ import android.content.Intent; import android.database.Cursor; import android.net.Uri; +import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.StructuredName; @@ -58,19 +59,14 @@ public void openContactSelection(Promise contactsPromise) { */ private void launchPicker(Promise contactsPromise, int requestCode) { mContactsPromise = contactsPromise; - Cursor cursor = this.contentResolver.query(Contacts.CONTENT_URI, null, null, null, null); - - if (cursor != null) { - Intent intent = new Intent(Intent.ACTION_PICK); - intent.setType(Contacts.CONTENT_TYPE); + + Intent intent = new Intent(Intent.ACTION_PICK,ContactsContract.CommonDataKinds.Phone.CONTENT_URI); +// intent.setType(Contacts.CONTENT_TYPE); Activity activity = getCurrentActivity(); if (intent.resolveActivity(activity.getPackageManager()) != null) { activity.startActivityForResult(intent, requestCode); } - cursor.close(); - } else { - mContactsPromise.reject(E_CONTACT_PERMISSION, "no permission"); - } + } @Override @@ -89,55 +85,42 @@ public void onActivityResult(Activity activity, int requestCode, int resultCode, WritableMap contactData = Arguments.createMap(); try { - String id = getContactId(intent.getData()); - contactData.putString("recordId", id); - Uri contactUri = buildContactUri(id); +// String id = getContactId(intent.getData()); +// contactData.putString("recordId", id); +// Uri contactUri = buildContactUri(id); boolean foundData = false; WritableArray phones = Arguments.createArray(); WritableArray emails = Arguments.createArray(); WritableArray postalAddresses = Arguments.createArray(); - Cursor cursor = openContactQuery(contactUri); - if (cursor.moveToFirst()) { - do { - String mime = cursor.getString(cursor.getColumnIndex(Entity.MIMETYPE)); - switch (mime) { - case StructuredName.CONTENT_ITEM_TYPE: - addNameData(contactData, cursor); - foundData = true; - break; - - case StructuredPostal.CONTENT_ITEM_TYPE: - addPostalData(postalAddresses, cursor, activity); - foundData = true; - break; - - case Phone.CONTENT_ITEM_TYPE: - addPhoneEntry(phones, cursor, activity); - foundData = true; - break; - - case Email.CONTENT_ITEM_TYPE: - addEmailEntry(emails, cursor, activity); - foundData = true; - break; - } - } while (cursor.moveToNext()); + + + Cursor cursor = activity.getContentResolver().query(intent.getData(), null, null, null, null); + if (cursor != null && cursor.moveToFirst()) { + + int any=cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); + String number = cursor.getString(any); + String fullName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); + foundData= true; + addPhoneEntry(phones, cursor, activity); + contactData.putArray("phones", phones); + contactData.putString("phone", number); + contactData.putString("name", fullName); + } cursor.close(); - contactData.putArray("phones", phones); - contactData.putArray("emails", emails); - contactData.putArray("postalAddresses", postalAddresses); + +// contactData.putArray("postalAddresses", postalAddresses); if (foundData) { mContactsPromise.resolve(contactData); } else { mContactsPromise.reject(E_CONTACT_NO_DATA, "No data found for contact"); } - } catch (SelectContactException e) { - mContactsPromise.reject(E_CONTACT_EXCEPTION, e.getMessage()); +// } catch (SelectContactException e) { +// mContactsPromise.reject(E_CONTACT_EXCEPTION, e.getMessage()); } catch (Exception e) { Log.e(TAG, "Unexpected exception reading from contacts", e); mContactsPromise.reject(E_CONTACT_EXCEPTION, e.getMessage()); From 4234747ab06f96d1283553315aef06e695e4509e Mon Sep 17 00:00:00 2001 From: chen834921478 Date: Thu, 5 Sep 2024 11:46:03 +0800 Subject: [PATCH 02/11] Update README.md --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c6d7231..eb20d4b 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,14 @@ This is a simple wrapper for the native iOS and Android Contact Picker UIs, with ### Installation ``` -yarn add react-native-select-contact +yarn add react-native-select-contact@https://github.com/chen834921478/react-native-contact-select.git + + ``` or with NPM ``` -npm install react-native-select-contact +npm install react-native-select-contact@https://github.com/chen834921478/react-native-contact-select.git + ``` For React Native => 0.59 only: From 6a6a1493cf3c9bb8f1d9bf53b2c2862784ec2c05 Mon Sep 17 00:00:00 2001 From: chen834921478 Date: Thu, 5 Sep 2024 14:55:48 +0800 Subject: [PATCH 03/11] Create npm-publish.yml --- .github/workflows/npm-publish.yml | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/npm-publish.yml diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 0000000..2a4766d --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,33 @@ +# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created +# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages + +name: Node.js Package + +on: + release: + types: [created] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + - run: npm ci + - run: npm test + + publish-npm: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: https://registry.npmjs.org/ + - run: npm ci + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{secrets.npm_token}} From 80ca9622ca5212ab89d43efcf95e433d359c3bf4 Mon Sep 17 00:00:00 2001 From: chen834921478 Date: Wed, 11 Mar 2026 17:29:29 +0800 Subject: [PATCH 04/11] Fix typo in build.gradle for mavenCentral MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 大小写 --- android/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 1a1583f..a7cd356 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -9,7 +9,7 @@ buildscript { if (project == rootProject) { repositories { google() - mavencentral() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:3.5.2' @@ -43,7 +43,7 @@ repositories { url "$rootDir/../node_modules/jsc-android/dist" } google() - mavencentral() + mavenCentral() } dependencies { From ae79aea1a1abf4e2267fb74a4013fff554080abc Mon Sep 17 00:00:00 2001 From: keke Date: Wed, 11 Mar 2026 17:31:58 +0800 Subject: [PATCH 05/11] 1.6.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f443b26..256bce0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-native-select-contact", "description": "A react native company to select a contact from your phone's contact list", - "version": "1.6.3", + "version": "1.6.4", "nativePackage": true, "typings": "./selectContact.d.ts", "scripts": { From b6ebace7a66976c4593ce0c2df4488f97fc5c6f4 Mon Sep 17 00:00:00 2001 From: keke Date: Wed, 11 Mar 2026 17:37:36 +0800 Subject: [PATCH 06/11] 1.7.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 256bce0..127d16e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-native-select-contact", "description": "A react native company to select a contact from your phone's contact list", - "version": "1.6.4", + "version": "1.7.0", "nativePackage": true, "typings": "./selectContact.d.ts", "scripts": { From 7d62cd13273bb11e95cc061961f9a399edb60789 Mon Sep 17 00:00:00 2001 From: keke Date: Wed, 11 Mar 2026 17:48:17 +0800 Subject: [PATCH 07/11] fix: include missing code for v1.7.0 --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 127d16e..8dd4e57 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "react-native-select-contact", + "name": "@chen834921478/react-native-select-contact", "description": "A react native company to select a contact from your phone's contact list", "version": "1.7.0", "nativePackage": true, @@ -9,7 +9,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/streem/react-native-select-contact.git" + "url": "git+https://github.com/chen834921478//react-native-select-contact.git" }, "keywords": [ "react", @@ -20,13 +20,13 @@ "select contact" ], "author": { - "name": "Streem (originally LynxIT iDigital)" + "name": "chen834921478/ (originally LynxIT iDigital)" }, "license": "MIT", "bugs": { - "url": "https://github.com/streem/react-native-select-contact/issues" + "url": "https://github.com/chen834921478//react-native-select-contact/issues" }, - "homepage": "https://github.com/streem/react-native-select-contact", + "homepage": "https://github.com/chen834921478/react-native-select-contact", "maintainers": [ { "name": "Sean Adkinson" From 29ec3aea7a9d5e8ac0a07867a7d8b86d99efb709 Mon Sep 17 00:00:00 2001 From: keke Date: Wed, 11 Mar 2026 17:58:10 +0800 Subject: [PATCH 08/11] fix: include missing code for v --- README.md | 115 +++++++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index eb20d4b..c2b45c2 100644 --- a/README.md +++ b/README.md @@ -7,23 +7,28 @@ This is a simple wrapper for the native iOS and Android Contact Picker UIs, with ### Installation ``` -yarn add react-native-select-contact@https://github.com/chen834921478/react-native-contact-select.git +yarn add react-native-select-contact@https://github.com/chen834921478/react-native-select-contact.git ``` + or with NPM + ``` -npm install react-native-select-contact@https://github.com/chen834921478/react-native-contact-select.git +npm install react-native-select-contact@https://github.com/chen834921478/react-native-select-contact.git ``` For React Native => 0.59 only: + ``` react-native link react-native-select-contact ``` #### Android + For Android support, make sure your manifest file includes permission to read contacts along with a query intent for Android 11+: + ```xml @@ -41,10 +46,13 @@ For Android support, make sure your manifest file includes permission to read co ``` + Also, in addition to declaring `READ_CONTACTS` permission in `AndroidManifest.xml`, you also need to explicitly request for the permission at runtime. So make sure `READ_CONTACT` permission is granted at runtime before calling API method(s). #### iOS + For iOS support, make sure to include usage description for contacts in your `Info.plist` file + ```xml @@ -70,12 +78,12 @@ selectContactEmail(): Promise; selectContactPostalAddress(): Promise; ``` -These methods all open up a separate ViewController (on IOS) or Activity (on Android) to select a contact. See Types below. +These methods all open up a separate ViewController (on IOS) or Activity (on Android) to select a contact. See Types below. For `selectContactPhone`, `selectContactEmail`, or `selectContactPostalAddress`, if there are more than one phone or email, an `ActionSheetIOS` is shown for IOS, and the first entry is returned for Android. -A return value `null` may be because the user cancelled the contact selection. You shouldn't need to worry about doing +A return value `null` may be because the user cancelled the contact selection. You shouldn't need to worry about doing anything if the promise resolves to `null`. #### Optional Android ActionSheet @@ -87,6 +95,7 @@ yarn add react-native-action-sheet ``` For React Native => 0.59 only: + ``` react-native link react-native-action-sheet ``` @@ -98,80 +107,80 @@ when there are more than one phone number or email on a selected contact. ```typescript interface PhoneEntry { - number: string, - type: string + number: string; + type: string; } interface EmailEntry { - address: string, - type: string + address: string; + type: string; } interface AddressEntry { - formattedAddress: string, // android only - type: string, // android only - street: string, - city: string, - state: string, - postalCode: string, - isoCountryCode: string + formattedAddress: string; // android only + type: string; // android only + street: string; + city: string; + state: string; + postalCode: string; + isoCountryCode: string; } interface Contact { - name: string, - phones: PhoneEntry[], - emails: EmailEntry[], - postalAddresses: AddressEntry[] + name: string; + phones: PhoneEntry[]; + emails: EmailEntry[]; + postalAddresses: AddressEntry[]; } interface ContactPhoneSelection { - contact: Contact, - selectedPhone: PhoneEntry + contact: Contact; + selectedPhone: PhoneEntry; } interface ContactEmailSelection { - contact: Contact, - selectedEmail: EmailEntry + contact: Contact; + selectedEmail: EmailEntry; } interface ContactPostalAddressSelection { - contact: Contact, - selectedAddress: AddressEntry + contact: Contact; + selectedAddress: AddressEntry; } ``` ### Example ```javascript - -import { selectContactPhone } from 'react-native-select-contact'; -import { PermissionsAndroid, Platform } from 'react-native'; +import { selectContactPhone } from "react-native-select-contact"; +import { PermissionsAndroid, Platform } from "react-native"; async function getPhoneNumber() { - // on android we need to explicitly request for contacts permission and make sure it's granted - // before calling API methods - if (Platform.OS === 'android') { - const request = await PermissionsAndroid.request( - PermissionsAndroid.PERMISSIONS.READ_CONTACTS, - ); - - // denied permission - if (request === PermissionsAndroid.RESULTS.DENIED) throw Error("Permission Denied"); - - // user chose 'deny, don't ask again' - else if (request === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN) throw Error("Permission Denied"); - } - - // Here we are sure permission is granted for android or that platform is not android - const selection = await selectContactPhone(); - if (!selection) { - return null; - } - - let { contact, selectedPhone } = selection; - console.log(`Selected ${selectedPhone.type} phone number ${selectedPhone.number} from ${contact.name}`); - return selectedPhone.number; + // on android we need to explicitly request for contacts permission and make sure it's granted + // before calling API methods + if (Platform.OS === "android") { + const request = await PermissionsAndroid.request( + PermissionsAndroid.PERMISSIONS.READ_CONTACTS, + ); + + // denied permission + if (request === PermissionsAndroid.RESULTS.DENIED) + throw Error("Permission Denied"); + // user chose 'deny, don't ask again' + else if (request === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN) + throw Error("Permission Denied"); + } + + // Here we are sure permission is granted for android or that platform is not android + const selection = await selectContactPhone(); + if (!selection) { + return null; + } + + let { contact, selectedPhone } = selection; + console.log( + `Selected ${selectedPhone.type} phone number ${selectedPhone.number} from ${contact.name}`, + ); + return selectedPhone.number; } - - ``` From ed0e091a1c3556efb6b3f65af0815ea39f6cc31d Mon Sep 17 00:00:00 2001 From: keke Date: Fri, 13 Mar 2026 11:59:31 +0800 Subject: [PATCH 09/11] gx --- android/.gitignore | 2 - .../selectcontact/SelectContactModule.java | 23 +- index.js | 318 +++++++++--------- package.json | 8 +- selectContact.d.ts | 22 +- 5 files changed, 168 insertions(+), 205 deletions(-) delete mode 100644 android/.gitignore diff --git a/android/.gitignore b/android/.gitignore deleted file mode 100644 index 635ae57..0000000 --- a/android/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.gradle -local.properties \ No newline at end of file diff --git a/android/src/main/java/com/streem/selectcontact/SelectContactModule.java b/android/src/main/java/com/streem/selectcontact/SelectContactModule.java index f2af0fb..18117bf 100644 --- a/android/src/main/java/com/streem/selectcontact/SelectContactModule.java +++ b/android/src/main/java/com/streem/selectcontact/SelectContactModule.java @@ -61,7 +61,6 @@ private void launchPicker(Promise contactsPromise, int requestCode) { mContactsPromise = contactsPromise; Intent intent = new Intent(Intent.ACTION_PICK,ContactsContract.CommonDataKinds.Phone.CONTENT_URI); -// intent.setType(Contacts.CONTENT_TYPE); Activity activity = getCurrentActivity(); if (intent.resolveActivity(activity.getPackageManager()) != null) { activity.startActivityForResult(intent, requestCode); @@ -74,28 +73,19 @@ public void onActivityResult(Activity activity, int requestCode, int resultCode, if (mContactsPromise == null || requestCode != CONTACT_REQUEST) { return; } - //Request was cancelled if (resultCode != Activity.RESULT_OK) { mContactsPromise.reject(E_CONTACT_CANCELLED, "Cancelled"); return; - } - - // Retrieve all possible data about contact and return as a JS object + } WritableMap contactData = Arguments.createMap(); try { -// String id = getContactId(intent.getData()); -// contactData.putString("recordId", id); -// Uri contactUri = buildContactUri(id); + boolean foundData = false; - WritableArray phones = Arguments.createArray(); WritableArray emails = Arguments.createArray(); WritableArray postalAddresses = Arguments.createArray(); - - - Cursor cursor = activity.getContentResolver().query(intent.getData(), null, null, null, null); if (cursor != null && cursor.moveToFirst()) { @@ -109,18 +99,13 @@ public void onActivityResult(Activity activity, int requestCode, int resultCode, contactData.putString("name", fullName); } - cursor.close(); - - -// contactData.putArray("postalAddresses", postalAddresses); + cursor.close(); if (foundData) { mContactsPromise.resolve(contactData); } else { mContactsPromise.reject(E_CONTACT_NO_DATA, "No data found for contact"); - } -// } catch (SelectContactException e) { -// mContactsPromise.reject(E_CONTACT_EXCEPTION, e.getMessage()); + } } catch (Exception e) { Log.e(TAG, "Unexpected exception reading from contacts", e); mContactsPromise.reject(E_CONTACT_EXCEPTION, e.getMessage()); diff --git a/index.js b/index.js index b740605..7a01bf9 100644 --- a/index.js +++ b/index.js @@ -1,158 +1,148 @@ -'use strict'; +"use strict"; -import { - Alert, - ActionSheetIOS, - NativeModules, - Platform -} from 'react-native'; +import { Alert, ActionSheetIOS, NativeModules, Platform } from "react-native"; const { SelectContact, ActionSheetAndroid } = NativeModules; const ActionSheet = Platform.select({ - ios: ActionSheetIOS, - android: ActionSheetAndroid + ios: ActionSheetIOS, + android: ActionSheetAndroid, }); -const DEFAULT_TEXT_OPTIONS = { - cancel: "Cancel", - selectPhone: "Select Phone", - selectPostalAddress: "Select Postal Address", - selectEmail: "Select Email", - errorNoPhoneNumbersTitle: "No Phone Numbers", - errorNoPhoneNumbersBody: "We could not find any phone numbers for ", - errorNoAddressTitle: "No Postal Addresses", - errorNoAddressBody: "We could not find any postal addresses for ", - errorNoEmailTitle: "No Email Addresses", - errorNoEmailBody: "We could not find any email addresses for ", - errorOpenTwice: "Cannot open the contact selector twice", -} - let currentlyOpen = false; const SelectContactApi = { + selectContact() { + if (currentlyOpen) { + if (Platform.OS === "ios") { + //这里再iOS 18的时候可能会出现无响应的时候点击再弹即可 + currentlyOpen = false; + } + return Promise.reject( + new Error("Cannot open the contact selector twice") + ); + } - selectContact(textOptions=DEFAULT_TEXT_OPTIONS) { - if (currentlyOpen) { - return Promise.reject(new Error(textOptions.errorOpenTwice)); - } + currentlyOpen = true; - currentlyOpen = true; - - return SelectContact.openContactSelection() - .then(contact => { - currentlyOpen = false; - return contact; - }) - .catch(err => { - currentlyOpen = false; - - // Resolve to null when cancelled - if (err.code === 'E_CONTACT_CANCELLED') { - return null; - } - - throw err; - }); - }, - - selectContactPostalAddress(textOptions=DEFAULT_TEXT_OPTIONS) { - return SelectContactApi.selectContact(textOptions) - .then(contact => { - if (!contact) { - return null; - } - - let addresses = contact && contact.postalAddresses || []; - if (addresses.length === 0) { - Alert.alert(textOptions.errorNoAddressTitle, `${textOptions.errorNoAddressBody}${contact.name}`); - return null; - } - - return selectPostalAddress(addresses) - .then(selectedAddress => { - return selectedAddress ? { contact, selectedAddress } : null; - }); - }) - }, - - selectContactPhone(textOptions=DEFAULT_TEXT_OPTIONS) { - return SelectContactApi.selectContact(textOptions) - .then(contact => { - if (!contact) { - return null; - } - - let phones = contact && contact.phones || []; - if (phones.length === 0) { - Alert.alert(textOptions.errorNoPhoneNumbersTitle, `${textOptions.errorNoPhoneNumbersBody}${contact.name}`); - return null; - } - - return selectPhone(phones, textOptions) - .then(selectedPhone => { - return selectedPhone ? { contact, selectedPhone } : null; - }); - }); - }, - - selectContactEmail(textOptions=DEFAULT_TEXT_OPTIONS) { - return SelectContactApi.selectContact(textOptions) - .then(contact => { - if (!contact) { - return null; - } - - let emails = contact && contact.emails || []; - if (emails.length === 0) { - Alert.alert(textOptions.errorNoEmailTitle, `${textOptions.errorNoEmailBody}${contact.name}`); - return null; - } - - return selectEmail(emails) - .then(selectedEmail => { - return selectedEmail ? { contact, selectedEmail } : null; - }); - }); - } + return SelectContact.openContactSelection() + .then((contact) => { + currentlyOpen = false; + return contact; + }) + .catch((err) => { + currentlyOpen = false; + + // Resolve to null when cancelled + if (err.code === "E_CONTACT_CANCELLED") { + return null; + } + throw err; + }); + }, + + selectContactPostalAddress() { + return SelectContactApi.selectContact().then((contact) => { + if (!contact) { + return null; + } + + let addresses = (contact && contact.postalAddresses) || []; + if (addresses.length === 0) { + Alert.alert( + "No Postal Addresses", + `We could not find any postal addresses for ${contact.name}` + ); + return null; + } + + return selectPostalAddress(addresses).then((selectedAddress) => { + return selectedAddress ? { contact, selectedAddress } : null; + }); + }); + }, + + selectContactPhone() { + return SelectContactApi.selectContact().then((contact) => { + if (!contact) { + return null; + } + + let phones = (contact && contact.phones) || []; + if (phones.length === 0) { + Alert.alert( + "No Phone Numbers", + `We could not find any phone numbers for ${contact.name}` + ); + return null; + } + + return selectPhone(phones).then((selectedPhone) => { + return selectedPhone ? { contact, selectedPhone } : null; + }); + }); + }, + + selectContactEmail() { + return SelectContactApi.selectContact().then((contact) => { + if (!contact) { + return null; + } + + let emails = (contact && contact.emails) || []; + if (emails.length === 0) { + Alert.alert( + "No Email Addresses", + `We could not find any email addresses for ${contact.name}` + ); + return null; + } + + return selectEmail(emails).then((selectedEmail) => { + return selectedEmail ? { contact, selectedEmail } : null; + }); + }); + }, }; module.exports = SelectContactApi; +function selectPhone(phones) { + if (phones.length < 2 || !ActionSheet) { + return Promise.resolve(phones[0]); + } -function selectPhone(phones, textOptions) { - if (phones.length < 2 || !ActionSheet) { - return Promise.resolve(phones[0]); - } - - let options = phones.map(phone => { - let { number, type } = phone; - return number + (type ? ` - ${type}` : ''); - }); + let options = phones.map((phone) => { + let { number, type } = phone; + return number + (type ? ` - ${type}` : ""); + }); - if (Platform.OS === 'ios') { - options.push(textOptions.cancel); - } + if (Platform.OS === "ios") { + options.push("Cancel"); + } - return new Promise(((resolve) => { - ActionSheet.showActionSheetWithOptions({ - title: textOptions.selectPhone, - options: options, - cancelButtonIndex: options.length - 1, - }, - (buttonIndex) => { - resolve(phones[buttonIndex]); - }); - })); + return new Promise((resolve) => { + ActionSheet.showActionSheetWithOptions( + { + title: "Select Phone", + options: options, + cancelButtonIndex: options.length - 1, + }, + (buttonIndex) => { + resolve(phones[buttonIndex]); + } + ); + }); } -function selectPostalAddress(addresses, textOptions) { +function selectPostalAddress(addresses) { if (addresses.length < 2 || !ActionSheet) { return Promise.resolve(addresses[0]); } - let options = addresses.map(address => { - let { formattedAddress, street, city, state, postalCode, isoCountryCode } = address; + let options = addresses.map((address) => { + let { formattedAddress, street, city, state, postalCode, isoCountryCode } = + address; if (formattedAddress) { return formattedAddress; @@ -161,44 +151,48 @@ function selectPostalAddress(addresses, textOptions) { return `${street} ${city}, ${state} ${postalCode} ${isoCountryCode}`; }); - if (Platform.OS === 'ios') { - options.push(textOptions.cancel); + if (Platform.OS === "ios") { + options.push("Cancel"); } - return new Promise(((resolve) => { - ActionSheet.showActionSheetWithOptions({ - title: textOptions.selectPostalAddress, - options: options, - cancelButtonIndex: options.length - 1, - }, - (buttonIndex) => { - resolve(addresses[buttonIndex]); - }); - })); + return new Promise((resolve) => { + ActionSheet.showActionSheetWithOptions( + { + title: "Select Postal Address", + options: options, + cancelButtonIndex: options.length - 1, + }, + (buttonIndex) => { + resolve(addresses[buttonIndex]); + } + ); + }); } function selectEmail(emails) { - if (emails.length < 2 || !ActionSheet) { - return Promise.resolve(emails[0]); - } + if (emails.length < 2 || !ActionSheet) { + return Promise.resolve(emails[0]); + } - let options = emails.map(email => { - let { address, type } = email; - return address + (type ? ` - ${type}` : ''); - }); + let options = emails.map((email) => { + let { address, type } = email; + return address + (type ? ` - ${type}` : ""); + }); - if (Platform.OS === 'ios') { - options.push(textOptions.cancel); - } + if (Platform.OS === "ios") { + options.push("Cancel"); + } - return new Promise(((resolve) => { - ActionSheet.showActionSheetWithOptions({ - title: textOptions.selectEmail, - options: options, - cancelButtonIndex: options.length - 1, - }, - (buttonIndex) => { - resolve(emails[buttonIndex]); - }); - })); + return new Promise((resolve) => { + ActionSheet.showActionSheetWithOptions( + { + title: "Select Email", + options: options, + cancelButtonIndex: options.length - 1, + }, + (buttonIndex) => { + resolve(emails[buttonIndex]); + } + ); + }); } diff --git a/package.json b/package.json index 8dd4e57..c26ba62 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@chen834921478/react-native-select-contact", "description": "A react native company to select a contact from your phone's contact list", - "version": "1.7.0", + "version": "1.6.3", "nativePackage": true, "typings": "./selectContact.d.ts", "scripts": { @@ -9,7 +9,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/chen834921478//react-native-select-contact.git" + "url": "git+https://github.com/chen834921478/react-native-select-contact.git" }, "keywords": [ "react", @@ -20,11 +20,11 @@ "select contact" ], "author": { - "name": "chen834921478/ (originally LynxIT iDigital)" + "name": "chen834921478 (originally LynxIT iDigital)" }, "license": "MIT", "bugs": { - "url": "https://github.com/chen834921478//react-native-select-contact/issues" + "url": "https://github.com/chen834921478/react-native-select-contact/issues" }, "homepage": "https://github.com/chen834921478/react-native-select-contact", "maintainers": [ diff --git a/selectContact.d.ts b/selectContact.d.ts index 688f9dd..a8cade6 100644 --- a/selectContact.d.ts +++ b/selectContact.d.ts @@ -1,8 +1,8 @@ -export function selectContact(textOptions? : TextOptions): Promise; -export function selectContactPhone(textOptions? : TextOptions): Promise; -export function selectContactEmail(textOptions? : TextOptions): Promise; -export function selectContactPostalAddress(textOptions? : TextOptions): Promise; +export function selectContact(): Promise; +export function selectContactPhone(): Promise; +export function selectContactEmail(): Promise; +export function selectContactPostalAddress(): Promise; export interface PhoneEntry { number: string, @@ -45,18 +45,4 @@ export interface ContactEmailSelection { export interface ContactPostalAddressSelection { contact: Contact, selectedAddress: AddressEntry -} - -export interface TextOptions { - cancel: String, - selectPhone: String, - selectPostalAddress: String, - selectEmail: String, - errorNoPhoneNumbersTitle: String, - errorNoPhoneNumbersBody: String, - errorNoAddressTitle: String, - errorNoAddressBody: String, - errorNoEmailTitle: String, - errorNoEmailBody: String, - errorOpenTwice: String, } \ No newline at end of file From a34f292e88377da5b90840ed8836d67ac61a8f9b Mon Sep 17 00:00:00 2001 From: keke Date: Fri, 13 Mar 2026 11:59:39 +0800 Subject: [PATCH 10/11] 1.6.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c26ba62..dae3ed7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@chen834921478/react-native-select-contact", "description": "A react native company to select a contact from your phone's contact list", - "version": "1.6.3", + "version": "1.6.4", "nativePackage": true, "typings": "./selectContact.d.ts", "scripts": { From 1bd6351fc3256938d985bbb1342df9144b016923 Mon Sep 17 00:00:00 2001 From: keke Date: Fri, 13 Mar 2026 14:01:35 +0800 Subject: [PATCH 11/11] gx --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dae3ed7..60932d4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@chen834921478/react-native-select-contact", "description": "A react native company to select a contact from your phone's contact list", - "version": "1.6.4", + "version": "1.7.1", "nativePackage": true, "typings": "./selectContact.d.ts", "scripts": {