Untitled
unknown
plain_text
2 years ago
7.1 kB
5
Indexable
import { APIs } from '../consts/api'; import { CallLog, FavoriteInfo, PhoneNumber } from '../types/api'; import { PageRes, getData } from '../utils/request'; import Contacts from 'react-native-contacts'; import { CallRecord, Contact, NumberFavorites } from '../models'; import { getAuthToken } from 'utils/token'; export function syncCallLog(realm: Realm) { return getData<PageRes<CallLog>>(APIs.CALL_RECENTS + `?ver=${Date.now()}&skip=0&take=100`).then( (res) => { realm.write(() => { res.data.forEach((call) => { realm.create<CallRecord>( 'CallRecord', { id: call.id, contact: call.contact, contact_name: call.name, outgoing: call.outgoing, video: call.type == 'video', created_at: call.created_at, state: call.state, duration: call.duration, }, 'modified' ); }); }); } ); } export function syncFavorites(realm: Realm) { return getData<PageRes<FavoriteInfo>>(APIs.FAVORITES + `?ver=${Date.now()}&skip=0&take=100`).then( (res) => { realm.write(() => { let data = realm.objects('NumberFavorites'); realm.delete(data); res.data.forEach((f) => { realm.create<NumberFavorites>( 'NumberFavorites', { id: f.id, number: f.number, created_at: f.created_at, }, 'modified' ); }); }); } ); } function build_name(c: Contacts.Contact) { let parts = []; if (c.givenName) { parts.push(c.givenName); } if (c.middleName) { parts.push(c.middleName); } if (c.familyName) { parts.push(c.familyName); } if (c.company) { parts.push(c.company); } if (parts.length == 0 && c.phoneNumbers.length > 0) { parts.push(c.phoneNumbers[0].number); } return parts.join(' '); } // normalize phone number, remove all space and contruoy code function normalize_number(number: string) { return number.replace(/\s/g, ''); } export async function syncContact(realm: Realm): Promise<string | null> { let now_ms = Date.now(); let updated: Map<string, boolean> = new Map(); let token = await getAuthToken(); let promise1 = async () => { try { let res = await Contacts.getAll(); return { res, error: null }; } catch (e) { return { res: [], error: 'Contacts permission denied' }; } }; let promise2 = async () => { if (!token) return; try { let res = await getData<PageRes<PhoneNumber>>( APIs.CONTACTS + `?ver=${Date.now()}&skip=0&take=1000` ); console.log('23232323', res); return { res, error: null }; } catch (e) { return { res: { data: [] }, error: 'Cannot get remote contacts' }; } }; return Promise.all([promise1(), promise2()]).then(([res1, res2]) => { const local_contacts = res1.res; const local_error = res1.error; const remote_contacts = res2?.res; const remote_error = res2?.error; // avoid contacts duplicate let map = new Map<string, Contacts.Contact>(); let local_contacts2: Contacts.Contact[] = []; local_contacts.forEach((contact) => { if (contact.phoneNumbers.length > 0) { let number = normalize_number(contact.phoneNumbers[0].number); if (!map.has(number)) { updated.set(number, true); map.set(number, contact); local_contacts2.push(contact); } } }); // contacts returned realm.write(() => { local_contacts2.forEach((contact) => { if (contact.phoneNumbers.length > 0) { let name = build_name(contact); let number = normalize_number(contact.phoneNumbers[0].number); let exiting = realm.objectForPrimaryKey<Contact>('Contact', number); if (!exiting) { console.log('create local contact:', name); realm.create<Contact>( 'Contact', { group_label: name.charAt(0).toUpperCase(), number, name: name, name_sort: name.toLowerCase(), last_updated: now_ms, is_local: true, }, 'modified' ); } else if (name != exiting.name || !exiting.is_local) { console.log( 'update local contact:', name, exiting.name, name != exiting.name, exiting.is_local ); exiting.group_label = name.charAt(0).toUpperCase(); exiting.name = name; exiting.name_sort = name.toLowerCase(); exiting.last_updated = now_ms; exiting.is_local = true; } } }); console.log('debug contact', remote_contacts); remote_contacts?.data.forEach((number) => { updated.set(number.number, true); let name = number.name || number.number; let remote_version = number.updated_at || number.created_at; let exiting = realm.objectForPrimaryKey<Contact>('Contact', number.number); if (!exiting) { console.log('create remote contact:', number.number); realm.create<Contact>( 'Contact', { group_label: name.charAt(0).toUpperCase(), number: number.number, name, avatar: number.avatar, is_register: number?.is_register, name_sort: name.toLowerCase(), last_updated: now_ms, }, 'modified' ); } else if (!exiting.is_local && exiting.last_updated < remote_version) { console.log('update remote contact:', number.number); exiting.group_label = name.charAt(0).toUpperCase(); exiting.name = name; exiting.name_sort = name.toLowerCase(); exiting.last_updated = now_ms; } else { if (exiting.is_local) { exiting.group_label = name.charAt(0).toUpperCase(); exiting.name = name; exiting.name_sort = name.toLowerCase(); exiting.avatar = number?.avatar; exiting.is_register = number?.is_register; } } }); //clean up which contact not shown in updated realm.objects<Contact>('Contact').forEach((contact) => { if (!updated.has(contact.number)) { console.log('delete contact:', contact.number, contact.name); if (contact.is_local && !local_error) { realm.delete(contact); } if (!contact.is_local && !remote_error) { realm.delete(contact); } } }); }); return local_error || remote_error || null; }); }
Editor is loading...