added locale for context-menu
This commit is contained in:
parent
ceca3408ff
commit
35efada37e
@ -29,6 +29,11 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
|
|||||||
ipcMain.handle('app:reload', () => mainWindow.reload())
|
ipcMain.handle('app:reload', () => mainWindow.reload())
|
||||||
ipcMain.handle('open:website', (_, url: string) => shell.openExternal(url))
|
ipcMain.handle('open:website', (_, url: string) => shell.openExternal(url))
|
||||||
|
|
||||||
|
// language
|
||||||
|
ipcMain.handle('app:set-language', (_, language) => {
|
||||||
|
configManager.setLanguage(language)
|
||||||
|
})
|
||||||
|
|
||||||
// theme
|
// theme
|
||||||
ipcMain.handle('app:set-theme', (_, theme: 'light' | 'dark') => {
|
ipcMain.handle('app:set-theme', (_, theme: 'light' | 'dark') => {
|
||||||
configManager.setTheme(theme)
|
configManager.setTheme(theme)
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
|
import { app } from 'electron'
|
||||||
import Store from 'electron-store'
|
import Store from 'electron-store'
|
||||||
|
|
||||||
|
type ThemeVarious = 'light' | 'dark'
|
||||||
|
type LanguageVarious = 'zh-CN' | 'zh-TW' | 'en-US'
|
||||||
|
|
||||||
export class ConfigManager {
|
export class ConfigManager {
|
||||||
private store: Store
|
private store: Store
|
||||||
|
|
||||||
@ -7,11 +11,19 @@ export class ConfigManager {
|
|||||||
this.store = new Store()
|
this.store = new Store()
|
||||||
}
|
}
|
||||||
|
|
||||||
getTheme(): 'light' | 'dark' {
|
getLanguage(): LanguageVarious {
|
||||||
return this.store.get('theme', 'light') as 'light' | 'dark'
|
return this.store.get('language', app.getLocale()) as LanguageVarious
|
||||||
}
|
}
|
||||||
|
|
||||||
setTheme(theme: 'light' | 'dark') {
|
setLanguage(theme: ThemeVarious) {
|
||||||
|
this.store.set('language', theme)
|
||||||
|
}
|
||||||
|
|
||||||
|
getTheme(): ThemeVarious {
|
||||||
|
return this.store.get('theme', 'light') as ThemeVarious
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme(theme: ThemeVarious) {
|
||||||
this.store.set('theme', theme)
|
this.store.set('theme', theme)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/main/utils/locales.ts
Normal file
11
src/main/utils/locales.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import EnUs from '../../renderer/src/i18n/locales/en-us.json'
|
||||||
|
import ZhCn from '../../renderer/src/i18n/locales/zh-cn.json'
|
||||||
|
import ZhTw from '../../renderer/src/i18n/locales/zh-tw.json'
|
||||||
|
|
||||||
|
const locales = {
|
||||||
|
'en-US': EnUs,
|
||||||
|
'zh-CN': ZhCn,
|
||||||
|
'zh-TW': ZhTw
|
||||||
|
}
|
||||||
|
|
||||||
|
export { locales }
|
||||||
@ -6,6 +6,7 @@ import { join } from 'path'
|
|||||||
import icon from '../../build/icon.png?asset'
|
import icon from '../../build/icon.png?asset'
|
||||||
import { titleBarOverlayDark, titleBarOverlayLight } from './config'
|
import { titleBarOverlayDark, titleBarOverlayLight } from './config'
|
||||||
import { configManager } from './services/ConfigManager'
|
import { configManager } from './services/ConfigManager'
|
||||||
|
import { locales } from './utils/locales'
|
||||||
|
|
||||||
export function createMainWindow() {
|
export function createMainWindow() {
|
||||||
// Load the previous state with fallback to defaults
|
// Load the previous state with fallback to defaults
|
||||||
@ -48,10 +49,13 @@ export function createMainWindow() {
|
|||||||
mainWindowState.manage(mainWindow)
|
mainWindowState.manage(mainWindow)
|
||||||
|
|
||||||
mainWindow.webContents.on('context-menu', () => {
|
mainWindow.webContents.on('context-menu', () => {
|
||||||
|
const locale = locales[configManager.getLanguage()]
|
||||||
|
const { common } = locale.translation
|
||||||
|
|
||||||
const menu = new Menu()
|
const menu = new Menu()
|
||||||
menu.append(new MenuItem({ label: '复制', role: 'copy' }))
|
menu.append(new MenuItem({ label: common.copy, role: 'copy' }))
|
||||||
menu.append(new MenuItem({ label: '粘贴', role: 'paste' }))
|
menu.append(new MenuItem({ label: common.paste, role: 'paste' }))
|
||||||
menu.append(new MenuItem({ label: '剪切', role: 'cut' }))
|
menu.append(new MenuItem({ label: common.cut, role: 'cut' }))
|
||||||
menu.popup()
|
menu.popup()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
2
src/preload/index.d.ts
vendored
2
src/preload/index.d.ts
vendored
@ -1,6 +1,7 @@
|
|||||||
import { ElectronAPI } from '@electron-toolkit/preload'
|
import { ElectronAPI } from '@electron-toolkit/preload'
|
||||||
import { FileType } from '@renderer/types'
|
import { FileType } from '@renderer/types'
|
||||||
import { WebDavConfig } from '@renderer/types'
|
import { WebDavConfig } from '@renderer/types'
|
||||||
|
import { LanguageVarious } from '@renderer/types'
|
||||||
import type { OpenDialogOptions } from 'electron'
|
import type { OpenDialogOptions } from 'electron'
|
||||||
import { Readable } from 'stream'
|
import { Readable } from 'stream'
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ declare global {
|
|||||||
checkForUpdate: () => void
|
checkForUpdate: () => void
|
||||||
openWebsite: (url: string) => void
|
openWebsite: (url: string) => void
|
||||||
setProxy: (proxy: string | undefined) => void
|
setProxy: (proxy: string | undefined) => void
|
||||||
|
setLanguage: (theme: LanguageVarious) => void
|
||||||
setTheme: (theme: 'light' | 'dark') => void
|
setTheme: (theme: 'light' | 'dark') => void
|
||||||
minApp: (options: { url: string; windowOptions?: Electron.BrowserWindowConstructorOptions }) => void
|
minApp: (options: { url: string; windowOptions?: Electron.BrowserWindowConstructorOptions }) => void
|
||||||
reload: () => void
|
reload: () => void
|
||||||
|
|||||||
@ -8,6 +8,7 @@ const api = {
|
|||||||
reload: () => ipcRenderer.invoke('app:reload'),
|
reload: () => ipcRenderer.invoke('app:reload'),
|
||||||
setProxy: (proxy: string) => ipcRenderer.invoke('app:proxy', proxy),
|
setProxy: (proxy: string) => ipcRenderer.invoke('app:proxy', proxy),
|
||||||
checkForUpdate: () => ipcRenderer.invoke('app:check-for-update'),
|
checkForUpdate: () => ipcRenderer.invoke('app:check-for-update'),
|
||||||
|
setLanguage: (lang: string) => ipcRenderer.invoke('app:set-language', lang),
|
||||||
setTheme: (theme: 'light' | 'dark') => ipcRenderer.invoke('app:set-theme', theme),
|
setTheme: (theme: 'light' | 'dark') => ipcRenderer.invoke('app:set-theme', theme),
|
||||||
openWebsite: (url: string) => ipcRenderer.invoke('open:website', url),
|
openWebsite: (url: string) => ipcRenderer.invoke('open:website', url),
|
||||||
minApp: (url: string) => ipcRenderer.invoke('minapp', url),
|
minApp: (url: string) => ipcRenderer.invoke('minapp', url),
|
||||||
|
|||||||
@ -17,6 +17,8 @@
|
|||||||
"edit": "Edit",
|
"edit": "Edit",
|
||||||
"duplicate": "Duplicate",
|
"duplicate": "Duplicate",
|
||||||
"copy": "Copy",
|
"copy": "Copy",
|
||||||
|
"paste": "Paste",
|
||||||
|
"cut": "Cut",
|
||||||
"regenerate": "Regenerate",
|
"regenerate": "Regenerate",
|
||||||
"provider": "Provider",
|
"provider": "Provider",
|
||||||
"you": "You",
|
"you": "You",
|
||||||
|
|||||||
@ -17,6 +17,8 @@
|
|||||||
"edit": "编辑",
|
"edit": "编辑",
|
||||||
"duplicate": "复制",
|
"duplicate": "复制",
|
||||||
"copy": "复制",
|
"copy": "复制",
|
||||||
|
"paste": "粘贴",
|
||||||
|
"cut": "剪切",
|
||||||
"regenerate": "重新生成",
|
"regenerate": "重新生成",
|
||||||
"provider": "提供商",
|
"provider": "提供商",
|
||||||
"you": "用户",
|
"you": "用户",
|
||||||
|
|||||||
@ -17,6 +17,8 @@
|
|||||||
"edit": "編輯",
|
"edit": "編輯",
|
||||||
"duplicate": "複製",
|
"duplicate": "複製",
|
||||||
"copy": "複製",
|
"copy": "複製",
|
||||||
|
"paste": "貼上",
|
||||||
|
"cut": "剪下",
|
||||||
"regenerate": "重新生成",
|
"regenerate": "重新生成",
|
||||||
"provider": "提供商",
|
"provider": "提供商",
|
||||||
"you": "您",
|
"you": "您",
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import i18n from '@renderer/i18n'
|
|||||||
import { useAppDispatch } from '@renderer/store'
|
import { useAppDispatch } from '@renderer/store'
|
||||||
import { setClickAssistantToShowTopic, setLanguage, setShowTopicTime } from '@renderer/store/settings'
|
import { setClickAssistantToShowTopic, setLanguage, setShowTopicTime } from '@renderer/store/settings'
|
||||||
import { setProxyUrl as _setProxyUrl } from '@renderer/store/settings'
|
import { setProxyUrl as _setProxyUrl } from '@renderer/store/settings'
|
||||||
import { ThemeMode } from '@renderer/types'
|
import { LanguageVarious, ThemeMode } from '@renderer/types'
|
||||||
import { isValidProxyUrl } from '@renderer/utils'
|
import { isValidProxyUrl } from '@renderer/utils'
|
||||||
import { Input, Select, Switch } from 'antd'
|
import { Input, Select, Switch } from 'antd'
|
||||||
import { FC, useState } from 'react'
|
import { FC, useState } from 'react'
|
||||||
@ -30,9 +30,10 @@ const GeneralSettings: FC = () => {
|
|||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const onSelectLanguage = (value: string) => {
|
const onSelectLanguage = (value: LanguageVarious) => {
|
||||||
dispatch(setLanguage(value))
|
dispatch(setLanguage(value))
|
||||||
localStorage.setItem('language', value)
|
localStorage.setItem('language', value)
|
||||||
|
window.api.setLanguage(value)
|
||||||
i18n.changeLanguage(value)
|
i18n.changeLanguage(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||||
import { ThemeMode } from '@renderer/types'
|
import { LanguageVarious, ThemeMode } from '@renderer/types'
|
||||||
|
|
||||||
export type SendMessageShortcut = 'Enter' | 'Shift+Enter'
|
export type SendMessageShortcut = 'Enter' | 'Shift+Enter'
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ export interface SettingsState {
|
|||||||
showAssistants: boolean
|
showAssistants: boolean
|
||||||
showTopics: boolean
|
showTopics: boolean
|
||||||
sendMessageShortcut: SendMessageShortcut
|
sendMessageShortcut: SendMessageShortcut
|
||||||
language: string
|
language: LanguageVarious
|
||||||
proxyUrl?: string
|
proxyUrl?: string
|
||||||
userName: string
|
userName: string
|
||||||
showMessageDivider: boolean
|
showMessageDivider: boolean
|
||||||
@ -36,7 +36,7 @@ const initialState: SettingsState = {
|
|||||||
showAssistants: true,
|
showAssistants: true,
|
||||||
showTopics: true,
|
showTopics: true,
|
||||||
sendMessageShortcut: 'Enter',
|
sendMessageShortcut: 'Enter',
|
||||||
language: navigator.language,
|
language: navigator.language as LanguageVarious,
|
||||||
proxyUrl: undefined,
|
proxyUrl: undefined,
|
||||||
userName: '',
|
userName: '',
|
||||||
showMessageDivider: false,
|
showMessageDivider: false,
|
||||||
@ -79,7 +79,7 @@ const settingsSlice = createSlice({
|
|||||||
setSendMessageShortcut: (state, action: PayloadAction<SendMessageShortcut>) => {
|
setSendMessageShortcut: (state, action: PayloadAction<SendMessageShortcut>) => {
|
||||||
state.sendMessageShortcut = action.payload
|
state.sendMessageShortcut = action.payload
|
||||||
},
|
},
|
||||||
setLanguage: (state, action: PayloadAction<string>) => {
|
setLanguage: (state, action: PayloadAction<LanguageVarious>) => {
|
||||||
state.language = action.payload
|
state.language = action.payload
|
||||||
},
|
},
|
||||||
setProxyUrl: (state, action: PayloadAction<string | undefined>) => {
|
setProxyUrl: (state, action: PayloadAction<string | undefined>) => {
|
||||||
|
|||||||
@ -136,6 +136,7 @@ export enum ThemeMode {
|
|||||||
dark = 'dark',
|
dark = 'dark',
|
||||||
auto = 'auto'
|
auto = 'auto'
|
||||||
}
|
}
|
||||||
|
export type LanguageVarious = 'zh-CN' | 'zh-TW' | 'en-US'
|
||||||
|
|
||||||
export type WebDavConfig = {
|
export type WebDavConfig = {
|
||||||
webdavHost: string
|
webdavHost: string
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user