From 88cc783a95731add834067a90fe7af01c64f60b0 Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Sun, 19 Jan 2025 20:03:45 +0800 Subject: [PATCH] fix: quick assistant bugs --- src/main/services/WindowService.ts | 4 +- src/renderer/src/hooks/useSettings.ts | 1 + .../pages/settings/QuickAssistantSettings.tsx | 11 +++-- src/renderer/src/store/migrate.ts | 1 + .../windows/mini/chat/components/Message.tsx | 6 ++- .../windows/mini/chat/components/Messages.tsx | 13 ++++++ .../src/windows/mini/home/HomeWindow.tsx | 8 ++-- .../windows/mini/home/components/InputBar.tsx | 2 +- .../mini/translate/TranslateWindow.tsx | 46 ++++++++++++------- 9 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/main/services/WindowService.ts b/src/main/services/WindowService.ts index 09430290..2da6ee16 100644 --- a/src/main/services/WindowService.ts +++ b/src/main/services/WindowService.ts @@ -305,7 +305,9 @@ export class WindowService { if (is.dev && process.env['ELECTRON_RENDERER_URL']) { this.miniWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + '#/mini') } else { - this.miniWindow.loadFile(join(__dirname, '../renderer/index.html') + '#/mini') + this.miniWindow.loadFile(join(__dirname, '../renderer/index.html'), { + hash: '#/mini' + }) } } diff --git a/src/renderer/src/hooks/useSettings.ts b/src/renderer/src/hooks/useSettings.ts index 8e0836b8..55b50984 100644 --- a/src/renderer/src/hooks/useSettings.ts +++ b/src/renderer/src/hooks/useSettings.ts @@ -22,6 +22,7 @@ export function useSettings() { }, setTray(isActive: boolean) { dispatch(setTray(isActive)) + window.api.setTray(isActive) }, setTheme(theme: ThemeMode) { dispatch(setTheme(theme)) diff --git a/src/renderer/src/pages/settings/QuickAssistantSettings.tsx b/src/renderer/src/pages/settings/QuickAssistantSettings.tsx index 85ff8b01..b8fecde1 100644 --- a/src/renderer/src/pages/settings/QuickAssistantSettings.tsx +++ b/src/renderer/src/pages/settings/QuickAssistantSettings.tsx @@ -14,7 +14,7 @@ import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingRowT const QuickAssistantSettings: FC = () => { const { t } = useTranslation() const { theme } = useTheme() - const { enableQuickAssistant, clickTrayToShowQuickAssistant, setTray } = useSettings() + const { enableQuickAssistant, clickTrayToShowQuickAssistant, tray, setTray } = useSettings() const dispatch = useAppDispatch() const handleEnableQuickAssistant = async (enable: boolean) => { @@ -32,15 +32,16 @@ const QuickAssistantSettings: FC = () => { key: 'quick-assistant-info' }) } + + if (enable && clickTrayToShowQuickAssistant) { + setTray(true) + } } const handleClickTrayToShowQuickAssistant = async (checked: boolean) => { dispatch(setClickTrayToShowQuickAssistant(checked)) await window.api.config.set('clickTrayToShowQuickAssistant', checked) - if (checked) { - setTray(true) - window.api.setTray(true) - } + checked && setTray(true) } return ( diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index a2d0c56a..64333389 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -847,6 +847,7 @@ const migrateConfig = { }) state.settings.enableQuickAssistant = false + state.settings.clickTrayToShowQuickAssistant = true return state } diff --git a/src/renderer/src/windows/mini/chat/components/Message.tsx b/src/renderer/src/windows/mini/chat/components/Message.tsx index 8daa355f..7d706276 100644 --- a/src/renderer/src/windows/mini/chat/components/Message.tsx +++ b/src/renderer/src/windows/mini/chat/components/Message.tsx @@ -12,7 +12,7 @@ import styled from 'styled-components' interface Props { message: Message index?: number - total?: number + total: number route: string onGetMessages?: () => Message[] onSetMessages?: Dispatch> @@ -36,6 +36,8 @@ const MessageItem: FC = ({ message: _message, index, total, route, onSetM const messageBackground = getMessageBackground(true, isAssistantMessage) + const maxWidth = window.location.hash === '#/mini' ? '480px' : '100%' + useEffect(() => { if (onGetMessages && onSetMessages) { if (message.status === 'sending') { @@ -70,7 +72,7 @@ const MessageItem: FC = ({ message: _message, index, total, route, onSetM + style={{ ...(isBubbleStyle ? { alignItems: isAssistantMessage ? 'start' : 'end' } : {}), maxWidth }}> = ({ assistant, route }) => { const containerRef = useRef(null) const messagesRef = useRef(messages) + const { t } = useTranslation() + messagesRef.current = messages const onSendMessage = useCallback( @@ -44,6 +49,14 @@ const Messages: FC = ({ assistant, route }) => { return () => unsubscribes.forEach((unsub) => unsub()) }, [assistant.id, onSendMessage]) + useShortcut('copy_last_message', () => { + const lastMessage = last(messages) + if (lastMessage) { + navigator.clipboard.writeText(lastMessage.content) + window.message.success(t('message.copy.success')) + } + }) + return ( {[...messages].reverse().map((message, index) => ( diff --git a/src/renderer/src/windows/mini/home/HomeWindow.tsx b/src/renderer/src/windows/mini/home/HomeWindow.tsx index 68904cee..870c75a7 100644 --- a/src/renderer/src/windows/mini/home/HomeWindow.tsx +++ b/src/renderer/src/windows/mini/home/HomeWindow.tsx @@ -30,9 +30,9 @@ const HomeWindow: FC = () => { const { t } = useTranslation() const textRef = useRef(text) - const referenceText = selectedText || clipboardText + const referenceText = selectedText || clipboardText || text - textRef.current = `${referenceText}\n\n${text}` + textRef.current = referenceText === text ? text : `${referenceText}\n\n${text}` const onReadClipboard = useCallback(async () => { const text = await navigator.clipboard.readText() @@ -58,6 +58,7 @@ const HomeWindow: FC = () => { } if (e.key === 'Enter') { + e.preventDefault() if (text.trim() === '') { return } @@ -69,11 +70,12 @@ const HomeWindow: FC = () => { const onSendMessage = useCallback( async (prompt?: string) => { + const text = textRef.current.trim() setTimeout(() => { const message = { id: uuid(), role: 'user', - content: prompt ? `${prompt}\n\n${textRef.current}` : textRef.current, + content: prompt ? `${prompt}\n\n${text}` : text, assistantId: defaultAssistant.id, topicId: defaultAssistant.topics[0].id || uuid(), createdAt: dayjs().format('YYYY-MM-DD HH:mm:ss'), diff --git a/src/renderer/src/windows/mini/home/components/InputBar.tsx b/src/renderer/src/windows/mini/home/components/InputBar.tsx index 012aeebc..689ce560 100644 --- a/src/renderer/src/windows/mini/home/components/InputBar.tsx +++ b/src/renderer/src/windows/mini/home/components/InputBar.tsx @@ -24,7 +24,7 @@ const InputBar: FC = ({ text, model, placeholder, handleKeyDown, bordered={false} autoFocus onKeyDown={handleKeyDown} - onChange={(e) => setText(e.target.value)} + onChange={(e) => setText(e.target.value.trim())} disabled={generating} /> diff --git a/src/renderer/src/windows/mini/translate/TranslateWindow.tsx b/src/renderer/src/windows/mini/translate/TranslateWindow.tsx index 9e8fd8ed..4b90cc97 100644 --- a/src/renderer/src/windows/mini/translate/TranslateWindow.tsx +++ b/src/renderer/src/windows/mini/translate/TranslateWindow.tsx @@ -9,7 +9,7 @@ import { Assistant, Message } from '@renderer/types' import { runAsyncFunction, uuid } from '@renderer/utils' import { Select, Space } from 'antd' import { isEmpty } from 'lodash' -import { FC, useCallback, useEffect, useState } from 'react' +import { FC, useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' @@ -24,26 +24,40 @@ const Translate: FC = ({ text }) => { const [targetLanguage, setTargetLanguage] = useState(_targetLanguage) const { translateModel } = useDefaultModel() const { t } = useTranslation() + const translatingRef = useRef(false) _targetLanguage = targetLanguage const translate = useCallback(async () => { if (!text.trim() || !translateModel) return - const assistant: Assistant = getDefaultTranslateAssistant(targetLanguage, text) - const message: Message = { - id: uuid(), - role: 'user', - content: text, - assistantId: assistant.id, - topicId: uuid(), - modelId: translateModel.id, - createdAt: new Date().toISOString(), - type: 'text', - status: 'sending' - } + if (translatingRef.current) return - await fetchTranslate({ message, assistant, onResponse: setResult }) + try { + translatingRef.current = true + + const targetLang = await db.settings.get({ id: 'translate:target:language' }) + const assistant: Assistant = getDefaultTranslateAssistant(targetLang?.value || targetLanguage, text) + const message: Message = { + id: uuid(), + role: 'user', + content: text, + assistantId: assistant.id, + topicId: uuid(), + modelId: translateModel.id, + createdAt: new Date().toISOString(), + type: 'text', + status: 'sending' + } + + await fetchTranslate({ message, assistant, onResponse: setResult }) + + translatingRef.current = false + } catch (error) { + console.error(error) + } finally { + translatingRef.current = false + } }, [text, targetLanguage, translateModel]) useEffect(() => { @@ -75,9 +89,9 @@ const Translate: FC = ({ text }) => { style={{ width: 200 }} optionFilterProp="label" options={TranslateLanguageOptions} - onChange={(value) => { + onChange={async (value) => { + await db.settings.put({ id: 'translate:target:language', value }) setTargetLanguage(value) - db.settings.put({ id: 'translate:target:language', value }) }} optionRender={(option) => (