src/contacts/W3cContacts.js
import {getDeviceId} from '../utils';
const NUM_MAX_PHONES_BY_CONTACT = 10;
function getAvatar(photos) {
if (photos && photos.length > 0) {
return photos[0].value;
}
return null;
}
function parsePhones(rawPhoneNumbers) {
return rawPhoneNumbers.slice(0, NUM_MAX_PHONES_BY_CONTACT).map((phone) => {
const name = phone.type;
const address = phone.value.replace(/\s/g, '');
return {name, address};
});
}
function parseEmails(rawEmails) {
if (!rawEmails) {
return [];
}
return rawEmails.map(email => ({
type: email.type,
email: email.value,
}));
}
function parseName(contact, phones) {
return contact.displayName || (contact.name && contact.name.formatted ? contact.name.formatted : phones[0].address);
}
/** @protected */
export const W3cContacts = (stack, window) => {
const navigator = window.navigator;
const deviceId = getDeviceId();
const ContactFindOptions = window.ContactFindOptions;
function existDeviceId() {
if (!deviceId) {
throw Error('W3C Contacts: Can`t get device ID');
}
}
function w3cContactToWacContact(contact) {
existDeviceId();
let phones = parsePhones(contact.phoneNumbers);
let emails = parseEmails(contact.emails);
let name = parseName(contact, phones);
return {
contactDeviceId: `w3c-contact-${contact.id}-${deviceId}`,
name: name,
source: 'device',
phones: phones,
emails: emails,
avatar: getAvatar(contact.photos),
deviceId: deviceId,
};
}
function avatarW3cContactToWacContact(contact) {
existDeviceId();
return {
contactDeviceId: `w3c-contact-${contact.id}-${deviceId}`,
avatar: getAvatar(contact.photos),
};
}
function getW3cContacts() {
return new Promise((resolve, reject) => {
let contactFindOptions = new ContactFindOptions();
contactFindOptions.multiple = true;
contactFindOptions.hasPhoneNumber = true;
contactFindOptions.desiredFields = [
navigator.contacts.fieldType.displayName,
navigator.contacts.fieldType.name,
navigator.contacts.fieldType.phoneNumbers,
navigator.contacts.fieldType.note,
navigator.contacts.fieldType.emails,
];
navigator.contacts.find(['*'], resolve, reject, contactFindOptions);
});
}
function getAvatarW3cContacts(fields = '*', filter = '') {
return new Promise((resolve, reject) => {
let contactFindOptions = new ContactFindOptions();
contactFindOptions.multiple = true;
contactFindOptions.hasPhoneNumber = true;
contactFindOptions.desiredFields = [
navigator.contacts.fieldType.photos,
];
if (filter) {
contactFindOptions.filter = filter;
}
navigator.contacts.find([fields], resolve, reject, contactFindOptions);
});
}
function allowedContacts() {
return stack.getCapabilities().includes('w3c-contacts-api') && navigator.contacts;
}
async function getContacts() {
if (!allowedContacts()) {
return [];
}
const contacts = await getW3cContacts();
return contacts
.filter(contact => contact.phoneNumbers && contact.phoneNumbers.length > 0)
.map(w3cContactToWacContact);
}
async function getAvatarContacts() {
if (!allowedContacts()) {
return [];
}
const contacts = await getAvatarW3cContacts();
return contacts.map(avatarW3cContactToWacContact);
}
return {
getContacts: getContacts,
getAvatarContacts: getAvatarContacts,
};
};