From 41981acd77c7b9ff8b53a3d73049a5d20d0e555c Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Sun, 13 Apr 2025 10:45:47 +0800 Subject: [PATCH] feat(Settings): implement assistant icon type selection and localization updates --- src/renderer/src/hooks/useSettings.ts | 7 ++- src/renderer/src/i18n/locales/en-us.json | 8 ++- src/renderer/src/i18n/locales/ja-jp.json | 6 +- src/renderer/src/i18n/locales/ru-ru.json | 6 +- src/renderer/src/i18n/locales/zh-cn.json | 6 +- src/renderer/src/i18n/locales/zh-tw.json | 6 +- .../src/pages/home/Tabs/AssistantItem.tsx | 59 ++++++++++++++----- .../DisplaySettings/DisplaySettings.tsx | 23 ++++++-- src/renderer/src/store/index.ts | 2 +- src/renderer/src/store/migrate.ts | 11 ++++ src/renderer/src/store/settings.ts | 12 ++-- 11 files changed, 112 insertions(+), 34 deletions(-) diff --git a/src/renderer/src/hooks/useSettings.ts b/src/renderer/src/hooks/useSettings.ts index 0a05a162..9e75b57d 100644 --- a/src/renderer/src/hooks/useSettings.ts +++ b/src/renderer/src/hooks/useSettings.ts @@ -1,10 +1,11 @@ import store, { useAppDispatch, useAppSelector } from '@renderer/store' import { + AssistantIconType, SendMessageShortcut, + setAssistantIconType, setLaunchOnBoot, setLaunchToTray, setSendMessageShortcut as _setSendMessageShortcut, - setShowAssistantIcon, setSidebarIcons, setTargetLanguage, setTheme, @@ -70,8 +71,8 @@ export function useSettings() { updateSidebarDisabledIcons(icons: SidebarIcon[]) { dispatch(setSidebarIcons({ disabled: icons })) }, - setShowAssistantIcon(showAssistantIcon: boolean) { - dispatch(setShowAssistantIcon(showAssistantIcon)) + setAssistantIconType(assistantIconType: AssistantIconType) { + dispatch(setAssistantIconType(assistantIconType)) } } } diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index 322d5d26..74cc35f9 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -43,6 +43,7 @@ "edit.title": "Edit Assistant", "save.success": "Saved successfully", "save.title": "Save to agent", + "icon.type": "Assistant Icon", "search": "Search assistants...", "settings.default_model": "Default Model", "settings.knowledge_base": "Knowledge Base Settings", @@ -787,7 +788,10 @@ "advanced.title": "Advanced Settings", "assistant": "Default Assistant", "assistant.model_params": "Model Parameters", - "assistant.show.icon": "Show model icon", + "assistant.icon.type": "Model Icon Type", + "assistant.icon.type.model": "Model Icon", + "assistant.icon.type.emoji": "Emoji Icon", + "assistant.icon.type.none": "Hide", "assistant.title": "Default Assistant", "data": { "app_data": "App Data", @@ -1393,4 +1397,4 @@ "visualization": "Visualization" } } -} \ No newline at end of file +} diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index d3a51115..a39d193d 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -43,6 +43,7 @@ "edit.title": "アシスタントを編集", "save.success": "保存に成功しました", "save.title": "エージェントに保存", + "icon.type": "アシスタントアイコン", "search": "アシスタントを検索...", "settings.mcp": "MCP サーバー", "settings.mcp.enableFirst": "まず MCP 設定でこのサーバーを有効にしてください", @@ -787,7 +788,10 @@ "advanced.title": "詳細設定", "assistant": "デフォルトアシスタント", "assistant.model_params": "モデルパラメータ", - "assistant.show.icon": "モデルアイコンを表示", + "assistant.icon.type": "モデルアイコンタイプ", + "assistant.icon.type.model": "モデルアイコン", + "assistant.icon.type.emoji": "Emoji アイコン", + "assistant.icon.type.none": "表示しない", "assistant.title": "デフォルトアシスタント", "data": { "app_data": "アプリデータ", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index 72d24e71..075f5048 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -43,6 +43,7 @@ "edit.title": "Редактировать ассистента", "save.success": "Успешно сохранено", "save.title": "Сохранить в агента", + "icon.type": "Иконка ассистента", "search": "Поиск ассистентов...", "settings.mcp": "Серверы MCP", "settings.mcp.enableFirst": "Сначала включите этот сервер в настройках MCP", @@ -787,7 +788,10 @@ "advanced.title": "Расширенные настройки", "assistant": "Ассистент по умолчанию", "assistant.model_params": "Параметры модели", - "assistant.show.icon": "Показывать модельный иконки", + "assistant.icon.type": "Тип модели иконки", + "assistant.icon.type.model": "Модель иконки", + "assistant.icon.type.emoji": "Emoji иконка", + "assistant.icon.type.none": "Не отображать", "assistant.title": "Ассистент по умолчанию", "data": { "app_data": "Данные приложения", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 1b7c54df..db3fe830 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -43,6 +43,7 @@ "edit.title": "编辑助手", "save.success": "保存成功", "save.title": "保存到智能体", + "icon.type": "助手图标", "search": "搜索助手", "settings.mcp": "MCP 服务器", "settings.mcp.enableFirst": "请先在 MCP 设置中启用此服务器", @@ -787,7 +788,10 @@ "advanced.title": "高级设置", "assistant": "默认助手", "assistant.model_params": "模型参数", - "assistant.show.icon": "显示模型图标", + "assistant.icon.type": "模型图标类型", + "assistant.icon.type.model": "模型图标", + "assistant.icon.type.emoji": "Emoji 表情", + "assistant.icon.type.none": "不显示", "assistant.title": "默认助手", "data": { "app_data": "应用数据", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index ab094b8e..1f70ddd3 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -43,6 +43,7 @@ "edit.title": "編輯助手", "save.success": "儲存成功", "save.title": "儲存到智慧代理人", + "icon.type": "助手圖示", "search": "搜尋助手...", "settings.mcp": "MCP 伺服器", "settings.mcp.enableFirst": "請先在 MCP 設定中啟用此伺服器", @@ -787,7 +788,10 @@ "advanced.title": "進階設定", "assistant": "預設助手", "assistant.model_params": "模型參數", - "assistant.show.icon": "顯示模型圖示", + "assistant.icon.type": "模型圖示類型", + "assistant.icon.type.model": "模型圖示", + "assistant.icon.type.emoji": "Emoji 表情", + "assistant.icon.type.none": "不顯示", "assistant.title": "預設助手", "data": { "app_data": "應用程式資料", diff --git a/src/renderer/src/pages/home/Tabs/AssistantItem.tsx b/src/renderer/src/pages/home/Tabs/AssistantItem.tsx index 1ffaa30b..1af70ecc 100644 --- a/src/renderer/src/pages/home/Tabs/AssistantItem.tsx +++ b/src/renderer/src/pages/home/Tabs/AssistantItem.tsx @@ -3,6 +3,7 @@ import { EditOutlined, MinusCircleOutlined, SaveOutlined, + SmileOutlined, SortAscendingOutlined, SortDescendingOutlined } from '@ant-design/icons' @@ -39,7 +40,7 @@ interface AssistantItemProps { const AssistantItem: FC = ({ assistant, isActive, onSwitch, onDelete, addAgent, addAssistant }) => { const { t } = useTranslation() const { removeAllTopics } = useAssistant(assistant.id) // 使用当前助手的ID - const { clickAssistantToShowTopic, topicPosition, showAssistantIcon } = useSettings() + const { clickAssistantToShowTopic, topicPosition, assistantIconType, setAssistantIconType } = useSettings() const defaultModel = getDefaultModel() const { assistants, updateAssistants } = useAssistants() @@ -119,6 +120,28 @@ const AssistantItem: FC = ({ assistant, isActive, onSwitch, }) } }, + { + label: t('assistants.icon.type'), + key: 'icon-type', + icon: , + children: [ + { + label: t('settings.assistant.icon.type.model'), + key: 'model', + onClick: () => setAssistantIconType('model') + }, + { + label: t('settings.assistant.icon.type.emoji'), + key: 'emoji', + onClick: () => setAssistantIconType('emoji') + }, + { + label: t('settings.assistant.icon.type.none'), + key: 'none', + onClick: () => setAssistantIconType('none') + } + ] + }, { type: 'divider' }, { label: t('common.sort.pinyin.asc'), @@ -174,18 +197,20 @@ const AssistantItem: FC = ({ assistant, isActive, onSwitch, - {showAssistantIcon ? ( + {assistantIconType === 'model' ? ( ) : ( - - {assistant.emoji || assistantName.slice(0, 1)} - + assistantIconType === 'emoji' && ( + + {assistant.emoji || assistantName.slice(0, 1)} + + ) )} {assistantName} @@ -203,7 +228,8 @@ const Container = styled.div` display: flex; flex-direction: row; justify-content: space-between; - padding: 7px 10px; + padding: 0 10px; + height: 37px; position: relative; font-family: Ubuntu; border-radius: var(--list-item-border-radius); @@ -231,20 +257,21 @@ const AssistantNameRow = styled.div` display: flex; flex-direction: row; align-items: center; - gap: 5px; + gap: 8px; ` const AssistantEmoji = styled.div<{ $emoji: string }>` - width: 22px; - height: 22px; - border-radius: 11px; + width: 26px; + height: 26px; + border-radius: 13px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; - font-size: 12px; + font-size: 15px; position: relative; overflow: hidden; + margin-right: 3px; &:before { width: 100%; height: 100%; @@ -261,7 +288,9 @@ const AssistantEmoji = styled.div<{ $emoji: string }>` } ` -const AssistantName = styled.div`` +const AssistantName = styled.div` + font-size: 13px; +` const MenuButton = styled.div` display: flex; diff --git a/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx b/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx index 2e29e298..d504cbe9 100644 --- a/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx +++ b/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx @@ -4,7 +4,9 @@ import { useTheme } from '@renderer/context/ThemeProvider' import { useSettings } from '@renderer/hooks/useSettings' import { useAppDispatch } from '@renderer/store' import { + AssistantIconType, DEFAULT_SIDEBAR_ICONS, + setAssistantIconType, setClickAssistantToShowTopic, setCustomCss, setShowTopicTime, @@ -31,8 +33,7 @@ const DisplaySettings: FC = () => { showTopicTime, customCss, sidebarIcons, - showAssistantIcon, - setShowAssistantIcon + assistantIconType } = useSettings() const { theme: themeMode } = useTheme() const { t } = useTranslation() @@ -87,6 +88,15 @@ const DisplaySettings: FC = () => { [t] ) + const assistantIconTypeOptions = useMemo( + () => [ + { value: 'model', label: t('settings.assistant.icon.type.model') }, + { value: 'emoji', label: t('settings.assistant.icon.type.emoji') }, + { value: 'none', label: t('settings.assistant.icon.type.none') } + ], + [t] + ) + return ( @@ -143,8 +153,13 @@ const DisplaySettings: FC = () => { {t('settings.display.assistant.title')} - {t('settings.assistant.show.icon')} - setShowAssistantIcon(checked)} /> + {t('settings.assistant.icon.type')} + dispatch(setAssistantIconType(value as AssistantIconType))} + options={assistantIconTypeOptions} + /> diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts index 7da3f889..2a441d29 100644 --- a/src/renderer/src/store/index.ts +++ b/src/renderer/src/store/index.ts @@ -42,7 +42,7 @@ const persistedReducer = persistReducer( { key: 'cherry-studio', storage, - version: 95, + version: 96, blacklist: ['runtime', 'messages'], migrate }, diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index 0f113187..52db25f1 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -1213,6 +1213,17 @@ const migrateConfig = { } catch (error) { return state } + }, + '96': (state: RootState) => { + try { + // @ts-ignore eslint-disable-next-line + state.settings.assistantIconType = state.settings?.showAssistantIcon ? 'model' : 'emoji' + // @ts-ignore eslint-disable-next-line + delete state.settings.showAssistantIcon + return state + } catch (error) { + return state + } } } diff --git a/src/renderer/src/store/settings.ts b/src/renderer/src/store/settings.ts index 66b1f91a..b7b4be71 100644 --- a/src/renderer/src/store/settings.ts +++ b/src/renderer/src/store/settings.ts @@ -21,6 +21,8 @@ export const DEFAULT_SIDEBAR_ICONS: SidebarIcon[] = [ export interface NutstoreSyncRuntime extends WebDAVSyncState {} +export type AssistantIconType = 'model' | 'emoji' | 'none' + export interface SettingsState { showAssistants: boolean showTopics: boolean @@ -42,7 +44,7 @@ export interface SettingsState { fontSize: number topicPosition: 'left' | 'right' showTopicTime: boolean - showAssistantIcon: boolean + assistantIconType: AssistantIconType pasteLongTextAsFile: boolean pasteLongTextThreshold: number clickAssistantToShowTopic: boolean @@ -147,7 +149,7 @@ export const initialState: SettingsState = { fontSize: 14, topicPosition: 'left', showTopicTime: false, - showAssistantIcon: false, + assistantIconType: 'emoji', pasteLongTextAsFile: false, pasteLongTextThreshold: 1500, clickAssistantToShowTopic: true, @@ -294,8 +296,8 @@ const settingsSlice = createSlice({ setShowTopicTime: (state, action: PayloadAction) => { state.showTopicTime = action.payload }, - setShowAssistantIcon: (state, action: PayloadAction) => { - state.showAssistantIcon = action.payload + setAssistantIconType: (state, action: PayloadAction) => { + state.assistantIconType = action.payload }, setPasteLongTextAsFile: (state, action: PayloadAction) => { state.pasteLongTextAsFile = action.payload @@ -508,7 +510,7 @@ export const { setWindowStyle, setTopicPosition, setShowTopicTime, - setShowAssistantIcon, + setAssistantIconType, setPasteLongTextAsFile, setAutoCheckUpdate, setRenderInputMessageAsMarkdown,