import { ask, message } from "@tauri-apps/api/dialog"; import { invoke } from "@tauri-apps/api/tauri"; import { open } from "@tauri-apps/api/shell"; import type { AppLogPaths, NativeConfirmOptions, ShowErrorNativeOptions, } from "./types"; /** * 统一封装原生确认框。 */ export async function confirmNative(options: NativeConfirmOptions): Promise { try { return await ask(options.message, { title: options.title, okLabel: options.okLabel, cancelLabel: options.cancelLabel, }); } catch (error) { throw new Error(`打开确认框失败: ${String(error)}`); } } async function fetchLogPaths(): Promise { return await invoke("get_log_paths"); } const ERROR_DIALOG_MAX_LINES = 6; /** 报错弹窗正文:最多 6 行;超过时保留前 5 行完整内容,第 6 行仅显示「...」。 */ function truncateErrorTextForDialog(text: string): string { const normalized = text.replace(/\r\n/g, "\n"); const lines = normalized.split("\n"); if (lines.length <= ERROR_DIALOG_MAX_LINES) { return normalized; } return `${lines.slice(0, ERROR_DIALOG_MAX_LINES - 1).join("\n")}\n...`; } /** * 原生错误提示。`options.logActions === "file"` 时正文仅展示错误信息(最多 6 行,第 6 行可为「...」), * 并提供「打开日志文件」/「确定」:前者用系统默认程序打开 app.log,后者仅关闭对话框。 */ export async function showErrorNative( content: string, title = "错误", options?: ShowErrorNativeOptions, ): Promise { const body = truncateErrorTextForDialog(content); const logActions = options?.logActions ?? "none"; if (logActions === "none") { try { await message(body, { title, type: "error" }); } catch (error) { throw new Error(`打开错误提示框失败: ${String(error)}`); } return; } let paths: AppLogPaths; try { paths = await fetchLogPaths(); } catch { try { await message(body, { title, type: "error" }); } catch (error) { throw new Error(`打开错误提示框失败: ${String(error)}`); } return; } try { const openFile = await ask(body, { title, type: "error", okLabel: "打开日志文件", cancelLabel: "确定", }); if (openFile) { await open(paths.logFile); } } catch (error) { try { const fallback = truncateErrorTextForDialog( `${content}\n(无法打开日志文件:${String(error)})`, ); await message(fallback, { title, type: "error", }); } catch (inner) { throw new Error(`打开错误提示框失败: ${String(inner)}`); } } } /** * 报错并可选择打开 app.log(正文仅错误摘要,等价于 `logActions: "file"`)。 */ export async function showErrorNativeWithLog( content: string, title = "错误", ): Promise { return showErrorNative(content, title, { logActions: "file" }); } /** * 原生信息提示(单按钮),用于非错误类说明。 */ export async function showInfoNative( content: string, title = "提示", ): Promise { try { await message(content, { title, type: "info" }); } catch (error) { throw new Error(`打开提示框失败: ${String(error)}`); } } /** * 原生警告提示(非 Element 浮层),用于校验提示等。 */ export async function showWarningNative( content: string, title = "提示", ): Promise { try { await message(content, { title, type: "warning" }); } catch (error) { throw new Error(`打开警告提示框失败: ${String(error)}`); } }