feat: improve chat input, themed menus and agent proposal cancellation

This commit is contained in:
2026-10-19 13:12:04 +09:00
parent 105342fbf3
commit 7b32668e1d
18 changed files with 641 additions and 94 deletions
+24 -1
View File
@@ -1,6 +1,29 @@
import { BrowserWindow, clipboard, Menu } from 'electron'
import type { IpcMainInvokeEvent, MenuItemConstructorOptions } from 'electron'
import type { ChatTextMenuAction, ChatTextMenuOptions } from '../shared/chatTextMenu'
import type { ChatClipboardAction, ChatTextMenuAction, ChatTextMenuOptions } from '../shared/chatTextMenu'
function trustedChatFrame(event: IpcMainInvokeEvent): boolean {
if (event.sender.isDestroyed() || event.senderFrame !== event.sender.mainFrame) return false
const window = BrowserWindow.fromWebContents(event.sender)
return Boolean(window && !window.isDestroyed())
}
export function readChatClipboardState(event: IpcMainInvokeEvent): { hasText: boolean } {
return { hasText: trustedChatFrame(event) && clipboard.readText().length > 0 }
}
export function performChatClipboardAction(event: IpcMainInvokeEvent, input: ChatClipboardAction): boolean {
if (!trustedChatFrame(event) || !input) return false
if (input.action === 'copy' && typeof input.text === 'string' && input.text.length > 0 && input.text.length <= 5_000_000) {
clipboard.writeText(input.text)
return true
}
if (input.action === 'paste' && clipboard.readText().length > 0) {
event.sender.paste()
return true
}
return false
}
export function showChatTextMenu(event: IpcMainInvokeEvent, input: ChatTextMenuOptions): Promise<ChatTextMenuAction> | null {
if (!input || !['message', 'input'].includes(input.kind) || event.sender.isDestroyed() || event.senderFrame !== event.sender.mainFrame) return null
+3 -1
View File
@@ -1,7 +1,7 @@
import { app, BrowserWindow, dialog, Menu, globalShortcut, ipcMain, screen, shell } from 'electron'
import { appLog } from './appLogging'
import { checkDockerStatus } from './dockerStatus'
import { showChatTextMenu } from './chatTextMenu'
import { performChatClipboardAction, readChatClipboardState, showChatTextMenu } from './chatTextMenu'
import { cameraRuntimeArtifacts } from './cameraRuntime'
import { remoteModuleFilesScript } from './remoteModuleFiles'
import { applyAgentFiles, runAgentFileTool } from './agentFileTools'
@@ -7037,6 +7037,8 @@ app.whenReady().then(() => {
})
ipcMain.handle('app-diagnostics:read', () => readAppDiagnostics())
ipcMain.handle('chat-text:context-menu', showChatTextMenu)
ipcMain.handle('chat-text:clipboard-state', readChatClipboardState)
ipcMain.handle('chat-text:clipboard-action', performChatClipboardAction)
ipcMain.on('titlebar-close', (event) => BrowserWindow.fromWebContents(event.sender)?.close())
ipcMain.on('app-quit', () => app.quit())
ipcMain.handle('learning-video:open', (event, input: LearningVideoInput) => openLearningVideoWindow(BrowserWindow.fromWebContents(event.sender), input))