Compare commits
1 commit
main
...
fix/prompt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcb5577a53 |
2 changed files with 36 additions and 3 deletions
|
|
@ -10,6 +10,7 @@ const api = {
|
|||
openSettings: () => ipcRenderer.invoke("openpets:prompt-window-open-settings"),
|
||||
resizeWindow: (bounds) => ipcRenderer.invoke("openpets:prompt-window-resize", bounds),
|
||||
close: () => ipcRenderer.invoke("openpets:prompt-window-close"),
|
||||
log: (level, message) => ipcRenderer.send("openpets:prompt-window-log", level, message),
|
||||
};
|
||||
|
||||
contextBridge.exposeInMainWorld("openPetsPromptWindow", api);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { app, BrowserWindow, ipcMain, screen, type IpcMainInvokeEvent } from "electron";
|
||||
import { join } from "node:path";
|
||||
import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { getAppStateSnapshot } from "./app-state.js";
|
||||
import { getDefaultPetWindowBounds } from "./default-pet-controller.js";
|
||||
|
|
@ -104,6 +106,13 @@ export function installPromptWindowHandlers(): void {
|
|||
promptWindow.close();
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on("openpets:prompt-window-log", (event, level: unknown, message: unknown) => {
|
||||
if (!promptWindow || promptWindow.isDestroyed() || event.sender !== promptWindow.webContents) return;
|
||||
const text = typeof message === "string" ? message : "";
|
||||
if (level === "error") logError("ui", "prompt window renderer error", { message: text });
|
||||
else if (level === "warn") logError("ui", "prompt window renderer warning", { message: text });
|
||||
});
|
||||
}
|
||||
|
||||
export function openPromptWindow(): void {
|
||||
|
|
@ -139,7 +148,7 @@ export function openPromptWindow(): void {
|
|||
contextIsolation: true,
|
||||
sandbox: true,
|
||||
webSecurity: true,
|
||||
preload: join(app.getAppPath(), "prompt-window-preload.cjs"),
|
||||
preload: join(dirname(fileURLToPath(import.meta.url)), "..", "prompt-window-preload.cjs"),
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -165,11 +174,23 @@ export function openPromptWindow(): void {
|
|||
window.show();
|
||||
window.focus();
|
||||
});
|
||||
|
||||
const promptHtml = buildPromptWindowUrl();
|
||||
const promptHtmlDir = join(app.getPath("temp"), "openpets-prompt");
|
||||
if (!existsSync(promptHtmlDir)) mkdirSync(promptHtmlDir, { recursive: true });
|
||||
const promptHtmlPath = join(promptHtmlDir, "prompt-window.html");
|
||||
writeFileSync(promptHtmlPath, promptHtml, "utf8");
|
||||
|
||||
window.on("closed", () => {
|
||||
promptWindow = null;
|
||||
try {
|
||||
rmSync(promptHtmlPath, { force: true });
|
||||
} catch {
|
||||
/* best-effort cleanup */
|
||||
}
|
||||
});
|
||||
|
||||
void window.loadURL(buildPromptWindowUrl()).catch((error: unknown) => {
|
||||
void window.loadFile(promptHtmlPath).catch((error: unknown) => {
|
||||
logError("ui", "prompt window load exception", error instanceof Error ? error : { error });
|
||||
});
|
||||
}
|
||||
|
|
@ -358,6 +379,17 @@ function buildPromptWindowUrl(): string {
|
|||
</style></head><body><div class="shell" id="shell"><div class="editor-shell" id="editorShell" hidden><div id="conversations" class="conversations-list" hidden aria-label="Conversations"></div><div id="history" class="history-list" aria-label="Conversation history"></div></div><div class="toolbar"><div class="toolbar-actions"><button class="icon-button" id="editor" type="button" aria-label="Toggle editor" title="Editor"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="5" width="16" height="14" rx="2"/><path d="M8 9h8"/><path d="M8 13h5"/></svg></button><button class="icon-button" id="newChat" type="button" aria-label="Start new chat" title="New chat"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14"/><path d="M5 12h14"/></svg></button><button class="icon-button" id="historyButton" type="button" aria-label="Open history" title="History"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 4v5h5"/><path d="M12 7v6l4 2"/></svg></button><button class="icon-button" id="settings" type="button" aria-label="Open settings" title="Settings"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3.2"/><path d="M19.4 15a1 1 0 0 0 .2 1.1l.1.1a1.2 1.2 0 0 1 0 1.7l-1.2 1.2a1.2 1.2 0 0 1-1.7 0l-.1-.1a1 1 0 0 0-1.1-.2 1 1 0 0 0-.6.9V20a1.2 1.2 0 0 1-1.2 1.2h-1.7A1.2 1.2 0 0 1 10.9 20v-.1a1 1 0 0 0-.6-.9 1 1 0 0 0-1.1.2l-.1.1a1.2 1.2 0 0 1-1.7 0l-1.2-1.2a1.2 1.2 0 0 1 0-1.7l.1-.1a1 1 0 0 0 .2-1.1 1 1 0 0 0-.9-.6H4A1.2 1.2 0 0 1 2.8 13v-2A1.2 1.2 0 0 1 4 9.8h.1a1 1 0 0 0 .9-.6 1 1 0 0 0-.2-1.1l-.1-.1a1.2 1.2 0 0 1 0-1.7l1.2-1.2a1.2 1.2 0 0 1 1.7 0l.1.1a1 1 0 0 0 1.1.2 1 1 0 0 0 .6-.9V4A1.2 1.2 0 0 1 10.6 2.8h1.7A1.2 1.2 0 0 1 13.5 4v.1a1 1 0 0 0 .6.9 1 1 0 0 0 1.1-.2l.1-.1a1.2 1.2 0 0 1 1.7 0l1.2 1.2a1.2 1.2 0 0 1 0 1.7l-.1.1a1 1 0 0 0-.2 1.1 1 1 0 0 0 .9.6H20a1.2 1.2 0 0 1 1.2 1.2v2A1.2 1.2 0 0 1 20 14.2h-.1a1 1 0 0 0-.9.8z"/></svg></button><button class="icon-button" id="close" type="button" aria-label="Close chat window" title="Close"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><path d="M6 6l12 12"/><path d="M18 6L6 18"/></svg></button></div></div><div class="composer"><input type="file" id="fileInput" multiple><div class="attachments" id="attachments" hidden></div><div class="prompt-shell" id="promptShell"><button class="attach-button" id="attach" type="button" aria-label="Attach file" title="Attach file"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg></button><div class="input-wrap"><textarea id="prompt" class="prompt-input" placeholder="Ask anything." aria-label="Prompt input"></textarea><div class="feedback" id="feedback" aria-live="polite"></div></div><button class="send-button" id="send" type="button" aria-label="Send prompt" title="Send"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h12"/><path d="M13 6l6 6-6 6"/></svg></button></div></div><div class="resize-grip" id="resizeGrip" aria-hidden="true"></div></div></div><script>
|
||||
const shellEl = document.getElementById('shell');
|
||||
const api = window.openPetsPromptWindow;
|
||||
if (!api) {
|
||||
document.body.innerHTML = '<div style="padding:12px;color:var(--text-primary)">Prompt window IPC bridge not loaded.</div>';
|
||||
throw new Error('openPetsPromptWindow bridge not available');
|
||||
}
|
||||
const requireApi = () => {
|
||||
if (api) return true;
|
||||
setFeedback('Prompt window not ready.', 'error', 'missing-api');
|
||||
return false;
|
||||
};
|
||||
window.addEventListener('error', (event) => { try { api.log('error', event.message); } catch {} });
|
||||
window.addEventListener('unhandledrejection', (event) => { try { api.log('error', String(event.reason)); } catch {} });
|
||||
const editorShellEl = document.getElementById('editorShell');
|
||||
const historyEl = document.getElementById('history');
|
||||
const conversationsEl = document.getElementById('conversations');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue