diff --git a/apps/web/src/components/PhoneContactsImport.vue b/apps/web/src/components/PhoneContactsImport.vue index a77569c..cd9b628 100644 --- a/apps/web/src/components/PhoneContactsImport.vue +++ b/apps/web/src/components/PhoneContactsImport.vue @@ -28,7 +28,7 @@ const emit = defineEmits<{ const pickerSupported = isContactPickerSupported(); /** یک مودال با دو مرحله تا بعد از انتخاب فایل، لیست تأیید گم نشود */ -const phase = ref<'closed' | 'help' | 'review'>('closed'); +const phase = ref<'closed' | 'choose' | 'help' | 'review'>('closed'); const importing = ref(false); const drafts = ref([]); const selected = ref>(new Set()); @@ -36,23 +36,17 @@ const listQuery = ref(''); const fileInput = ref(null); const modalOpen = computed(() => phase.value !== 'closed'); -const modalTitle = computed(() => - phase.value === 'review' ? 'انتخاب مخاطبین برای ورود' : 'ورود از مخاطبین گوشی', -); +const modalTitle = computed(() => { + if (phase.value === 'review') return 'انتخاب مخاطبین برای ورود'; + if (phase.value === 'choose') return 'ورود از مخاطبین گوشی'; + return 'ورود از فایل مخاطبین'; +}); const visibleDrafts = computed(() => filterPhoneContacts(drafts.value, listQuery.value), ); const selectedCount = computed( () => drafts.value.filter((d) => selected.value.has(d.key)).length, ); -const allSelected = computed( - () => drafts.value.length > 0 && selectedCount.value === drafts.value.length, -); -const visibleAllSelected = computed( - () => - visibleDrafts.value.length > 0 && - visibleDrafts.value.every((d) => selected.value.has(d.key)), -); function apiMessage(e: unknown, fallback: string) { if (axios.isAxiosError(e)) { @@ -111,18 +105,19 @@ function openHelp() { phase.value = 'help'; } -async function startPicker() { +function openChoose() { + phase.value = 'choose'; +} + +async function runDevicePicker() { try { - if (!pickerSupported) { - openHelp(); - return; - } const rows = await pickPhoneContacts({ multiple: true }); if (!rows.length) { emit('fail', 'مخاطبی انتخاب نشد.'); return; } - await showReview(rows, { selectAll: true }); + // مثل vcf: جستجو/انتخاب دستی، نه ورود خودکار همه + await showReview(rows, { selectAll: false }); } catch (e) { const name = e instanceof DOMException ? e.name : ''; const message = e instanceof Error ? e.message : ''; @@ -135,6 +130,14 @@ async function startPicker() { } } +function startPicker() { + if (pickerSupported) { + openChoose(); + return; + } + openHelp(); +} + async function onVcfFile(ev: Event) { const el = ev.target as HTMLInputElement; const file = el.files?.[0]; @@ -144,13 +147,13 @@ async function onVcfFile(ev: Event) { const rows = await parseVCardFile(file); if (!rows.length) { emit('fail', 'مخاطبی برای ورود پیدا نشد.'); - phase.value = 'help'; + phase.value = pickerSupported ? 'choose' : 'help'; return; } await showReview(rows, { selectAll: false }); } catch { emit('fail', 'خواندن فایل مخاطبین (.vcf) ناموفق بود.'); - phase.value = 'help'; + phase.value = pickerSupported ? 'choose' : 'help'; } } @@ -213,7 +216,23 @@ async function importSelected() { /> -