import { UnavailabilityError } from 'expo-modules-core'; import type { EventSubscription } from 'expo-modules-core'; import expoContactsModule from './ExpoContactsNext'; import { FallbackContainer } from './types/Container'; import { FallbackGroup } from './types/Group'; /** * Represents a contact in the device's address book. * * - Data Retrieval: * Contact details can be accessed using the `getDetails` method * or via specific getters such as `getEmails` and `getPhones`. * * - Modification: * To update the contact, use bulk operations via `patch` or `update`, * or specific modifiers like `addEmail` and `deletePhone`. * @example * ```ts * const contact = await Contact.create({ * givenName: 'John', * familyName: 'Doe', * phones: [{ label: 'mobile', number: '+12123456789' }] * }); * ``` */ export class Contact extends expoContactsModule.Contact {} /** * Represents a group of contacts (for example, "Family", "Coworkers"). * Groups belong to a specific Container and can contain multiple Contacts. * @platform ios */ export class Group extends (expoContactsModule.Group || FallbackGroup) {} /** * Represents a container for contacts. * A container (often called an "Account" in UI terms) is a source of contacts, such as a local device storage, iCloud, Google, or Exchange account. * @platform ios */ export class Container extends (expoContactsModule.Container || FallbackContainer) {} /** * Adds a listener that is called when contacts are added, updated, or deleted. * * **Platform differences:** * - **Android**: Uses `ContentObserver`, which may delay notifications by 5-7 seconds. Because it observes both `RawContacts` and `Contacts`, some changes may emit two events. * - **iOS**: Uses `CNContactStoreDidChangeNotification` and emits updates immediately. * * On Android, the delay comes from the system contact provider batching notifications for performance and battery life. * If your app needs fresher data after returning from the native Contacts app, consider refreshing contacts when the app comes back to the foreground. * * @param listener A callback invoked when contacts change. The callback receives no arguments. * @returns A subscription object with a `remove` method that stops listening for changes. * @example * ```jsx * const subscription = Contacts.addContactChangeListener(() => { * console.log('Contacts changed - refreshing contact list'); * loadContacts(); * }); * * subscription.remove(); * ``` */ export function addContactsChangeListener(listener: () => void): EventSubscription { if (!expoContactsModule.addListener) { throw new UnavailabilityError('Contacts', 'addContactsChangeListener'); } return expoContactsModule.addListener('contactsDidChange', listener); } /** * Removes all contact change listeners registered with `addContactsChangeListener`. */ export function removeAllContactsChangeListeners(): void { expoContactsModule.removeAllListeners('contactsDidChange'); } /** * Checks user's permissions for accessing contacts data. * @returns A promise that resolves to a [`ContactsPermissionResponse`](#contactspermissionresponse) object. */ export async function getPermissionsAsync() { return expoContactsModule.getPermissionsAsync(); } /** * Asks the user to grant permissions for accessing contacts data. * @returns A promise that resolves to a [`ContactsPermissionResponse`](#contactspermissionresponse) object. */ export async function requestPermissionsAsync() { return expoContactsModule.requestPermissionsAsync(); }