mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 03:31:24 +08:00
refactor: update preference keys and enhance preference management
- Updated preference keys from 'app.theme.*' to 'ui.*' for better organization and clarity. - Introduced new preferences for assistant tab sorting and visibility. - Refactored components to utilize the updated preference keys, improving consistency across the codebase. - Cleaned up unused code and comments related to previous settings for maintainability. - Updated auto-generated preference mappings to reflect the new structure.
This commit is contained in:
parent
0a67ab4103
commit
820d6a6e96
@ -40,3 +40,5 @@ export type LanguageVarious = 'zh-CN' | 'zh-TW' | 'el-GR' | 'en-US' | 'es-ES' |
|
||||
export type WindowStyle = 'transparent' | 'opaque'
|
||||
|
||||
export type SendMessageShortcut = 'Enter' | 'Shift+Enter' | 'Ctrl+Enter' | 'Command+Enter' | 'Alt+Enter'
|
||||
|
||||
export type AssistantTabSortType = 'tags' | 'list'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Auto-generated preferences configuration
|
||||
* Generated at: 2025-09-02T04:48:55.916Z
|
||||
* Generated at: 2025-09-02T06:55:00.341Z
|
||||
*
|
||||
* This file is automatically generated from classification.json
|
||||
* To update this file, modify classification.json and run:
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
import { TRANSLATE_PROMPT } from '@shared/config/prompts'
|
||||
import type {
|
||||
AssistantTabSortType,
|
||||
SelectionActionItem,
|
||||
SelectionFilterMode,
|
||||
SelectionTriggerMode,
|
||||
@ -58,12 +59,6 @@ export interface PreferencesType {
|
||||
'app.spell_check.enabled': boolean
|
||||
// redux/settings/spellCheckLanguages
|
||||
'app.spell_check.languages': unknown[]
|
||||
// redux/settings/theme
|
||||
'app.theme.mode': ThemeMode
|
||||
// redux/settings/userTheme.colorPrimary
|
||||
'app.theme.user.color_primary': string
|
||||
// redux/settings/windowStyle
|
||||
'app.theme.window_style': WindowStyle
|
||||
// redux/settings/tray
|
||||
'app.tray.enabled': boolean
|
||||
// redux/settings/trayOnClose
|
||||
@ -76,6 +71,14 @@ export interface PreferencesType {
|
||||
'app.user.name': string
|
||||
// electronStore/ZoomFactor/ZoomFactor
|
||||
'app.zoom_factor': number
|
||||
// redux/settings/clickAssistantToShowTopic
|
||||
'assistant.click_to_show_topic': boolean
|
||||
// redux/settings/assistantIconType
|
||||
'assistant.icon_type': string
|
||||
// redux/settings/showAssistants
|
||||
'assistant.tab.show': boolean
|
||||
// redux/settings/assistantsTabSortType
|
||||
'assistant.tab.sort_type': AssistantTabSortType
|
||||
// redux/settings/codeCollapsible
|
||||
'chat.code.collapsible': boolean
|
||||
// redux/settings/codeEditor.autocompletion
|
||||
@ -290,6 +293,8 @@ export interface PreferencesType {
|
||||
'feature.minapp.open_link_external': boolean
|
||||
// redux/settings/showOpenedMinappsInSidebar
|
||||
'feature.minapp.show_opened_in_sidebar': boolean
|
||||
// redux/settings/showWorkspace
|
||||
'feature.notes.show_workspace': boolean
|
||||
// redux/settings/clickTrayToShowQuickAssistant
|
||||
'feature.quick_assistant.click_tray_to_show': boolean
|
||||
// redux/settings/enableQuickAssistant
|
||||
@ -358,20 +363,24 @@ export interface PreferencesType {
|
||||
'topic.naming.enabled': boolean
|
||||
// redux/settings/topicNamingPrompt
|
||||
'topic.naming.prompt': string
|
||||
// redux/settings/pinTopicsToTop
|
||||
'topic.pin_to_top': boolean
|
||||
// redux/settings/topicPosition
|
||||
'topic.position': string
|
||||
// redux/settings/pinTopicsToTop
|
||||
'topic.tab.pin_to_top': boolean
|
||||
// redux/settings/showTopics
|
||||
'topic.tab.show': boolean
|
||||
// redux/settings/showTopicTime
|
||||
'topic.show_time': boolean
|
||||
// redux/settings/assistantIconType
|
||||
'ui.assistant_icon_type': string
|
||||
// redux/settings/clickAssistantToShowTopic
|
||||
'ui.click_assistant_to_show_topic': boolean
|
||||
'topic.tab.show_time': boolean
|
||||
// redux/settings/customCss
|
||||
'ui.custom_css': string
|
||||
// redux/settings/navbarPosition
|
||||
'ui.navbar.position': 'left' | 'top'
|
||||
// redux/settings/theme
|
||||
'ui.theme_mode': ThemeMode
|
||||
// redux/settings/userTheme.colorPrimary
|
||||
'ui.theme_user.color_primary': string
|
||||
// redux/settings/windowStyle
|
||||
'ui.window_style': WindowStyle
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,15 +403,16 @@ export const DefaultPreferences: PreferencesType = {
|
||||
'app.proxy.url': null,
|
||||
'app.spell_check.enabled': false,
|
||||
'app.spell_check.languages': [],
|
||||
'app.theme.mode': ThemeMode.system,
|
||||
'app.theme.user.color_primary': '#00b96b',
|
||||
'app.theme.window_style': 'opaque',
|
||||
'app.tray.enabled': true,
|
||||
'app.tray.on_close': true,
|
||||
'app.tray.on_launch': false,
|
||||
'app.user.id': 'uuid()',
|
||||
'app.user.name': '',
|
||||
'app.zoom_factor': 1,
|
||||
'assistant.click_to_show_topic': true,
|
||||
'assistant.icon_type': 'emoji',
|
||||
'assistant.tab.show': true,
|
||||
'assistant.tab.sort_type': 'list',
|
||||
'chat.code.collapsible': false,
|
||||
'chat.code.editor.autocompletion': true,
|
||||
'chat.code.editor.enabled': false,
|
||||
@ -510,6 +520,7 @@ export const DefaultPreferences: PreferencesType = {
|
||||
'feature.minapp.max_keep_alive': 3,
|
||||
'feature.minapp.open_link_external': false,
|
||||
'feature.minapp.show_opened_in_sidebar': true,
|
||||
'feature.notes.show_workspace': true,
|
||||
'feature.quick_assistant.click_tray_to_show': false,
|
||||
'feature.quick_assistant.enabled': false,
|
||||
'feature.quick_assistant.read_clipboard_at_startup': true,
|
||||
@ -591,13 +602,15 @@ export const DefaultPreferences: PreferencesType = {
|
||||
'shortcut.topic.new': { editable: true, enabled: true, key: ['CommandOrControl', 'N'], system: false },
|
||||
'topic.naming.enabled': true,
|
||||
'topic.naming.prompt': '',
|
||||
'topic.pin_to_top': false,
|
||||
'topic.position': 'left',
|
||||
'topic.show_time': false,
|
||||
'ui.assistant_icon_type': 'emoji',
|
||||
'ui.click_assistant_to_show_topic': true,
|
||||
'topic.tab.pin_to_top': false,
|
||||
'topic.tab.show': true,
|
||||
'topic.tab.show_time': false,
|
||||
'ui.custom_css': '',
|
||||
'ui.navbar.position': 'top'
|
||||
'ui.navbar.position': 'top',
|
||||
'ui.theme_mode': ThemeMode.system,
|
||||
'ui.theme_user.color_primary': '#00b96b',
|
||||
'ui.window_style': 'opaque'
|
||||
}
|
||||
}
|
||||
|
||||
@ -605,8 +618,8 @@ export const DefaultPreferences: PreferencesType = {
|
||||
|
||||
/**
|
||||
* 生成统计:
|
||||
* - 总配置项: 173
|
||||
* - 总配置项: 177
|
||||
* - electronStore项: 1
|
||||
* - redux项: 172
|
||||
* - redux项: 176
|
||||
* - localStorage项: 0
|
||||
*/
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Auto-generated preference mappings from classification.json
|
||||
* Generated at: 2025-09-02T05:21:08.374Z
|
||||
* Generated at: 2025-09-02T06:27:50.213Z
|
||||
*
|
||||
* This file contains pure mapping relationships without default values.
|
||||
* Default values are managed in packages/shared/data/preferences.ts
|
||||
@ -72,7 +72,7 @@ export const REDUX_STORE_MAPPINGS = {
|
||||
},
|
||||
{
|
||||
originalKey: 'theme',
|
||||
targetKey: 'app.theme.mode'
|
||||
targetKey: 'ui.theme_mode'
|
||||
},
|
||||
{
|
||||
originalKey: 'tray',
|
||||
@ -82,6 +82,18 @@ export const REDUX_STORE_MAPPINGS = {
|
||||
originalKey: 'trayOnClose',
|
||||
targetKey: 'app.tray.on_close'
|
||||
},
|
||||
{
|
||||
originalKey: 'showAssistants',
|
||||
targetKey: 'assistant.tab.show'
|
||||
},
|
||||
{
|
||||
originalKey: 'showTopics',
|
||||
targetKey: 'topic.tab.show'
|
||||
},
|
||||
{
|
||||
originalKey: 'assistantsTabSortType',
|
||||
targetKey: 'assistant.tab.sort_type'
|
||||
},
|
||||
{
|
||||
originalKey: 'sendMessageShortcut',
|
||||
targetKey: 'chat.input.send_message_shortcut'
|
||||
@ -132,11 +144,11 @@ export const REDUX_STORE_MAPPINGS = {
|
||||
},
|
||||
{
|
||||
originalKey: 'userTheme.colorPrimary',
|
||||
targetKey: 'app.theme.user.color_primary'
|
||||
targetKey: 'ui.theme_user.color_primary'
|
||||
},
|
||||
{
|
||||
originalKey: 'windowStyle',
|
||||
targetKey: 'app.theme.window_style'
|
||||
targetKey: 'ui.window_style'
|
||||
},
|
||||
{
|
||||
originalKey: 'fontSize',
|
||||
@ -148,15 +160,15 @@ export const REDUX_STORE_MAPPINGS = {
|
||||
},
|
||||
{
|
||||
originalKey: 'showTopicTime',
|
||||
targetKey: 'topic.show_time'
|
||||
targetKey: 'topic.tab.show_time'
|
||||
},
|
||||
{
|
||||
originalKey: 'pinTopicsToTop',
|
||||
targetKey: 'topic.pin_to_top'
|
||||
targetKey: 'topic.tab.pin_to_top'
|
||||
},
|
||||
{
|
||||
originalKey: 'assistantIconType',
|
||||
targetKey: 'ui.assistant_icon_type'
|
||||
targetKey: 'assistant.icon_type'
|
||||
},
|
||||
{
|
||||
originalKey: 'pasteLongTextAsFile',
|
||||
@ -168,7 +180,7 @@ export const REDUX_STORE_MAPPINGS = {
|
||||
},
|
||||
{
|
||||
originalKey: 'clickAssistantToShowTopic',
|
||||
targetKey: 'ui.click_assistant_to_show_topic'
|
||||
targetKey: 'assistant.click_to_show_topic'
|
||||
},
|
||||
{
|
||||
originalKey: 'codeExecution.enabled',
|
||||
@ -732,9 +744,9 @@ export const REDUX_STORE_MAPPINGS = {
|
||||
/**
|
||||
* 映射统计:
|
||||
* - ElectronStore项: 1
|
||||
* - Redux Store项: 172
|
||||
* - Redux Store项: 175
|
||||
* - Redux分类: settings, selectionStore, nutstore, shortcuts
|
||||
* - 总配置项: 173
|
||||
* - 总配置项: 176
|
||||
*
|
||||
* 使用说明:
|
||||
* 1. ElectronStore读取: configManager.get(mapping.originalKey)
|
||||
|
||||
@ -8,18 +8,18 @@ import { titleBarOverlayDark, titleBarOverlayLight } from '../config'
|
||||
class ThemeService {
|
||||
private theme: ThemeMode = ThemeMode.system
|
||||
constructor() {
|
||||
this.theme = preferenceService.get('app.theme.mode')
|
||||
this.theme = preferenceService.get('ui.theme_mode')
|
||||
|
||||
if (this.theme === ThemeMode.dark || this.theme === ThemeMode.light || this.theme === ThemeMode.system) {
|
||||
nativeTheme.themeSource = this.theme
|
||||
} else {
|
||||
// 兼容旧版本
|
||||
preferenceService.set('app.theme.mode', ThemeMode.system)
|
||||
preferenceService.set('ui.theme_mode', ThemeMode.system)
|
||||
nativeTheme.themeSource = ThemeMode.system
|
||||
}
|
||||
nativeTheme.on('updated', this.themeUpdatadHandler.bind(this))
|
||||
|
||||
preferenceService.subscribeChange('app.theme.mode', (newTheme) => {
|
||||
preferenceService.subscribeChange('ui.theme_mode', (newTheme) => {
|
||||
this.theme = newTheme
|
||||
nativeTheme.themeSource = newTheme
|
||||
})
|
||||
|
||||
@ -17,7 +17,7 @@ import { useTheme } from './ThemeProvider'
|
||||
|
||||
const AntdProvider: FC<PropsWithChildren> = ({ children }) => {
|
||||
const [language] = usePreference('app.language')
|
||||
const [colorPrimary] = usePreference('app.theme.user.color_primary')
|
||||
const [colorPrimary] = usePreference('ui.theme_user.color_primary')
|
||||
const { theme: _theme } = useTheme()
|
||||
|
||||
return (
|
||||
|
||||
@ -27,7 +27,7 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
|
||||
// 用户设置的主题
|
||||
// const { theme: settedTheme, setTheme: setSettedTheme } = useSettings()
|
||||
|
||||
const [settedTheme, setSettedTheme] = usePreference('app.theme.mode')
|
||||
const [settedTheme, setSettedTheme] = usePreference('ui.theme_mode')
|
||||
|
||||
const [actualTheme, setActualTheme] = useState<ThemeMode>(
|
||||
window.matchMedia('(prefers-color-scheme: dark)').matches ? ThemeMode.dark : ThemeMode.light
|
||||
|
||||
@ -38,7 +38,7 @@ export function useAppInit() {
|
||||
enableDataCollection
|
||||
} = useSettings()
|
||||
const [language] = usePreference('app.language')
|
||||
const [windowStyle] = usePreference('app.theme.window_style')
|
||||
const [windowStyle] = usePreference('ui.window_style')
|
||||
const [customCss] = usePreference('ui.custom_css')
|
||||
|
||||
const { minappShow } = useRuntime()
|
||||
|
||||
@ -2,7 +2,7 @@ import { usePreference } from '@data/hooks/usePreference'
|
||||
import { isMac } from '@renderer/config/constant'
|
||||
|
||||
function useNavBackgroundColor() {
|
||||
const [windowStyle] = usePreference('app.theme.window_style')
|
||||
const [windowStyle] = usePreference('ui.window_style')
|
||||
|
||||
const macTransparentWindow = isMac && windowStyle === 'transparent'
|
||||
|
||||
|
||||
@ -1,54 +1,42 @@
|
||||
import { useAppDispatch, useAppSelector } from '@renderer/store'
|
||||
import {
|
||||
setAssistantsTabSortType,
|
||||
setShowAssistants,
|
||||
setShowTopics,
|
||||
setShowWorkspace,
|
||||
toggleShowAssistants,
|
||||
toggleShowTopics,
|
||||
toggleShowWorkspace
|
||||
} from '@renderer/store/settings'
|
||||
import { AssistantsSortType } from '@renderer/types'
|
||||
//FIXME 这个文件有必要存在吗? fullex@data refactor
|
||||
|
||||
import { usePreference } from '@data/hooks/usePreference'
|
||||
|
||||
export function useShowAssistants() {
|
||||
const showAssistants = useAppSelector((state) => state.settings.showAssistants)
|
||||
const dispatch = useAppDispatch()
|
||||
const [showAssistants, setShowAssistants] = usePreference('assistant.tab.show')
|
||||
|
||||
return {
|
||||
showAssistants,
|
||||
setShowAssistants: (show: boolean) => dispatch(setShowAssistants(show)),
|
||||
toggleShowAssistants: () => dispatch(toggleShowAssistants())
|
||||
setShowAssistants,
|
||||
toggleShowAssistants: () => setShowAssistants(!showAssistants)
|
||||
}
|
||||
}
|
||||
|
||||
export function useShowTopics() {
|
||||
const showTopics = useAppSelector((state) => state.settings.showTopics)
|
||||
const dispatch = useAppDispatch()
|
||||
const [showTopics, setShowTopics] = usePreference('topic.tab.show')
|
||||
|
||||
return {
|
||||
showTopics,
|
||||
setShowTopics: (show: boolean) => dispatch(setShowTopics(show)),
|
||||
toggleShowTopics: () => dispatch(toggleShowTopics())
|
||||
setShowTopics,
|
||||
toggleShowTopics: () => setShowTopics(!showTopics)
|
||||
}
|
||||
}
|
||||
|
||||
export function useAssistantsTabSortType() {
|
||||
const assistantsTabSortType = useAppSelector((state) => state.settings.assistantsTabSortType)
|
||||
const dispatch = useAppDispatch()
|
||||
const [assistantsTabSortType, setAssistantsTabSortType] = usePreference('assistant.tab.sort_type')
|
||||
|
||||
return {
|
||||
assistantsTabSortType,
|
||||
setAssistantsTabSortType: (sortType: AssistantsSortType) => dispatch(setAssistantsTabSortType(sortType))
|
||||
setAssistantsTabSortType
|
||||
}
|
||||
}
|
||||
|
||||
export function useShowWorkspace() {
|
||||
const showWorkspace = useAppSelector((state) => state.settings.showWorkspace)
|
||||
const dispatch = useAppDispatch()
|
||||
const [showWorkspace, setShowWorkspace] = usePreference('feature.notes.show_workspace')
|
||||
|
||||
return {
|
||||
showWorkspace,
|
||||
setShowWorkspace: (show: boolean) => dispatch(setShowWorkspace(show)),
|
||||
toggleShowWorkspace: () => dispatch(toggleShowWorkspace())
|
||||
setShowWorkspace,
|
||||
toggleShowWorkspace: () => setShowWorkspace(!showWorkspace)
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import { usePreference } from '@data/hooks/usePreference'
|
||||
import Color from 'color'
|
||||
|
||||
export default function useUserTheme() {
|
||||
const [colorPrimary, setColorPrimary] = usePreference('app.theme.user.color_primary')
|
||||
const [colorPrimary, setColorPrimary] = usePreference('ui.theme_user.color_primary')
|
||||
|
||||
const initUserTheme = (theme: { colorPrimary: string } = { colorPrimary }) => {
|
||||
const colorPrimary = Color(theme.colorPrimary)
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { usePreference } from '@data/hooks/usePreference'
|
||||
import { NavbarHeader } from '@renderer/components/app/Navbar'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import SearchPopup from '@renderer/components/Popups/SearchPopup'
|
||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||
import { modelGenerating } from '@renderer/hooks/useRuntime'
|
||||
import { useSettings } from '@renderer/hooks/useSettings'
|
||||
import { useShortcut } from '@renderer/hooks/useShortcuts'
|
||||
import { useShowAssistants, useShowTopics } from '@renderer/hooks/useStore'
|
||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
|
||||
@ -32,7 +32,10 @@ interface Props {
|
||||
const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveAssistant, activeTopic, setActiveTopic }) => {
|
||||
const { assistant } = useAssistant(activeAssistant.id)
|
||||
const { showAssistants, toggleShowAssistants } = useShowAssistants()
|
||||
const { topicPosition, narrowMode } = useSettings()
|
||||
|
||||
const [topicPosition] = usePreference('topic.position')
|
||||
const [narrowMode] = usePreference('chat.narrow_mode')
|
||||
|
||||
const { showTopics, toggleShowTopics } = useShowTopics()
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
|
||||
@ -5,7 +5,8 @@ import { useAgents } from '@renderer/hooks/useAgents'
|
||||
import { useAssistants } from '@renderer/hooks/useAssistant'
|
||||
import { useAssistantsTabSortType } from '@renderer/hooks/useStore'
|
||||
import { useTags } from '@renderer/hooks/useTags'
|
||||
import { Assistant, AssistantsSortType } from '@renderer/types'
|
||||
import { Assistant } from '@renderer/types'
|
||||
import type { AssistantTabSortType } from '@shared/data/preferenceTypes'
|
||||
import { Tooltip, Typography } from 'antd'
|
||||
import { Plus } from 'lucide-react'
|
||||
import { FC, useCallback, useMemo, useRef, useState } from 'react'
|
||||
@ -47,7 +48,7 @@ const Assistants: FC<AssistantsTabProps> = ({
|
||||
)
|
||||
|
||||
const handleSortByChange = useCallback(
|
||||
(sortType: AssistantsSortType) => {
|
||||
(sortType: AssistantTabSortType) => {
|
||||
setAssistantsTabSortType(sortType)
|
||||
},
|
||||
[setAssistantsTabSortType]
|
||||
|
||||
@ -8,9 +8,10 @@ import { useTags } from '@renderer/hooks/useTags'
|
||||
import AssistantSettingsPopup from '@renderer/pages/settings/AssistantSettings'
|
||||
import { getDefaultModel } from '@renderer/services/AssistantService'
|
||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
|
||||
import { Assistant, AssistantsSortType } from '@renderer/types'
|
||||
import { Assistant } from '@renderer/types'
|
||||
import { getLeadingEmoji, uuid } from '@renderer/utils'
|
||||
import { hasTopicPendingRequests } from '@renderer/utils/queue'
|
||||
import type { AssistantTabSortType } from '@shared/data/preferenceTypes'
|
||||
import { Dropdown, MenuProps } from 'antd'
|
||||
import { omit } from 'lodash'
|
||||
import {
|
||||
@ -36,14 +37,14 @@ import AssistantTagsPopup from './AssistantTagsPopup'
|
||||
interface AssistantItemProps {
|
||||
assistant: Assistant
|
||||
isActive: boolean
|
||||
sortBy: AssistantsSortType
|
||||
sortBy: AssistantTabSortType
|
||||
onSwitch: (assistant: Assistant) => void
|
||||
onDelete: (assistant: Assistant) => void
|
||||
onCreateDefaultAssistant: () => void
|
||||
addAgent: (agent: any) => void
|
||||
copyAssistant: (assistant: Assistant) => void
|
||||
onTagClick?: (tag: string) => void
|
||||
handleSortByChange?: (sortType: AssistantsSortType) => void
|
||||
handleSortByChange?: (sortType: AssistantTabSortType) => void
|
||||
}
|
||||
|
||||
const AssistantItem: FC<AssistantItemProps> = ({
|
||||
|
||||
@ -68,7 +68,7 @@ const DisplaySettings: FC = () => {
|
||||
sidebarIcons,
|
||||
assistantIconType
|
||||
} = useSettings()
|
||||
const [windowStyle, setWindowStyle] = usePreference('app.theme.window_style')
|
||||
const [windowStyle, setWindowStyle] = usePreference('ui.window_style')
|
||||
const [customCss, setCustomCss] = usePreference('ui.custom_css')
|
||||
|
||||
const { navbarPosition, setNavbarPosition } = useNavbarPosition()
|
||||
|
||||
@ -3,7 +3,6 @@ import { isMac } from '@renderer/config/constant'
|
||||
import { DEFAULT_SIDEBAR_ICONS } from '@renderer/config/sidebar'
|
||||
import {
|
||||
ApiServerConfig,
|
||||
AssistantsSortType,
|
||||
CodeStyleVarious,
|
||||
MathEngine,
|
||||
OpenAIServiceTier,
|
||||
@ -17,6 +16,7 @@ import { uuid } from '@renderer/utils'
|
||||
import { UpgradeChannel } from '@shared/config/constant'
|
||||
import { TRANSLATE_PROMPT } from '@shared/config/prompts'
|
||||
import type { SendMessageShortcut } from '@shared/data/preferenceTypes'
|
||||
import type { AssistantTabSortType } from '@shared/data/preferenceTypes'
|
||||
import { LanguageVarious, ThemeMode } from '@shared/data/preferenceTypes'
|
||||
import { OpenAIVerbosity } from '@types'
|
||||
|
||||
@ -38,7 +38,7 @@ export type UserTheme = {
|
||||
export interface SettingsState {
|
||||
showAssistants: boolean
|
||||
showTopics: boolean
|
||||
assistantsTabSortType: AssistantsSortType
|
||||
assistantsTabSortType: AssistantTabSortType
|
||||
sendMessageShortcut: SendMessageShortcut
|
||||
language: LanguageVarious
|
||||
targetLanguage: TranslateLanguageCode
|
||||
@ -432,7 +432,7 @@ const settingsSlice = createSlice({
|
||||
toggleShowTopics: (state) => {
|
||||
state.showTopics = !state.showTopics
|
||||
},
|
||||
setAssistantsTabSortType: (state, action: PayloadAction<AssistantsSortType>) => {
|
||||
setAssistantsTabSortType: (state, action: PayloadAction<AssistantTabSortType>) => {
|
||||
state.assistantsTabSortType = action.payload
|
||||
},
|
||||
setSendMessageShortcut: (state, action: PayloadAction<SendMessageShortcut>) => {
|
||||
@ -861,10 +861,10 @@ const settingsSlice = createSlice({
|
||||
export const {
|
||||
setShowModelNameInMarkdown,
|
||||
setShowModelProviderInMarkdown,
|
||||
setShowAssistants,
|
||||
toggleShowAssistants,
|
||||
setShowTopics,
|
||||
toggleShowTopics,
|
||||
// setShowAssistants,
|
||||
// toggleShowAssistants,
|
||||
// setShowTopics,
|
||||
// toggleShowTopics,
|
||||
setAssistantsTabSortType,
|
||||
setSendMessageShortcut,
|
||||
setLanguage,
|
||||
|
||||
@ -53,7 +53,7 @@ export const isTranslateAssistant = (assistant: Assistant): assistant is Transla
|
||||
return (assistant.model && assistant.targetLanguage && typeof assistant.content === 'string') !== undefined
|
||||
}
|
||||
|
||||
export type AssistantsSortType = 'tags' | 'list'
|
||||
// export type AssistantsSortType = 'tags' | 'list'
|
||||
|
||||
export type AssistantMessage = {
|
||||
role: 'user' | 'assistant'
|
||||
|
||||
@ -49,7 +49,7 @@ const TestApp: React.FC = () => {
|
||||
const windowNumber = getWindowNumber()
|
||||
|
||||
// Add theme preference monitoring for UI changes
|
||||
const [theme, setTheme] = usePreference('app.theme.mode')
|
||||
const [theme, setTheme] = usePreference('ui.theme_mode')
|
||||
const [language] = usePreference('app.language')
|
||||
const [zoomFactor] = usePreference('app.zoom_factor')
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ const { Option } = Select
|
||||
* Tests single preference management with React hooks
|
||||
*/
|
||||
const PreferenceBasicTests: React.FC = () => {
|
||||
const [selectedKey, setSelectedKey] = useState<PreferenceKeyType>('app.theme.mode')
|
||||
const [selectedKey, setSelectedKey] = useState<PreferenceKeyType>('ui.theme_mode')
|
||||
|
||||
// Use the hook with the selected key
|
||||
const [value, setValue] = usePreference(selectedKey)
|
||||
@ -20,7 +20,7 @@ const PreferenceBasicTests: React.FC = () => {
|
||||
const [inputValue, setInputValue] = useState<string>('')
|
||||
|
||||
// Add theme monitoring for visual changes
|
||||
const [currentTheme] = usePreference('app.theme.mode')
|
||||
const [currentTheme] = usePreference('ui.theme_mode')
|
||||
const isDarkTheme = currentTheme === ThemeMode.dark
|
||||
|
||||
const handleSetValue = async () => {
|
||||
@ -51,7 +51,7 @@ const PreferenceBasicTests: React.FC = () => {
|
||||
}
|
||||
|
||||
const testCases = [
|
||||
{ key: 'app.theme.mode', label: 'App Theme Mode', sampleValue: 'ThemeMode.dark', type: 'enum' },
|
||||
{ key: 'ui.theme_mode', label: 'App Theme Mode', sampleValue: 'ThemeMode.dark', type: 'enum' },
|
||||
{ key: 'app.language', label: 'App Language', sampleValue: 'zh-CN', type: 'enum' },
|
||||
{ key: 'app.spell_check.enabled', label: 'Spell Check', sampleValue: 'true', type: 'boolean' },
|
||||
{ key: 'app.zoom_factor', label: 'Zoom Factor', sampleValue: '1.2', type: 'number', min: 0.5, max: 2.0, step: 0.1 },
|
||||
@ -132,7 +132,7 @@ const PreferenceBasicTests: React.FC = () => {
|
||||
<Text strong>快速操作:</Text>
|
||||
<Space wrap style={{ marginTop: 8 }}>
|
||||
{/* Theme Toggle with Visual Feedback */}
|
||||
{selectedKey === 'app.theme.mode' && (
|
||||
{selectedKey === 'ui.theme_mode' && (
|
||||
<Button
|
||||
size="small"
|
||||
type={isDarkTheme ? 'default' : 'primary'}
|
||||
|
||||
@ -18,13 +18,13 @@ const PreferenceHookTests: React.FC = () => {
|
||||
const [subscriptionCount, setSubscriptionCount] = useState(0)
|
||||
|
||||
// Test multiple hooks with same key
|
||||
const [theme1] = usePreference('app.theme.mode')
|
||||
const [theme2] = usePreference('app.theme.mode')
|
||||
const [theme1] = usePreference('ui.theme_mode')
|
||||
const [theme2] = usePreference('ui.theme_mode')
|
||||
const [language] = usePreference('app.language')
|
||||
|
||||
// Manual preload implementation using useEffect
|
||||
React.useEffect(() => {
|
||||
const preloadKeys: PreferenceKeyType[] = ['app.theme.mode', 'app.language', 'app.zoom_factor']
|
||||
const preloadKeys: PreferenceKeyType[] = ['ui.theme_mode', 'app.language', 'app.zoom_factor']
|
||||
preferenceService.preload(preloadKeys).catch((error) => {
|
||||
logger.error('Failed to preload preferences:', error as Error)
|
||||
})
|
||||
@ -36,7 +36,7 @@ const PreferenceHookTests: React.FC = () => {
|
||||
|
||||
const testSubscriptions = () => {
|
||||
// Test subscription behavior
|
||||
const unsubscribe = preferenceService.subscribeChange('app.theme.mode')(() => {
|
||||
const unsubscribe = preferenceService.subscribeChange('ui.theme_mode')(() => {
|
||||
setSubscriptionCount((prev) => prev + 1)
|
||||
})
|
||||
|
||||
@ -51,7 +51,7 @@ const PreferenceHookTests: React.FC = () => {
|
||||
|
||||
const testCacheWarming = async () => {
|
||||
try {
|
||||
const keys: PreferenceKeyType[] = ['app.theme.mode', 'app.language', 'app.zoom_factor', 'app.spell_check.enabled']
|
||||
const keys: PreferenceKeyType[] = ['ui.theme_mode', 'app.language', 'app.zoom_factor', 'app.spell_check.enabled']
|
||||
await preferenceService.preload(keys)
|
||||
|
||||
const cachedStates = keys.map((key) => ({
|
||||
@ -69,7 +69,7 @@ const PreferenceHookTests: React.FC = () => {
|
||||
|
||||
const testBatchOperations = async () => {
|
||||
try {
|
||||
const keys: PreferenceKeyType[] = ['app.theme.mode', 'app.language']
|
||||
const keys: PreferenceKeyType[] = ['ui.theme_mode', 'app.language']
|
||||
const result = await preferenceService.getMultiple(keys)
|
||||
|
||||
message.success(`批量获取成功: ${Object.keys(result).length} 项`)
|
||||
@ -77,7 +77,7 @@ const PreferenceHookTests: React.FC = () => {
|
||||
|
||||
// Test batch set
|
||||
await preferenceService.setMultiple({
|
||||
'app.theme.mode': theme1 === ThemeMode.dark ? ThemeMode.light : ThemeMode.dark,
|
||||
'ui.theme_mode': theme1 === ThemeMode.dark ? ThemeMode.light : ThemeMode.dark,
|
||||
'app.language': language === 'zh-CN' ? 'en-US' : 'zh-CN'
|
||||
})
|
||||
|
||||
@ -94,7 +94,7 @@ const PreferenceHookTests: React.FC = () => {
|
||||
try {
|
||||
// Test rapid reads
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
preferenceService.getCachedValue('app.theme.mode')
|
||||
preferenceService.getCachedValue('ui.theme_mode')
|
||||
}
|
||||
|
||||
const readTime = performance.now() - start
|
||||
@ -103,7 +103,7 @@ const PreferenceHookTests: React.FC = () => {
|
||||
const writeStart = performance.now()
|
||||
for (let i = 0; i < 10; i++) {
|
||||
await preferenceService.set(
|
||||
'app.theme.mode',
|
||||
'ui.theme_mode',
|
||||
i % 3 === 0 ? ThemeMode.light : i % 3 === 1 ? ThemeMode.dark : ThemeMode.system
|
||||
)
|
||||
}
|
||||
@ -158,7 +158,7 @@ const PreferenceHookTests: React.FC = () => {
|
||||
<Text>
|
||||
Service实例: <Text code>{preferenceService ? '已连接' : '未连接'}</Text>
|
||||
</Text>
|
||||
<Text>预加载Keys: app.theme.mode, app.language, app.zoom_factor</Text>
|
||||
<Text>预加载Keys: ui.theme_mode, app.language, app.zoom_factor</Text>
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>
|
||||
usePreferenceService() 返回的是同一个单例实例
|
||||
</Text>
|
||||
@ -169,7 +169,7 @@ const PreferenceHookTests: React.FC = () => {
|
||||
<Card size="small" title="Hook 行为测试">
|
||||
<Space direction="vertical" size="small" style={{ width: '100%' }}>
|
||||
<Text strong>实时同步测试:</Text>
|
||||
<Text type="secondary">1. 在其他测试组件中修改 app.theme.mode 或 app.language</Text>
|
||||
<Text type="secondary">1. 在其他测试组件中修改 ui.theme_mode 或 app.language</Text>
|
||||
<Text type="secondary">2. 观察此组件中的值是否实时更新</Text>
|
||||
<Text type="secondary">3. 检查订阅触发次数是否增加</Text>
|
||||
</Space>
|
||||
|
||||
@ -17,12 +17,12 @@ const PreferenceMultipleTests: React.FC = () => {
|
||||
|
||||
const scenarios = {
|
||||
basic: {
|
||||
theme: 'app.theme.mode',
|
||||
theme: 'ui.theme_mode',
|
||||
language: 'app.language',
|
||||
zoom: 'app.zoom_factor'
|
||||
},
|
||||
ui: {
|
||||
theme: 'app.theme.mode',
|
||||
theme: 'ui.theme_mode',
|
||||
zoom: 'app.zoom_factor',
|
||||
spell: 'app.spell_check.enabled'
|
||||
},
|
||||
@ -37,7 +37,7 @@ const PreferenceMultipleTests: React.FC = () => {
|
||||
opacity: 'feature.selection.action_window_opacity'
|
||||
},
|
||||
custom: {
|
||||
key1: 'app.theme.mode',
|
||||
key1: 'ui.theme_mode',
|
||||
key2: 'app.language',
|
||||
key3: 'app.zoom_factor',
|
||||
key4: 'app.spell_check.enabled'
|
||||
@ -79,7 +79,7 @@ const PreferenceMultipleTests: React.FC = () => {
|
||||
const prefKey = currentKeys[localKey as keyof typeof currentKeys]
|
||||
|
||||
switch (prefKey) {
|
||||
case 'app.theme.mode':
|
||||
case 'ui.theme_mode':
|
||||
sampleUpdates[localKey] = values[localKey] === 'ThemeMode.dark' ? 'ThemeMode.light' : 'ThemeMode.dark'
|
||||
break
|
||||
case 'app.language':
|
||||
@ -150,7 +150,7 @@ const PreferenceMultipleTests: React.FC = () => {
|
||||
width: 150,
|
||||
render: (_, record) => (
|
||||
<Space size="small">
|
||||
{record.prefKey === 'app.theme.mode' && (
|
||||
{record.prefKey === 'ui.theme_mode' && (
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() =>
|
||||
@ -339,7 +339,7 @@ const PreferenceMultipleTests: React.FC = () => {
|
||||
onClick={async () => {
|
||||
const toggles: Record<string, any> = {}
|
||||
Object.entries(currentKeys).forEach(([localKey, prefKey]) => {
|
||||
if (prefKey === 'app.theme.mode') {
|
||||
if (prefKey === 'ui.theme_mode') {
|
||||
toggles[localKey] = values[localKey] === 'ThemeMode.dark' ? 'ThemeMode.light' : 'ThemeMode.dark'
|
||||
} else if (prefKey === 'app.spell_check.enabled') {
|
||||
toggles[localKey] = !values[localKey]
|
||||
|
||||
@ -12,13 +12,13 @@ const { Text } = Typography
|
||||
* Tests the service layer functionality without React hooks
|
||||
*/
|
||||
const PreferenceServiceTests: React.FC = () => {
|
||||
const [testKey, setTestKey] = useState<string>('app.theme.mode')
|
||||
const [testKey, setTestKey] = useState<string>('ui.theme_mode')
|
||||
const [testValue, setTestValue] = useState<string>(ThemeMode.dark)
|
||||
const [getResult, setGetResult] = useState<any>(null)
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
// Theme monitoring for visual changes
|
||||
const [currentTheme] = usePreference('app.theme.mode')
|
||||
const [currentTheme] = usePreference('ui.theme_mode')
|
||||
const isDarkTheme = currentTheme === ThemeMode.dark
|
||||
|
||||
const handleGet = async () => {
|
||||
@ -173,10 +173,10 @@ const PreferenceServiceTests: React.FC = () => {
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() => {
|
||||
setTestKey('app.theme.mode')
|
||||
setTestKey('ui.theme_mode')
|
||||
setTestValue(ThemeMode.dark)
|
||||
}}>
|
||||
Test: app.theme.mode
|
||||
Test: ui.theme_mode
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
|
||||
@ -40,7 +40,7 @@ const logger = loggerService.withContext('HomeWindow')
|
||||
const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => {
|
||||
const [readClipboardAtStartup] = usePreference('feature.quick_assistant.read_clipboard_at_startup')
|
||||
const [language] = usePreference('app.language')
|
||||
const [windowStyle] = usePreference('app.theme.window_style')
|
||||
const [windowStyle] = usePreference('ui.window_style')
|
||||
const { theme } = useTheme()
|
||||
const { t } = useTranslation()
|
||||
|
||||
|
||||
@ -22,8 +22,8 @@ loggerService.initWindowSource('SelectionActionWindow')
|
||||
await preferenceService.preload([
|
||||
'app.language',
|
||||
'ui.custom_css',
|
||||
'app.theme.mode',
|
||||
'app.theme.user.color_primary',
|
||||
'ui.theme_mode',
|
||||
'ui.theme_user.color_primary',
|
||||
'feature.selection.auto_close',
|
||||
'feature.selection.auto_pin',
|
||||
'feature.selection.action_window_opacity'
|
||||
|
||||
@ -12,8 +12,8 @@ loggerService.initWindowSource('SelectionToolbar')
|
||||
await preferenceService.preload([
|
||||
'app.language',
|
||||
'ui.custom_css',
|
||||
'app.theme.mode',
|
||||
'app.theme.user.color_primary',
|
||||
'ui.theme_mode',
|
||||
'ui.theme_user.color_primary',
|
||||
'feature.selection.compact',
|
||||
'feature.selection.action_items'
|
||||
])
|
||||
|
||||
Loading…
Reference in New Issue
Block a user