mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-09-03 10:00:22 +08:00
[Enhancement] Add i18n support for Electron menu
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
// electron/main/app-menu.ts (updated with i18n support)
|
||||
import {
|
||||
app,
|
||||
BrowserWindow,
|
||||
@@ -12,11 +13,12 @@ import {
|
||||
getCurrentPresetId,
|
||||
setCurrentPreset,
|
||||
} from "./config-manager"
|
||||
import { detectSystemLocale, getMenuTranslations } from "./menu-i18n"
|
||||
import { restartNextServer } from "./next-server"
|
||||
import { showSettingsWindow } from "./settings-window"
|
||||
|
||||
/**
|
||||
* Build and set the application menu
|
||||
* Build and set the application menu with i18n support
|
||||
*/
|
||||
export function buildAppMenu(): void {
|
||||
const template = getMenuTemplate()
|
||||
@@ -25,18 +27,22 @@ export function buildAppMenu(): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild the menu (call this when presets change)
|
||||
* Rebuild the menu (call this when presets change or language changes)
|
||||
*/
|
||||
export function rebuildAppMenu(): void {
|
||||
buildAppMenu()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the menu template
|
||||
* Get the menu template with translations
|
||||
*/
|
||||
function getMenuTemplate(): MenuItemConstructorOptions[] {
|
||||
const isMac = process.platform === "darwin"
|
||||
|
||||
// Get translations for current system locale
|
||||
const locale = detectSystemLocale(app.getLocale())
|
||||
const t = getMenuTranslations(locale)
|
||||
|
||||
const template: MenuItemConstructorOptions[] = []
|
||||
|
||||
// macOS app menu
|
||||
@@ -44,10 +50,10 @@ function getMenuTemplate(): MenuItemConstructorOptions[] {
|
||||
template.push({
|
||||
label: app.name,
|
||||
submenu: [
|
||||
{ role: "about" },
|
||||
{ role: "about" }, // System-translated
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "Settings...",
|
||||
label: t.settings,
|
||||
accelerator: "CmdOrCtrl+,",
|
||||
click: () => {
|
||||
const win = BrowserWindow.getFocusedWindow()
|
||||
@@ -55,26 +61,26 @@ function getMenuTemplate(): MenuItemConstructorOptions[] {
|
||||
},
|
||||
},
|
||||
{ type: "separator" },
|
||||
{ role: "services" },
|
||||
{ role: "services" }, // System-translated
|
||||
{ type: "separator" },
|
||||
{ role: "hide" },
|
||||
{ role: "hideOthers" },
|
||||
{ role: "unhide" },
|
||||
{ role: "hide" }, // System-translated
|
||||
{ role: "hideOthers" }, // System-translated
|
||||
{ role: "unhide" }, // System-translated
|
||||
{ type: "separator" },
|
||||
{ role: "quit" },
|
||||
{ role: "quit" }, // System-translated
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
// File menu
|
||||
template.push({
|
||||
label: "File",
|
||||
label: t.file,
|
||||
submenu: [
|
||||
...(isMac
|
||||
? []
|
||||
: [
|
||||
{
|
||||
label: "Settings",
|
||||
label: t.settings,
|
||||
accelerator: "CmdOrCtrl+,",
|
||||
click: () => {
|
||||
const win = BrowserWindow.getFocusedWindow()
|
||||
@@ -83,76 +89,76 @@ function getMenuTemplate(): MenuItemConstructorOptions[] {
|
||||
},
|
||||
{ type: "separator" } as MenuItemConstructorOptions,
|
||||
]),
|
||||
isMac ? { role: "close" } : { role: "quit" },
|
||||
isMac ? { role: "close" } : { role: "quit" }, // System-translated
|
||||
],
|
||||
})
|
||||
|
||||
// Edit menu
|
||||
template.push({
|
||||
label: "Edit",
|
||||
label: t.edit,
|
||||
submenu: [
|
||||
{ role: "undo" },
|
||||
{ role: "redo" },
|
||||
{ role: "undo" }, // System-translated
|
||||
{ role: "redo" }, // System-translated
|
||||
{ type: "separator" },
|
||||
{ role: "cut" },
|
||||
{ role: "copy" },
|
||||
{ role: "paste" },
|
||||
{ role: "cut" }, // System-translated
|
||||
{ role: "copy" }, // System-translated
|
||||
{ role: "paste" }, // System-translated
|
||||
...(isMac
|
||||
? [
|
||||
{
|
||||
role: "pasteAndMatchStyle",
|
||||
} as MenuItemConstructorOptions,
|
||||
{ role: "delete" } as MenuItemConstructorOptions,
|
||||
{ role: "selectAll" } as MenuItemConstructorOptions,
|
||||
} as MenuItemConstructorOptions, // System-translated
|
||||
{ role: "delete" } as MenuItemConstructorOptions, // System-translated
|
||||
{ role: "selectAll" } as MenuItemConstructorOptions, // System-translated
|
||||
]
|
||||
: [
|
||||
{ role: "delete" } as MenuItemConstructorOptions,
|
||||
{ role: "delete" } as MenuItemConstructorOptions, // System-translated
|
||||
{ type: "separator" } as MenuItemConstructorOptions,
|
||||
{ role: "selectAll" } as MenuItemConstructorOptions,
|
||||
{ role: "selectAll" } as MenuItemConstructorOptions, // System-translated
|
||||
]),
|
||||
],
|
||||
})
|
||||
|
||||
// View menu
|
||||
template.push({
|
||||
label: "View",
|
||||
label: t.view,
|
||||
submenu: [
|
||||
{ role: "reload" },
|
||||
{ role: "forceReload" },
|
||||
{ role: "toggleDevTools" },
|
||||
{ role: "reload" }, // System-translated
|
||||
{ role: "forceReload" }, // System-translated
|
||||
{ role: "toggleDevTools" }, // System-translated
|
||||
{ type: "separator" },
|
||||
{ role: "resetZoom" },
|
||||
{ role: "zoomIn" },
|
||||
{ role: "zoomOut" },
|
||||
{ role: "resetZoom" }, // System-translated
|
||||
{ role: "zoomIn" }, // System-translated
|
||||
{ role: "zoomOut" }, // System-translated
|
||||
{ type: "separator" },
|
||||
{ role: "togglefullscreen" },
|
||||
{ role: "togglefullscreen" }, // System-translated
|
||||
],
|
||||
})
|
||||
|
||||
// Configuration menu with presets
|
||||
template.push(buildConfigMenu())
|
||||
template.push(buildConfigMenu(t))
|
||||
|
||||
// Window menu
|
||||
template.push({
|
||||
label: "Window",
|
||||
label: t.window,
|
||||
submenu: [
|
||||
{ role: "minimize" },
|
||||
{ role: "zoom" },
|
||||
{ role: "minimize" }, // System-translated
|
||||
{ role: "zoom" }, // System-translated
|
||||
...(isMac
|
||||
? [
|
||||
{ type: "separator" } as MenuItemConstructorOptions,
|
||||
{ role: "front" } as MenuItemConstructorOptions,
|
||||
{ role: "front" } as MenuItemConstructorOptions, // System-translated
|
||||
]
|
||||
: [{ role: "close" } as MenuItemConstructorOptions]),
|
||||
: [{ role: "close" } as MenuItemConstructorOptions]), // System-translated
|
||||
],
|
||||
})
|
||||
|
||||
// Help menu
|
||||
template.push({
|
||||
label: "Help",
|
||||
label: t.help,
|
||||
submenu: [
|
||||
{
|
||||
label: "Documentation",
|
||||
label: t.documentation,
|
||||
click: async () => {
|
||||
await shell.openExternal(
|
||||
"https://github.com/dayuanjiang/next-ai-draw-io",
|
||||
@@ -160,7 +166,7 @@ function getMenuTemplate(): MenuItemConstructorOptions[] {
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Report Issue",
|
||||
label: t.reportIssue,
|
||||
click: async () => {
|
||||
await shell.openExternal(
|
||||
"https://github.com/dayuanjiang/next-ai-draw-io/issues",
|
||||
@@ -176,7 +182,9 @@ function getMenuTemplate(): MenuItemConstructorOptions[] {
|
||||
/**
|
||||
* Build the Configuration menu with presets
|
||||
*/
|
||||
function buildConfigMenu(): MenuItemConstructorOptions {
|
||||
function buildConfigMenu(
|
||||
t: ReturnType<typeof getMenuTranslations>,
|
||||
): MenuItemConstructorOptions {
|
||||
const presets = getAllPresets()
|
||||
const currentPresetId = getCurrentPresetId()
|
||||
|
||||
@@ -216,11 +224,11 @@ function buildConfigMenu(): MenuItemConstructorOptions {
|
||||
}))
|
||||
|
||||
return {
|
||||
label: "Configuration",
|
||||
label: t.configuration,
|
||||
submenu: [
|
||||
...(presetItems.length > 0
|
||||
? [
|
||||
{ label: "Switch Preset", enabled: false },
|
||||
{ label: t.switchPreset, enabled: false },
|
||||
{ type: "separator" } as MenuItemConstructorOptions,
|
||||
...presetItems,
|
||||
{ type: "separator" } as MenuItemConstructorOptions,
|
||||
@@ -229,8 +237,8 @@ function buildConfigMenu(): MenuItemConstructorOptions {
|
||||
{
|
||||
label:
|
||||
presetItems.length > 0
|
||||
? "Manage Presets..."
|
||||
: "Add Configuration Preset...",
|
||||
? t.managePresets
|
||||
: t.addConfigurationPreset,
|
||||
click: () => {
|
||||
const win = BrowserWindow.getFocusedWindow()
|
||||
showSettingsWindow(win || undefined)
|
||||
|
||||
Reference in New Issue
Block a user