mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-28 13:31:32 +08:00
feat(ContextMenu): add spell check and dictionary suggestions to context menu (#7067)
* feat(ContextMenu): add spell check and dictionary suggestions to context menu - Implemented spell check functionality in the context menu with options to learn spelling and view dictionary suggestions. - Updated WindowService to enable spellcheck in the webview. - Enabled spell check in Inputbar and MessageEditor components. * feat(SpellCheck): implement spell check language settings and initialization - Added support for configuring spell check languages based on user-selected language. - Introduced IPC channel for setting spell check languages. - Updated settings to manage spell check enablement and languages. - Enhanced UI to allow users to toggle spell check functionality and select languages. - Default spell check languages are set based on the current UI language if none are specified. * refactor(SpellCheck): enhance spell check language mapping and UI settings - Updated spell check language mapping to default to English for unsupported languages. - Improved UI logic to only update spell check languages when enabled and no manual selections are made. - Added a new selection component for users to choose from commonly supported spell check languages. * feat(SpellCheck): integrate spell check functionality into Inputbar and MessageEditor - Added enableSpellCheck setting to control spell check functionality in both Inputbar and MessageEditor components. - Updated spellCheck prop to utilize the new setting, enhancing user experience by allowing customization of spell check behavior. * refactor(SpellCheck): move spell check initialization to WindowService - Removed spell check language initialization from index.ts and integrated it into WindowService. - Added setupSpellCheck method to configure spell check languages based on user settings. - Enhanced error handling for spell check language setup. * feat(SpellCheck): add enable spell check functionality and IPC channel - Introduced a new IPC channel for enabling/disabling spell check functionality. - Updated the preload API to include a method for setting spell check enablement. - Modified the main IPC handler to manage spell check settings based on user input. - Simplified spell check language handling in the settings component by directly invoking the new API method. * refactor(SpellCheck): remove spellcheck option from WindowService configuration - Removed the spellcheck property from the WindowService configuration object. - This change streamlines the configuration setup as spell check functionality is now managed through IPC channels. * feat(i18n): add spell check translations for Japanese, Russian, and Traditional Chinese - Added new translations for spell check functionality in ja-jp, ru-ru, and zh-tw locale files. - Included descriptions and language selection options for spell check settings to enhance user experience. * feat(migrate): add spell check configuration migration - Implemented migration for spell check settings, disabling spell check and clearing selected languages in the new configuration. - Enhanced error handling to ensure state consistency during migration process. * fix(migrate): ensure spell check settings are updated safely - Added a check to ensure state.settings exists before modifying spell check settings during migration. - Removed redundant error handling that returned the state unmodified in case of an error. * fix(WindowService): set default values for spell check configuration and update related UI texts * refactor(Inputbar, MessageEditor): remove contextMenu attribute and add context menu handling in MessageEditor --------- Co-authored-by: beyondkmp <beyondkmkp@gmail.com>
This commit is contained in:
parent
be15206234
commit
bbe380cc9e
@ -3,6 +3,8 @@ export enum IpcChannel {
|
||||
App_ClearCache = 'app:clear-cache',
|
||||
App_SetLaunchOnBoot = 'app:set-launch-on-boot',
|
||||
App_SetLanguage = 'app:set-language',
|
||||
App_SetEnableSpellCheck = 'app:set-enable-spell-check',
|
||||
App_SetSpellCheckLanguages = 'app:set-spell-check-languages',
|
||||
App_ShowUpdateDialog = 'app:show-update-dialog',
|
||||
App_CheckForUpdate = 'app:check-for-update',
|
||||
App_Reload = 'app:reload',
|
||||
|
||||
@ -87,6 +87,26 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
|
||||
configManager.setLanguage(language)
|
||||
})
|
||||
|
||||
// spell check
|
||||
ipcMain.handle(IpcChannel.App_SetEnableSpellCheck, (_, isEnable: boolean) => {
|
||||
const windows = BrowserWindow.getAllWindows()
|
||||
windows.forEach((window) => {
|
||||
window.webContents.session.setSpellCheckerEnabled(isEnable)
|
||||
})
|
||||
})
|
||||
|
||||
// spell check languages
|
||||
ipcMain.handle(IpcChannel.App_SetSpellCheckLanguages, (_, languages: string[]) => {
|
||||
if (languages.length === 0) {
|
||||
return
|
||||
}
|
||||
const windows = BrowserWindow.getAllWindows()
|
||||
windows.forEach((window) => {
|
||||
window.webContents.session.setSpellCheckerLanguages(languages)
|
||||
})
|
||||
configManager.set('spellCheckLanguages', languages)
|
||||
})
|
||||
|
||||
// launch on boot
|
||||
ipcMain.handle(IpcChannel.App_SetLaunchOnBoot, (_, openAtLogin: boolean) => {
|
||||
// Set login item settings for windows and mac
|
||||
|
||||
@ -9,7 +9,18 @@ class ContextMenu {
|
||||
const template: MenuItemConstructorOptions[] = this.createEditMenuItems(properties)
|
||||
const filtered = template.filter((item) => item.visible !== false)
|
||||
if (filtered.length > 0) {
|
||||
const menu = Menu.buildFromTemplate([...filtered, ...this.createInspectMenuItems(w)])
|
||||
let template = [...filtered, ...this.createInspectMenuItems(w)]
|
||||
const dictionarySuggestions = this.createDictionarySuggestions(properties, w)
|
||||
if (dictionarySuggestions.length > 0) {
|
||||
template = [
|
||||
...dictionarySuggestions,
|
||||
{ type: 'separator' },
|
||||
this.createSpellCheckMenuItem(properties, w),
|
||||
{ type: 'separator' },
|
||||
...template
|
||||
]
|
||||
}
|
||||
const menu = Menu.buildFromTemplate(template)
|
||||
menu.popup()
|
||||
}
|
||||
})
|
||||
@ -72,6 +83,53 @@ class ContextMenu {
|
||||
|
||||
return template
|
||||
}
|
||||
|
||||
private createSpellCheckMenuItem(
|
||||
properties: Electron.ContextMenuParams,
|
||||
mainWindow: Electron.BrowserWindow
|
||||
): MenuItemConstructorOptions {
|
||||
const hasText = properties.selectionText.length > 0
|
||||
|
||||
return {
|
||||
id: 'learnSpelling',
|
||||
label: '&Learn Spelling',
|
||||
visible: Boolean(properties.isEditable && hasText && properties.misspelledWord),
|
||||
click: () => {
|
||||
mainWindow.webContents.session.addWordToSpellCheckerDictionary(properties.misspelledWord)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private createDictionarySuggestions(
|
||||
properties: Electron.ContextMenuParams,
|
||||
mainWindow: Electron.BrowserWindow
|
||||
): MenuItemConstructorOptions[] {
|
||||
const hasText = properties.selectionText.length > 0
|
||||
|
||||
if (!hasText || !properties.misspelledWord) {
|
||||
return []
|
||||
}
|
||||
|
||||
if (properties.dictionarySuggestions.length === 0) {
|
||||
return [
|
||||
{
|
||||
id: 'dictionarySuggestions',
|
||||
label: 'No Guesses Found',
|
||||
visible: true,
|
||||
enabled: false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
return properties.dictionarySuggestions.map((suggestion) => ({
|
||||
id: 'dictionarySuggestions',
|
||||
label: suggestion,
|
||||
visible: Boolean(properties.isEditable && hasText && properties.misspelledWord),
|
||||
click: (menuItem: Electron.MenuItem) => {
|
||||
mainWindow.webContents.replaceMisspelling(menuItem.label)
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
export const contextMenu = new ContextMenu()
|
||||
|
||||
@ -95,6 +95,7 @@ export class WindowService {
|
||||
|
||||
this.setupMaximize(mainWindow, mainWindowState.isMaximized)
|
||||
this.setupContextMenu(mainWindow)
|
||||
this.setupSpellCheck(mainWindow)
|
||||
this.setupWindowEvents(mainWindow)
|
||||
this.setupWebContentsHandlers(mainWindow)
|
||||
this.setupWindowLifecycleEvents(mainWindow)
|
||||
@ -102,6 +103,18 @@ export class WindowService {
|
||||
this.loadMainWindowContent(mainWindow)
|
||||
}
|
||||
|
||||
private setupSpellCheck(mainWindow: BrowserWindow) {
|
||||
const enableSpellCheck = configManager.get('enableSpellCheck', false)
|
||||
if (enableSpellCheck) {
|
||||
try {
|
||||
const spellCheckLanguages = configManager.get('spellCheckLanguages', []) as string[]
|
||||
spellCheckLanguages.length > 0 && mainWindow.webContents.session.setSpellCheckerLanguages(spellCheckLanguages)
|
||||
} catch (error) {
|
||||
Logger.error('Failed to set spell check languages:', error as Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private setupMainWindowMonitor(mainWindow: BrowserWindow) {
|
||||
mainWindow.webContents.on('render-process-gone', (_, details) => {
|
||||
Logger.error(`Renderer process crashed with: ${JSON.stringify(details)}`)
|
||||
|
||||
@ -17,6 +17,8 @@ const api = {
|
||||
checkForUpdate: () => ipcRenderer.invoke(IpcChannel.App_CheckForUpdate),
|
||||
showUpdateDialog: () => ipcRenderer.invoke(IpcChannel.App_ShowUpdateDialog),
|
||||
setLanguage: (lang: string) => ipcRenderer.invoke(IpcChannel.App_SetLanguage, lang),
|
||||
setEnableSpellCheck: (isEnable: boolean) => ipcRenderer.invoke(IpcChannel.App_SetEnableSpellCheck, isEnable),
|
||||
setSpellCheckLanguages: (languages: string[]) => ipcRenderer.invoke(IpcChannel.App_SetSpellCheckLanguages, languages),
|
||||
setLaunchOnBoot: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetLaunchOnBoot, isActive),
|
||||
setLaunchToTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetLaunchToTray, isActive),
|
||||
setTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTray, isActive),
|
||||
|
||||
@ -864,7 +864,7 @@
|
||||
"paint_course": "tutorial",
|
||||
"prompt_placeholder_edit": "Enter your image description, text drawing uses \"double quotes\" to wrap",
|
||||
"prompt_placeholder_en": "Enter your image description, currently Imagen only supports English prompts",
|
||||
"proxy_required": "Open the proxy and enable “TUN mode” to view generated images or copy them to the browser for opening. In the future, domestic direct connection will be supported",
|
||||
"proxy_required": "Open the proxy and enable \"TUN mode\" to view generated images or copy them to the browser for opening. In the future, domestic direct connection will be supported",
|
||||
"image_file_required": "Please upload an image first",
|
||||
"image_file_retry": "Please re-upload an image first",
|
||||
"image_placeholder": "No image available",
|
||||
@ -1392,6 +1392,8 @@
|
||||
"general.user_name": "User Name",
|
||||
"general.user_name.placeholder": "Enter your name",
|
||||
"general.view_webdav_settings": "View WebDAV settings",
|
||||
"general.spell_check": "Spell Check",
|
||||
"general.spell_check.languages": "Use spell check for",
|
||||
"input.auto_translate_with_space": "Quickly translate with 3 spaces",
|
||||
"input.show_translate_confirm": "Show translation confirmation dialog",
|
||||
"input.target_language": "Target language",
|
||||
|
||||
@ -1387,6 +1387,8 @@
|
||||
"general.user_name": "ユーザー名",
|
||||
"general.user_name.placeholder": "ユーザー名を入力",
|
||||
"general.view_webdav_settings": "WebDAV設定を表示",
|
||||
"general.spell_check": "スペルチェック",
|
||||
"general.spell_check.languages": "スペルチェック言語",
|
||||
"input.auto_translate_with_space": "スペースを3回押して翻訳",
|
||||
"input.target_language": "目標言語",
|
||||
"input.target_language.chinese": "簡体字中国語",
|
||||
|
||||
@ -1387,6 +1387,8 @@
|
||||
"general.user_name": "Имя пользователя",
|
||||
"general.user_name.placeholder": "Введите ваше имя",
|
||||
"general.view_webdav_settings": "Просмотр настроек WebDAV",
|
||||
"general.spell_check": "Проверка орфографии",
|
||||
"general.spell_check.languages": "Языки проверки орфографии",
|
||||
"input.auto_translate_with_space": "Быстрый перевод с помощью 3-х пробелов",
|
||||
"input.target_language": "Целевой язык",
|
||||
"input.target_language.chinese": "Китайский упрощенный",
|
||||
|
||||
@ -863,8 +863,8 @@
|
||||
"learn_more": "了解更多",
|
||||
"paint_course": "教程",
|
||||
"prompt_placeholder_edit": "输入你的图片描述,文本绘制用 \"双引号\" 包裹",
|
||||
"prompt_placeholder_en": "输入”英文“图片描述,目前 Imagen 仅支持英文提示词",
|
||||
"proxy_required": "打开代理并开启”TUN模式“查看生成图片或复制到浏览器打开,后续会支持国内直连",
|
||||
"prompt_placeholder_en": "输入\"英文\"图片描述,目前 Imagen 仅支持英文提示词",
|
||||
"proxy_required": "打开代理并开启\"TUN模式\"查看生成图片或复制到浏览器打开,后续会支持国内直连",
|
||||
"image_file_required": "请先上传图片",
|
||||
"image_file_retry": "请重新上传图片",
|
||||
"image_placeholder": "暂无图片",
|
||||
@ -960,7 +960,7 @@
|
||||
"magic_prompt_option_tip": "智能优化放大提示词"
|
||||
},
|
||||
"text_desc_required": "请先输入图片描述",
|
||||
"req_error_text": "运行失败,请重试。提示词避免“版权词”和”敏感词”哦。",
|
||||
"req_error_text": "运行失败,请重试。提示词避免\"版权词\"和\"敏感词\"哦。",
|
||||
"req_error_token": "请检查令牌有效性",
|
||||
"req_error_no_balance": "请检查令牌有效性",
|
||||
"image_handle_required": "请先上传图片",
|
||||
@ -1390,9 +1390,11 @@
|
||||
"general.restore.button": "恢复",
|
||||
"general.title": "常规设置",
|
||||
"general.user_name": "用户名",
|
||||
"general.user_name.placeholder": "请输入用户名",
|
||||
"general.user_name.placeholder": "输入您的姓名",
|
||||
"general.view_webdav_settings": "查看 WebDAV 设置",
|
||||
"input.auto_translate_with_space": "快速敲击3次空格翻译",
|
||||
"general.spell_check": "拼写检查",
|
||||
"general.spell_check.languages": "拼写检查语言",
|
||||
"input.auto_translate_with_space": "3个空格快速翻译",
|
||||
"input.show_translate_confirm": "显示翻译确认对话框",
|
||||
"input.target_language": "目标语言",
|
||||
"input.target_language.chinese": "简体中文",
|
||||
|
||||
@ -1389,6 +1389,8 @@
|
||||
"general.user_name": "使用者名稱",
|
||||
"general.user_name.placeholder": "輸入您的名稱",
|
||||
"general.view_webdav_settings": "檢視 WebDAV 設定",
|
||||
"general.spell_check": "拼寫檢查",
|
||||
"general.spell_check.languages": "拼寫檢查語言",
|
||||
"input.auto_translate_with_space": "快速敲擊 3 次空格翻譯",
|
||||
"input.show_translate_confirm": "顯示翻譯確認對話框",
|
||||
"input.target_language": "目標語言",
|
||||
|
||||
@ -77,7 +77,8 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
||||
showInputEstimatedTokens,
|
||||
autoTranslateWithSpace,
|
||||
enableQuickPanelTriggers,
|
||||
enableBackspaceDeleteModel
|
||||
enableBackspaceDeleteModel,
|
||||
enableSpellCheck
|
||||
} = useSettings()
|
||||
const [expended, setExpend] = useState(false)
|
||||
const [estimateTokenCount, setEstimateTokenCount] = useState(0)
|
||||
@ -780,9 +781,8 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
||||
: t('chat.input.placeholder', { key: getSendMessageShortcutLabel(sendMessageShortcut) })
|
||||
}
|
||||
autoFocus
|
||||
contextMenu="true"
|
||||
variant="borderless"
|
||||
spellCheck={false}
|
||||
spellCheck={enableSpellCheck}
|
||||
rows={2}
|
||||
ref={textareaRef}
|
||||
style={{
|
||||
|
||||
@ -40,7 +40,7 @@ const MessageBlockEditor: FC<Props> = ({ message, onSave, onResend, onCancel })
|
||||
const model = assistant.model || assistant.defaultModel
|
||||
const isVision = useMemo(() => isVisionModel(model), [model])
|
||||
const supportExts = useMemo(() => [...textExts, ...documentExts, ...(isVision ? imageExts : [])], [isVision])
|
||||
const { pasteLongTextAsFile, pasteLongTextThreshold, fontSize, sendMessageShortcut } = useSettings()
|
||||
const { pasteLongTextAsFile, pasteLongTextThreshold, fontSize, sendMessageShortcut, enableSpellCheck } = useSettings()
|
||||
const { t } = useTranslation()
|
||||
const textareaRef = useRef<TextAreaRef>(null)
|
||||
const attachmentButtonRef = useRef<AttachmentButtonRef>(null)
|
||||
@ -222,13 +222,16 @@ const MessageBlockEditor: FC<Props> = ({ message, onSave, onResend, onCancel })
|
||||
}}
|
||||
onKeyDown={(e) => handleKeyDown(e, block.id)}
|
||||
autoFocus
|
||||
contextMenu="true"
|
||||
spellCheck={false}
|
||||
spellCheck={enableSpellCheck}
|
||||
onPaste={(e) => onPaste(e.nativeEvent)}
|
||||
onFocus={() => {
|
||||
// 记录当前聚焦的组件
|
||||
PasteService.setLastFocusedComponent('messageEditor')
|
||||
}}
|
||||
onContextMenu={(e) => {
|
||||
// 阻止事件冒泡,避免触发全局的 Electron contextMenu
|
||||
e.stopPropagation()
|
||||
}}
|
||||
style={{
|
||||
fontSize,
|
||||
padding: '0px 15px 8px 15px'
|
||||
|
||||
@ -2,8 +2,15 @@ import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { useSettings } from '@renderer/hooks/useSettings'
|
||||
import i18n from '@renderer/i18n'
|
||||
import { RootState, useAppDispatch } from '@renderer/store'
|
||||
import { setEnableDataCollection, setLanguage, setNotificationSettings } from '@renderer/store/settings'
|
||||
import { setProxyMode, setProxyUrl as _setProxyUrl } from '@renderer/store/settings'
|
||||
import {
|
||||
setEnableDataCollection,
|
||||
setEnableSpellCheck,
|
||||
setLanguage,
|
||||
setNotificationSettings,
|
||||
setProxyMode,
|
||||
setProxyUrl as _setProxyUrl,
|
||||
setSpellCheckLanguages
|
||||
} from '@renderer/store/settings'
|
||||
import { LanguageVarious } from '@renderer/types'
|
||||
import { NotificationSource } from '@renderer/types/notification'
|
||||
import { isValidProxyUrl } from '@renderer/utils'
|
||||
@ -26,7 +33,8 @@ const GeneralSettings: FC = () => {
|
||||
trayOnClose,
|
||||
tray,
|
||||
proxyMode: storeProxyMode,
|
||||
enableDataCollection
|
||||
enableDataCollection,
|
||||
enableSpellCheck
|
||||
} = useSettings()
|
||||
const [proxyUrl, setProxyUrl] = useState<string | undefined>(storeProxyUrl)
|
||||
const { theme } = useTheme()
|
||||
@ -69,6 +77,11 @@ const GeneralSettings: FC = () => {
|
||||
i18n.changeLanguage(value)
|
||||
}
|
||||
|
||||
const handleSpellCheckChange = (checked: boolean) => {
|
||||
dispatch(setEnableSpellCheck(checked))
|
||||
window.api.setEnableSpellCheck(checked)
|
||||
}
|
||||
|
||||
const onSetProxyUrl = () => {
|
||||
if (proxyUrl && !isValidProxyUrl(proxyUrl)) {
|
||||
window.message.error({ content: t('message.error.invalid.proxy.url'), key: 'proxy-error' })
|
||||
@ -109,11 +122,30 @@ const GeneralSettings: FC = () => {
|
||||
]
|
||||
|
||||
const notificationSettings = useSelector((state: RootState) => state.settings.notification)
|
||||
const spellCheckLanguages = useSelector((state: RootState) => state.settings.spellCheckLanguages)
|
||||
|
||||
const handleNotificationChange = (type: NotificationSource, value: boolean) => {
|
||||
dispatch(setNotificationSettings({ ...notificationSettings, [type]: value }))
|
||||
}
|
||||
|
||||
// Define available spell check languages with display names (only commonly supported languages)
|
||||
const spellCheckLanguageOptions = [
|
||||
{ value: 'en-US', label: 'English (US)', flag: '🇺🇸' },
|
||||
{ value: 'es', label: 'Español', flag: '🇪🇸' },
|
||||
{ value: 'fr', label: 'Français', flag: '🇫🇷' },
|
||||
{ value: 'de', label: 'Deutsch', flag: '🇩🇪' },
|
||||
{ value: 'it', label: 'Italiano', flag: '🇮🇹' },
|
||||
{ value: 'pt', label: 'Português', flag: '🇵🇹' },
|
||||
{ value: 'ru', label: 'Русский', flag: '🇷🇺' },
|
||||
{ value: 'nl', label: 'Nederlands', flag: '🇳🇱' },
|
||||
{ value: 'pl', label: 'Polski', flag: '🇵🇱' }
|
||||
]
|
||||
|
||||
const handleSpellCheckLanguagesChange = (selectedLanguages: string[]) => {
|
||||
dispatch(setSpellCheckLanguages(selectedLanguages))
|
||||
window.api.setSpellCheckLanguages(selectedLanguages)
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingContainer theme={theme}>
|
||||
<SettingGroup theme={theme}>
|
||||
@ -135,6 +167,37 @@ const GeneralSettings: FC = () => {
|
||||
</Select>
|
||||
</SettingRow>
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
<SettingRowTitle>{t('settings.general.spell_check')}</SettingRowTitle>
|
||||
<Switch checked={enableSpellCheck} onChange={handleSpellCheckChange} />
|
||||
</SettingRow>
|
||||
{enableSpellCheck && (
|
||||
<>
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
<SettingRowTitle>{t('settings.general.spell_check.languages')}</SettingRowTitle>
|
||||
<Select
|
||||
mode="multiple"
|
||||
value={spellCheckLanguages}
|
||||
style={{ width: 280 }}
|
||||
placeholder={t('settings.general.spell_check.languages')}
|
||||
onChange={handleSpellCheckLanguagesChange}
|
||||
options={spellCheckLanguageOptions.map((lang) => ({
|
||||
value: lang.value,
|
||||
label: (
|
||||
<Space.Compact direction="horizontal" block>
|
||||
<Space.Compact block>{lang.label}</Space.Compact>
|
||||
<span role="img" aria-label={lang.flag}>
|
||||
{lang.flag}
|
||||
</span>
|
||||
</Space.Compact>
|
||||
)
|
||||
}))}
|
||||
/>
|
||||
</SettingRow>
|
||||
</>
|
||||
)}
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
<SettingRowTitle>{t('settings.proxy.mode.title')}</SettingRowTitle>
|
||||
<Select
|
||||
|
||||
@ -1603,6 +1603,10 @@ const migrateConfig = {
|
||||
state.settings.exportMenuOptions.plain_text = true
|
||||
}
|
||||
}
|
||||
if (state.settings) {
|
||||
state.settings.enableSpellCheck = false
|
||||
state.settings.spellCheckLanguages = []
|
||||
}
|
||||
return state
|
||||
} catch (error) {
|
||||
return state
|
||||
|
||||
@ -155,6 +155,8 @@ export interface SettingsState {
|
||||
minappsOpenLinkExternal: boolean
|
||||
// 隐私设置
|
||||
enableDataCollection: boolean
|
||||
enableSpellCheck: boolean
|
||||
spellCheckLanguages: string[]
|
||||
enableQuickPanelTriggers: boolean
|
||||
enableBackspaceDeleteModel: boolean
|
||||
exportMenuOptions: {
|
||||
@ -298,6 +300,8 @@ export const initialState: SettingsState = {
|
||||
showOpenedMinappsInSidebar: true,
|
||||
minappsOpenLinkExternal: false,
|
||||
enableDataCollection: false,
|
||||
enableSpellCheck: false,
|
||||
spellCheckLanguages: [],
|
||||
enableQuickPanelTriggers: false,
|
||||
enableBackspaceDeleteModel: true,
|
||||
exportMenuOptions: {
|
||||
@ -657,6 +661,12 @@ const settingsSlice = createSlice({
|
||||
setEnableDataCollection: (state, action: PayloadAction<boolean>) => {
|
||||
state.enableDataCollection = action.payload
|
||||
},
|
||||
setEnableSpellCheck: (state, action: PayloadAction<boolean>) => {
|
||||
state.enableSpellCheck = action.payload
|
||||
},
|
||||
setSpellCheckLanguages: (state, action: PayloadAction<string[]>) => {
|
||||
state.spellCheckLanguages = action.payload
|
||||
},
|
||||
setExportMenuOptions: (state, action: PayloadAction<typeof initialState.exportMenuOptions>) => {
|
||||
state.exportMenuOptions = action.payload
|
||||
},
|
||||
@ -776,8 +786,10 @@ export const {
|
||||
setShowOpenedMinappsInSidebar,
|
||||
setMinappsOpenLinkExternal,
|
||||
setEnableDataCollection,
|
||||
setEnableQuickPanelTriggers,
|
||||
setEnableSpellCheck,
|
||||
setSpellCheckLanguages,
|
||||
setExportMenuOptions,
|
||||
setEnableQuickPanelTriggers,
|
||||
setEnableBackspaceDeleteModel,
|
||||
setOpenAISummaryText,
|
||||
setOpenAIServiceTier,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user