mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-03 11:19:10 +08:00
refactor: enhance preference management and update mappings
- Updated preferences to utilize the new SendMessageShortcut type for better type safety. - Refactored components to use the usePreference hook instead of useSettings for improved preference handling. - Added new preferences for target language and send message shortcut in various components. - Cleaned up unused code and comments related to settings for better maintainability. - Updated auto-generated preference mappings to reflect recent changes in preference structure.
This commit is contained in:
parent
5cc7390bb6
commit
0a67ab4103
@ -38,3 +38,5 @@ export enum ThemeMode {
|
|||||||
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'
|
export type WindowStyle = 'transparent' | 'opaque'
|
||||||
|
|
||||||
|
export type SendMessageShortcut = 'Enter' | 'Shift+Enter' | 'Ctrl+Enter' | 'Command+Enter' | 'Alt+Enter'
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Auto-generated preferences configuration
|
* Auto-generated preferences configuration
|
||||||
* Generated at: 2025-09-02T02:45:09.198Z
|
* Generated at: 2025-09-02T04:48:55.916Z
|
||||||
*
|
*
|
||||||
* 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:
|
||||||
@ -14,6 +14,7 @@ import type {
|
|||||||
SelectionActionItem,
|
SelectionActionItem,
|
||||||
SelectionFilterMode,
|
SelectionFilterMode,
|
||||||
SelectionTriggerMode,
|
SelectionTriggerMode,
|
||||||
|
SendMessageShortcut,
|
||||||
WindowStyle
|
WindowStyle
|
||||||
} from '@shared/data/preferenceTypes'
|
} from '@shared/data/preferenceTypes'
|
||||||
import { LanguageVarious, ThemeMode } from '@shared/data/preferenceTypes'
|
import { LanguageVarious, ThemeMode } from '@shared/data/preferenceTypes'
|
||||||
@ -116,7 +117,7 @@ export interface PreferencesType {
|
|||||||
// redux/settings/enableQuickPanelTriggers
|
// redux/settings/enableQuickPanelTriggers
|
||||||
'chat.input.quick_panel.triggers_enabled': boolean
|
'chat.input.quick_panel.triggers_enabled': boolean
|
||||||
// redux/settings/sendMessageShortcut
|
// redux/settings/sendMessageShortcut
|
||||||
'chat.input.send_message_shortcut': string
|
'chat.input.send_message_shortcut': SendMessageShortcut
|
||||||
// redux/settings/showInputEstimatedTokens
|
// redux/settings/showInputEstimatedTokens
|
||||||
'chat.input.show_estimated_tokens': boolean
|
'chat.input.show_estimated_tokens': boolean
|
||||||
// redux/settings/autoTranslateWithSpace
|
// redux/settings/autoTranslateWithSpace
|
||||||
@ -143,8 +144,6 @@ export interface PreferencesType {
|
|||||||
'chat.message.show_divider': boolean
|
'chat.message.show_divider': boolean
|
||||||
// redux/settings/showPrompt
|
// redux/settings/showPrompt
|
||||||
'chat.message.show_prompt': boolean
|
'chat.message.show_prompt': boolean
|
||||||
// redux/settings/showTokens
|
|
||||||
'chat.message.show_tokens': boolean
|
|
||||||
// redux/settings/messageStyle
|
// redux/settings/messageStyle
|
||||||
'chat.message.style': string
|
'chat.message.style': string
|
||||||
// redux/settings/thoughtAutoCollapse
|
// redux/settings/thoughtAutoCollapse
|
||||||
@ -321,6 +320,8 @@ export interface PreferencesType {
|
|||||||
'feature.selection.trigger_mode': SelectionTriggerMode
|
'feature.selection.trigger_mode': SelectionTriggerMode
|
||||||
// redux/settings/translateModelPrompt
|
// redux/settings/translateModelPrompt
|
||||||
'feature.translate.model_prompt': string
|
'feature.translate.model_prompt': string
|
||||||
|
// redux/settings/targetLanguage
|
||||||
|
'feature.translate.target_language': string
|
||||||
// redux/shortcuts/shortcuts.exit_fullscreen
|
// redux/shortcuts/shortcuts.exit_fullscreen
|
||||||
'shortcut.app.exit_fullscreen': Record<string, unknown>
|
'shortcut.app.exit_fullscreen': Record<string, unknown>
|
||||||
// redux/shortcuts/shortcuts.search_message
|
// redux/shortcuts/shortcuts.search_message
|
||||||
@ -436,7 +437,6 @@ export const DefaultPreferences: PreferencesType = {
|
|||||||
'chat.message.navigation_mode': 'none',
|
'chat.message.navigation_mode': 'none',
|
||||||
'chat.message.show_divider': true,
|
'chat.message.show_divider': true,
|
||||||
'chat.message.show_prompt': true,
|
'chat.message.show_prompt': true,
|
||||||
'chat.message.show_tokens': true,
|
|
||||||
'chat.message.style': 'plain',
|
'chat.message.style': 'plain',
|
||||||
'chat.message.thought.auto_collapse': true,
|
'chat.message.thought.auto_collapse': true,
|
||||||
'chat.narrow_mode': false,
|
'chat.narrow_mode': false,
|
||||||
@ -552,6 +552,7 @@ export const DefaultPreferences: PreferencesType = {
|
|||||||
'feature.selection.remember_win_size': false,
|
'feature.selection.remember_win_size': false,
|
||||||
'feature.selection.trigger_mode': 'selected',
|
'feature.selection.trigger_mode': 'selected',
|
||||||
'feature.translate.model_prompt': TRANSLATE_PROMPT,
|
'feature.translate.model_prompt': TRANSLATE_PROMPT,
|
||||||
|
'feature.translate.target_language': 'en-us',
|
||||||
'shortcut.app.exit_fullscreen': { editable: false, enabled: true, key: ['Escape'], system: true },
|
'shortcut.app.exit_fullscreen': { editable: false, enabled: true, key: ['Escape'], system: true },
|
||||||
'shortcut.app.search_message': {
|
'shortcut.app.search_message': {
|
||||||
editable: true,
|
editable: true,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Auto-generated preference mappings from classification.json
|
* Auto-generated preference mappings from classification.json
|
||||||
* Generated at: 2025-09-01T14:38:08.063Z
|
* Generated at: 2025-09-02T05:21:08.374Z
|
||||||
*
|
*
|
||||||
* This file contains pure mapping relationships without default values.
|
* This file contains pure mapping relationships without default values.
|
||||||
* Default values are managed in packages/shared/data/preferences.ts
|
* Default values are managed in packages/shared/data/preferences.ts
|
||||||
@ -14,10 +14,6 @@
|
|||||||
* ElectronStore没有嵌套,originalKey直接对应configManager.get(key)
|
* ElectronStore没有嵌套,originalKey直接对应configManager.get(key)
|
||||||
*/
|
*/
|
||||||
export const ELECTRON_STORE_MAPPINGS = [
|
export const ELECTRON_STORE_MAPPINGS = [
|
||||||
{
|
|
||||||
originalKey: 'Language',
|
|
||||||
targetKey: 'app.language'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
originalKey: 'ZoomFactor',
|
originalKey: 'ZoomFactor',
|
||||||
targetKey: 'app.zoom_factor'
|
targetKey: 'app.zoom_factor'
|
||||||
@ -58,6 +54,10 @@ export const REDUX_STORE_MAPPINGS = {
|
|||||||
originalKey: 'enableQuickAssistant',
|
originalKey: 'enableQuickAssistant',
|
||||||
targetKey: 'feature.quick_assistant.enabled'
|
targetKey: 'feature.quick_assistant.enabled'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
originalKey: 'language',
|
||||||
|
targetKey: 'app.language'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
originalKey: 'launchToTray',
|
originalKey: 'launchToTray',
|
||||||
targetKey: 'app.tray.on_launch'
|
targetKey: 'app.tray.on_launch'
|
||||||
@ -86,6 +86,10 @@ export const REDUX_STORE_MAPPINGS = {
|
|||||||
originalKey: 'sendMessageShortcut',
|
originalKey: 'sendMessageShortcut',
|
||||||
targetKey: 'chat.input.send_message_shortcut'
|
targetKey: 'chat.input.send_message_shortcut'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
originalKey: 'targetLanguage',
|
||||||
|
targetKey: 'feature.translate.target_language'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
originalKey: 'proxyMode',
|
originalKey: 'proxyMode',
|
||||||
targetKey: 'app.proxy.mode'
|
targetKey: 'app.proxy.mode'
|
||||||
@ -110,10 +114,6 @@ export const REDUX_STORE_MAPPINGS = {
|
|||||||
originalKey: 'showPrompt',
|
originalKey: 'showPrompt',
|
||||||
targetKey: 'chat.message.show_prompt'
|
targetKey: 'chat.message.show_prompt'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
originalKey: 'showTokens',
|
|
||||||
targetKey: 'chat.message.show_tokens'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
originalKey: 'showMessageDivider',
|
originalKey: 'showMessageDivider',
|
||||||
targetKey: 'chat.message.show_divider'
|
targetKey: 'chat.message.show_divider'
|
||||||
@ -180,7 +180,7 @@ export const REDUX_STORE_MAPPINGS = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
originalKey: 'codeEditor.enabled',
|
originalKey: 'codeEditor.enabled',
|
||||||
targetKey: 'chat.code.editor.highlight_active_line'
|
targetKey: 'chat.code.editor.enabled'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
originalKey: 'codeEditor.themeLight',
|
originalKey: 'codeEditor.themeLight',
|
||||||
@ -190,6 +190,10 @@ export const REDUX_STORE_MAPPINGS = {
|
|||||||
originalKey: 'codeEditor.themeDark',
|
originalKey: 'codeEditor.themeDark',
|
||||||
targetKey: 'chat.code.editor.theme_dark'
|
targetKey: 'chat.code.editor.theme_dark'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
originalKey: 'codeEditor.highlightActiveLine',
|
||||||
|
targetKey: 'chat.code.editor.highlight_active_line'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
originalKey: 'codeEditor.foldGutter',
|
originalKey: 'codeEditor.foldGutter',
|
||||||
targetKey: 'chat.code.editor.fold_gutter'
|
targetKey: 'chat.code.editor.fold_gutter'
|
||||||
@ -298,6 +302,10 @@ export const REDUX_STORE_MAPPINGS = {
|
|||||||
originalKey: 'webdavDisableStream',
|
originalKey: 'webdavDisableStream',
|
||||||
targetKey: 'data.backup.webdav.disable_stream'
|
targetKey: 'data.backup.webdav.disable_stream'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
originalKey: 'translateModelPrompt',
|
||||||
|
targetKey: 'feature.translate.model_prompt'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
originalKey: 'autoTranslateWithSpace',
|
originalKey: 'autoTranslateWithSpace',
|
||||||
targetKey: 'chat.input.translate.auto_translate_with_space'
|
targetKey: 'chat.input.translate.auto_translate_with_space'
|
||||||
@ -723,10 +731,10 @@ export const REDUX_STORE_MAPPINGS = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 映射统计:
|
* 映射统计:
|
||||||
* - ElectronStore项: 2
|
* - ElectronStore项: 1
|
||||||
* - Redux Store项: 169
|
* - Redux Store项: 172
|
||||||
* - Redux分类: settings, selectionStore, nutstore, shortcuts
|
* - Redux分类: settings, selectionStore, nutstore, shortcuts
|
||||||
* - 总配置项: 171
|
* - 总配置项: 173
|
||||||
*
|
*
|
||||||
* 使用说明:
|
* 使用说明:
|
||||||
* 1. ElectronStore读取: configManager.get(mapping.originalKey)
|
* 1. ElectronStore读取: configManager.get(mapping.originalKey)
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import { ActionTool } from '@renderer/components/ActionTools'
|
import { ActionTool } from '@renderer/components/ActionTools'
|
||||||
import CodeEditor, { CodeEditorHandles } from '@renderer/components/CodeEditor'
|
import CodeEditor, { CodeEditorHandles } from '@renderer/components/CodeEditor'
|
||||||
@ -16,7 +17,6 @@ import CodeViewer from '@renderer/components/CodeViewer'
|
|||||||
import ImageViewer from '@renderer/components/ImageViewer'
|
import ImageViewer from '@renderer/components/ImageViewer'
|
||||||
import { BasicPreviewHandles } from '@renderer/components/Preview'
|
import { BasicPreviewHandles } from '@renderer/components/Preview'
|
||||||
import { MAX_COLLAPSED_CODE_HEIGHT } from '@renderer/config/constant'
|
import { MAX_COLLAPSED_CODE_HEIGHT } from '@renderer/config/constant'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
|
||||||
import { pyodideService } from '@renderer/services/PyodideService'
|
import { pyodideService } from '@renderer/services/PyodideService'
|
||||||
import { getExtensionByLanguage } from '@renderer/utils/code-language'
|
import { getExtensionByLanguage } from '@renderer/utils/code-language'
|
||||||
import { extractHtmlTitle } from '@renderer/utils/formats'
|
import { extractHtmlTitle } from '@renderer/utils/formats'
|
||||||
@ -28,7 +28,6 @@ import styled, { css } from 'styled-components'
|
|||||||
import { SPECIAL_VIEW_COMPONENTS, SPECIAL_VIEWS } from './constants'
|
import { SPECIAL_VIEW_COMPONENTS, SPECIAL_VIEWS } from './constants'
|
||||||
import StatusBar from './StatusBar'
|
import StatusBar from './StatusBar'
|
||||||
import { ViewMode } from './types'
|
import { ViewMode } from './types'
|
||||||
|
|
||||||
const logger = loggerService.withContext('CodeBlockView')
|
const logger = loggerService.withContext('CodeBlockView')
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -55,7 +54,13 @@ interface Props {
|
|||||||
*/
|
*/
|
||||||
export const CodeBlockView: React.FC<Props> = memo(({ children, language, onSave }) => {
|
export const CodeBlockView: React.FC<Props> = memo(({ children, language, onSave }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { codeEditor, codeExecution, codeImageTools, codeCollapsible, codeWrappable } = useSettings()
|
|
||||||
|
const [codeEditorEnabled] = usePreference('chat.code.editor.enabled')
|
||||||
|
const [codeExecutionEnabled] = usePreference('chat.code.execution.enabled')
|
||||||
|
const [codeExecutionTimeoutMinutes] = usePreference('chat.code.execution.timeout_minutes')
|
||||||
|
const [codeCollapsible] = usePreference('chat.code.collapsible')
|
||||||
|
const [codeWrappable] = usePreference('chat.code.wrappable')
|
||||||
|
const [codeImageTools] = usePreference('chat.code.image_tools')
|
||||||
|
|
||||||
const [viewState, setViewState] = useState({
|
const [viewState, setViewState] = useState({
|
||||||
mode: 'special' as ViewMode,
|
mode: 'special' as ViewMode,
|
||||||
@ -87,8 +92,8 @@ export const CodeBlockView: React.FC<Props> = memo(({ children, language, onSave
|
|||||||
const [tools, setTools] = useState<ActionTool[]>([])
|
const [tools, setTools] = useState<ActionTool[]>([])
|
||||||
|
|
||||||
const isExecutable = useMemo(() => {
|
const isExecutable = useMemo(() => {
|
||||||
return codeExecution.enabled && language === 'python'
|
return codeExecutionEnabled && language === 'python'
|
||||||
}, [codeExecution.enabled, language])
|
}, [codeExecutionEnabled, language])
|
||||||
|
|
||||||
const sourceViewRef = useRef<CodeEditorHandles>(null)
|
const sourceViewRef = useRef<CodeEditorHandles>(null)
|
||||||
const specialViewRef = useRef<BasicPreviewHandles>(null)
|
const specialViewRef = useRef<BasicPreviewHandles>(null)
|
||||||
@ -153,7 +158,7 @@ export const CodeBlockView: React.FC<Props> = memo(({ children, language, onSave
|
|||||||
setExecutionResult(null)
|
setExecutionResult(null)
|
||||||
|
|
||||||
pyodideService
|
pyodideService
|
||||||
.runScript(children, {}, codeExecution.timeoutMinutes * 60000)
|
.runScript(children, {}, codeExecutionTimeoutMinutes * 60000)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
setExecutionResult(result)
|
setExecutionResult(result)
|
||||||
})
|
})
|
||||||
@ -166,7 +171,7 @@ export const CodeBlockView: React.FC<Props> = memo(({ children, language, onSave
|
|||||||
.finally(() => {
|
.finally(() => {
|
||||||
setIsRunning(false)
|
setIsRunning(false)
|
||||||
})
|
})
|
||||||
}, [children, codeExecution.timeoutMinutes])
|
}, [children, codeExecutionTimeoutMinutes])
|
||||||
|
|
||||||
const showPreviewTools = useMemo(() => {
|
const showPreviewTools = useMemo(() => {
|
||||||
return viewMode !== 'source' && hasSpecialView
|
return viewMode !== 'source' && hasSpecialView
|
||||||
@ -191,7 +196,7 @@ export const CodeBlockView: React.FC<Props> = memo(({ children, language, onSave
|
|||||||
// 特殊视图的编辑/查看源码按钮,在分屏模式下不可用
|
// 特殊视图的编辑/查看源码按钮,在分屏模式下不可用
|
||||||
useViewSourceTool({
|
useViewSourceTool({
|
||||||
enabled: hasSpecialView,
|
enabled: hasSpecialView,
|
||||||
editable: codeEditor.enabled,
|
editable: codeEditorEnabled,
|
||||||
viewMode,
|
viewMode,
|
||||||
onViewModeChange: setViewMode,
|
onViewModeChange: setViewMode,
|
||||||
setTools
|
setTools
|
||||||
@ -233,7 +238,7 @@ export const CodeBlockView: React.FC<Props> = memo(({ children, language, onSave
|
|||||||
|
|
||||||
// 代码编辑器的保存按钮
|
// 代码编辑器的保存按钮
|
||||||
useSaveTool({
|
useSaveTool({
|
||||||
enabled: codeEditor.enabled && !isInSpecialView,
|
enabled: codeEditorEnabled && !isInSpecialView,
|
||||||
sourceViewRef,
|
sourceViewRef,
|
||||||
setTools
|
setTools
|
||||||
})
|
})
|
||||||
@ -241,7 +246,7 @@ export const CodeBlockView: React.FC<Props> = memo(({ children, language, onSave
|
|||||||
// 源代码视图组件
|
// 源代码视图组件
|
||||||
const sourceView = useMemo(
|
const sourceView = useMemo(
|
||||||
() =>
|
() =>
|
||||||
codeEditor.enabled ? (
|
codeEditorEnabled ? (
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
className="source-view"
|
className="source-view"
|
||||||
ref={sourceViewRef}
|
ref={sourceViewRef}
|
||||||
@ -264,7 +269,7 @@ export const CodeBlockView: React.FC<Props> = memo(({ children, language, onSave
|
|||||||
{children}
|
{children}
|
||||||
</CodeViewer>
|
</CodeViewer>
|
||||||
),
|
),
|
||||||
[children, codeEditor.enabled, handleHeightChange, language, onSave, shouldExpand, shouldWrap]
|
[children, codeEditorEnabled, handleHeightChange, language, onSave, shouldExpand, shouldWrap]
|
||||||
)
|
)
|
||||||
|
|
||||||
// 特殊视图组件映射
|
// 特殊视图组件映射
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
|
import { useMultiplePreferences, usePreference } from '@data/hooks/usePreference'
|
||||||
import { useCodeStyle } from '@renderer/context/CodeStyleProvider'
|
import { useCodeStyle } from '@renderer/context/CodeStyleProvider'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
|
||||||
import CodeMirror, { Annotation, BasicSetupOptions, EditorView, Extension } from '@uiw/react-codemirror'
|
import CodeMirror, { Annotation, BasicSetupOptions, EditorView, Extension } from '@uiw/react-codemirror'
|
||||||
import diff from 'fast-diff'
|
import diff from 'fast-diff'
|
||||||
import { useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react'
|
import { useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react'
|
||||||
@ -117,7 +117,17 @@ const CodeEditor = ({
|
|||||||
expanded = true,
|
expanded = true,
|
||||||
wrapped = true
|
wrapped = true
|
||||||
}: CodeEditorProps) => {
|
}: CodeEditorProps) => {
|
||||||
const { fontSize: _fontSize, codeShowLineNumbers: _lineNumbers, codeEditor } = useSettings()
|
const [_fontSize] = usePreference('chat.message.font_size')
|
||||||
|
const [_lineNumbers] = usePreference('chat.code.show_line_numbers')
|
||||||
|
const [codeEditor] = useMultiplePreferences({
|
||||||
|
autocompletion: 'chat.code.editor.autocompletion',
|
||||||
|
foldGutter: 'chat.code.editor.fold_gutter',
|
||||||
|
highlightActiveLine: 'chat.code.editor.highlight_active_line',
|
||||||
|
keymap: 'chat.code.editor.keymap',
|
||||||
|
themeLight: 'chat.code.editor.theme_light',
|
||||||
|
themeDark: 'chat.code.editor.theme_dark'
|
||||||
|
})
|
||||||
|
|
||||||
const enableKeymap = useMemo(() => options?.keymap ?? codeEditor.keymap, [options?.keymap, codeEditor.keymap])
|
const enableKeymap = useMemo(() => options?.keymap ?? codeEditor.keymap, [options?.keymap, codeEditor.keymap])
|
||||||
|
|
||||||
// 合并 codeEditor 和 options 的 basicSetup,options 优先
|
// 合并 codeEditor 和 options 的 basicSetup,options 优先
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import { MAX_COLLAPSED_CODE_HEIGHT } from '@renderer/config/constant'
|
import { MAX_COLLAPSED_CODE_HEIGHT } from '@renderer/config/constant'
|
||||||
import { useCodeStyle } from '@renderer/context/CodeStyleProvider'
|
import { useCodeStyle } from '@renderer/context/CodeStyleProvider'
|
||||||
import { useCodeHighlight } from '@renderer/hooks/useCodeHighlight'
|
import { useCodeHighlight } from '@renderer/hooks/useCodeHighlight'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
|
||||||
import { uuid } from '@renderer/utils'
|
import { uuid } from '@renderer/utils'
|
||||||
import { getReactStyleFromToken } from '@renderer/utils/shiki'
|
import { getReactStyleFromToken } from '@renderer/utils/shiki'
|
||||||
import { useVirtualizer } from '@tanstack/react-virtual'
|
import { useVirtualizer } from '@tanstack/react-virtual'
|
||||||
@ -27,7 +27,8 @@ interface CodeViewerProps {
|
|||||||
* - 并发安全
|
* - 并发安全
|
||||||
*/
|
*/
|
||||||
const CodeViewer = ({ children, language, expanded, wrapped, onHeightChange, className, height }: CodeViewerProps) => {
|
const CodeViewer = ({ children, language, expanded, wrapped, onHeightChange, className, height }: CodeViewerProps) => {
|
||||||
const { codeShowLineNumbers, fontSize } = useSettings()
|
const [codeShowLineNumbers] = usePreference('chat.code.show_line_numbers')
|
||||||
|
const [fontSize] = usePreference('chat.message.font_size')
|
||||||
const { getShikiPreProperties, isShikiThemeDark } = useCodeStyle()
|
const { getShikiPreProperties, isShikiThemeDark } = useCodeStyle()
|
||||||
const shikiThemeRef = useRef<HTMLDivElement>(null)
|
const shikiThemeRef = useRef<HTMLDivElement>(null)
|
||||||
const scrollerRef = useRef<HTMLDivElement>(null)
|
const scrollerRef = useRef<HTMLDivElement>(null)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { LoadingOutlined } from '@ant-design/icons'
|
import { LoadingOutlined } from '@ant-design/icons'
|
||||||
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
|
||||||
import useTranslate from '@renderer/hooks/useTranslate'
|
import useTranslate from '@renderer/hooks/useTranslate'
|
||||||
import { translateText } from '@renderer/services/TranslateService'
|
import { translateText } from '@renderer/services/TranslateService'
|
||||||
import { Modal, ModalProps } from 'antd'
|
import { Modal, ModalProps } from 'antd'
|
||||||
@ -42,7 +42,8 @@ const PopupContainer: React.FC<Props> = ({
|
|||||||
const [textValue, setTextValue] = useState(text)
|
const [textValue, setTextValue] = useState(text)
|
||||||
const [isTranslating, setIsTranslating] = useState(false)
|
const [isTranslating, setIsTranslating] = useState(false)
|
||||||
const textareaRef = useRef<TextAreaRef>(null)
|
const textareaRef = useRef<TextAreaRef>(null)
|
||||||
const { targetLanguage, showTranslateConfirm } = useSettings()
|
const [targetLanguage] = usePreference('feature.translate.target_language')
|
||||||
|
const [showTranslateConfirm] = usePreference('chat.input.translate.show_confirm')
|
||||||
const isMounted = useRef(true)
|
const isMounted = useRef(true)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { LoadingOutlined } from '@ant-design/icons'
|
import { LoadingOutlined } from '@ant-design/icons'
|
||||||
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
|
||||||
import useTranslate from '@renderer/hooks/useTranslate'
|
import useTranslate from '@renderer/hooks/useTranslate'
|
||||||
import { translateText } from '@renderer/services/TranslateService'
|
import { translateText } from '@renderer/services/TranslateService'
|
||||||
import { Button, Tooltip } from 'antd'
|
import { Button, Tooltip } from 'antd'
|
||||||
@ -22,7 +22,8 @@ const logger = loggerService.withContext('TranslateButton')
|
|||||||
const TranslateButton: FC<Props> = ({ text, onTranslated, disabled, style, isLoading }) => {
|
const TranslateButton: FC<Props> = ({ text, onTranslated, disabled, style, isLoading }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [isTranslating, setIsTranslating] = useState(false)
|
const [isTranslating, setIsTranslating] = useState(false)
|
||||||
const { targetLanguage, showTranslateConfirm } = useSettings()
|
const [targetLanguage] = usePreference('feature.translate.target_language')
|
||||||
|
const [showTranslateConfirm] = usePreference('chat.input.translate.show_confirm')
|
||||||
const { getLanguageByLangcode } = useTranslate()
|
const { getLanguageByLangcode } = useTranslate()
|
||||||
|
|
||||||
const translateConfirm = () => {
|
const translateConfirm = () => {
|
||||||
|
|||||||
@ -30,13 +30,14 @@ export function useAppInit() {
|
|||||||
const {
|
const {
|
||||||
proxyUrl,
|
proxyUrl,
|
||||||
proxyBypassRules,
|
proxyBypassRules,
|
||||||
language,
|
// language,
|
||||||
// windowStyle,
|
// windowStyle,
|
||||||
autoCheckUpdate,
|
autoCheckUpdate,
|
||||||
proxyMode,
|
proxyMode,
|
||||||
// customCss,
|
// customCss,
|
||||||
enableDataCollection
|
enableDataCollection
|
||||||
} = useSettings()
|
} = useSettings()
|
||||||
|
const [language] = usePreference('app.language')
|
||||||
const [windowStyle] = usePreference('app.theme.window_style')
|
const [windowStyle] = usePreference('app.theme.window_style')
|
||||||
const [customCss] = usePreference('ui.custom_css')
|
const [customCss] = usePreference('ui.custom_css')
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import store, { useAppDispatch, useAppSelector } from '@renderer/store'
|
import store, { useAppDispatch, useAppSelector } from '@renderer/store'
|
||||||
import {
|
import {
|
||||||
AssistantIconType,
|
AssistantIconType,
|
||||||
SendMessageShortcut,
|
|
||||||
setAssistantIconType,
|
setAssistantIconType,
|
||||||
setAutoCheckUpdate as _setAutoCheckUpdate,
|
setAutoCheckUpdate as _setAutoCheckUpdate,
|
||||||
// setDisableHardwareAcceleration,
|
// setDisableHardwareAcceleration,
|
||||||
@ -22,6 +21,7 @@ import {
|
|||||||
} 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'
|
||||||
|
import type { SendMessageShortcut } from '@shared/data/preferenceTypes'
|
||||||
|
|
||||||
export function useSettings() {
|
export function useSettings() {
|
||||||
const settings = useAppSelector((state) => state.settings)
|
const settings = useAppSelector((state) => state.settings)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { HolderOutlined } from '@ant-design/icons'
|
import { HolderOutlined } from '@ant-design/icons'
|
||||||
|
import { usePreference } from '@data/hooks/usePreference'
|
||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import { QuickPanelView, useQuickPanel } from '@renderer/components/QuickPanel'
|
import { QuickPanelView, useQuickPanel } from '@renderer/components/QuickPanel'
|
||||||
import TranslateButton from '@renderer/components/TranslateButton'
|
import TranslateButton from '@renderer/components/TranslateButton'
|
||||||
@ -18,7 +19,6 @@ import { useAssistant } from '@renderer/hooks/useAssistant'
|
|||||||
import { useKnowledgeBases } from '@renderer/hooks/useKnowledge'
|
import { useKnowledgeBases } from '@renderer/hooks/useKnowledge'
|
||||||
import { useMessageOperations, useTopicLoading } from '@renderer/hooks/useMessageOperations'
|
import { useMessageOperations, useTopicLoading } from '@renderer/hooks/useMessageOperations'
|
||||||
import { modelGenerating, useRuntime } from '@renderer/hooks/useRuntime'
|
import { modelGenerating, useRuntime } from '@renderer/hooks/useRuntime'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
|
||||||
import { useShortcut, useShortcutDisplay } from '@renderer/hooks/useShortcuts'
|
import { useShortcut, useShortcutDisplay } from '@renderer/hooks/useShortcuts'
|
||||||
import { useSidebarIconShow } from '@renderer/hooks/useSidebarIcon'
|
import { useSidebarIconShow } from '@renderer/hooks/useSidebarIcon'
|
||||||
import { useTimer } from '@renderer/hooks/useTimer'
|
import { useTimer } from '@renderer/hooks/useTimer'
|
||||||
@ -75,20 +75,20 @@ let _text = ''
|
|||||||
let _files: FileType[] = []
|
let _files: FileType[] = []
|
||||||
|
|
||||||
const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) => {
|
const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) => {
|
||||||
|
const [targetLanguage] = usePreference('feature.translate.target_language')
|
||||||
|
const [sendMessageShortcut] = usePreference('chat.input.send_message_shortcut')
|
||||||
|
const [pasteLongTextAsFile] = usePreference('chat.input.paste_long_text_as_file')
|
||||||
|
const [pasteLongTextThreshold] = usePreference('chat.input.paste_long_text_threshold')
|
||||||
|
const [showInputEstimatedTokens] = usePreference('chat.input.show_estimated_tokens')
|
||||||
|
const [autoTranslateWithSpace] = usePreference('chat.input.translate.auto_translate_with_space')
|
||||||
|
const [enableQuickPanelTriggers] = usePreference('chat.input.quick_panel.triggers_enabled')
|
||||||
|
const [enableSpellCheck] = usePreference('app.spell_check.enabled')
|
||||||
|
const [fontSize] = usePreference('chat.message.font_size')
|
||||||
|
|
||||||
const [text, setText] = useState(_text)
|
const [text, setText] = useState(_text)
|
||||||
const [inputFocus, setInputFocus] = useState(false)
|
const [inputFocus, setInputFocus] = useState(false)
|
||||||
const { assistant, addTopic, model, setModel, updateAssistant } = useAssistant(_assistant.id)
|
const { assistant, addTopic, model, setModel, updateAssistant } = useAssistant(_assistant.id)
|
||||||
const {
|
|
||||||
targetLanguage,
|
|
||||||
sendMessageShortcut,
|
|
||||||
fontSize,
|
|
||||||
pasteLongTextAsFile,
|
|
||||||
pasteLongTextThreshold,
|
|
||||||
showInputEstimatedTokens,
|
|
||||||
autoTranslateWithSpace,
|
|
||||||
enableQuickPanelTriggers,
|
|
||||||
enableSpellCheck
|
|
||||||
} = useSettings()
|
|
||||||
const [expanded, setExpand] = useState(false)
|
const [expanded, setExpand] = useState(false)
|
||||||
const [estimateTokenCount, setEstimateTokenCount] = useState(0)
|
const [estimateTokenCount, setEstimateTokenCount] = useState(0)
|
||||||
const [contextCount, setContextCount] = useState({ current: 0, max: 0 })
|
const [contextCount, setContextCount] = useState({ current: 0, max: 0 })
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import { CollapsibleSettingGroup } from '@renderer/pages/settings/SettingGroup'
|
|||||||
import { getDefaultModel } from '@renderer/services/AssistantService'
|
import { getDefaultModel } from '@renderer/services/AssistantService'
|
||||||
import { useAppDispatch } from '@renderer/store'
|
import { useAppDispatch } from '@renderer/store'
|
||||||
import {
|
import {
|
||||||
SendMessageShortcut,
|
|
||||||
setAutoTranslateWithSpace,
|
setAutoTranslateWithSpace,
|
||||||
setCodeCollapsible,
|
setCodeCollapsible,
|
||||||
setCodeEditor,
|
setCodeEditor,
|
||||||
@ -48,6 +47,7 @@ import {
|
|||||||
import { Assistant, AssistantSettings, CodeStyleVarious, MathEngine } from '@renderer/types'
|
import { Assistant, AssistantSettings, CodeStyleVarious, MathEngine } from '@renderer/types'
|
||||||
import { modalConfirm } from '@renderer/utils'
|
import { modalConfirm } from '@renderer/utils'
|
||||||
import { getSendMessageShortcutLabel } from '@renderer/utils/input'
|
import { getSendMessageShortcutLabel } from '@renderer/utils/input'
|
||||||
|
import type { SendMessageShortcut } from '@shared/data/preferenceTypes'
|
||||||
import { ThemeMode } from '@shared/data/preferenceTypes'
|
import { ThemeMode } from '@shared/data/preferenceTypes'
|
||||||
import { Button, Col, InputNumber, Row, Slider, Switch, Tooltip } from 'antd'
|
import { Button, Col, InputNumber, Row, Slider, Switch, Tooltip } from 'antd'
|
||||||
import { CircleHelp, Settings2 } from 'lucide-react'
|
import { CircleHelp, Settings2 } from 'lucide-react'
|
||||||
|
|||||||
@ -1,89 +1,103 @@
|
|||||||
// import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||||
// import { SelectionActionItem, FilterMode, SelectionState, TriggerMode } from '@shared/data/preferenceTypes'
|
import type { SelectionActionItem, SelectionFilterMode, SelectionTriggerMode } from '@shared/data/preferenceTypes'
|
||||||
|
|
||||||
// export const defaultActionItems: ActionItem[] = [
|
interface SelectionState {
|
||||||
// { id: 'translate', name: 'selection.action.builtin.translate', enabled: true, isBuiltIn: true, icon: 'languages' },
|
selectionEnabled: boolean
|
||||||
// { id: 'explain', name: 'selection.action.builtin.explain', enabled: true, isBuiltIn: true, icon: 'file-question' },
|
triggerMode: SelectionTriggerMode
|
||||||
// { id: 'summary', name: 'selection.action.builtin.summary', enabled: true, isBuiltIn: true, icon: 'scan-text' },
|
isCompact: boolean
|
||||||
// {
|
isAutoClose: boolean
|
||||||
// id: 'search',
|
isAutoPin: boolean
|
||||||
// name: 'selection.action.builtin.search',
|
isFollowToolbar: boolean
|
||||||
// enabled: true,
|
isRemeberWinSize: boolean
|
||||||
// isBuiltIn: true,
|
filterMode: SelectionFilterMode
|
||||||
// icon: 'search',
|
filterList: string[]
|
||||||
// searchEngine: 'Google|https://www.google.com/search?q={{queryString}}'
|
actionWindowOpacity: number
|
||||||
// },
|
actionItems: SelectionActionItem[]
|
||||||
// { id: 'copy', name: 'selection.action.builtin.copy', enabled: true, isBuiltIn: true, icon: 'clipboard-copy' },
|
}
|
||||||
// { id: 'refine', name: 'selection.action.builtin.refine', enabled: false, isBuiltIn: true, icon: 'wand-sparkles' },
|
|
||||||
// { id: 'quote', name: 'selection.action.builtin.quote', enabled: false, isBuiltIn: true, icon: 'quote' }
|
|
||||||
// ]
|
|
||||||
|
|
||||||
// export const initialState: SelectionState = {
|
export const defaultActionItems: SelectionActionItem[] = [
|
||||||
// selectionEnabled: false,
|
{ id: 'translate', name: 'selection.action.builtin.translate', enabled: true, isBuiltIn: true, icon: 'languages' },
|
||||||
// triggerMode: 'selected',
|
{ id: 'explain', name: 'selection.action.builtin.explain', enabled: true, isBuiltIn: true, icon: 'file-question' },
|
||||||
// isCompact: false,
|
{ id: 'summary', name: 'selection.action.builtin.summary', enabled: true, isBuiltIn: true, icon: 'scan-text' },
|
||||||
// isAutoClose: false,
|
{
|
||||||
// isAutoPin: false,
|
id: 'search',
|
||||||
// isFollowToolbar: true,
|
name: 'selection.action.builtin.search',
|
||||||
// isRemeberWinSize: false,
|
enabled: true,
|
||||||
// filterMode: 'default',
|
isBuiltIn: true,
|
||||||
// filterList: [],
|
icon: 'search',
|
||||||
// actionWindowOpacity: 100,
|
searchEngine: 'Google|https://www.google.com/search?q={{queryString}}'
|
||||||
// actionItems: defaultActionItems
|
},
|
||||||
// }
|
{ id: 'copy', name: 'selection.action.builtin.copy', enabled: true, isBuiltIn: true, icon: 'clipboard-copy' },
|
||||||
|
{ id: 'refine', name: 'selection.action.builtin.refine', enabled: false, isBuiltIn: true, icon: 'wand-sparkles' },
|
||||||
|
{ id: 'quote', name: 'selection.action.builtin.quote', enabled: false, isBuiltIn: true, icon: 'quote' }
|
||||||
|
]
|
||||||
|
|
||||||
// const selectionSlice = createSlice({
|
export const initialState: SelectionState = {
|
||||||
// name: 'selectionStore',
|
selectionEnabled: false,
|
||||||
// initialState,
|
triggerMode: 'selected',
|
||||||
// reducers: {
|
isCompact: false,
|
||||||
// setSelectionEnabled: (state, action: PayloadAction<boolean>) => {
|
isAutoClose: false,
|
||||||
// state.selectionEnabled = action.payload
|
isAutoPin: false,
|
||||||
// },
|
isFollowToolbar: true,
|
||||||
// setTriggerMode: (state, action: PayloadAction<TriggerMode>) => {
|
isRemeberWinSize: false,
|
||||||
// state.triggerMode = action.payload
|
filterMode: 'default',
|
||||||
// },
|
filterList: [],
|
||||||
// setIsCompact: (state, action: PayloadAction<boolean>) => {
|
actionWindowOpacity: 100,
|
||||||
// state.isCompact = action.payload
|
actionItems: defaultActionItems
|
||||||
// },
|
}
|
||||||
// setIsAutoClose: (state, action: PayloadAction<boolean>) => {
|
|
||||||
// state.isAutoClose = action.payload
|
|
||||||
// },
|
|
||||||
// setIsAutoPin: (state, action: PayloadAction<boolean>) => {
|
|
||||||
// state.isAutoPin = action.payload
|
|
||||||
// },
|
|
||||||
// setIsFollowToolbar: (state, action: PayloadAction<boolean>) => {
|
|
||||||
// state.isFollowToolbar = action.payload
|
|
||||||
// },
|
|
||||||
// setIsRemeberWinSize: (state, action: PayloadAction<boolean>) => {
|
|
||||||
// state.isRemeberWinSize = action.payload
|
|
||||||
// },
|
|
||||||
// setFilterMode: (state, action: PayloadAction<FilterMode>) => {
|
|
||||||
// state.filterMode = action.payload
|
|
||||||
// },
|
|
||||||
// setFilterList: (state, action: PayloadAction<string[]>) => {
|
|
||||||
// state.filterList = action.payload
|
|
||||||
// },
|
|
||||||
// setActionWindowOpacity: (state, action: PayloadAction<number>) => {
|
|
||||||
// state.actionWindowOpacity = action.payload
|
|
||||||
// },
|
|
||||||
// setActionItems: (state, action: PayloadAction<ActionItem[]>) => {
|
|
||||||
// state.actionItems = action.payload
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// export const {
|
const selectionSlice = createSlice({
|
||||||
// setSelectionEnabled,
|
name: 'selectionStore',
|
||||||
// setTriggerMode,
|
initialState,
|
||||||
// setIsCompact,
|
reducers: {
|
||||||
// setIsAutoClose,
|
setSelectionEnabled: (state, action: PayloadAction<boolean>) => {
|
||||||
// setIsAutoPin,
|
state.selectionEnabled = action.payload
|
||||||
// setIsFollowToolbar,
|
},
|
||||||
// setIsRemeberWinSize,
|
setTriggerMode: (state, action: PayloadAction<SelectionTriggerMode>) => {
|
||||||
// setFilterMode,
|
state.triggerMode = action.payload
|
||||||
// setFilterList,
|
},
|
||||||
// setActionWindowOpacity,
|
setIsCompact: (state, action: PayloadAction<boolean>) => {
|
||||||
// setActionItems
|
state.isCompact = action.payload
|
||||||
// } = selectionSlice.actions
|
},
|
||||||
|
setIsAutoClose: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.isAutoClose = action.payload
|
||||||
|
},
|
||||||
|
setIsAutoPin: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.isAutoPin = action.payload
|
||||||
|
},
|
||||||
|
setIsFollowToolbar: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.isFollowToolbar = action.payload
|
||||||
|
},
|
||||||
|
setIsRemeberWinSize: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.isRemeberWinSize = action.payload
|
||||||
|
},
|
||||||
|
setFilterMode: (state, action: PayloadAction<SelectionFilterMode>) => {
|
||||||
|
state.filterMode = action.payload
|
||||||
|
},
|
||||||
|
setFilterList: (state, action: PayloadAction<string[]>) => {
|
||||||
|
state.filterList = action.payload
|
||||||
|
},
|
||||||
|
setActionWindowOpacity: (state, action: PayloadAction<number>) => {
|
||||||
|
state.actionWindowOpacity = action.payload
|
||||||
|
},
|
||||||
|
setActionItems: (state, action: PayloadAction<SelectionActionItem[]>) => {
|
||||||
|
state.actionItems = action.payload
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// export default selectionSlice.reducer
|
export const {
|
||||||
|
setSelectionEnabled,
|
||||||
|
setTriggerMode,
|
||||||
|
setIsCompact,
|
||||||
|
setIsAutoClose,
|
||||||
|
setIsAutoPin,
|
||||||
|
setIsFollowToolbar,
|
||||||
|
setIsRemeberWinSize,
|
||||||
|
setFilterMode,
|
||||||
|
setFilterList,
|
||||||
|
setActionWindowOpacity,
|
||||||
|
setActionItems
|
||||||
|
} = selectionSlice.actions
|
||||||
|
|
||||||
|
export default selectionSlice.reducer
|
||||||
|
|||||||
@ -16,12 +16,13 @@ import {
|
|||||||
import { uuid } from '@renderer/utils'
|
import { uuid } from '@renderer/utils'
|
||||||
import { UpgradeChannel } from '@shared/config/constant'
|
import { UpgradeChannel } from '@shared/config/constant'
|
||||||
import { TRANSLATE_PROMPT } from '@shared/config/prompts'
|
import { TRANSLATE_PROMPT } from '@shared/config/prompts'
|
||||||
|
import type { SendMessageShortcut } from '@shared/data/preferenceTypes'
|
||||||
import { LanguageVarious, ThemeMode } from '@shared/data/preferenceTypes'
|
import { LanguageVarious, ThemeMode } from '@shared/data/preferenceTypes'
|
||||||
import { OpenAIVerbosity } from '@types'
|
import { OpenAIVerbosity } from '@types'
|
||||||
|
|
||||||
import { RemoteSyncState } from './backup'
|
import { RemoteSyncState } from './backup'
|
||||||
|
|
||||||
export type SendMessageShortcut = 'Enter' | 'Shift+Enter' | 'Ctrl+Enter' | 'Command+Enter' | 'Alt+Enter'
|
// export type SendMessageShortcut = 'Enter' | 'Shift+Enter' | 'Ctrl+Enter' | 'Command+Enter' | 'Alt+Enter'
|
||||||
|
|
||||||
// Re-export for backward compatibility
|
// Re-export for backward compatibility
|
||||||
export { DEFAULT_SIDEBAR_ICONS }
|
export { DEFAULT_SIDEBAR_ICONS }
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { SendMessageShortcut } from '@renderer/store/settings'
|
import type { SendMessageShortcut } from '@shared/data/preferenceTypes'
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
|
|
||||||
import { getFilesFromDropEvent, getSendMessageShortcutLabel, isSendMessageKeyPressed } from '../input'
|
import { getFilesFromDropEvent, getSendMessageShortcutLabel, isSendMessageKeyPressed } from '../input'
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import { isMac, isWin } from '@renderer/config/constant'
|
import { isMac, isWin } from '@renderer/config/constant'
|
||||||
import type { SendMessageShortcut } from '@renderer/store/settings'
|
|
||||||
import { FileMetadata } from '@renderer/types'
|
import { FileMetadata } from '@renderer/types'
|
||||||
|
import type { SendMessageShortcut } from '@shared/data/preferenceTypes'
|
||||||
|
|
||||||
const logger = loggerService.withContext('Utils:Input')
|
const logger = loggerService.withContext('Utils:Input')
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user