import { Alert } from "react-native"; import { getDesktopHost, type DesktopDialogAskOptions } from "@/desktop/host"; import { isNative } from "@/constants/platform"; export interface ConfirmDialogInput { title: string; message: string; confirmLabel?: string; cancelLabel?: string; destructive?: boolean; } interface ConfirmButtonConfig { confirmLabel: string; cancelLabel: string; } function resolveButtonLabels(input: ConfirmDialogInput): ConfirmButtonConfig { return { confirmLabel: input.confirmLabel ?? "Confirm", cancelLabel: input.cancelLabel ?? "Cancel", }; } async function showNativeConfirmDialog(input: ConfirmDialogInput): Promise { const labels = resolveButtonLabels(input); return new Promise((resolve) => { Alert.alert( input.title, input.message, [ { text: labels.cancelLabel, style: "cancel", onPress: () => resolve(false), }, { text: labels.confirmLabel, style: input.destructive ? "destructive" : "default", onPress: () => resolve(true), }, ], { cancelable: true, onDismiss: () => resolve(false), }, ); }); } function getDesktopApi() { if (isNative) { return null; } return getDesktopHost(); } function buildDesktopAskOptions(input: ConfirmDialogInput): DesktopDialogAskOptions { const labels = resolveButtonLabels(input); return { title: input.title, okLabel: labels.confirmLabel, cancelLabel: labels.cancelLabel, kind: input.destructive ? "warning" : "info", }; } function blurActiveWebElement(): void { if (isNative) { return; } const activeElement = (globalThis as { document?: Document }).document?.activeElement; (activeElement as HTMLElement | null)?.blur?.(); } async function showDesktopConfirmDialog(input: ConfirmDialogInput): Promise { const desktopApi = getDesktopApi(); if (!desktopApi) { return null; } blurActiveWebElement(); const options = buildDesktopAskOptions(input); const desktopAsk = desktopApi.dialog?.ask; if (typeof desktopAsk === "function") { return await desktopAsk(input.message, options); } return null; } function showWebConfirmDialog(input: ConfirmDialogInput): boolean { const browserConfirm = (globalThis as { confirm?: (message?: string) => boolean }).confirm; if (typeof browserConfirm !== "function") { throw new Error("[ConfirmDialog] No web confirmation backend is available."); } blurActiveWebElement(); const promptMessage = `${input.title}\n\n${input.message}`; return browserConfirm(promptMessage); } export async function confirmDialog(input: ConfirmDialogInput): Promise { if (isNative) { return showNativeConfirmDialog(input); } const desktopResult = await showDesktopConfirmDialog(input); if (desktopResult !== null) { return desktopResult; } return showWebConfirmDialog(input); } export const __private__ = { blurActiveWebElement, buildDesktopAskOptions, };