diff --git a/src/main/index.ts b/src/main/index.ts index 6cbda25..5c573bd 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -371,6 +371,10 @@ app.whenReady().then(() => { return await threadManager.updateThreadNodePositions(threadId, positions) }) + ipcMain.handle('toggle-reference-frame', async (_event, { threadId, filePath }) => { + return await threadManager.toggleThreadReferenceFrame(threadId, filePath) + }) + ipcMain.handle('show-confirmation', async (_event, { title, message, detail, type = 'question', buttons = ['Cancel', 'Yes'], defaultId = 1, cancelId = 0 }) => { const focusedWindow = BrowserWindow.getFocusedWindow() if (!focusedWindow) return cancelId diff --git a/src/main/threads/index.ts b/src/main/threads/index.ts index de601fa..9c8fcd3 100644 --- a/src/main/threads/index.ts +++ b/src/main/threads/index.ts @@ -653,6 +653,30 @@ class ThreadManager { return !!result } + + async toggleThreadReferenceFrame(threadId: string, filePath: string): Promise { + const thread = this.getThread(threadId) + if (!thread) return false + + const currentRefs = thread.preprocessing?.['reference-frames'] || [] + const index = currentRefs.indexOf(filePath) + + let newRefs: string[] + if (index === -1) { + newRefs = [...currentRefs, filePath] + } else { + newRefs = currentRefs.filter(r => r !== filePath) + } + + const result = await this.updateThread(threadId, { + preprocessing: { + ...(thread.preprocessing || {}), + 'reference-frames': newRefs + } + }) + + return !!result + } } export const threadManager = new ThreadManager() diff --git a/src/preload/index.ts b/src/preload/index.ts index 23c2984..ba8ba01 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -58,6 +58,8 @@ const api = { ipcRenderer.invoke('remove-single-message', { threadId, messageId }), updateMessage: (threadId: string, messageId: string, updates: any) => ipcRenderer.invoke('update-message', { threadId, messageId, updates }), + toggleReferenceFrame: (threadId: string, filePath: string) => + ipcRenderer.invoke('toggle-reference-frame', { threadId, filePath }), showConfirmation: (options: { title: string, message: string, detail?: string, type?: string, buttons?: string[], defaultId?: number, cancelId?: number }) => ipcRenderer.invoke('show-confirmation', options), saveVideo: (sourcePath: string) => ipcRenderer.invoke('save-video', sourcePath), diff --git a/src/renderer/src/components/SlimTooltip.vue b/src/renderer/src/components/SlimTooltip.vue new file mode 100644 index 0000000..d2768fe --- /dev/null +++ b/src/renderer/src/components/SlimTooltip.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/src/renderer/src/components/chat/BaseMessageInput.vue b/src/renderer/src/components/chat/BaseMessageInput.vue index 3cc9e6e..604f261 100644 --- a/src/renderer/src/components/chat/BaseMessageInput.vue +++ b/src/renderer/src/components/chat/BaseMessageInput.vue @@ -6,15 +6,16 @@ class="relative rounded-xl overflow-hidden group shadow-sm border border-zinc-200 dark:border-zinc-800 transition-all hover:scale-105" :class="compact ? 'w-10 h-10' : 'w-16 h-16'"> - + + + @@ -25,8 +26,10 @@ : 'space-x-4 p-1.5 rounded-2xl border border-zinc-200 dark:border-zinc-800 bg-white/50 dark:bg-zinc-950/20 backdrop-blur-xl shadow-lg focus-within:ring-2 focus-within:ring-primary/20' ]"> - + + +
- + + + @@ -46,6 +51,7 @@