feat: add display settings

This commit is contained in:
kangfenmao 2024-12-16 11:59:15 +08:00
parent 356da1ea67
commit 96737ed695
12 changed files with 198 additions and 106 deletions

View File

@ -22,7 +22,7 @@ const Sidebar: FC = () => {
const { generating } = useRuntime()
const { t } = useTranslation()
const navigate = useNavigate()
const { windowStyle } = useSettings()
const { windowStyle, showMinappIcon, showFilesIcon } = useSettings()
const { theme, toggleTheme } = useTheme()
const isRoute = (path: string): string => (pathname === path ? 'active' : '')
@ -79,20 +79,24 @@ const Sidebar: FC = () => {
</Icon>
</StyledLink>
</Tooltip>
<Tooltip title={t('minapp.title')} mouseEnterDelay={0.8} placement="right">
<StyledLink onClick={() => to('/apps')}>
<Icon className={isRoute('/apps')}>
<i className="iconfont icon-appstore" />
</Icon>
</StyledLink>
</Tooltip>
<Tooltip title={t('files.title')} mouseEnterDelay={0.8} placement="right">
<StyledLink onClick={() => to('/files')}>
<Icon className={isRoute('/files')}>
<FolderOutlined />
</Icon>
</StyledLink>
</Tooltip>
{showMinappIcon && (
<Tooltip title={t('minapp.title')} mouseEnterDelay={0.8} placement="right">
<StyledLink onClick={() => to('/apps')}>
<Icon className={isRoute('/apps')}>
<i className="iconfont icon-appstore" />
</Icon>
</StyledLink>
</Tooltip>
)}
{showFilesIcon && (
<Tooltip title={t('files.title')} mouseEnterDelay={0.8} placement="right">
<StyledLink onClick={() => to('/files')}>
<Icon className={isRoute('/files')}>
<FolderOutlined />
</Icon>
</StyledLink>
</Tooltip>
)}
</Menus>
</MainMenus>
<Menus onClick={MinApp.onClose}>

View File

@ -378,6 +378,11 @@
"general.user_name": "User Name",
"general.user_name.placeholder": "Enter your name",
"general.view_webdav_settings": "View WebDAV settings",
"general.display.title": "Display Settings",
"display.sidebar.minapp.icon": "Show MinApp icon",
"display.sidebar.files.icon": "Show Files icon",
"display.sidebar.title": "Sidebar Settings",
"display.topic.title": "Topic Settings",
"input.auto_translate_with_space": "Quickly translate with 3 spaces",
"messages.divider": "Show divider between messages",
"messages.input.paste_long_text_as_file": "Paste long text as file",

View File

@ -378,6 +378,11 @@
"general.user_name": "Имя пользователя",
"general.user_name.placeholder": "Введите ваше имя",
"general.view_webdav_settings": "Просмотр настроек WebDAV",
"general.display.title": "Настройки отображения",
"display.sidebar.minapp.icon": "Показывать иконку мини-приложения",
"display.sidebar.files.icon": "Показывать иконку файлов",
"display.sidebar.title": "Настройки боковой панели",
"display.topic.title": "Настройки топиков",
"input.auto_translate_with_space": "Быстрый перевод с помощью 3-х пробелов",
"messages.divider": "Показывать разделитель между сообщениями",
"messages.input.paste_long_text_as_file": "Вставлять длинный текст как файл",

View File

@ -378,6 +378,11 @@
"general.user_name": "用户名",
"general.user_name.placeholder": "请输入用户名",
"general.view_webdav_settings": "查看 WebDAV 设置",
"general.display.title": "显示设置",
"display.sidebar.minapp.icon": "显示小程序图标",
"display.sidebar.files.icon": "显示文件图标",
"display.sidebar.title": "侧边栏设置",
"display.topic.title": "话题设置",
"input.auto_translate_with_space": "快速敲击3次空格翻译",
"messages.divider": "消息分割线",
"messages.input.paste_long_text_as_file": "长文本粘贴为文件",

View File

@ -378,6 +378,11 @@
"general.user_name": "使用者名稱",
"general.user_name.placeholder": "輸入您的名稱",
"general.view_webdav_settings": "查看 WebDAV 設定",
"general.display.title": "顯示設定",
"display.sidebar.minapp.icon": "顯示小程序圖示",
"display.sidebar.files.icon": "顯示文件圖示",
"display.sidebar.title": "側邊欄設定",
"display.topic.title": "話題設定",
"input.auto_translate_with_space": "快速敲擊3次空格翻譯",
"messages.divider": "訊息間顯示分隔線",
"messages.input.paste_long_text_as_file": "將長文本貼上為檔案",

View File

@ -15,7 +15,6 @@ import { SettingDivider, SettingRow, SettingRowTitle, SettingSubtitle } from '@r
import { useAppDispatch } from '@renderer/store'
import {
setAutoTranslateWithSpace,
setClickAssistantToShowTopic,
setCodeCollapsible,
setCodeShowLineNumbers,
setCodeStyle,
@ -26,8 +25,7 @@ import {
setPasteLongTextAsFile,
setRenderInputMessageAsMarkdown,
setShowInputEstimatedTokens,
setShowMessageDivider,
setShowTopicTime
setShowMessageDivider
} from '@renderer/store/settings'
import { Assistant, AssistantSettings, ThemeMode } from '@renderer/types'
import { Col, Row, Select, Slider, Switch, Tooltip } from 'antd'
@ -64,11 +62,7 @@ const SettingsTab: FC<Props> = (props) => {
codeShowLineNumbers,
codeCollapsible,
mathEngine,
topicPosition,
showTopicTime,
clickAssistantToShowTopic,
autoTranslateWithSpace,
setTopicPosition
autoTranslateWithSpace
} = useSettings()
const onUpdateAssistantSettings = (settings: Partial<AssistantSettings>) => {
@ -366,41 +360,6 @@ const SettingsTab: FC<Props> = (props) => {
/>
</SettingRow>
</SettingGroup>
<SettingGroup>
<SettingSubtitle style={{ marginTop: 0 }}>{t('settings.display.title')}</SettingSubtitle>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.topic.position')}</SettingRowTitle>
<Select
defaultValue={topicPosition || 'right'}
style={{ width: 135 }}
onChange={setTopicPosition}
size="small"
options={[
{ value: 'left', label: t('settings.topic.position.left') },
{ value: 'right', label: t('settings.topic.position.right') }
]}
/>
</SettingRow>
<SettingDivider />
{topicPosition === 'left' && (
<>
<SettingRow>
<SettingRowTitle>{t('settings.advanced.auto_switch_to_topics')}</SettingRowTitle>
<Switch
size="small"
checked={clickAssistantToShowTopic}
onChange={(checked) => dispatch(setClickAssistantToShowTopic(checked))}
/>
</SettingRow>
<SettingDivider />
</>
)}
<SettingRow>
<SettingRowTitle>{t('settings.topic.show.time')}</SettingRowTitle>
<Switch size="small" checked={showTopicTime} onChange={(checked) => dispatch(setShowTopicTime(checked))} />
</SettingRow>
</SettingGroup>
</Container>
)
}

View File

@ -0,0 +1,118 @@
import { isMac } from '@renderer/config/constant'
import { useTheme } from '@renderer/context/ThemeProvider'
import { useSettings } from '@renderer/hooks/useSettings'
import { useAppDispatch } from '@renderer/store'
import {
setClickAssistantToShowTopic,
setShowFilesIcon,
setShowMinappIcon,
setShowTopicTime
} from '@renderer/store/settings'
import { ThemeMode } from '@renderer/types'
import { Select, Switch } from 'antd'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '.'
const DisplaySettings: FC = () => {
const {
setTheme,
theme,
windowStyle,
setWindowStyle,
showMinappIcon,
showFilesIcon,
topicPosition,
setTopicPosition,
clickAssistantToShowTopic,
showTopicTime
} = useSettings()
const { theme: themeMode } = useTheme()
const { t } = useTranslation()
const dispatch = useAppDispatch()
const handleWindowStyleChange = (checked: boolean) => {
setWindowStyle(checked ? 'transparent' : 'opaque')
}
return (
<SettingContainer theme={themeMode}>
<SettingGroup theme={theme}>
<SettingTitle>{t('settings.display.title')}</SettingTitle>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.theme.title')}</SettingRowTitle>
<Select
defaultValue={theme}
style={{ width: 120 }}
onChange={setTheme}
options={[
{ value: ThemeMode.light, label: t('settings.theme.light') },
{ value: ThemeMode.dark, label: t('settings.theme.dark') },
{ value: ThemeMode.auto, label: t('settings.theme.auto') }
]}
/>
</SettingRow>
{isMac && (
<>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.theme.window.style.transparent')}</SettingRowTitle>
<Switch checked={windowStyle === 'transparent'} onChange={handleWindowStyleChange} />
</SettingRow>
</>
)}
</SettingGroup>
<SettingGroup theme={theme}>
<SettingTitle>{t('settings.display.topic.title')}</SettingTitle>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.topic.position')}</SettingRowTitle>
<Select
defaultValue={topicPosition || 'right'}
style={{ width: 120 }}
onChange={setTopicPosition}
options={[
{ value: 'left', label: t('settings.topic.position.left') },
{ value: 'right', label: t('settings.topic.position.right') }
]}
/>
</SettingRow>
<SettingDivider />
{topicPosition === 'left' && (
<>
<SettingRow>
<SettingRowTitle>{t('settings.advanced.auto_switch_to_topics')}</SettingRowTitle>
<Switch
checked={clickAssistantToShowTopic}
onChange={(checked) => dispatch(setClickAssistantToShowTopic(checked))}
/>
</SettingRow>
<SettingDivider />
</>
)}
<SettingRow>
<SettingRowTitle>{t('settings.topic.show.time')}</SettingRowTitle>
<Switch checked={showTopicTime} onChange={(checked) => dispatch(setShowTopicTime(checked))} />
</SettingRow>
</SettingGroup>
<SettingGroup theme={theme}>
<SettingTitle>{t('settings.display.sidebar.title')}</SettingTitle>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.display.sidebar.minapp.icon')}</SettingRowTitle>
<Switch checked={showMinappIcon} onChange={(value) => dispatch(setShowMinappIcon(value))} />
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.display.sidebar.files.icon')}</SettingRowTitle>
<Switch checked={showFilesIcon} onChange={(value) => dispatch(setShowFilesIcon(value))} />
</SettingRow>
</SettingGroup>
</SettingContainer>
)
}
export default DisplaySettings

View File

@ -1,11 +1,10 @@
import { isMac } from '@renderer/config/constant'
import { useTheme } from '@renderer/context/ThemeProvider'
import { useSettings } from '@renderer/hooks/useSettings'
import i18n from '@renderer/i18n'
import { useAppDispatch } from '@renderer/store'
import { setLanguage } from '@renderer/store/settings'
import { setProxyMode, setProxyUrl as _setProxyUrl } from '@renderer/store/settings'
import { LanguageVarious, ThemeMode } from '@renderer/types'
import { LanguageVarious } from '@renderer/types'
import { isValidProxyUrl } from '@renderer/utils'
import { Input, Select, Space, Switch } from 'antd'
import { FC, useState } from 'react'
@ -14,17 +13,7 @@ import { useTranslation } from 'react-i18next'
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '.'
const GeneralSettings: FC = () => {
const {
language,
proxyUrl: storeProxyUrl,
setTheme,
theme,
setTray,
tray,
windowStyle,
setWindowStyle,
proxyMode: storeProxyMode
} = useSettings()
const { language, proxyUrl: storeProxyUrl, theme, setTray, tray, proxyMode: storeProxyMode } = useSettings()
const [proxyUrl, setProxyUrl] = useState<string | undefined>(storeProxyUrl)
const { theme: themeMode } = useTheme()
@ -98,37 +87,6 @@ const GeneralSettings: FC = () => {
</Select>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.theme.title')}</SettingRowTitle>
<Select
defaultValue={theme}
style={{ width: 180 }}
onChange={setTheme}
options={[
{ value: ThemeMode.light, label: t('settings.theme.light') },
{ value: ThemeMode.dark, label: t('settings.theme.dark') },
{ value: ThemeMode.auto, label: t('settings.theme.auto') }
]}
/>
</SettingRow>
{isMac && (
<>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.theme.window.style.title')}</SettingRowTitle>
<Select
defaultValue={windowStyle || 'opaque'}
style={{ width: 180 }}
onChange={setWindowStyle}
options={[
{ value: 'transparent', label: t('settings.theme.window.style.transparent') },
{ value: 'opaque', label: t('settings.theme.window.style.opaque') }
]}
/>
</SettingRow>
</>
)}
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.proxy.mode.title')}</SettingRowTitle>
<Select

View File

@ -1,4 +1,11 @@
import { CloudOutlined, InfoCircleOutlined, MacCommandOutlined, SaveOutlined, SettingOutlined } from '@ant-design/icons'
import {
CloudOutlined,
InfoCircleOutlined,
LayoutOutlined,
MacCommandOutlined,
SaveOutlined,
SettingOutlined
} from '@ant-design/icons'
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
import { isLocalAi } from '@renderer/config/env'
import { FC } from 'react'
@ -8,6 +15,7 @@ import styled from 'styled-components'
import AboutSettings from './AboutSettings'
import DataSettings from './DataSettings/DataSettings'
import DisplaySettings from './DisplaySettings'
import GeneralSettings from './GeneralSettings'
import ModelSettings from './ModalSettings/ModelSettings'
import ProvidersList from './ProviderSettings'
@ -48,6 +56,12 @@ const SettingsPage: FC = () => {
{t('settings.general')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/display">
<MenuItem className={isRoute('/settings/display')}>
<LayoutOutlined />
{t('settings.display.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/shortcut">
<MenuItem className={isRoute('/settings/shortcut')}>
<MacCommandOutlined />
@ -72,6 +86,7 @@ const SettingsPage: FC = () => {
<Route path="provider" element={<ProvidersList />} />
<Route path="model" element={<ModelSettings />} />
<Route path="general/*" element={<GeneralSettings />} />
<Route path="display" element={<DisplaySettings />} />
<Route path="data/*" element={<DataSettings />} />
<Route path="shortcut" element={<ShortcutSettings />} />
<Route path="about" element={<AboutSettings />} />

View File

@ -26,7 +26,7 @@ const persistedReducer = persistReducer(
{
key: 'cherry-studio',
storage,
version: 48,
version: 49,
blacklist: ['runtime'],
migrate
},

View File

@ -749,6 +749,11 @@ const migrateConfig = {
})
}
return state
},
'49': (state: RootState) => {
state.settings.showMinappIcon = true
state.settings.showFilesIcon = true
return state
}
}

View File

@ -38,6 +38,9 @@ export interface SettingsState {
translateModelPrompt: string
autoTranslateWithSpace: boolean
enableTopicNaming: boolean
// Sidebar icons
showMinappIcon: boolean
showFilesIcon: boolean
}
const initialState: SettingsState = {
@ -72,7 +75,9 @@ const initialState: SettingsState = {
webdavPath: '/cherry-studio',
translateModelPrompt: TRANSLATE_PROMPT,
autoTranslateWithSpace: false,
enableTopicNaming: true
enableTopicNaming: true,
showMinappIcon: true,
showFilesIcon: true
}
const settingsSlice = createSlice({
@ -181,6 +186,12 @@ const settingsSlice = createSlice({
},
setEnableTopicNaming: (state, action: PayloadAction<boolean>) => {
state.enableTopicNaming = action.payload
},
setShowMinappIcon: (state, action: PayloadAction<boolean>) => {
state.showMinappIcon = action.payload
},
setShowFilesIcon: (state, action: PayloadAction<boolean>) => {
state.showFilesIcon = action.payload
}
}
})
@ -219,7 +230,9 @@ export const {
setCodeStyle,
setTranslateModelPrompt,
setAutoTranslateWithSpace,
setEnableTopicNaming
setEnableTopicNaming,
setShowMinappIcon,
setShowFilesIcon
} = settingsSlice.actions
export default settingsSlice.reducer