mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-07 22:10:21 +08:00
refactor: update preference handling and remove unused settings
- Commented out the App_SetDisableHardwareAcceleration IPC channel and related code for hardware acceleration settings. - Updated preferences to utilize the new WindowStyle type for window style settings. - Refactored components to use the usePreference hook instead of useSettings for better preference management. - Cleaned up unused code and comments related to hardware acceleration and window style for improved maintainability.
This commit is contained in:
parent
7b2570974e
commit
2ce4fabc7d
@ -42,7 +42,7 @@ export enum IpcChannel {
|
|||||||
App_MacRequestProcessTrust = 'app:mac-request-process-trust',
|
App_MacRequestProcessTrust = 'app:mac-request-process-trust',
|
||||||
|
|
||||||
App_QuoteToMain = 'app:quote-to-main',
|
App_QuoteToMain = 'app:quote-to-main',
|
||||||
App_SetDisableHardwareAcceleration = 'app:set-disable-hardware-acceleration',
|
// App_SetDisableHardwareAcceleration = 'app:set-disable-hardware-acceleration',
|
||||||
|
|
||||||
Notification_Send = 'notification:send',
|
Notification_Send = 'notification:send',
|
||||||
Notification_OnClick = 'notification:on-click',
|
Notification_OnClick = 'notification:on-click',
|
||||||
|
|||||||
@ -36,3 +36,5 @@ export enum ThemeMode {
|
|||||||
|
|
||||||
/** 有限的UI语言 */
|
/** 有限的UI语言 */
|
||||||
export type LanguageVarious = 'zh-CN' | 'zh-TW' | 'el-GR' | 'en-US' | 'es-ES' | 'fr-FR' | 'ja-JP' | 'pt-PT' | 'ru-RU'
|
export type LanguageVarious = 'zh-CN' | 'zh-TW' | 'el-GR' | 'en-US' | 'es-ES' | 'fr-FR' | 'ja-JP' | 'pt-PT' | 'ru-RU'
|
||||||
|
|
||||||
|
export type WindowStyle = 'transparent' | 'opaque'
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Auto-generated preferences configuration
|
* Auto-generated preferences configuration
|
||||||
* Generated at: 2025-09-01T16:31:20.203Z
|
* Generated at: 2025-09-02T02:45:09.198Z
|
||||||
*
|
*
|
||||||
* This file is automatically generated from classification.json
|
* This file is automatically generated from classification.json
|
||||||
* To update this file, modify classification.json and run:
|
* To update this file, modify classification.json and run:
|
||||||
@ -10,7 +10,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { TRANSLATE_PROMPT } from '@shared/config/prompts'
|
import { TRANSLATE_PROMPT } from '@shared/config/prompts'
|
||||||
import type { SelectionActionItem, SelectionFilterMode, SelectionTriggerMode } from '@shared/data/preferenceTypes'
|
import type {
|
||||||
|
SelectionActionItem,
|
||||||
|
SelectionFilterMode,
|
||||||
|
SelectionTriggerMode,
|
||||||
|
WindowStyle
|
||||||
|
} from '@shared/data/preferenceTypes'
|
||||||
import { LanguageVarious, ThemeMode } from '@shared/data/preferenceTypes'
|
import { LanguageVarious, ThemeMode } from '@shared/data/preferenceTypes'
|
||||||
|
|
||||||
/* eslint @typescript-eslint/member-ordering: ["error", {
|
/* eslint @typescript-eslint/member-ordering: ["error", {
|
||||||
@ -57,7 +62,7 @@ export interface PreferencesType {
|
|||||||
// redux/settings/userTheme.colorPrimary
|
// redux/settings/userTheme.colorPrimary
|
||||||
'app.theme.user.color_primary': string
|
'app.theme.user.color_primary': string
|
||||||
// redux/settings/windowStyle
|
// redux/settings/windowStyle
|
||||||
'app.theme.window_style': string
|
'app.theme.window_style': WindowStyle
|
||||||
// redux/settings/tray
|
// redux/settings/tray
|
||||||
'app.tray.enabled': boolean
|
'app.tray.enabled': boolean
|
||||||
// redux/settings/trayOnClose
|
// redux/settings/trayOnClose
|
||||||
@ -74,9 +79,11 @@ export interface PreferencesType {
|
|||||||
'chat.code.collapsible': boolean
|
'chat.code.collapsible': boolean
|
||||||
// redux/settings/codeEditor.autocompletion
|
// redux/settings/codeEditor.autocompletion
|
||||||
'chat.code.editor.autocompletion': boolean
|
'chat.code.editor.autocompletion': boolean
|
||||||
|
// redux/settings/codeEditor.enabled
|
||||||
|
'chat.code.editor.enabled': boolean
|
||||||
// redux/settings/codeEditor.foldGutter
|
// redux/settings/codeEditor.foldGutter
|
||||||
'chat.code.editor.fold_gutter': boolean
|
'chat.code.editor.fold_gutter': boolean
|
||||||
// redux/settings/codeEditor.enabled
|
// redux/settings/codeEditor.highlightActiveLine
|
||||||
'chat.code.editor.highlight_active_line': boolean
|
'chat.code.editor.highlight_active_line': boolean
|
||||||
// redux/settings/codeEditor.keymap
|
// redux/settings/codeEditor.keymap
|
||||||
'chat.code.editor.keymap': boolean
|
'chat.code.editor.keymap': boolean
|
||||||
@ -397,6 +404,7 @@ export const DefaultPreferences: PreferencesType = {
|
|||||||
'app.zoom_factor': 1,
|
'app.zoom_factor': 1,
|
||||||
'chat.code.collapsible': false,
|
'chat.code.collapsible': false,
|
||||||
'chat.code.editor.autocompletion': true,
|
'chat.code.editor.autocompletion': true,
|
||||||
|
'chat.code.editor.enabled': false,
|
||||||
'chat.code.editor.fold_gutter': false,
|
'chat.code.editor.fold_gutter': false,
|
||||||
'chat.code.editor.highlight_active_line': false,
|
'chat.code.editor.highlight_active_line': false,
|
||||||
'chat.code.editor.keymap': false,
|
'chat.code.editor.keymap': false,
|
||||||
@ -596,8 +604,8 @@ export const DefaultPreferences: PreferencesType = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成统计:
|
* 生成统计:
|
||||||
* - 总配置项: 172
|
* - 总配置项: 173
|
||||||
* - electronStore项: 1
|
* - electronStore项: 1
|
||||||
* - redux项: 171
|
* - redux项: 172
|
||||||
* - localStorage项: 0
|
* - localStorage项: 0
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -356,7 +356,7 @@ export class PreferenceService {
|
|||||||
const windowKeys = this.subscriptions.get(windowId)!
|
const windowKeys = this.subscriptions.get(windowId)!
|
||||||
keys.forEach((key) => windowKeys.add(key))
|
keys.forEach((key) => windowKeys.add(key))
|
||||||
|
|
||||||
logger.debug(`Window ${windowId} subscribed to ${keys.length} preference keys`)
|
logger.verbose(`Window ${windowId} subscribed to ${keys.length} preference keys: ${keys.join(', ')}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -364,7 +364,9 @@ export class PreferenceService {
|
|||||||
*/
|
*/
|
||||||
public unsubscribeForWindow(windowId: number): void {
|
public unsubscribeForWindow(windowId: number): void {
|
||||||
this.subscriptions.delete(windowId)
|
this.subscriptions.delete(windowId)
|
||||||
logger.debug(`Window ${windowId} unsubscribed from preference changes`)
|
logger.verbose(
|
||||||
|
`Window ${windowId} unsubscribed from preference changes: ${Array.from(this.subscriptions.keys()).join(', ')}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -36,6 +36,8 @@ const logger = loggerService.withContext('MainEntry')
|
|||||||
/**
|
/**
|
||||||
* Disable hardware acceleration if setting is enabled
|
* Disable hardware acceleration if setting is enabled
|
||||||
*/
|
*/
|
||||||
|
//FIXME should not use configManager, use usePreference instead
|
||||||
|
//TODO 我们需要调整配置管理的加载位置,以保证其在 preferenceService 初始化之前被调用
|
||||||
const disableHardwareAcceleration = configManager.getDisableHardwareAcceleration()
|
const disableHardwareAcceleration = configManager.getDisableHardwareAcceleration()
|
||||||
if (disableHardwareAcceleration) {
|
if (disableHardwareAcceleration) {
|
||||||
app.disableHardwareAcceleration()
|
app.disableHardwareAcceleration()
|
||||||
|
|||||||
@ -716,9 +716,9 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
|
|||||||
|
|
||||||
ipcMain.handle(IpcChannel.App_QuoteToMain, (_, text: string) => windowService.quoteToMainWindow(text))
|
ipcMain.handle(IpcChannel.App_QuoteToMain, (_, text: string) => windowService.quoteToMainWindow(text))
|
||||||
|
|
||||||
ipcMain.handle(IpcChannel.App_SetDisableHardwareAcceleration, (_, isDisable: boolean) => {
|
// ipcMain.handle(IpcChannel.App_SetDisableHardwareAcceleration, (_, isDisable: boolean) => {
|
||||||
configManager.setDisableHardwareAcceleration(isDisable)
|
// configManager.setDisableHardwareAcceleration(isDisable)
|
||||||
})
|
// })
|
||||||
ipcMain.handle(IpcChannel.TRACE_SAVE_DATA, (_, topicId: string) => saveSpans(topicId))
|
ipcMain.handle(IpcChannel.TRACE_SAVE_DATA, (_, topicId: string) => saveSpans(topicId))
|
||||||
ipcMain.handle(IpcChannel.TRACE_GET_DATA, (_, topicId: string, traceId: string, modelName?: string) =>
|
ipcMain.handle(IpcChannel.TRACE_GET_DATA, (_, topicId: string, traceId: string, modelName?: string) =>
|
||||||
getSpans(topicId, traceId, modelName)
|
getSpans(topicId, traceId, modelName)
|
||||||
|
|||||||
@ -222,9 +222,9 @@ export class ConfigManager {
|
|||||||
return this.get<boolean>(ConfigKeys.DisableHardwareAcceleration, false)
|
return this.get<boolean>(ConfigKeys.DisableHardwareAcceleration, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
setDisableHardwareAcceleration(value: boolean) {
|
// setDisableHardwareAcceleration(value: boolean) {
|
||||||
this.set(ConfigKeys.DisableHardwareAcceleration, value)
|
// this.set(ConfigKeys.DisableHardwareAcceleration, value)
|
||||||
}
|
// }
|
||||||
|
|
||||||
setAndNotify(key: string, value: unknown) {
|
setAndNotify(key: string, value: unknown) {
|
||||||
this.set(key, value, true)
|
this.set(key, value, true)
|
||||||
|
|||||||
@ -470,11 +470,11 @@ export class SelectionService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
/** uncomment to open dev tools in dev mode */
|
/** uncomment to open dev tools in dev mode */
|
||||||
if (isDev) {
|
// if (isDev) {
|
||||||
this.toolbarWindow.once('ready-to-show', () => {
|
// this.toolbarWindow.once('ready-to-show', () => {
|
||||||
this.toolbarWindow!.webContents.openDevTools({ mode: 'detach' })
|
// this.toolbarWindow!.webContents.openDevTools({ mode: 'detach' })
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (readyCallback) {
|
if (readyCallback) {
|
||||||
this.toolbarWindow.once('ready-to-show', readyCallback)
|
this.toolbarWindow.once('ready-to-show', readyCallback)
|
||||||
|
|||||||
@ -47,7 +47,7 @@ const api = {
|
|||||||
ipcRenderer.invoke(IpcChannel.App_Proxy, proxy, bypassRules),
|
ipcRenderer.invoke(IpcChannel.App_Proxy, proxy, bypassRules),
|
||||||
checkForUpdate: () => ipcRenderer.invoke(IpcChannel.App_CheckForUpdate),
|
checkForUpdate: () => ipcRenderer.invoke(IpcChannel.App_CheckForUpdate),
|
||||||
showUpdateDialog: () => ipcRenderer.invoke(IpcChannel.App_ShowUpdateDialog),
|
showUpdateDialog: () => ipcRenderer.invoke(IpcChannel.App_ShowUpdateDialog),
|
||||||
setLanguage: (lang: string) => ipcRenderer.invoke(IpcChannel.App_SetLanguage, lang),
|
// setLanguage: (lang: string) => ipcRenderer.invoke(IpcChannel.App_SetLanguage, lang),
|
||||||
setEnableSpellCheck: (isEnable: boolean) => ipcRenderer.invoke(IpcChannel.App_SetEnableSpellCheck, isEnable),
|
setEnableSpellCheck: (isEnable: boolean) => ipcRenderer.invoke(IpcChannel.App_SetEnableSpellCheck, isEnable),
|
||||||
setSpellCheckLanguages: (languages: string[]) => ipcRenderer.invoke(IpcChannel.App_SetSpellCheckLanguages, languages),
|
setSpellCheckLanguages: (languages: string[]) => ipcRenderer.invoke(IpcChannel.App_SetSpellCheckLanguages, languages),
|
||||||
setLaunchOnBoot: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetLaunchOnBoot, isActive),
|
setLaunchOnBoot: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetLaunchOnBoot, isActive),
|
||||||
@ -396,8 +396,8 @@ const api = {
|
|||||||
pinActionWindow: (isPinned: boolean) => ipcRenderer.invoke(IpcChannel.Selection_ActionWindowPin, isPinned)
|
pinActionWindow: (isPinned: boolean) => ipcRenderer.invoke(IpcChannel.Selection_ActionWindowPin, isPinned)
|
||||||
},
|
},
|
||||||
quoteToMainWindow: (text: string) => ipcRenderer.invoke(IpcChannel.App_QuoteToMain, text),
|
quoteToMainWindow: (text: string) => ipcRenderer.invoke(IpcChannel.App_QuoteToMain, text),
|
||||||
setDisableHardwareAcceleration: (isDisable: boolean) =>
|
// setDisableHardwareAcceleration: (isDisable: boolean) =>
|
||||||
ipcRenderer.invoke(IpcChannel.App_SetDisableHardwareAcceleration, isDisable),
|
// ipcRenderer.invoke(IpcChannel.App_SetDisableHardwareAcceleration, isDisable),
|
||||||
trace: {
|
trace: {
|
||||||
saveData: (topicId: string) => ipcRenderer.invoke(IpcChannel.TRACE_SAVE_DATA, topicId),
|
saveData: (topicId: string) => ipcRenderer.invoke(IpcChannel.TRACE_SAVE_DATA, topicId),
|
||||||
getData: (topicId: string, traceId: string, modelName?: string) =>
|
getData: (topicId: string, traceId: string, modelName?: string) =>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
|
import { defaultLanguage } from '@shared/config/constant'
|
||||||
import { LanguageVarious } from '@shared/data/preferenceTypes'
|
import { LanguageVarious } from '@shared/data/preferenceTypes'
|
||||||
import { ConfigProvider, theme } from 'antd'
|
import { ConfigProvider, theme } from 'antd'
|
||||||
import elGR from 'antd/locale/el_GR'
|
import elGR from 'antd/locale/el_GR'
|
||||||
@ -15,15 +16,13 @@ import { FC, PropsWithChildren } from 'react'
|
|||||||
import { useTheme } from './ThemeProvider'
|
import { useTheme } from './ThemeProvider'
|
||||||
|
|
||||||
const AntdProvider: FC<PropsWithChildren> = ({ children }) => {
|
const AntdProvider: FC<PropsWithChildren> = ({ children }) => {
|
||||||
const {
|
const [language] = usePreference('app.language')
|
||||||
language,
|
const [colorPrimary] = usePreference('app.theme.user.color_primary')
|
||||||
userTheme: { colorPrimary }
|
|
||||||
} = useSettings()
|
|
||||||
const { theme: _theme } = useTheme()
|
const { theme: _theme } = useTheme()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigProvider
|
<ConfigProvider
|
||||||
locale={getAntdLocale(language)}
|
locale={getAntdLocale((language || navigator.language || defaultLanguage) as LanguageVarious)}
|
||||||
theme={{
|
theme={{
|
||||||
cssVar: true,
|
cssVar: true,
|
||||||
hashed: false,
|
hashed: false,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||||
import { useMermaid } from '@renderer/hooks/useMermaid'
|
import { useMermaid } from '@renderer/hooks/useMermaid'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
|
||||||
import { HighlightChunkResult, ShikiPreProperties, shikiStreamService } from '@renderer/services/ShikiStreamService'
|
import { HighlightChunkResult, ShikiPreProperties, shikiStreamService } from '@renderer/services/ShikiStreamService'
|
||||||
import { getHighlighter, getMarkdownIt, getShiki, loadLanguageIfNeeded, loadThemeIfNeeded } from '@renderer/utils/shiki'
|
import { getHighlighter, getMarkdownIt, getShiki, loadLanguageIfNeeded, loadThemeIfNeeded } from '@renderer/utils/shiki'
|
||||||
import { ThemeMode } from '@shared/data/preferenceTypes'
|
import { ThemeMode } from '@shared/data/preferenceTypes'
|
||||||
@ -8,7 +8,6 @@ import * as cmThemes from '@uiw/codemirror-themes-all'
|
|||||||
import type React from 'react'
|
import type React from 'react'
|
||||||
import { createContext, type PropsWithChildren, use, useCallback, useEffect, useMemo, useState } from 'react'
|
import { createContext, type PropsWithChildren, use, useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import type { BundledThemeInfo } from 'shiki/types'
|
import type { BundledThemeInfo } from 'shiki/types'
|
||||||
|
|
||||||
interface CodeStyleContextType {
|
interface CodeStyleContextType {
|
||||||
highlightCodeChunk: (trunk: string, language: string, callerId: string) => Promise<HighlightChunkResult>
|
highlightCodeChunk: (trunk: string, language: string, callerId: string) => Promise<HighlightChunkResult>
|
||||||
highlightStreamingCode: (code: string, language: string, callerId: string) => Promise<HighlightChunkResult>
|
highlightStreamingCode: (code: string, language: string, callerId: string) => Promise<HighlightChunkResult>
|
||||||
@ -38,24 +37,29 @@ const defaultCodeStyleContext: CodeStyleContextType = {
|
|||||||
const CodeStyleContext = createContext<CodeStyleContextType>(defaultCodeStyleContext)
|
const CodeStyleContext = createContext<CodeStyleContextType>(defaultCodeStyleContext)
|
||||||
|
|
||||||
export const CodeStyleProvider: React.FC<PropsWithChildren> = ({ children }) => {
|
export const CodeStyleProvider: React.FC<PropsWithChildren> = ({ children }) => {
|
||||||
const { codeEditor, codeViewer } = useSettings()
|
const [codeEditorEnabled] = usePreference('chat.code.editor.enabled')
|
||||||
|
const [codeEditorThemeLight] = usePreference('chat.code.editor.theme_light')
|
||||||
|
const [codeEditorThemeDark] = usePreference('chat.code.editor.theme_dark')
|
||||||
|
const [codeViewerThemeLight] = usePreference('chat.code.viewer.theme_light')
|
||||||
|
const [codeViewerThemeDark] = usePreference('chat.code.viewer.theme_dark')
|
||||||
|
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const [shikiThemesInfo, setShikiThemesInfo] = useState<BundledThemeInfo[]>([])
|
const [shikiThemesInfo, setShikiThemesInfo] = useState<BundledThemeInfo[]>([])
|
||||||
useMermaid()
|
useMermaid()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!codeEditor.enabled) {
|
if (!codeEditorEnabled) {
|
||||||
getShiki().then(({ bundledThemesInfo }) => {
|
getShiki().then(({ bundledThemesInfo }) => {
|
||||||
setShikiThemesInfo(bundledThemesInfo)
|
setShikiThemesInfo(bundledThemesInfo)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [codeEditor.enabled])
|
}, [codeEditorEnabled])
|
||||||
|
|
||||||
// 获取支持的主题名称列表
|
// 获取支持的主题名称列表
|
||||||
const themeNames = useMemo(() => {
|
const themeNames = useMemo(() => {
|
||||||
// CodeMirror 主题
|
// CodeMirror 主题
|
||||||
// 更保险的做法可能是硬编码主题列表
|
// 更保险的做法可能是硬编码主题列表
|
||||||
if (codeEditor.enabled) {
|
if (codeEditorEnabled) {
|
||||||
return ['auto', 'light', 'dark']
|
return ['auto', 'light', 'dark']
|
||||||
.concat(Object.keys(cmThemes))
|
.concat(Object.keys(cmThemes))
|
||||||
.filter((item) => typeof cmThemes[item as keyof typeof cmThemes] !== 'function')
|
.filter((item) => typeof cmThemes[item as keyof typeof cmThemes] !== 'function')
|
||||||
@ -64,17 +68,17 @@ export const CodeStyleProvider: React.FC<PropsWithChildren> = ({ children }) =>
|
|||||||
|
|
||||||
// Shiki 主题,取出所有 BundledThemeInfo 的 id 作为主题名
|
// Shiki 主题,取出所有 BundledThemeInfo 的 id 作为主题名
|
||||||
return ['auto', ...shikiThemesInfo.map((info) => info.id)]
|
return ['auto', ...shikiThemesInfo.map((info) => info.id)]
|
||||||
}, [codeEditor.enabled, shikiThemesInfo])
|
}, [codeEditorEnabled, shikiThemesInfo])
|
||||||
|
|
||||||
// 获取当前使用的 Shiki 主题名称(只用于代码预览)
|
// 获取当前使用的 Shiki 主题名称(只用于代码预览)
|
||||||
const activeShikiTheme = useMemo(() => {
|
const activeShikiTheme = useMemo(() => {
|
||||||
const field = theme === ThemeMode.light ? 'themeLight' : 'themeDark'
|
const codeStyle = theme === ThemeMode.light ? codeViewerThemeLight : codeViewerThemeDark
|
||||||
const codeStyle = codeViewer[field]
|
|
||||||
if (!codeStyle || codeStyle === 'auto' || !themeNames.includes(codeStyle)) {
|
if (!codeStyle || codeStyle === 'auto' || !themeNames.includes(codeStyle)) {
|
||||||
return theme === ThemeMode.light ? 'one-light' : 'material-theme-darker'
|
return theme === ThemeMode.light ? 'one-light' : 'material-theme-darker'
|
||||||
}
|
}
|
||||||
return codeStyle
|
return codeStyle
|
||||||
}, [theme, codeViewer, themeNames])
|
}, [theme, codeViewerThemeLight, codeViewerThemeDark, themeNames])
|
||||||
|
|
||||||
const isShikiThemeDark = useMemo(() => {
|
const isShikiThemeDark = useMemo(() => {
|
||||||
const themeInfo = shikiThemesInfo.find((info) => info.id === activeShikiTheme)
|
const themeInfo = shikiThemesInfo.find((info) => info.id === activeShikiTheme)
|
||||||
@ -83,13 +87,13 @@ export const CodeStyleProvider: React.FC<PropsWithChildren> = ({ children }) =>
|
|||||||
|
|
||||||
// 获取当前使用的 CodeMirror 主题对象(只用于编辑器)
|
// 获取当前使用的 CodeMirror 主题对象(只用于编辑器)
|
||||||
const activeCmTheme = useMemo(() => {
|
const activeCmTheme = useMemo(() => {
|
||||||
const field = theme === ThemeMode.light ? 'themeLight' : 'themeDark'
|
const codeStyle = theme === ThemeMode.light ? codeEditorThemeLight : codeEditorThemeDark
|
||||||
let themeName = codeEditor[field]
|
let themeName = codeStyle
|
||||||
if (!themeName || themeName === 'auto' || !themeNames.includes(themeName)) {
|
if (!themeName || themeName === 'auto' || !themeNames.includes(themeName)) {
|
||||||
themeName = theme === ThemeMode.light ? 'materialLight' : 'dark'
|
themeName = theme === ThemeMode.light ? 'materialLight' : 'dark'
|
||||||
}
|
}
|
||||||
return cmThemes[themeName as keyof typeof cmThemes] || themeName
|
return cmThemes[themeName as keyof typeof cmThemes] || themeName
|
||||||
}, [theme, codeEditor, themeNames])
|
}, [theme, codeEditorThemeLight, codeEditorThemeDark, themeNames])
|
||||||
|
|
||||||
// 自定义 shiki 语言别名
|
// 自定义 shiki 语言别名
|
||||||
const languageAliases = useMemo(() => {
|
const languageAliases = useMemo(() => {
|
||||||
|
|||||||
@ -357,7 +357,7 @@ export class PreferenceService {
|
|||||||
try {
|
try {
|
||||||
await window.api.preference.subscribe(keysToSubscribe)
|
await window.api.preference.subscribe(keysToSubscribe)
|
||||||
keysToSubscribe.forEach((key) => this.subscribedKeys.add(key))
|
keysToSubscribe.forEach((key) => this.subscribedKeys.add(key))
|
||||||
logger.debug(`Subscribed to preference keys: ${keysToSubscribe.join(', ')}`)
|
logger.verbose(`Subscribed to preference keys: ${keysToSubscribe.join(', ')}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Failed to subscribe to preference keys ${keysToSubscribe.join(', ')}:`, error as Error)
|
logger.error(`Failed to subscribe to preference keys ${keysToSubscribe.join(', ')}:`, error as Error)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import { isMac } from '@renderer/config/constant'
|
import { isMac } from '@renderer/config/constant'
|
||||||
import { isLocalAi } from '@renderer/config/env'
|
import { isLocalAi } from '@renderer/config/env'
|
||||||
@ -22,7 +23,6 @@ import useFullScreenNotice from './useFullScreenNotice'
|
|||||||
import { useRuntime } from './useRuntime'
|
import { useRuntime } from './useRuntime'
|
||||||
import { useSettings } from './useSettings'
|
import { useSettings } from './useSettings'
|
||||||
import useUpdateHandler from './useUpdateHandler'
|
import useUpdateHandler from './useUpdateHandler'
|
||||||
|
|
||||||
const logger = loggerService.withContext('useAppInit')
|
const logger = loggerService.withContext('useAppInit')
|
||||||
|
|
||||||
export function useAppInit() {
|
export function useAppInit() {
|
||||||
@ -31,12 +31,15 @@ export function useAppInit() {
|
|||||||
proxyUrl,
|
proxyUrl,
|
||||||
proxyBypassRules,
|
proxyBypassRules,
|
||||||
language,
|
language,
|
||||||
windowStyle,
|
// windowStyle,
|
||||||
autoCheckUpdate,
|
autoCheckUpdate,
|
||||||
proxyMode,
|
proxyMode,
|
||||||
customCss,
|
// customCss,
|
||||||
enableDataCollection
|
enableDataCollection
|
||||||
} = useSettings()
|
} = useSettings()
|
||||||
|
const [windowStyle] = usePreference('app.theme.window_style')
|
||||||
|
const [customCss] = usePreference('ui.custom_css')
|
||||||
|
|
||||||
const { minappShow } = useRuntime()
|
const { minappShow } = useRuntime()
|
||||||
const { setDefaultModel, setQuickModel, setTranslateModel } = useDefaultModel()
|
const { setDefaultModel, setQuickModel, setTranslateModel } = useDefaultModel()
|
||||||
const avatar = useLiveQuery(() => db.settings.get('image://avatar'))
|
const avatar = useLiveQuery(() => db.settings.get('image://avatar'))
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import { isMac } from '@renderer/config/constant'
|
import { isMac } from '@renderer/config/constant'
|
||||||
|
|
||||||
import { useSettings } from './useSettings'
|
|
||||||
|
|
||||||
function useNavBackgroundColor() {
|
function useNavBackgroundColor() {
|
||||||
const { windowStyle } = useSettings()
|
const [windowStyle] = usePreference('app.theme.window_style')
|
||||||
|
|
||||||
const macTransparentWindow = isMac && windowStyle === 'transparent'
|
const macTransparentWindow = isMac && windowStyle === 'transparent'
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import {
|
|||||||
SendMessageShortcut,
|
SendMessageShortcut,
|
||||||
setAssistantIconType,
|
setAssistantIconType,
|
||||||
setAutoCheckUpdate as _setAutoCheckUpdate,
|
setAutoCheckUpdate as _setAutoCheckUpdate,
|
||||||
setDisableHardwareAcceleration,
|
// setDisableHardwareAcceleration,
|
||||||
setEnableDeveloperMode,
|
setEnableDeveloperMode,
|
||||||
setLaunchOnBoot,
|
setLaunchOnBoot,
|
||||||
setLaunchToTray,
|
setLaunchToTray,
|
||||||
@ -18,8 +18,8 @@ import {
|
|||||||
SettingsState,
|
SettingsState,
|
||||||
setTopicPosition,
|
setTopicPosition,
|
||||||
setTray as _setTray,
|
setTray as _setTray,
|
||||||
setTrayOnClose,
|
setTrayOnClose
|
||||||
setWindowStyle
|
// setWindowStyle
|
||||||
} from '@renderer/store/settings'
|
} from '@renderer/store/settings'
|
||||||
import { SidebarIcon, TranslateLanguageCode } from '@renderer/types'
|
import { SidebarIcon, TranslateLanguageCode } from '@renderer/types'
|
||||||
import { UpgradeChannel } from '@shared/config/constant'
|
import { UpgradeChannel } from '@shared/config/constant'
|
||||||
@ -75,9 +75,9 @@ export function useSettings() {
|
|||||||
// setTheme(theme: ThemeMode) {
|
// setTheme(theme: ThemeMode) {
|
||||||
// dispatch(setTheme(theme))
|
// dispatch(setTheme(theme))
|
||||||
// },
|
// },
|
||||||
setWindowStyle(windowStyle: 'transparent' | 'opaque') {
|
// setWindowStyle(windowStyle: 'transparent' | 'opaque') {
|
||||||
dispatch(setWindowStyle(windowStyle))
|
// dispatch(setWindowStyle(windowStyle))
|
||||||
},
|
// },
|
||||||
setTargetLanguage(targetLanguage: TranslateLanguageCode) {
|
setTargetLanguage(targetLanguage: TranslateLanguageCode) {
|
||||||
dispatch(setTargetLanguage(targetLanguage))
|
dispatch(setTargetLanguage(targetLanguage))
|
||||||
},
|
},
|
||||||
@ -101,11 +101,11 @@ export function useSettings() {
|
|||||||
},
|
},
|
||||||
setShowTokens(showTokens: boolean) {
|
setShowTokens(showTokens: boolean) {
|
||||||
dispatch(setShowTokens(showTokens))
|
dispatch(setShowTokens(showTokens))
|
||||||
},
|
|
||||||
setDisableHardwareAcceleration(disableHardwareAcceleration: boolean) {
|
|
||||||
dispatch(setDisableHardwareAcceleration(disableHardwareAcceleration))
|
|
||||||
window.api.setDisableHardwareAcceleration(disableHardwareAcceleration)
|
|
||||||
}
|
}
|
||||||
|
// setDisableHardwareAcceleration(disableHardwareAcceleration: boolean) {
|
||||||
|
// dispatch(setDisableHardwareAcceleration(disableHardwareAcceleration))
|
||||||
|
// window.api.setDisableHardwareAcceleration(disableHardwareAcceleration)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import CodeEditor from '@renderer/components/CodeEditor'
|
import CodeEditor from '@renderer/components/CodeEditor'
|
||||||
import { ResetIcon } from '@renderer/components/Icons'
|
import { ResetIcon } from '@renderer/components/Icons'
|
||||||
import { HStack } from '@renderer/components/Layout'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
@ -13,7 +14,6 @@ import {
|
|||||||
AssistantIconType,
|
AssistantIconType,
|
||||||
setAssistantIconType,
|
setAssistantIconType,
|
||||||
setClickAssistantToShowTopic,
|
setClickAssistantToShowTopic,
|
||||||
setCustomCss,
|
|
||||||
setPinTopicsToTop,
|
setPinTopicsToTop,
|
||||||
setShowTopicTime,
|
setShowTopicTime,
|
||||||
setSidebarIcons
|
setSidebarIcons
|
||||||
@ -57,24 +57,26 @@ const ColorCircle = styled.div<{ color: string; isActive?: boolean }>`
|
|||||||
|
|
||||||
const DisplaySettings: FC = () => {
|
const DisplaySettings: FC = () => {
|
||||||
const {
|
const {
|
||||||
windowStyle,
|
// windowStyle,
|
||||||
setWindowStyle,
|
// setWindowStyle,
|
||||||
topicPosition,
|
topicPosition,
|
||||||
setTopicPosition,
|
setTopicPosition,
|
||||||
clickAssistantToShowTopic,
|
clickAssistantToShowTopic,
|
||||||
showTopicTime,
|
showTopicTime,
|
||||||
pinTopicsToTop,
|
pinTopicsToTop,
|
||||||
customCss,
|
// customCss,
|
||||||
sidebarIcons,
|
sidebarIcons,
|
||||||
assistantIconType
|
assistantIconType
|
||||||
} = useSettings()
|
} = useSettings()
|
||||||
|
const [windowStyle, setWindowStyle] = usePreference('app.theme.window_style')
|
||||||
|
const [customCss, setCustomCss] = usePreference('ui.custom_css')
|
||||||
|
|
||||||
const { navbarPosition, setNavbarPosition } = useNavbarPosition()
|
const { navbarPosition, setNavbarPosition } = useNavbarPosition()
|
||||||
const { theme, settedTheme, setTheme } = useTheme()
|
const { theme, settedTheme, setTheme } = useTheme()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const [currentZoom, setCurrentZoom] = useState(1.0)
|
const [currentZoom, setCurrentZoom] = useState(1.0)
|
||||||
const { userTheme, setUserTheme } = useUserTheme()
|
const { userTheme, setUserTheme } = useUserTheme()
|
||||||
|
|
||||||
const [visibleIcons, setVisibleIcons] = useState(sidebarIcons?.visible || DEFAULT_SIDEBAR_ICONS)
|
const [visibleIcons, setVisibleIcons] = useState(sidebarIcons?.visible || DEFAULT_SIDEBAR_ICONS)
|
||||||
const [disabledIcons, setDisabledIcons] = useState(sidebarIcons?.disabled || [])
|
const [disabledIcons, setDisabledIcons] = useState(sidebarIcons?.disabled || [])
|
||||||
|
|
||||||
@ -335,7 +337,7 @@ const DisplaySettings: FC = () => {
|
|||||||
value={customCss}
|
value={customCss}
|
||||||
language="css"
|
language="css"
|
||||||
placeholder={t('settings.display.custom.css.placeholder')}
|
placeholder={t('settings.display.custom.css.placeholder')}
|
||||||
onChange={(value) => dispatch(setCustomCss(value))}
|
onChange={(value) => setCustomCss(value)}
|
||||||
height="60vh"
|
height="60vh"
|
||||||
expanded={false}
|
expanded={false}
|
||||||
wrapped
|
wrapped
|
||||||
|
|||||||
@ -40,9 +40,7 @@ const GeneralSettings: FC = () => {
|
|||||||
tray,
|
tray,
|
||||||
proxyMode: storeProxyMode,
|
proxyMode: storeProxyMode,
|
||||||
enableDataCollection,
|
enableDataCollection,
|
||||||
enableSpellCheck,
|
enableSpellCheck
|
||||||
disableHardwareAcceleration,
|
|
||||||
setDisableHardwareAcceleration
|
|
||||||
} = useSettings()
|
} = useSettings()
|
||||||
const [proxyUrl, setProxyUrl] = useState<string | undefined>(storeProxyUrl)
|
const [proxyUrl, setProxyUrl] = useState<string | undefined>(storeProxyUrl)
|
||||||
const [proxyBypassRules, setProxyBypassRules] = useState<string | undefined>(storeProxyBypassRules)
|
const [proxyBypassRules, setProxyBypassRules] = useState<string | undefined>(storeProxyBypassRules)
|
||||||
@ -51,6 +49,9 @@ const GeneralSettings: FC = () => {
|
|||||||
const { setTimeoutTimer } = useTimer()
|
const { setTimeoutTimer } = useTimer()
|
||||||
|
|
||||||
const [language, setLanguage] = usePreference('app.language')
|
const [language, setLanguage] = usePreference('app.language')
|
||||||
|
const [disableHardwareAcceleration, setDisableHardwareAcceleration] = usePreference(
|
||||||
|
'app.disable_hardware_acceleration'
|
||||||
|
)
|
||||||
|
|
||||||
const updateTray = (isShowTray: boolean) => {
|
const updateTray = (isShowTray: boolean) => {
|
||||||
setTray(isShowTray)
|
setTray(isShowTray)
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import {
|
|||||||
SYSTEM_MODELS
|
SYSTEM_MODELS
|
||||||
} from '@renderer/config/models'
|
} from '@renderer/config/models'
|
||||||
import { BUILTIN_OCR_PROVIDERS, BUILTIN_OCR_PROVIDERS_MAP, DEFAULT_OCR_PROVIDER } from '@renderer/config/ocr'
|
import { BUILTIN_OCR_PROVIDERS, BUILTIN_OCR_PROVIDERS_MAP, DEFAULT_OCR_PROVIDER } from '@renderer/config/ocr'
|
||||||
import { TRANSLATE_PROMPT } from '@shared/config/prompts'
|
|
||||||
import {
|
import {
|
||||||
isSupportArrayContentProvider,
|
isSupportArrayContentProvider,
|
||||||
isSupportDeveloperRoleProvider,
|
isSupportDeveloperRoleProvider,
|
||||||
@ -33,6 +32,7 @@ import {
|
|||||||
} from '@renderer/types'
|
} from '@renderer/types'
|
||||||
import { getDefaultGroupName, getLeadingEmoji, runAsyncFunction, uuid } from '@renderer/utils'
|
import { getDefaultGroupName, getLeadingEmoji, runAsyncFunction, uuid } from '@renderer/utils'
|
||||||
import { defaultByPassRules, UpgradeChannel } from '@shared/config/constant'
|
import { defaultByPassRules, UpgradeChannel } from '@shared/config/constant'
|
||||||
|
import { TRANSLATE_PROMPT } from '@shared/config/prompts'
|
||||||
import { isEmpty } from 'lodash'
|
import { isEmpty } from 'lodash'
|
||||||
import { createMigrate } from 'redux-persist'
|
import { createMigrate } from 'redux-persist'
|
||||||
|
|
||||||
|
|||||||
@ -776,9 +776,9 @@ const settingsSlice = createSlice({
|
|||||||
setEnableQuickPanelTriggers: (state, action: PayloadAction<boolean>) => {
|
setEnableQuickPanelTriggers: (state, action: PayloadAction<boolean>) => {
|
||||||
state.enableQuickPanelTriggers = action.payload
|
state.enableQuickPanelTriggers = action.payload
|
||||||
},
|
},
|
||||||
setDisableHardwareAcceleration: (state, action: PayloadAction<boolean>) => {
|
// setDisableHardwareAcceleration: (state, action: PayloadAction<boolean>) => {
|
||||||
state.disableHardwareAcceleration = action.payload
|
// state.disableHardwareAcceleration = action.payload
|
||||||
},
|
// },
|
||||||
setOpenAISummaryText: (state, action: PayloadAction<OpenAISummaryText>) => {
|
setOpenAISummaryText: (state, action: PayloadAction<OpenAISummaryText>) => {
|
||||||
state.openAI.summaryText = action.payload
|
state.openAI.summaryText = action.payload
|
||||||
},
|
},
|
||||||
@ -956,7 +956,7 @@ export const {
|
|||||||
setSpellCheckLanguages,
|
setSpellCheckLanguages,
|
||||||
setExportMenuOptions,
|
setExportMenuOptions,
|
||||||
setEnableQuickPanelTriggers,
|
setEnableQuickPanelTriggers,
|
||||||
setDisableHardwareAcceleration,
|
// setDisableHardwareAcceleration,
|
||||||
setOpenAISummaryText,
|
setOpenAISummaryText,
|
||||||
setOpenAIVerbosity,
|
setOpenAIVerbosity,
|
||||||
setNotificationSettings,
|
setNotificationSettings,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import '@renderer/databases'
|
import '@renderer/databases'
|
||||||
|
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import store, { persistor } from '@renderer/store'
|
import store, { persistor } from '@renderer/store'
|
||||||
import { message } from 'antd'
|
import { message } from 'antd'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
@ -14,7 +14,7 @@ import HomeWindow from './home/HomeWindow'
|
|||||||
|
|
||||||
// Inner component that uses the hook after Redux is initialized
|
// Inner component that uses the hook after Redux is initialized
|
||||||
function MiniWindowContent(): React.ReactElement {
|
function MiniWindowContent(): React.ReactElement {
|
||||||
const { customCss } = useSettings()
|
const [customCss] = usePreference('ui.custom_css')
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let customCssElement = document.getElementById('user-defined-custom-css') as HTMLStyleElement
|
let customCssElement = document.getElementById('user-defined-custom-css') as HTMLStyleElement
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
// import MessageContent from './MessageContent'
|
// import MessageContent from './MessageContent'
|
||||||
import MessageContent from '@renderer/pages/home/Messages/MessageContent'
|
import MessageContent from '@renderer/pages/home/Messages/MessageContent'
|
||||||
import MessageErrorBoundary from '@renderer/pages/home/Messages/MessageErrorBoundary'
|
import MessageErrorBoundary from '@renderer/pages/home/Messages/MessageErrorBoundary'
|
||||||
@ -22,7 +22,8 @@ const MessageItem: FC<Props> = ({ message, index, total, route }) => {
|
|||||||
// const [message, setMessage] = useState(_message)
|
// const [message, setMessage] = useState(_message)
|
||||||
// const [bl, setTextBlock] = useState<MainTextMessageBlock | null>(null)
|
// const [bl, setTextBlock] = useState<MainTextMessageBlock | null>(null)
|
||||||
// const model = useModel(getMessageModelId(message))
|
// const model = useModel(getMessageModelId(message))
|
||||||
const { messageFont, fontSize } = useSettings()
|
const [messageFont] = usePreference('chat.message.font')
|
||||||
|
const [fontSize] = usePreference('chat.message.font_size')
|
||||||
const messageContainerRef = useRef<HTMLDivElement>(null)
|
const messageContainerRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
const isAssistantMessage = message.role === 'assistant'
|
const isAssistantMessage = message.role === 'assistant'
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import { isMac } from '@renderer/config/constant'
|
import { isMac } from '@renderer/config/constant'
|
||||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
|
||||||
import i18n from '@renderer/i18n'
|
import i18n from '@renderer/i18n'
|
||||||
import { fetchChatCompletion } from '@renderer/services/ApiService'
|
import { fetchChatCompletion } from '@renderer/services/ApiService'
|
||||||
import { getDefaultTopic } from '@renderer/services/AssistantService'
|
import { getDefaultTopic } from '@renderer/services/AssistantService'
|
||||||
@ -38,7 +38,9 @@ import InputBar from './components/InputBar'
|
|||||||
const logger = loggerService.withContext('HomeWindow')
|
const logger = loggerService.withContext('HomeWindow')
|
||||||
|
|
||||||
const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => {
|
const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => {
|
||||||
const { language, readClipboardAtStartup, windowStyle } = useSettings()
|
const [readClipboardAtStartup] = usePreference('feature.quick_assistant.read_clipboard_at_startup')
|
||||||
|
const [language] = usePreference('app.language')
|
||||||
|
const [windowStyle] = usePreference('app.theme.window_style')
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import LanguageSelect from '@renderer/components/LanguageSelect'
|
|||||||
import { LanguagesEnum, UNKNOWN } from '@renderer/config/translate'
|
import { LanguagesEnum, UNKNOWN } from '@renderer/config/translate'
|
||||||
import db from '@renderer/databases'
|
import db from '@renderer/databases'
|
||||||
import { useTopicMessages } from '@renderer/hooks/useMessageOperations'
|
import { useTopicMessages } from '@renderer/hooks/useMessageOperations'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
|
||||||
import useTranslate from '@renderer/hooks/useTranslate'
|
import useTranslate from '@renderer/hooks/useTranslate'
|
||||||
import MessageContent from '@renderer/pages/home/Messages/MessageContent'
|
import MessageContent from '@renderer/pages/home/Messages/MessageContent'
|
||||||
import { getDefaultTopic, getDefaultTranslateAssistant } from '@renderer/services/AssistantService'
|
import { getDefaultTopic, getDefaultTranslateAssistant } from '@renderer/services/AssistantService'
|
||||||
@ -14,6 +13,7 @@ import { Assistant, Topic, TranslateLanguage, TranslateLanguageCode } from '@ren
|
|||||||
import { runAsyncFunction } from '@renderer/utils'
|
import { runAsyncFunction } from '@renderer/utils'
|
||||||
import { abortCompletion } from '@renderer/utils/abortController'
|
import { abortCompletion } from '@renderer/utils/abortController'
|
||||||
import { detectLanguage } from '@renderer/utils/translate'
|
import { detectLanguage } from '@renderer/utils/translate'
|
||||||
|
import { defaultLanguage } from '@shared/config/constant'
|
||||||
import type { SelectionActionItem } from '@shared/data/preferenceTypes'
|
import type { SelectionActionItem } from '@shared/data/preferenceTypes'
|
||||||
import { Tooltip } from 'antd'
|
import { Tooltip } from 'antd'
|
||||||
import { ArrowRightFromLine, ArrowRightToLine, ChevronDown, CircleHelp, Globe } from 'lucide-react'
|
import { ArrowRightFromLine, ArrowRightToLine, ChevronDown, CircleHelp, Globe } from 'lucide-react'
|
||||||
@ -32,8 +32,8 @@ const logger = loggerService.withContext('ActionTranslate')
|
|||||||
|
|
||||||
const ActionTranslate: FC<Props> = ({ action, scrollToBottom }) => {
|
const ActionTranslate: FC<Props> = ({ action, scrollToBottom }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { language } = useSettings()
|
|
||||||
|
|
||||||
|
const [language] = usePreference('app.language')
|
||||||
const [translateModelPrompt] = usePreference('feature.translate.model_prompt')
|
const [translateModelPrompt] = usePreference('feature.translate.model_prompt')
|
||||||
|
|
||||||
const [targetLanguage, setTargetLanguage] = useState<TranslateLanguage>(LanguagesEnum.enUS)
|
const [targetLanguage, setTargetLanguage] = useState<TranslateLanguage>(LanguagesEnum.enUS)
|
||||||
@ -60,7 +60,7 @@ const ActionTranslate: FC<Props> = ({ action, scrollToBottom }) => {
|
|||||||
let alterLang: TranslateLanguage
|
let alterLang: TranslateLanguage
|
||||||
|
|
||||||
if (!biDirectionLangPair || !biDirectionLangPair.value[0]) {
|
if (!biDirectionLangPair || !biDirectionLangPair.value[0]) {
|
||||||
const lang = getLanguageByLangcode(language)
|
const lang = getLanguageByLangcode(language || navigator.language || defaultLanguage)
|
||||||
if (lang !== UNKNOWN) {
|
if (lang !== UNKNOWN) {
|
||||||
targetLang = lang
|
targetLang = lang
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user