mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-27 04:31:27 +08:00
* 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>
136 lines
3.9 KiB
TypeScript
136 lines
3.9 KiB
TypeScript
import { Menu, MenuItemConstructorOptions } from 'electron'
|
|
|
|
import { locales } from '../utils/locales'
|
|
import { configManager } from './ConfigManager'
|
|
|
|
class ContextMenu {
|
|
public contextMenu(w: Electron.BrowserWindow) {
|
|
w.webContents.on('context-menu', (_event, properties) => {
|
|
const template: MenuItemConstructorOptions[] = this.createEditMenuItems(properties)
|
|
const filtered = template.filter((item) => item.visible !== false)
|
|
if (filtered.length > 0) {
|
|
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()
|
|
}
|
|
})
|
|
}
|
|
|
|
private createInspectMenuItems(w: Electron.BrowserWindow): MenuItemConstructorOptions[] {
|
|
const locale = locales[configManager.getLanguage()]
|
|
const { common } = locale.translation
|
|
const template: MenuItemConstructorOptions[] = [
|
|
{
|
|
id: 'inspect',
|
|
label: common.inspect,
|
|
click: () => {
|
|
w.webContents.toggleDevTools()
|
|
},
|
|
enabled: true
|
|
}
|
|
]
|
|
|
|
return template
|
|
}
|
|
|
|
private createEditMenuItems(properties: Electron.ContextMenuParams): MenuItemConstructorOptions[] {
|
|
const locale = locales[configManager.getLanguage()]
|
|
const { common } = locale.translation
|
|
const hasText = properties.selectionText.trim().length > 0
|
|
const can = (type: string) => properties.editFlags[`can${type}`] && hasText
|
|
|
|
const template: MenuItemConstructorOptions[] = [
|
|
{
|
|
id: 'copy',
|
|
label: common.copy,
|
|
role: 'copy',
|
|
enabled: can('Copy'),
|
|
visible: properties.isEditable || hasText
|
|
},
|
|
{
|
|
id: 'paste',
|
|
label: common.paste,
|
|
role: 'paste',
|
|
enabled: properties.editFlags.canPaste,
|
|
visible: properties.isEditable
|
|
},
|
|
{
|
|
id: 'cut',
|
|
label: common.cut,
|
|
role: 'cut',
|
|
enabled: can('Cut'),
|
|
visible: properties.isEditable
|
|
}
|
|
]
|
|
|
|
// remove role from items that are not enabled
|
|
// https://github.com/electron/electron/issues/13554
|
|
template.forEach((item) => {
|
|
if (item.enabled === false) {
|
|
item.role = undefined
|
|
}
|
|
})
|
|
|
|
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()
|