From ce804ce02b03436e9a01f927cfe40fa307f9ccc6 Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Mon, 4 Aug 2025 19:03:29 +0800 Subject: [PATCH] style(ModelList): adjust GroupHeader height and update icon in ModelListItem --- electron-builder.yml | 1 + .../components/ModelList/EditModelPopup.tsx | 57 --- src/renderer/src/i18n/locales/en-us.json | 11 +- src/renderer/src/i18n/locales/ja-jp.json | 11 +- src/renderer/src/i18n/locales/ru-ru.json | 9 +- src/renderer/src/i18n/locales/zh-cn.json | 11 +- src/renderer/src/i18n/locales/zh-tw.json | 11 +- src/renderer/src/i18n/translate/el-gr.json | 3 +- src/renderer/src/i18n/translate/es-es.json | 3 +- src/renderer/src/i18n/translate/fr-fr.json | 3 +- src/renderer/src/i18n/translate/pt-pt.json | 3 +- src/renderer/src/pages/agents/AgentsPage.tsx | 5 +- src/renderer/src/pages/files/FilesPage.tsx | 1 + .../src/pages/knowledge/KnowledgeContent.tsx | 5 +- .../src/pages/launchpad/LaunchpadPage.tsx | 4 +- .../settings/MCPSettings/McpSettings.tsx | 9 +- .../settings/ModelSettings/ModelSettings.tsx | 132 +---- .../EditModelPopup/EditModelPopup.tsx | 88 ++++ .../EditModelPopup}/ModelEditContent.tsx | 462 ++++++++++-------- .../EditModelPopup/ModelTypeSelector.tsx | 182 +++++++ .../ModelList/AddModelPopup.tsx | 0 .../ModelList/HealthCheckPopup.tsx | 0 .../ModelList/ManageModelsList.tsx | 4 +- .../ModelList/ManageModelsPopup.tsx | 6 +- .../ProviderSettings}/ModelList/ModelList.tsx | 52 +- .../ModelList/ModelListGroup.tsx | 0 .../ModelList/ModelListItem.tsx | 5 +- .../ModelList/NewApiAddModelPopup.tsx | 0 .../ModelList/NewApiBatchAddModelPopup.tsx | 0 .../ProviderSettings}/ModelList/index.ts | 4 +- .../ModelList/useHealthCheck.ts | 0 .../ProviderSettings}/ModelList/utils.ts | 0 .../ProviderSettings/ProviderSetting.tsx | 2 +- .../pages/settings/QuickAssistantSettings.tsx | 128 ++++- .../SelectionAssistantSettings.tsx | 25 +- .../components/SelectionActionsList.tsx | 5 +- .../src/pages/settings/SettingsPage.tsx | 41 +- .../QuickPhraseSettings.tsx} | 0 .../src/pages/settings/ToolSettings/index.tsx | 54 +- src/renderer/src/store/settings.ts | 2 +- .../windows/mini/chat/components/Message.tsx | 2 +- .../src/windows/mini/home/HomeWindow.tsx | 12 +- 42 files changed, 801 insertions(+), 552 deletions(-) delete mode 100644 src/renderer/src/components/ModelList/EditModelPopup.tsx create mode 100644 src/renderer/src/pages/settings/ProviderSettings/EditModelPopup/EditModelPopup.tsx rename src/renderer/src/{components/ModelList => pages/settings/ProviderSettings/EditModelPopup}/ModelEditContent.tsx (50%) create mode 100644 src/renderer/src/pages/settings/ProviderSettings/EditModelPopup/ModelTypeSelector.tsx rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/AddModelPopup.tsx (100%) rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/HealthCheckPopup.tsx (100%) rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/ManageModelsList.tsx (98%) rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/ManageModelsPopup.tsx (97%) rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/ModelList.tsx (78%) rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/ModelListGroup.tsx (100%) rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/ModelListItem.tsx (94%) rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/NewApiAddModelPopup.tsx (100%) rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/NewApiBatchAddModelPopup.tsx (100%) rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/index.ts (71%) rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/useHealthCheck.ts (100%) rename src/renderer/src/{components => pages/settings/ProviderSettings}/ModelList/utils.ts (100%) rename src/renderer/src/pages/settings/{QuickPhraseSettings/index.tsx => ToolSettings/QuickPhraseSettings.tsx} (100%) diff --git a/electron-builder.yml b/electron-builder.yml index 2756d4941..02c0725dd 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -128,3 +128,4 @@ releaseInfo: 内存泄漏修复:优化代码逻辑,解决内存泄漏问题,提升运行稳定性 嵌入模型简化:降低嵌入模型配置复杂度,提高易用性 MCP Tool 长时间运行:增强 MCP 工具的稳定性,支持长时间任务执行 + 设置页面优化:优化设置页面布局,提升用户体验 diff --git a/src/renderer/src/components/ModelList/EditModelPopup.tsx b/src/renderer/src/components/ModelList/EditModelPopup.tsx deleted file mode 100644 index 8f99c9bb7..000000000 --- a/src/renderer/src/components/ModelList/EditModelPopup.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import ModelEditContent from '@renderer/components/ModelList/ModelEditContent' -import { TopView } from '@renderer/components/TopView' -import { Model, Provider } from '@renderer/types' -import React from 'react' - -interface ShowParams { - provider: Provider - model: Model -} - -interface Props extends ShowParams { - resolve: (data?: Model) => void -} - -const PopupContainer: React.FC = ({ provider, model, resolve }) => { - const handleUpdateModel = (updatedModel: Model) => { - resolve(updatedModel) - } - - const handleClose = () => { - resolve(undefined) // Resolve with no data on close - } - - return ( - - ) -} - -const TopViewKey = 'EditModelPopup' - -export default class EditModelPopup { - static hide() { - TopView.hide(TopViewKey) - } - - static show(props: ShowParams) { - return new Promise((resolve) => { - TopView.show( - { - resolve(v) - this.hide() - }} - />, - TopViewKey - ) - }) - } -} diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index 87ddc434e..b0191d552 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -1463,7 +1463,7 @@ "function_calling": "Tool", "reasoning": "Reasoning", "rerank": "Reranker", - "select": "Select Model Types", + "select": "Model Types", "text": "Text", "vision": "Vision", "websearch": "WebSearch" @@ -2716,6 +2716,8 @@ "jsonSaveError": "Failed to save JSON configuration.", "jsonSaveSuccess": "JSON configuration has been saved.", "logoUrl": "Logo URL", + "longRunning": "Long Running Mode", + "longRunningTooltip": "When enabled, the server supports long-running tasks. When receiving progress notifications, the timeout will be reset and the maximum execution time will be extended to 10 minutes.", "missingDependencies": "is Missing, please install it to continue.", "more": { "awesome": "Curated MCP Server List", @@ -2962,8 +2964,8 @@ "tooltip": "Optional e.g. GPT-4" }, "supported_text_delta": { - "label": "Incremental text output", - "tooltip": "When the model is not supported, close the button" + "label": "Support incremental text output", + "tooltip": "The model returns text incrementally, rather than all at once. Enabled by default, if the model does not support it, please disable this option" } }, "api_key": "API Key", @@ -3019,7 +3021,6 @@ "provider_name": "Provider Name", "quick_assistant_default_tag": "Default", "quick_assistant_model": "Quick Assistant Model", - "quick_assistant_model_description": "Default model used by Quick Assistant", "quick_assistant_selection": "Select Assistant", "topic_naming_model": "Topic Naming Model", "topic_naming_model_description": "Model used when automatically naming a new topic", @@ -3337,7 +3338,7 @@ "title": "Pre Process", "tooltip": "In Settings -> Tools, set a document preprocessing service provider. Document preprocessing can effectively improve the retrieval performance of complex format documents and scanned documents." }, - "title": "Tools Settings", + "title": "Other Settings", "websearch": { "apikey": "API key", "blacklist": "Blacklist", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index 10b0d2791..d2cb0530b 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -1463,7 +1463,7 @@ "function_calling": "ツール", "reasoning": "推論", "rerank": "再順序付け", - "select": "モデルタイプを選択", + "select": "モデルタイプ", "text": "テキスト", "vision": "画像", "websearch": "ウェブ検索" @@ -2716,6 +2716,8 @@ "jsonSaveError": "JSON設定の保存に失敗しました", "jsonSaveSuccess": "JSON設定が保存されました。", "logoUrl": "ロゴURL", + "longRunning": "長時間運行モード", + "longRunningTooltip": "このオプションを有効にすると、サーバーは長時間のタスクをサポートします。進行状況通知を受信すると、タイムアウトがリセットされ、最大実行時間が10分に延長されます。", "missingDependencies": "が不足しています。続行するにはインストールしてください。", "more": { "awesome": "厳選された MCP サーバーリスト", @@ -2962,8 +2964,8 @@ "tooltip": "例:GPT-4" }, "supported_text_delta": { - "label": "インクリメンタルテキスト出力", - "tooltip": "モデルがサポートされていない場合は、ボタンを閉じます" + "label": "インクリメンタルテキスト出力のサポート", + "tooltip": "モデルがテキストをチャンクで返す場合、デフォルトで有効になっています。モデルがサポートしていない場合は、このオプションを無効にしてください" } }, "api_key": "API キー", @@ -3019,7 +3021,6 @@ "provider_name": "プロバイダー名", "quick_assistant_default_tag": "デフォルト", "quick_assistant_model": "クイックアシスタントモデル", - "quick_assistant_model_description": "クイックアシスタントで使用されるデフォルトモデル", "quick_assistant_selection": "アシスタントを選択します", "topic_naming_model": "トピック命名モデル", "topic_naming_model_description": "新しいトピックを自動的に命名する際に使用されるモデル", @@ -3337,7 +3338,7 @@ "title": "前処理", "tooltip": "設定 → ツールで、ドキュメント前処理サービスプロバイダーを設定します。ドキュメント前処理は、複雑な形式のドキュメントやスキャンされたドキュメントの検索性能を効果的に向上させます。" }, - "title": "ツール設定", + "title": "その他の設定", "websearch": { "apikey": "APIキー", "blacklist": "ブラックリスト", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index f30681c3b..bf286aa06 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -2716,6 +2716,8 @@ "jsonSaveError": "Не удалось сохранить конфигурацию JSON", "jsonSaveSuccess": "JSON конфигурация сохранена", "logoUrl": "URL логотипа", + "longRunning": "Длительный режим работы", + "longRunningTooltip": "Включив эту опцию, сервер будет поддерживать длительные задачи. При получении уведомлений о ходе выполнения будет сброшен тайм-аут и максимальное время выполнения будет увеличено до 10 минут.", "missingDependencies": "отсутствует, пожалуйста, установите для продолжения.", "more": { "awesome": "Кураторский список серверов MCP", @@ -2962,8 +2964,8 @@ "tooltip": "Необязательно, например, GPT-4" }, "supported_text_delta": { - "label": "Инкрементный текст вывод", - "tooltip": "Когда модель не поддерживается, закройте кнопку" + "label": "Поддержка инкрементного текстового вывода", + "tooltip": "Модель возвращает текст по частям, а не одним блоком, по умолчанию включено, если модель не поддерживает, закройте эту опцию" } }, "api_key": "API ключ", @@ -3019,7 +3021,6 @@ "provider_name": "Имя провайдера", "quick_assistant_default_tag": "умолчанию", "quick_assistant_model": "Модель быстрого помощника", - "quick_assistant_model_description": "Модель по умолчанию, используемая быстрым помощником", "quick_assistant_selection": "Выберите помощника", "topic_naming_model": "Модель именования топика", "topic_naming_model_description": "Модель, используемая при автоматическом именовании нового топика", @@ -3337,7 +3338,7 @@ "title": "Предварительная обработка", "tooltip": "В настройках (Настройки -> Инструменты) укажите поставщика услуги предварительной обработки документов. Предварительная обработка документов может значительно повысить эффективность поиска для документов сложных форматов и отсканированных документов." }, - "title": "Настройки инструментов", + "title": "Другие настройки", "websearch": { "apikey": "API ключ", "blacklist": "Черный список", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 4b056b0e2..b845343ba 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -1463,7 +1463,7 @@ "function_calling": "工具", "reasoning": "推理", "rerank": "重排", - "select": "选择模型类型", + "select": "模型类型", "text": "文本", "vision": "视觉", "websearch": "联网" @@ -2716,6 +2716,8 @@ "jsonSaveError": "保存 JSON 配置失败", "jsonSaveSuccess": "JSON 配置已保存", "logoUrl": "标志网址", + "longRunning": "长时间运行模式", + "longRunningTooltip": "启用后,服务器支持长时间任务,接收到进度通知时会重置超时计时器,并延长最大超时时间至10分钟", "missingDependencies": "缺失,请安装它以继续", "more": { "awesome": "精选的 MCP 服务器列表", @@ -2962,8 +2964,8 @@ "tooltip": "例如 GPT-4" }, "supported_text_delta": { - "label": "增量文本输出", - "tooltip": "当模型不支持的时候,将该按钮关闭" + "label": "支持增量文本输出", + "tooltip": "模型每次返回文本增量,而不是一次性返回所有文本,默认开启,如果模型不支持,请关闭" } }, "api_key": "API 密钥", @@ -3019,7 +3021,6 @@ "provider_name": "服务商名称", "quick_assistant_default_tag": "默认", "quick_assistant_model": "快捷助手模型", - "quick_assistant_model_description": "快捷助手使用的默认模型", "quick_assistant_selection": "选择助手", "topic_naming_model": "话题命名模型", "topic_naming_model_description": "自动命名新话题时使用的模型", @@ -3337,7 +3338,7 @@ "title": "文档预处理", "tooltip": "在设置 -> 工具中设置文档预处理服务商,文档预处理可以有效提升复杂格式文档与扫描版文档的检索效果" }, - "title": "工具设置", + "title": "其他设置", "websearch": { "apikey": "API 密钥", "blacklist": "黑名单", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 3429f92b2..1eec82600 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -1463,7 +1463,7 @@ "function_calling": "工具", "reasoning": "推理", "rerank": "重排", - "select": "選擇模型類型", + "select": "模型類型", "text": "文字", "vision": "視覺", "websearch": "網路搜尋" @@ -2716,6 +2716,8 @@ "jsonSaveError": "保存 JSON 配置失敗", "jsonSaveSuccess": "JSON 配置已儲存", "logoUrl": "標誌網址", + "longRunning": "長時間運行模式", + "longRunningTooltip": "啟用後,伺服器支援長時間任務,接收到進度通知時會重置超時計時器,並延長最大超時時間至10分鐘", "missingDependencies": "缺失,請安裝它以繼續", "more": { "awesome": "精選的 MCP 伺服器清單", @@ -2962,8 +2964,8 @@ "tooltip": "例如 GPT-4" }, "supported_text_delta": { - "label": "增量文本輸出", - "tooltip": "當模型不支持的時候,將該按鈕關閉" + "label": "支持增量文本輸出", + "tooltip": "模型每次返回文本增量,而不是一次性返回所有文本,預設開啟,如果模型不支持,請關閉" } }, "api_key": "API 密鑰", @@ -3019,7 +3021,6 @@ "provider_name": "提供者名稱", "quick_assistant_default_tag": "預設", "quick_assistant_model": "快捷助手模型", - "quick_assistant_model_description": "快捷助手使用的預設模型", "quick_assistant_selection": "選擇助手", "topic_naming_model": "話題命名模型", "topic_naming_model_description": "自動命名新話題時使用的模型", @@ -3337,7 +3338,7 @@ "title": "前置處理", "tooltip": "在「設定」->「工具」中設定文件預處理服務供應商。文件預處理可有效提升複雜格式文件及掃描文件的檢索效能" }, - "title": "工具設定", + "title": "其他設定", "websearch": { "apikey": "API 金鑰", "blacklist": "黑名單", diff --git a/src/renderer/src/i18n/translate/el-gr.json b/src/renderer/src/i18n/translate/el-gr.json index e703e4f82..7ba4a69d9 100644 --- a/src/renderer/src/i18n/translate/el-gr.json +++ b/src/renderer/src/i18n/translate/el-gr.json @@ -1463,7 +1463,7 @@ "function_calling": "κλήση συνάρτησης", "reasoning": "λογική", "rerank": "Τακτοποιώ", - "select": "Επιλέξτε τύπο μοντέλου", + "select": "Τύποι μοντέλου", "text": "κείμενο", "vision": "εικόνα", "websearch": "δικτύωση" @@ -3018,7 +3018,6 @@ "provider_name": "Όνομα Παρόχου", "quick_assistant_default_tag": "Προεπιλογή", "quick_assistant_model": "Μοντέλο Γρήγορου Βοηθού", - "quick_assistant_model_description": "Προεπιλεγμένο μοντέλο που χρησιμοποιείται από το Γρήγορο Βοηθό", "quick_assistant_selection": "Επιλογή Βοηθού", "topic_naming_model": "Μοντέλο αναδόμησης θεμάτων", "topic_naming_model_description": "Το μοντέλο που χρησιμοποιείται όταν αυτόματα ονομάζεται ένα νέο θέμα", diff --git a/src/renderer/src/i18n/translate/es-es.json b/src/renderer/src/i18n/translate/es-es.json index 59a1958d1..83ec9a0ac 100644 --- a/src/renderer/src/i18n/translate/es-es.json +++ b/src/renderer/src/i18n/translate/es-es.json @@ -1463,7 +1463,7 @@ "function_calling": "Llamada a función", "reasoning": "Razonamiento", "rerank": "Reclasificar", - "select": "Seleccionar tipo de modelo", + "select": "Tipos de modelo", "text": "Texto", "vision": "Imagen", "websearch": "Búsqueda en línea" @@ -3018,7 +3018,6 @@ "provider_name": "Nombre del proveedor", "quick_assistant_default_tag": "Predeterminado", "quick_assistant_model": "Modelo del asistente rápido", - "quick_assistant_model_description": "Modelo predeterminado utilizado por el asistente rápido", "quick_assistant_selection": "Seleccionar asistente", "topic_naming_model": "Modelo de nombramiento de temas", "topic_naming_model_description": "Modelo utilizado para nombrar temas automáticamente", diff --git a/src/renderer/src/i18n/translate/fr-fr.json b/src/renderer/src/i18n/translate/fr-fr.json index b558c3024..6f84b6add 100644 --- a/src/renderer/src/i18n/translate/fr-fr.json +++ b/src/renderer/src/i18n/translate/fr-fr.json @@ -1463,7 +1463,7 @@ "function_calling": "Appel de fonction", "reasoning": "Raisonnement", "rerank": "Reclasser", - "select": "Sélectionnez le type de modèle", + "select": "Types de modèle", "text": "Texte", "vision": "Image", "websearch": "Recherche web" @@ -3018,7 +3018,6 @@ "provider_name": "Nom du fournisseur", "quick_assistant_default_tag": "Par défaut", "quick_assistant_model": "Modèle de l'assistant rapide", - "quick_assistant_model_description": "Modèle par défaut utilisé par l'assistant rapide", "quick_assistant_selection": "Sélectionner l'assistant", "topic_naming_model": "Modèle de renommage des sujets", "topic_naming_model_description": "Modèle utilisé pour le renommage automatique des nouveaux sujets", diff --git a/src/renderer/src/i18n/translate/pt-pt.json b/src/renderer/src/i18n/translate/pt-pt.json index c03ca04f8..1dc8ed5cd 100644 --- a/src/renderer/src/i18n/translate/pt-pt.json +++ b/src/renderer/src/i18n/translate/pt-pt.json @@ -1463,7 +1463,7 @@ "function_calling": "chamada de função", "reasoning": "raciocínio", "rerank": "Reclassificar", - "select": "selecione o tipo de modelo", + "select": "Tipos de modelo", "text": "texto", "vision": "imagem", "websearch": "Procurar na web" @@ -3018,7 +3018,6 @@ "provider_name": "Nome do Provedor", "quick_assistant_default_tag": "Padrão", "quick_assistant_model": "Modelo do Assistente Rápido", - "quick_assistant_model_description": "Modelo padrão usado pelo assistente rápido", "quick_assistant_selection": "Selecionar Assistente", "topic_naming_model": "Modelo de nomenclatura de tópicos", "topic_naming_model_description": "Modelo usado para nomear tópicos automaticamente", diff --git a/src/renderer/src/pages/agents/AgentsPage.tsx b/src/renderer/src/pages/agents/AgentsPage.tsx index e6f7f9aca..727e06566 100644 --- a/src/renderer/src/pages/agents/AgentsPage.tsx +++ b/src/renderer/src/pages/agents/AgentsPage.tsx @@ -1,6 +1,7 @@ import { ImportOutlined, PlusOutlined } from '@ant-design/icons' import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar' import CustomTag from '@renderer/components/CustomTag' +import { HStack } from '@renderer/components/Layout' import ListItem from '@renderer/components/ListItem' import Scrollbar from '@renderer/components/Scrollbar' import { useAgents } from '@renderer/hooks/useAgents' @@ -213,11 +214,11 @@ const AgentsPage: FC = () => { {getLocalizedGroupName(group)} { -
+ {agentGroups[group].length} -
+ } } diff --git a/src/renderer/src/pages/files/FilesPage.tsx b/src/renderer/src/pages/files/FilesPage.tsx index 649ff6e18..e3690826b 100644 --- a/src/renderer/src/pages/files/FilesPage.tsx +++ b/src/renderer/src/pages/files/FilesPage.tsx @@ -63,6 +63,7 @@ const FilesPage: FC = () => { okText={t('common.confirm')} cancelText={t('common.cancel')} onConfirm={() => handleDelete(file.id, t)} + placement="left" icon={}> + )} + + + ) + } + + return ( +
= ({ provider, model, onUpdate form.setFieldValue('name', value) form.setFieldValue('group', getDefaultGroupName(value)) }} + suffix={ + { + const val = form.getFieldValue('name') + navigator.clipboard.writeText((val.id || model.id) as string) + message.success(t('message.copied')) + }} + /> + } /> - = ({ provider, model, onUpdate {showMoreSettings && (
- {t('models.type.select')}: - {(() => { - const isDisabled = selectedTypes.includes('rerank') || selectedTypes.includes('embedding') - - const isRerankDisabled = selectedTypes.includes('embedding') - const isEmbeddingDisabled = selectedTypes.includes('rerank') - const showTypeConfirmModal = (newCapability: ModelCapability) => { - const onUpdateType = selectedTypes?.find((t) => t === newCapability.type) - window.modal.confirm({ - title: t('settings.moresetting.warn'), - content: t('settings.moresetting.check.warn'), - okText: t('settings.moresetting.check.confirm'), - cancelText: t('common.cancel'), - okButtonProps: { danger: true }, - cancelButtonProps: { type: 'primary' }, - onOk: () => { - if (onUpdateType) { - const updatedModelCapabilities = modelCapabilities?.map((t) => { - if (t.type === newCapability.type) { - return { ...t, isUserSelected: true } - } - if ( - ((onUpdateType !== t.type && onUpdateType === 'rerank') || - (onUpdateType === 'embedding' && onUpdateType !== t.type)) && - t.isUserSelected !== false - ) { - changedTypesRef.current.push(t.type) - return { ...t, isUserSelected: false } - } - return t - }) - setModelCapabilities(uniqueObjectArray(updatedModelCapabilities as ModelCapability[])) - } else { - const updatedModelCapabilities = modelCapabilities?.map((t) => { - if ( - ((newCapability.type !== t.type && newCapability.type === 'rerank') || - (newCapability.type === 'embedding' && newCapability.type !== t.type)) && - t.isUserSelected !== false - ) { - changedTypesRef.current.push(t.type) - return { ...t, isUserSelected: false } - } - if (newCapability.type === t.type) { - return { ...t, isUserSelected: true } - } - return t - }) - updatedModelCapabilities.push(newCapability as any) - setModelCapabilities(uniqueObjectArray(updatedModelCapabilities as ModelCapability[])) - } - }, - onCancel: () => {}, - centered: true - }) - } - - const handleTypeChange = (types: string[]) => { - setHasUserModified(true) // 标记用户已进行修改 - const diff = types.length > selectedTypes.length - if (diff) { - const newCapability = getDifference(types, selectedTypes) // checkbox的特性,确保了newCapability只有一个元素 - showTypeConfirmModal({ - type: newCapability[0] as ModelType, - isUserSelected: true - }) - } else { - const disabledTypes = getDifference(selectedTypes, types) - const onUpdateType = modelCapabilities?.find((t) => t.type === disabledTypes[0]) - if (onUpdateType) { - const updatedTypes = modelCapabilities?.map((t) => { - if (t.type === disabledTypes[0]) { - return { ...t, isUserSelected: false } - } - if ( - ((onUpdateType !== t && onUpdateType.type === 'rerank') || - (onUpdateType.type === 'embedding' && onUpdateType !== t)) && - t.isUserSelected === false - ) { - if (changedTypesRef.current.includes(t.type)) { - return { ...t, isUserSelected: true } - } - } - return t - }) - setModelCapabilities(uniqueObjectArray(updatedTypes as ModelCapability[])) - } else { - const updatedModelCapabilities = modelCapabilities?.map((t) => { - if ( - (disabledTypes[0] === 'rerank' && t.type !== 'rerank') || - (disabledTypes[0] === 'embedding' && t.type !== 'embedding' && t.isUserSelected === false) - ) { - return { ...t, isUserSelected: true } - } - return t - }) - updatedModelCapabilities.push({ type: disabledTypes[0] as ModelType, isUserSelected: false }) - setModelCapabilities(uniqueObjectArray(updatedModelCapabilities as ModelCapability[])) - } - changedTypesRef.current.length = 0 - } - } - - const handleResetTypes = () => { - setModelCapabilities(originalModelCapabilities) - setHasUserModified(false) // 重置后清除修改标志 - } - - return ( -
- - - {hasUserModified && ( - - )} - -
- ) - })()} + {t('models.type.select')} + + - setSupportedTextDelta(checked)} /> + { + setSupportedTextDelta(checked) + // 直接传递新值给autoSave + autoSave({ supported_text_delta: checked }) + }} + /> - {t('models.price.price')} + dispatch(setQuickAssistantId(value))} + placeholder={t('settings.models.quick_assistant_selection')}> + + + + {defaultAssistant.name} + + {t('settings.models.quick_assistant_default_tag')} + + + {assistants + .filter((a) => a.id !== defaultAssistant.id) + .map((a) => ( + + + + {a.name} + + + + ))} + + + )} + + { + dispatch(setQuickAssistantId(defaultAssistant.id)) + }} + selected={!!quickAssistantId}> + {t('settings.models.use_assistant')} + + dispatch(setQuickAssistantId(''))} + selected={!quickAssistantId}> + {t('settings.models.use_model')} + + + + + + )} {enableQuickAssistant && ( - + )} @@ -105,4 +173,58 @@ const AssistantContainer = styled.div` overflow: hidden; ` +const AssistantItem = styled.div` + display: flex; + flex-direction: row; + align-items: center; + gap: 8px; + height: 28px; +` + +const AssistantName = styled.span` + max-width: calc(100% - 60px); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +` + +const Spacer = styled.div` + flex: 1; +` + +const DefaultTag = styled.span<{ isCurrent: boolean }>` + color: ${(props) => (props.isCurrent ? 'var(--color-primary)' : 'var(--color-text-3)')}; + font-size: 12px; + padding: 2px 4px; + border-radius: 4px; +` + +const StyledButton = styled(Button)<{ selected: boolean }>` + border-radius: ${(props) => (props.selected ? '6px' : '6px')}; + z-index: ${(props) => (props.selected ? 1 : 0)}; + min-width: 80px; + + &:first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right-width: 0; // No right border for the first button when not selected + } + + &:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-left-width: 1px; // Ensure left border for the last button + } + + // Override Ant Design's default hover and focus styles for a cleaner look + + &:hover, + &:focus { + z-index: 1; + border-color: ${(props) => (props.selected ? 'var(--ant-primary-color)' : 'var(--ant-primary-color-hover)')}; + box-shadow: ${(props) => + props.selected ? '0 0 0 2px var(--ant-primary-color-outline)' : '0 0 0 2px var(--ant-primary-color-outline)'}; + } +` + export default QuickAssistantSettings diff --git a/src/renderer/src/pages/settings/SelectionAssistantSettings/SelectionAssistantSettings.tsx b/src/renderer/src/pages/settings/SelectionAssistantSettings/SelectionAssistantSettings.tsx index d9e284a58..1ca437aa1 100644 --- a/src/renderer/src/pages/settings/SelectionAssistantSettings/SelectionAssistantSettings.tsx +++ b/src/renderer/src/pages/settings/SelectionAssistantSettings/SelectionAssistantSettings.tsx @@ -91,7 +91,7 @@ const SelectionAssistantSettings: FC = () => { return ( - + {t('selection.name')} @@ -124,11 +124,9 @@ const SelectionAssistantSettings: FC = () => { {selectionEnabled && ( <> - + {t('selection.settings.toolbar.title')} - - @@ -167,9 +165,7 @@ const SelectionAssistantSettings: FC = () => { - - {t('selection.settings.toolbar.compact_mode.title')} @@ -179,11 +175,9 @@ const SelectionAssistantSettings: FC = () => { - + {t('selection.settings.window.title')} - - {t('selection.settings.window.follow_toolbar.title')} @@ -191,9 +185,7 @@ const SelectionAssistantSettings: FC = () => { setIsFollowToolbar(checked)} /> - - {t('selection.settings.window.remember_size.title')} @@ -201,9 +193,7 @@ const SelectionAssistantSettings: FC = () => { setIsRemeberWinSize(checked)} /> - - {t('selection.settings.window.auto_close.title')} @@ -211,9 +201,7 @@ const SelectionAssistantSettings: FC = () => { setIsAutoClose(checked)} /> - - {t('selection.settings.window.auto_pin.title')} @@ -221,9 +209,7 @@ const SelectionAssistantSettings: FC = () => { setIsAutoPin(checked)} /> - - {t('selection.settings.window.opacity.title')} @@ -245,11 +231,9 @@ const SelectionAssistantSettings: FC = () => { - + {t('selection.settings.advanced.title')} - - {t('selection.settings.advanced.filter_mode.title')} @@ -277,7 +261,6 @@ const SelectionAssistantSettings: FC = () => { {t('common.edit')} - setIsFilterListModalOpen(false)} diff --git a/src/renderer/src/pages/settings/SelectionAssistantSettings/components/SelectionActionsList.tsx b/src/renderer/src/pages/settings/SelectionAssistantSettings/components/SelectionActionsList.tsx index 7077de2f4..3925dfbb5 100644 --- a/src/renderer/src/pages/settings/SelectionAssistantSettings/components/SelectionActionsList.tsx +++ b/src/renderer/src/pages/settings/SelectionAssistantSettings/components/SelectionActionsList.tsx @@ -1,4 +1,5 @@ import { DragDropContext } from '@hello-pangea/dnd' +import { useTheme } from '@renderer/context/ThemeProvider' import { defaultActionItems } from '@renderer/store/selectionStore' import type { ActionItem } from '@renderer/types/selectionTypes' import SelectionToolbar from '@renderer/windows/selection/toolbar/SelectionToolbar' @@ -45,12 +46,14 @@ const SelectionActionsList: FC = ({ actionItems, setA MAX_ENABLED_ITEMS } = useActionItems(actionItems, setActionItems) + const { theme } = useTheme() + if (!actionItems || actionItems.length === 0) { setActionItems(defaultActionItems) } return ( - + { {t('settings.display.title')} + + + + {t('settings.data.title')} + + @@ -82,21 +86,21 @@ const SettingsPage: FC = () => { {t('memory.title')} - - - - {t('settings.tool.title')} - - {t('settings.shortcuts.title')} + + + + {t('settings.tool.title')} + + - + {t('settings.quickAssistant.title')} @@ -106,18 +110,6 @@ const SettingsPage: FC = () => { {t('selection.name')} - - - - {t('settings.quickPhrase.title')} - - - - - - {t('settings.data.title')} - - @@ -139,7 +131,6 @@ const SettingsPage: FC = () => { } /> } /> } /> - } /> diff --git a/src/renderer/src/pages/settings/QuickPhraseSettings/index.tsx b/src/renderer/src/pages/settings/ToolSettings/QuickPhraseSettings.tsx similarity index 100% rename from src/renderer/src/pages/settings/QuickPhraseSettings/index.tsx rename to src/renderer/src/pages/settings/ToolSettings/QuickPhraseSettings.tsx diff --git a/src/renderer/src/pages/settings/ToolSettings/index.tsx b/src/renderer/src/pages/settings/ToolSettings/index.tsx index 1c42c5230..1b277846a 100644 --- a/src/renderer/src/pages/settings/ToolSettings/index.tsx +++ b/src/renderer/src/pages/settings/ToolSettings/index.tsx @@ -1,42 +1,55 @@ import { GlobalOutlined } from '@ant-design/icons' import { HStack } from '@renderer/components/Layout' import ListItem from '@renderer/components/ListItem' -import { FileCode } from 'lucide-react' -import { FC, useState } from 'react' +import { FileCode, Zap } from 'lucide-react' +import { FC } from 'react' import { useTranslation } from 'react-i18next' +import { Link, Route, Routes, useLocation } from 'react-router-dom' import styled from 'styled-components' import PreprocessSettings from './PreprocessSettings' +import QuickPhraseSettings from './QuickPhraseSettings' import WebSearchSettings from './WebSearchSettings' -let _menu: string = 'web-search' - const ToolSettings: FC = () => { const { t } = useTranslation() - const [menu, setMenu] = useState(_menu) + const { pathname } = useLocation() const menuItems = [ { key: 'web-search', title: 'settings.tool.websearch.title', icon: }, - { key: 'preprocess', title: 'settings.tool.preprocess.title', icon: } + { key: 'preprocess', title: 'settings.tool.preprocess.title', icon: }, + { key: 'quick-phrase', title: 'settings.quickPhrase.title', icon: } ] - _menu = menu + const isActive = (key: string): boolean => { + const basePath = '/settings/tool' + if (key === 'web-search') { + return pathname === basePath || pathname === `${basePath}/` || pathname === `${basePath}/${key}` + } + return pathname === `${basePath}/${key}` + } return ( {menuItems.map((item) => ( - setMenu(item.key)} - titleStyle={{ fontWeight: 500 }} - icon={item.icon} - /> + + + ))} - {menu == 'web-search' && } - {menu == 'preprocess' && } + + + } /> + } /> + } /> + } /> + + ) } @@ -44,6 +57,7 @@ const ToolSettings: FC = () => { const Container = styled(HStack)` flex: 1; ` + const MenuList = styled.div` display: flex; flex-direction: column; @@ -56,4 +70,10 @@ const MenuList = styled.div` line-height: 16px; } ` + +const ContentArea = styled.div` + display: flex; + flex: 1; + height: 100%; +` export default ToolSettings diff --git a/src/renderer/src/store/settings.ts b/src/renderer/src/store/settings.ts index b32d6e6f8..be1d950b2 100644 --- a/src/renderer/src/store/settings.ts +++ b/src/renderer/src/store/settings.ts @@ -381,7 +381,7 @@ export const initialState: SettingsState = { // Developer mode enableDeveloperMode: false, // UI - navbarPosition: 'left', + navbarPosition: 'top', // API Server apiServer: { enabled: false, diff --git a/src/renderer/src/windows/mini/chat/components/Message.tsx b/src/renderer/src/windows/mini/chat/components/Message.tsx index 6c1c01af8..93671fac4 100644 --- a/src/renderer/src/windows/mini/chat/components/Message.tsx +++ b/src/renderer/src/windows/mini/chat/components/Message.tsx @@ -89,7 +89,7 @@ const MessageContentContainer = styled.div` flex: 1; flex-direction: column; justify-content: space-between; - margin-top: 5px; + margin-top: 20px; ` export default memo(MessageItem) diff --git a/src/renderer/src/windows/mini/home/HomeWindow.tsx b/src/renderer/src/windows/mini/home/HomeWindow.tsx index 10e1b3d18..3444de725 100644 --- a/src/renderer/src/windows/mini/home/HomeWindow.tsx +++ b/src/renderer/src/windows/mini/home/HomeWindow.tsx @@ -36,7 +36,7 @@ import InputBar from './components/InputBar' const logger = loggerService.withContext('HomeWindow') -const HomeWindow: FC = () => { +const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => { const { language, readClipboardAtStartup, windowStyle } = useSettings() const { theme } = useTheme() const { t } = useTranslation() @@ -487,7 +487,7 @@ const HomeWindow: FC = () => { case 'summary': case 'explanation': return ( - + {route === 'chat' && ( <> { case 'translate': return ( - +