diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 515ea508..4e6ede0f 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -9,6 +9,7 @@ import { AntdThemeConfig, getAntdLocale } from './config/antd' import AppsPage from './pages/apps/AppsPage' import HomePage from './pages/home/HomePage' import SettingsPage from './pages/settings/SettingsPage' +import TranslatePage from './pages/translate/TranslatePage' function App(): JSX.Element { return ( @@ -21,6 +22,7 @@ function App(): JSX.Element { } /> } /> + } /> } /> diff --git a/src/renderer/src/assets/fonts/icon-fonts/iconfont.css b/src/renderer/src/assets/fonts/icon-fonts/iconfont.css new file mode 100644 index 00000000..098b60a9 --- /dev/null +++ b/src/renderer/src/assets/fonts/icon-fonts/iconfont.css @@ -0,0 +1,47 @@ +@font-face { + font-family: "iconfont"; /* Project id 4563475 */ + src: url('iconfont.woff2?t=1722099305424') format('woff2'), + url('iconfont.woff?t=1722099305424') format('woff'), + url('iconfont.ttf?t=1722099305424') format('truetype'); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-translate_line:before { + content: "\e7de"; +} + +.icon-history:before { + content: "\e758"; +} + +.icon-hidesidebarhoriz:before { + content: "\e8eb"; +} + +.icon-showsidebarhoriz:before { + content: "\e944"; +} + +.icon-a-addchat:before { + content: "\e658"; +} + +.icon-appstore:before { + content: "\e792"; +} + +.icon-chat:before { + content: "\e615"; +} + +.icon-setting:before { + content: "\e78e"; +} + diff --git a/src/renderer/src/assets/fonts/icon-fonts/iconfont.ttf b/src/renderer/src/assets/fonts/icon-fonts/iconfont.ttf new file mode 100644 index 00000000..64e9a4e3 Binary files /dev/null and b/src/renderer/src/assets/fonts/icon-fonts/iconfont.ttf differ diff --git a/src/renderer/src/assets/fonts/icon-fonts/iconfont.woff b/src/renderer/src/assets/fonts/icon-fonts/iconfont.woff new file mode 100644 index 00000000..44baa8be Binary files /dev/null and b/src/renderer/src/assets/fonts/icon-fonts/iconfont.woff differ diff --git a/src/renderer/src/assets/fonts/icon-fonts/iconfont.woff2 b/src/renderer/src/assets/fonts/icon-fonts/iconfont.woff2 new file mode 100644 index 00000000..c2e0fb69 Binary files /dev/null and b/src/renderer/src/assets/fonts/icon-fonts/iconfont.woff2 differ diff --git a/src/renderer/src/assets/styles/index.scss b/src/renderer/src/assets/styles/index.scss index 5d1f089a..211f849f 100644 --- a/src/renderer/src/assets/styles/index.scss +++ b/src/renderer/src/assets/styles/index.scss @@ -1,4 +1,4 @@ -@import 'https://at.alicdn.com/t/c/font_4563475_hrx8c92awui.css'; +@import '../fonts/icon-fonts/iconfont.css'; @import './markdown.scss'; @import './scrollbar.scss'; diff --git a/src/renderer/src/components/app/Sidebar.tsx b/src/renderer/src/components/app/Sidebar.tsx index 155182d0..3de3e7ca 100644 --- a/src/renderer/src/components/app/Sidebar.tsx +++ b/src/renderer/src/components/app/Sidebar.tsx @@ -4,6 +4,7 @@ import styled from 'styled-components' import { Link, useLocation } from 'react-router-dom' import useAvatar from '@renderer/hooks/useAvatar' import { isMac, isWindows } from '@renderer/config/constant' +import { TranslationOutlined } from '@ant-design/icons' const Sidebar: FC = () => { const { pathname } = useLocation() @@ -29,6 +30,11 @@ const Sidebar: FC = () => { + + + + + @@ -85,22 +91,28 @@ const Icon = styled.div` margin-bottom: 5px; transition: background-color 0.2s ease; -webkit-app-region: none; - .iconfont { + .iconfont, + .anticon { color: var(--color-icon); font-size: 20px; transition: color 0.2s ease; text-decoration: none; } + .anticon { + font-size: 17px; + } &:hover { background-color: #ffffff30; cursor: pointer; - .iconfont { + .iconfont, + .anticon { color: var(--color-icon-white); } } &.active { background-color: #ffffff20; - .iconfont { + .iconfont, + .anticon { color: var(--color-icon-white); } } diff --git a/src/renderer/src/hooks/useAssistant.ts b/src/renderer/src/hooks/useAssistant.ts index f923910d..817a9835 100644 --- a/src/renderer/src/hooks/useAssistant.ts +++ b/src/renderer/src/hooks/useAssistant.ts @@ -14,7 +14,7 @@ import { updateTopic, updateTopics } from '@renderer/store/assistants' -import { setDefaultModel as _setDefaultModel, setTopicNamingModel as _setTopicNamingModel } from '@renderer/store/llm' +import { setDefaultModel, setTopicNamingModel, setTranslateModel } from '@renderer/store/llm' import { Assistant, AssistantSettings, Model, Topic } from '@renderer/types' import localforage from 'localforage' @@ -71,13 +71,15 @@ export function useDefaultAssistant() { } export function useDefaultModel() { - const { defaultModel, topicNamingModel } = useAppSelector((state) => state.llm) + const { defaultModel, topicNamingModel, translateModel } = useAppSelector((state) => state.llm) const dispatch = useAppDispatch() return { defaultModel, topicNamingModel, - setDefaultModel: (model: Model) => dispatch(_setDefaultModel({ model })), - setTopicNamingModel: (model: Model) => dispatch(_setTopicNamingModel({ model })) + translateModel, + setDefaultModel: (model: Model) => dispatch(setDefaultModel({ model })), + setTopicNamingModel: (model: Model) => dispatch(setTopicNamingModel({ model })), + setTranslateModel: (model: Model) => dispatch(setTranslateModel({ model })) } } diff --git a/src/renderer/src/i18n/index.ts b/src/renderer/src/i18n/index.ts index ab46ca35..0a903840 100644 --- a/src/renderer/src/i18n/index.ts +++ b/src/renderer/src/i18n/index.ts @@ -102,7 +102,7 @@ const resources = { title: 'Settings', general: 'General Settings', provider: 'Model Provider', - model: 'Model Settings', + model: 'Default Model', assistant: 'Default Assistant', about: 'About & Feedback', 'messages.model.title': 'Model Settings', @@ -124,6 +124,7 @@ const resources = { 'provider.api.url.reset': 'Reset', 'models.default_assistant_model': 'Default Assistant Model', 'models.topic_naming_model': 'Topic Naming Model', + 'models.translate_model': 'Translate Model', 'models.add.add_model': 'Add Model', 'models.add.model_id.placeholder': 'Required e.g. gpt-3.5-turbo', 'models.add.model_id': 'Model ID', @@ -156,6 +157,27 @@ const resources = { 'about.contact.title': '📧 Contact', 'about.contact.button': 'Email', 'proxy.title': 'Proxy Address' + }, + translate: { + title: 'Translation', + 'any.language': 'Any language', + 'button.translate': 'Translate', + 'error.not_configured': 'Translation model is not configured', + 'input.placeholder': 'Enter text to translate', + 'output.placeholder': 'Translation' + }, + languages: { + english: 'English', + chinese: 'Chinese', + 'chinese-traditional': 'Traditional Chinese', + japanese: 'Japanese', + korean: 'Korean', + russian: 'Russian', + spanish: 'Spanish', + french: 'French', + italian: 'Italian', + portuguese: 'Portuguese', + arabic: 'Arabic' } } }, @@ -258,7 +280,7 @@ const resources = { title: '设置', general: '常规设置', provider: '模型提供商', - model: '模型设置', + model: '默认模型', assistant: '默认助手', about: '关于我们', 'messages.model.title': '模型设置', @@ -280,6 +302,7 @@ const resources = { 'provider.api.url.reset': '重置', 'models.default_assistant_model': '默认助手模型', 'models.topic_naming_model': '话题命名模型', + 'models.translate_model': '翻译模型', 'models.add.add_model': '添加模型', 'models.add.model_id.placeholder': '必填 例如 gpt-3.5-turbo', 'models.add.model_id': '模型 ID', @@ -312,6 +335,27 @@ const resources = { 'about.contact.title': '📧 邮件联系', 'about.contact.button': '邮件', 'proxy.title': '代理地址' + }, + translate: { + title: '翻译', + 'any.language': '任意语言', + 'button.translate': '翻译', + 'error.not_configured': '翻译模型未配置', + 'input.placeholder': '输入文本进行翻译', + 'output.placeholder': '翻译' + }, + languages: { + english: '英文', + chinese: '简体中文', + 'chinese-traditional': '繁体中文', + japanese: '日文', + korean: '韩文', + russian: '俄文', + spanish: '西班牙文', + french: '法文', + italian: '意大利文', + portuguese: '葡萄牙文', + arabic: '阿拉伯文' } } } diff --git a/src/renderer/src/pages/settings/ModelSettings.tsx b/src/renderer/src/pages/settings/ModelSettings.tsx index 0937a34a..2fa73d6f 100644 --- a/src/renderer/src/pages/settings/ModelSettings.tsx +++ b/src/renderer/src/pages/settings/ModelSettings.tsx @@ -6,9 +6,11 @@ import { useDefaultModel } from '@renderer/hooks/useAssistant' import { find } from 'lodash' import { Model } from '@renderer/types' import { useTranslation } from 'react-i18next' +import { EditOutlined, MessageOutlined, TranslationOutlined } from '@ant-design/icons' const ModelSettings: FC = () => { - const { defaultModel, topicNamingModel, setDefaultModel, setTopicNamingModel } = useDefaultModel() + const { defaultModel, topicNamingModel, translateModel, setDefaultModel, setTopicNamingModel, setTranslateModel } = + useDefaultModel() const { providers } = useProviders() const allModels = providers.map((p) => p.models).flat() const { t } = useTranslation() @@ -24,9 +26,16 @@ const ModelSettings: FC = () => { })) })) + const iconStyle = { fontSize: 16, marginRight: 8 } + return ( - {t('settings.models.default_assistant_model')} + +
+ + {t('settings.models.default_assistant_model')} +
+
{ onChange={(id) => setTopicNamingModel(find(allModels, { id }) as Model)} options={selectOptions} /> +
+ +
+ + {t('settings.models.translate_model')} +
+
+ + + +