From cefe64158697f05e863b7347bc2bf797a264c78b Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Mon, 2 Mar 2026 13:23:58 -0800 Subject: [PATCH] Remove unused prompt dialog infrastructure The inline rename replaces the prompt dialog entirely, so remove the promptDialog.ts file, IPC channels, bridge methods, and related tests. Context menu improvements (destructive, position) are kept. Co-Authored-By: Claude Opus 4.6 --- apps/desktop/src/main.ts | 16 --- apps/desktop/src/preload.ts | 2 - apps/desktop/src/promptDialog.ts | 231 ------------------------------- apps/web/src/wsNativeApi.test.ts | 34 ----- apps/web/src/wsNativeApi.ts | 10 -- packages/contracts/src/ipc.ts | 2 - 6 files changed, 295 deletions(-) delete mode 100644 apps/desktop/src/promptDialog.ts diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index 2c9aa9feef0009de69fd06b91d2c0aeccb634539..107371cc16ebe5782a99fad33f13488604fc2504 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -10,13 +10,11 @@ import type { MenuItemConstructorOptions } from "electron"; import { showDesktopConfirmDialog } from "./confirmDialog"; import { fixPath } from "./fixPath"; -import { showDesktopPromptDialog } from "./promptDialog"; fixPath(); const PICK_FOLDER_CHANNEL = "desktop:pick-folder"; const CONFIRM_CHANNEL = "desktop:confirm"; -const PROMPT_CHANNEL = "desktop:prompt"; const CONTEXT_MENU_CHANNEL = "desktop:context-menu"; const OPEN_EXTERNAL_CHANNEL = "desktop:open-external"; const MENU_ACTION_CHANNEL = "desktop:menu-action"; @@ -436,20 +434,6 @@ function registerIpcHandlers(): void { return showDesktopConfirmDialog(message, owner); }); - ipcMain.removeHandler(PROMPT_CHANNEL); - ipcMain.handle(PROMPT_CHANNEL, async (_event, message: unknown, defaultValue: unknown) => { - if (typeof message !== "string") { - return null; - } - - const owner = BrowserWindow.getFocusedWindow() ?? mainWindow; - return showDesktopPromptDialog( - message, - typeof defaultValue === "string" ? defaultValue : "", - owner, - ); - }); - ipcMain.removeHandler(CONTEXT_MENU_CHANNEL); ipcMain.handle( CONTEXT_MENU_CHANNEL, diff --git a/apps/desktop/src/preload.ts b/apps/desktop/src/preload.ts index c251075e86844c8f58f4e1e03d25ccb574df4ec6..be8fbbddd82cb5654dd51172215965fbf4c47f40 100644 --- a/apps/desktop/src/preload.ts +++ b/apps/desktop/src/preload.ts @@ -3,7 +3,6 @@ import type { DesktopBridge } from "@t3tools/contracts"; const PICK_FOLDER_CHANNEL = "desktop:pick-folder"; const CONFIRM_CHANNEL = "desktop:confirm"; -const PROMPT_CHANNEL = "desktop:prompt"; const CONTEXT_MENU_CHANNEL = "desktop:context-menu"; const OPEN_EXTERNAL_CHANNEL = "desktop:open-external"; const MENU_ACTION_CHANNEL = "desktop:menu-action"; @@ -13,7 +12,6 @@ contextBridge.exposeInMainWorld("desktopBridge", { getWsUrl: () => wsUrl, pickFolder: () => ipcRenderer.invoke(PICK_FOLDER_CHANNEL), confirm: (message) => ipcRenderer.invoke(CONFIRM_CHANNEL, message), - prompt: (message, defaultValue) => ipcRenderer.invoke(PROMPT_CHANNEL, message, defaultValue), showContextMenu: (items, position) => ipcRenderer.invoke(CONTEXT_MENU_CHANNEL, items, position), openExternal: (url: string) => ipcRenderer.invoke(OPEN_EXTERNAL_CHANNEL, url), onMenuAction: (listener) => { diff --git a/apps/desktop/src/promptDialog.ts b/apps/desktop/src/promptDialog.ts deleted file mode 100644 index 81f14dfcaf39c4a4fb966749a2cf440628aef557..0000000000000000000000000000000000000000 --- a/apps/desktop/src/promptDialog.ts +++ /dev/null @@ -1,231 +0,0 @@ -import { randomBytes } from "node:crypto"; -import { BrowserWindow, ipcMain } from "electron"; - -const PROMPT_WIDTH = 420; -const PROMPT_HEIGHT = 188; - -function createPromptHtml(input: { - message: string; - defaultValue: string; - submitChannel: string; - cancelChannel: string; -}): string { - const scriptConfig = JSON.stringify(input); - return ` - - - - - ${input.message} - - - -

-
- -
- - -
-
- - -`; -} - -export async function showDesktopPromptDialog( - message: string, - defaultValue: string, - ownerWindow: BrowserWindow | null, -): Promise { - const normalizedMessage = message.trim(); - if (normalizedMessage.length === 0) { - return null; - } - - const token = randomBytes(12).toString("hex"); - const submitChannel = `desktop:prompt-dialog:submit:${token}`; - const cancelChannel = `desktop:prompt-dialog:cancel:${token}`; - - const promptWindow = new BrowserWindow({ - width: PROMPT_WIDTH, - height: PROMPT_HEIGHT, - useContentSize: true, - show: false, - resizable: false, - minimizable: false, - maximizable: false, - fullscreenable: false, - autoHideMenuBar: true, - title: normalizedMessage, - ...(ownerWindow ? { parent: ownerWindow } : {}), - modal: ownerWindow !== null, - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - }, - }); - promptWindow.removeMenu(); - - return new Promise((resolve) => { - let settled = false; - - const settle = (value: string | null) => { - if (settled) return; - settled = true; - cleanup(); - resolve(value); - }; - - const cleanup = () => { - ipcMain.removeAllListeners(submitChannel); - ipcMain.removeAllListeners(cancelChannel); - if (!promptWindow.isDestroyed()) { - promptWindow.destroy(); - } - }; - - ipcMain.once(submitChannel, (_event, value: unknown) => { - if (typeof value !== "string") { - settle(null); - return; - } - settle(value); - }); - ipcMain.once(cancelChannel, () => settle(null)); - promptWindow.once("closed", () => settle(null)); - - const html = createPromptHtml({ - message: normalizedMessage, - defaultValue, - submitChannel, - cancelChannel, - }); - void promptWindow - .loadURL(`data:text/html;charset=utf-8,${encodeURIComponent(html)}`) - .then(() => { - if (!promptWindow.isDestroyed()) { - promptWindow.show(); - } - }) - .catch(() => settle(null)); - }); -} diff --git a/apps/web/src/wsNativeApi.test.ts b/apps/web/src/wsNativeApi.test.ts index 4e4f61e6d2217e931180120fa8265c61460c337d..80e283ee40fbe6630285ea7238876eb0963426fa 100644 --- a/apps/web/src/wsNativeApi.test.ts +++ b/apps/web/src/wsNativeApi.test.ts @@ -68,7 +68,6 @@ beforeEach(() => { subscribeMock.mockClear(); channelListeners.clear(); Reflect.deleteProperty(getWindowForTest(), "desktopBridge"); - Reflect.deleteProperty(getWindowForTest(), "prompt"); }); afterEach(() => { @@ -377,37 +376,4 @@ describe("wsNativeApi", () => { ); }); - it("forwards prompt calls to desktop bridge", async () => { - const prompt = vi.fn().mockResolvedValue("renamed"); - Object.defineProperty(getWindowForTest(), "desktopBridge", { - configurable: true, - writable: true, - value: { - prompt, - }, - }); - - const { createWsNativeApi } = await import("./wsNativeApi"); - const api = createWsNativeApi(); - const value = await api.dialogs.prompt("Rename thread", "Old title"); - - expect(value).toBe("renamed"); - expect(prompt).toHaveBeenCalledWith("Rename thread", "Old title"); - }); - - it("uses browser prompt fallback when desktop bridge is unavailable", async () => { - const prompt = vi.fn().mockReturnValue("renamed"); - Object.defineProperty(getWindowForTest(), "prompt", { - configurable: true, - writable: true, - value: prompt, - }); - - const { createWsNativeApi } = await import("./wsNativeApi"); - const api = createWsNativeApi(); - const value = await api.dialogs.prompt("Rename thread", "Old title"); - - expect(value).toBe("renamed"); - expect(prompt).toHaveBeenCalledWith("Rename thread", "Old title"); - }); }); diff --git a/apps/web/src/wsNativeApi.ts b/apps/web/src/wsNativeApi.ts index aa6830022b91daa126c6c72091d40708ef7d2cd6..871e01c911126daee8a492a33ec57fff44c42d82 100644 --- a/apps/web/src/wsNativeApi.ts +++ b/apps/web/src/wsNativeApi.ts @@ -124,16 +124,6 @@ export function createWsNativeApi(): NativeApi { } return window.confirm(message); }, - prompt: async (message, defaultValue) => { - if (window.desktopBridge) { - return window.desktopBridge.prompt(message, defaultValue); - } - try { - return window.prompt(message, defaultValue ?? ""); - } catch { - return null; - } - }, }, terminal: { open: (input) => transport.request(WS_METHODS.terminalOpen, input), diff --git a/packages/contracts/src/ipc.ts b/packages/contracts/src/ipc.ts index bf12d8cb5d8be47bb388edeebd7de6af74e538e2..aeec16ca0c32c9bee0d9b1f3c481e0917ac7587f 100644 --- a/packages/contracts/src/ipc.ts +++ b/packages/contracts/src/ipc.ts @@ -47,7 +47,6 @@ export interface DesktopBridge { getWsUrl: () => string | null; pickFolder: () => Promise; confirm: (message: string) => Promise; - prompt: (message: string, defaultValue?: string) => Promise; showContextMenu: ( items: readonly ContextMenuItem[], position?: { x: number; y: number }, @@ -60,7 +59,6 @@ export interface NativeApi { dialogs: { pickFolder: () => Promise; confirm: (message: string) => Promise; - prompt: (message: string, defaultValue?: string) => Promise; }; terminal: { open: (input: TerminalOpenInput) => Promise; -- 2.54.0