feat(DisplaySettings): add theme color presets and zoom settings

- Introduced a new color selection feature in DisplaySettings, allowing users to choose from predefined theme color presets.
- Added a dedicated section for zoom settings in the DisplaySettings component, enhancing user customization options.
- Updated localization files to include new zoom settings titles in multiple languages.
This commit is contained in:
kangfenmao 2025-05-29 15:28:28 +08:00
parent 49ede72406
commit a7aed926cb
13 changed files with 103 additions and 33 deletions

View File

@ -15,3 +15,18 @@ export const TOKENFLUX_HOST = 'https://tokenflux.ai'
// Messages loading configuration
export const INITIAL_MESSAGES_COUNT = 20
export const LOAD_MORE_COUNT = 20
export const DEFAULT_COLOR_PRIMARY = '#00b96b'
export const THEME_COLOR_PRESETS = [
DEFAULT_COLOR_PRIMARY,
'#FF5470', // Coral Pink
'#14B8A6', // Teal
'#6366F1', // Indigo
'#8B5CF6', // Purple
'#EC4899', // Pink
'#3B82F6', // Blue
'#F59E0B', // Amber
'#6D28D9', // Violet
'#0EA5E9', // Sky Blue
'#0284C7' // Light Blue
]

View File

@ -4,6 +4,7 @@ import Color from 'color'
export default function useUserTheme() {
const userTheme = useAppSelector((state) => state.settings.userTheme)
const dispatch = useAppDispatch()
const initUserTheme = (theme: UserTheme = userTheme) => {

View File

@ -262,7 +262,7 @@
"settings.show_line_numbers": "Show line numbers in code",
"settings.temperature": "Temperature",
"settings.temperature.tip": "Higher values make the model more creative and unpredictable, while lower values make it more deterministic and precise.",
"settings.thought_auto_collapse": "Automatically Collapse Thought Content",
"settings.thought_auto_collapse": "Collapse Thought Content",
"settings.thought_auto_collapse.tip": "Automatically collapse thought content after thinking ends",
"settings.top_p": "Top-P",
"settings.top_p.tip": "Default value is 1, the smaller the value, the less variety in the answers, the easier to understand, the larger the value, the larger the range of the AI's vocabulary, the more diverse",
@ -657,7 +657,7 @@
"message.code_style": "Code style",
"message.delete.content": "Are you sure you want to delete this message?",
"message.delete.title": "Delete Message",
"message.multi_model_style": "Multi-model response style",
"message.multi_model_style": "Group style",
"message.multi_model_style.fold": "Fold view",
"message.multi_model_style.fold.compress": "Switch to compact layout",
"message.multi_model_style.fold.expand": "Switch to expanded layout",
@ -1265,6 +1265,7 @@
"display.sidebar.translate.icon": "Show Translate icon",
"display.sidebar.visible": "Show icons",
"display.title": "Display Settings",
"display.zoom.title": "Zoom Settings",
"display.topic.title": "Topic Settings",
"miniapps": {
"title": "Mini Apps Settings",
@ -1500,14 +1501,14 @@
"messages.input.send_shortcuts": "Send shortcuts",
"messages.input.show_estimated_tokens": "Show estimated tokens",
"messages.input.title": "Input Settings",
"messages.input.enable_quick_triggers": "Enable '/' and '@' triggers",
"messages.input.enable_quick_triggers": "Enable / and @ triggers",
"messages.input.enable_delete_model": "Enable the backspace key to delete models/attachments.",
"messages.markdown_rendering_input_message": "Markdown render input message",
"messages.math_engine": "Math engine",
"messages.math_engine.none": "None",
"messages.metrics": "{{time_first_token_millsec}}ms to first token | {{token_speed}} tok/sec",
"messages.model.title": "Model Settings",
"messages.navigation": "Message Navigation",
"messages.navigation": "Navigation bar",
"messages.navigation.anchor": "Message Anchor",
"messages.navigation.buttons": "Navigation Buttons",
"messages.navigation.none": "None",

View File

@ -1263,6 +1263,7 @@
"display.sidebar.translate.icon": "翻訳のアイコンを表示",
"display.sidebar.visible": "アイコンを表示",
"display.title": "表示設定",
"display.zoom.title": "ズーム設定",
"display.topic.title": "トピック設定",
"miniapps": {
"title": "ミニアプリ設定",

View File

@ -1264,6 +1264,7 @@
"display.sidebar.translate.icon": "Показывать иконку перевода",
"display.sidebar.visible": "Показывать иконки",
"display.title": "Настройки отображения",
"display.zoom.title": "Настройки масштаба",
"display.topic.title": "Настройки топиков",
"miniapps": {
"title": "Настройки мини-приложений",

View File

@ -1265,6 +1265,7 @@
"display.sidebar.translate.icon": "显示翻译图标",
"display.sidebar.visible": "显示的图标",
"display.title": "显示设置",
"display.zoom.title": "缩放设置",
"display.topic.title": "话题设置",
"miniapps": {
"title": "小程序设置",

View File

@ -1265,6 +1265,7 @@
"display.sidebar.translate.icon": "顯示翻譯圖示",
"display.sidebar.visible": "顯示的圖示",
"display.title": "顯示設定",
"display.zoom.title": "縮放設定",
"display.topic.title": "話題設定",
"miniapps": {
"title": "小程式設置",

View File

@ -1140,6 +1140,7 @@
"display.sidebar.translate.icon": "Εμφάνιση εικονιδίου μετάφρασης",
"display.sidebar.visible": "Εμφανιζόμενα εικονίδια",
"display.title": "Ρυθμίσεις εμφάνισης",
"display.zoom.title": "Ρυθμίσεις κλίμακας",
"display.topic.title": "Ρυθμίσεις Θεμάτων",
"font_size.title": "Μέγεθος γραμμάτων των μηνυμάτων",
"general": "Γενικές ρυθμίσεις",

View File

@ -1139,6 +1139,7 @@
"display.sidebar.translate.icon": "Mostrar icono de traducción",
"display.sidebar.visible": "Iconos visibles",
"display.title": "Configuración de visualización",
"display.zoom.title": "Configuración de zoom",
"display.topic.title": "Configuración de tema",
"font_size.title": "Tamaño de fuente de mensajes",
"general": "Configuración general",

View File

@ -1140,6 +1140,7 @@
"display.sidebar.translate.icon": "Afficher l'icône de traduction",
"display.sidebar.visible": "Icônes affichées",
"display.title": "Paramètres d'affichage",
"display.zoom.title": "Paramètres de zoom",
"display.topic.title": "Paramètres de sujet",
"font_size.title": "Taille de police des messages",
"general": "Paramètres généraux",

View File

@ -1142,6 +1142,7 @@
"display.sidebar.translate.icon": "Mostrar ícone de tradução",
"display.sidebar.visible": "Ícones visíveis",
"display.title": "Configurações de exibição",
"display.zoom.title": "Configurações de zoom",
"display.topic.title": "Configurações de tópico",
"font_size.title": "Tamanho da fonte da mensagem",
"general": "Configurações gerais",

View File

@ -1,5 +1,6 @@
import { SyncOutlined } from '@ant-design/icons'
import { isMac } from '@renderer/config/constant'
import { HStack } from '@renderer/components/Layout'
import { isMac, THEME_COLOR_PRESETS } from '@renderer/config/constant'
import { useTheme } from '@renderer/context/ThemeProvider'
import { useSettings } from '@renderer/hooks/useSettings'
import useUserTheme from '@renderer/hooks/useUserTheme'
@ -15,15 +16,42 @@ import {
setSidebarIcons
} from '@renderer/store/settings'
import { ThemeMode } from '@renderer/types'
import { Minus, Plus, RotateCcw } from 'lucide-react'
import { Button, ColorPicker, Input, Segmented, Switch } from 'antd'
import { FC, useCallback, useMemo, useState, useEffect } from 'react'
import { Minus, Plus, RotateCcw } from 'lucide-react'
import { FC, useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '..'
import SidebarIconsManager from './SidebarIconsManager'
const ColorCircleWrapper = styled.div`
width: 24px;
height: 24px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
`
const ColorCircle = styled.div<{ color: string; isActive?: boolean }>`
position: absolute;
top: 50%;
left: 50%;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: ${(props) => props.color};
cursor: pointer;
transform: translate(-50%, -50%);
border: 2px solid ${(props) => (props.isActive ? 'var(--color-border)' : 'transparent')};
transition: opacity 0.2s;
&:hover {
opacity: 0.8;
}
`
const DisplaySettings: FC = () => {
const {
setTheme,
@ -149,6 +177,48 @@ const DisplaySettings: FC = () => {
<Segmented value={theme} shape="round" onChange={setTheme} options={themeOptions} />
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.theme.color_primary')}</SettingRowTitle>
<HStack gap="12px" alignItems="center">
<HStack gap="12px">
{THEME_COLOR_PRESETS.map((color) => (
<ColorCircleWrapper key={color}>
<ColorCircle
color={color}
isActive={userTheme.colorPrimary === color}
onClick={() => handleColorPrimaryChange(color)}
/>
</ColorCircleWrapper>
))}
</HStack>
<ColorPicker
className="color-picker"
value={userTheme.colorPrimary}
onChange={(color) => handleColorPrimaryChange(color.toHexString())}
showText
style={{ width: '110px' }}
presets={[
{
label: 'Presets',
colors: THEME_COLOR_PRESETS
}
]}
/>
</HStack>
</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.zoom.title')}</SettingTitle>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.zoom.title')}</SettingRowTitle>
<ZoomButtonGroup>
@ -162,31 +232,6 @@ const DisplaySettings: FC = () => {
/>
</ZoomButtonGroup>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.theme.color_primary')}</SettingRowTitle>
<ColorPicker
className="color-picker"
value={userTheme.colorPrimary}
onChange={(color) => handleColorPrimaryChange(color.toHexString())}
showText
presets={[
{
label: 'Presets',
colors: ['#007BFF', '#F74F9E', '#FF5257', '#F7821B', '#FFC600', '#62BA46', '#000000']
}
]}
/>
</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>

View File

@ -50,7 +50,7 @@ const persistedReducer = persistReducer(
{
key: 'cherry-studio',
storage,
version: 107,
version: 109,
blacklist: ['runtime', 'messages', 'messageBlocks'],
migrate
},