Edit: Add from Android phone contacts

This commit is contained in:
2026-09-21 20:51:06 +03:30
parent 9249302eac
commit be97a067f9
3 changed files with 110 additions and 41 deletions
+53 -9
View File
@@ -10,7 +10,7 @@ import {
filterPhoneContacts,
isContactPickerSupported,
parseVCardFile,
pickOnePhoneContact,
pickPhoneContacts,
sortPhoneContacts,
type PhoneContactDraft,
} from '@/lib/phone-contacts';
@@ -69,6 +69,7 @@ const loyaltyTierName = ref('');
const contactPickerSupported = isContactPickerSupported();
const pickingContact = ref(false);
const contactFileInput = ref<HTMLInputElement | null>(null);
const sourceOpen = ref(false);
const pickOpen = ref(false);
const pickDrafts = ref<PhoneContactDraft[]>([]);
const pickQuery = ref('');
@@ -112,6 +113,10 @@ function closePick() {
pickQuery.value = '';
}
function closeSource() {
sourceOpen.value = false;
}
function choosePick(row: PhoneContactDraft) {
applyContactDraft(row);
closePick();
@@ -120,23 +125,34 @@ function choosePick(row: PhoneContactDraft) {
async function openPickList(rows: PhoneContactDraft[]) {
pickDrafts.value = sortPhoneContacts(rows);
pickQuery.value = '';
sourceOpen.value = false;
pickOpen.value = false;
await nextTick();
pickOpen.value = true;
}
async function fillFromPhoneContact() {
function fillFromPhoneContact() {
if (pickingContact.value || saving.value) return;
error.value = '';
if (contactPickerSupported) {
sourceOpen.value = true;
return;
}
contactFileInput.value?.click();
}
async function pickFromDevice() {
if (pickingContact.value || saving.value) return;
pickingContact.value = true;
error.value = '';
sourceOpen.value = false;
try {
if (!contactPickerSupported) {
contactFileInput.value?.click();
const rows = await pickPhoneContacts({ multiple: true });
if (!rows.length) {
error.value = 'مخاطبی انتخاب نشد.';
return;
}
const draft = await pickOnePhoneContact();
if (!draft) return;
applyContactDraft(draft);
await openPickList(rows);
} catch (e) {
const name = e instanceof DOMException ? e.name : '';
const message = e instanceof Error ? e.message : '';
@@ -151,6 +167,11 @@ async function fillFromPhoneContact() {
}
}
function pickFromVcf() {
sourceOpen.value = false;
contactFileInput.value?.click();
}
async function onContactVcfFile(ev: Event) {
const el = ev.target as HTMLInputElement;
const file = el.files?.[0];
@@ -339,9 +360,27 @@ onMounted(load);
@change="onContactVcfFile"
/>
<UiModal :open="pickOpen" title="انتخاب مخاطب" @close="closePick">
<UiModal nest :open="sourceOpen" title="از مخاطبین" @close="closeSource">
<p class="pick-lead">
{{ toFaDigits(pickDrafts.length) }} مخاطب در فایل (مرتب‌شده الفبایی).
چند مخاطب را از دفترچه یا فایل بگیرید؛ بعد در لیست الفبایی جستجو کنید و یکی را برای پر کردن موبایل انتخاب کنید.
</p>
<div class="pick-choose">
<UiButton variant="primary" block :disabled="pickingContact" @click="pickFromDevice">
<UiIcon name="phone" :size="16" />
از دفترچه تلفن
</UiButton>
<UiButton variant="ghost" block :disabled="pickingContact" @click="pickFromVcf">
از فایل .vcf
</UiButton>
</div>
<template #footer>
<UiButton variant="ghost" @click="closeSource">انصراف</UiButton>
</template>
</UiModal>
<UiModal nest :open="pickOpen" title="انتخاب مخاطب" @close="closePick">
<p class="pick-lead">
{{ toFaDigits(pickDrafts.length) }} مخاطب (مرتب‌شده الفبایی).
یکی را انتخاب کنید تا فقط موبایل (و در صورت خالی بودن، نام) پر شود.
</p>
<div class="pick-search">
@@ -561,6 +600,11 @@ onMounted(load);
line-height: 1.7;
}
.pick-choose {
display: grid;
gap: 0.55rem;
}
.pick-search {
display: flex;
align-items: center;