feat: add display settings
This commit is contained in:
parent
356da1ea67
commit
96737ed695
@ -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}>
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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": "Вставлять длинный текст как файл",
|
||||
|
||||
@ -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": "长文本粘贴为文件",
|
||||
|
||||
@ -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": "將長文本貼上為檔案",
|
||||
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
118
src/renderer/src/pages/settings/DisplaySettings.tsx
Normal file
118
src/renderer/src/pages/settings/DisplaySettings.tsx
Normal 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
|
||||
@ -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
|
||||
|
||||
@ -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 />} />
|
||||
|
||||
@ -26,7 +26,7 @@ const persistedReducer = persistReducer(
|
||||
{
|
||||
key: 'cherry-studio',
|
||||
storage,
|
||||
version: 48,
|
||||
version: 49,
|
||||
blacklist: ['runtime'],
|
||||
migrate
|
||||
},
|
||||
|
||||
@ -749,6 +749,11 @@ const migrateConfig = {
|
||||
})
|
||||
}
|
||||
return state
|
||||
},
|
||||
'49': (state: RootState) => {
|
||||
state.settings.showMinappIcon = true
|
||||
state.settings.showFilesIcon = true
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user