refs #151 Add i18next and translate main menu

This commit is contained in:
AkiraFukushima 2018-08-10 08:47:29 +09:00
parent 4c5adbe481
commit 12be5bc3d6
9 changed files with 346 additions and 163 deletions

78
package-lock.json generated
View File

@ -715,7 +715,6 @@
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"requires": {
"sprintf-js": "1.0.3"
}
@ -3404,6 +3403,11 @@
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
},
"coffeescript": {
"version": "1.12.7",
"resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.12.7.tgz",
"integrity": "sha512-pLXHFxQMPklVoEekowk8b3erNynC+DVJzChxS/LCBBgR6/8AJkHivkm//zbowcfc7BTCAjryuhx6gPqPRfsFoA=="
},
"collapse-white-space": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.4.tgz",
@ -4022,6 +4026,14 @@
"integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
"dev": true
},
"cson-parser": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-3.0.0.tgz",
"integrity": "sha512-khmLtNmwe6SSlWz5vrhay9yWd/Fwwyiel+vt+1vIcCT9AsdqNuLXuK9tYhhAw1FdSSHjLc56PW8xa565/x73XQ==",
"requires": {
"coffeescript": "1.12.7"
}
},
"css": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/css/-/css-2.2.3.tgz",
@ -6070,8 +6082,7 @@
"esprima": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
"dev": true
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE="
},
"esquery": {
"version": "1.0.1",
@ -8833,6 +8844,62 @@
"integrity": "sha1-pls0RZrWNnrbs3B6gqPJ+RYWcDA=",
"dev": true
},
"i18next": {
"version": "11.5.0",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-11.5.0.tgz",
"integrity": "sha512-PM2G3iY1LoHonDwygLT9xyBAINuHujXnisnrib7RXdLtE9Tb1dT8RKXwWB+MCl9VOcM5rJwWO9iLw/3KftVEoA=="
},
"i18next-node-fs-backend": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/i18next-node-fs-backend/-/i18next-node-fs-backend-1.2.1.tgz",
"integrity": "sha512-lMd/tWsdgDFb158FwXHff63WZpTXggO3j8YOFEko+EvzRPzoIWkvfqdU5Oogn/p4nYfOMnCeEns29ksPF6rZBQ==",
"requires": {
"cson-parser": "3.0.0",
"js-yaml": "3.5.4",
"json5": "0.5.0"
},
"dependencies": {
"js-yaml": {
"version": "3.5.4",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.4.tgz",
"integrity": "sha1-9k8W3NeL65zoNhBo5zPr5HsHkXk=",
"requires": {
"argparse": "1.0.10",
"esprima": "2.7.3"
}
},
"json5": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.0.tgz",
"integrity": "sha1-myBxWwJsvjd4/Xae3M2CLYMypbI="
}
}
},
"i18next-sync-fs-backend": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/i18next-sync-fs-backend/-/i18next-sync-fs-backend-1.1.0.tgz",
"integrity": "sha512-Lj2QE06GB77hNtkG60vJ5mRQWDKTIaCnVkQYfp9j9NHbvICpKlidtrR6fewVSWHQLxxfjFzNniI7vVB7b5LpUw==",
"requires": {
"js-yaml": "3.5.4",
"json5": "0.5.0"
},
"dependencies": {
"js-yaml": {
"version": "3.5.4",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.4.tgz",
"integrity": "sha1-9k8W3NeL65zoNhBo5zPr5HsHkXk=",
"requires": {
"argparse": "1.0.10",
"esprima": "2.7.3"
}
},
"json5": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.0.tgz",
"integrity": "sha1-myBxWwJsvjd4/Xae3M2CLYMypbI="
}
}
},
"iconv-lite": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
@ -10628,7 +10695,7 @@
},
"onetime": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
"dev": true
},
@ -16014,8 +16081,7 @@
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"sshpk": {
"version": "1.14.2",

View File

@ -104,6 +104,9 @@
"element-ui": "^2.3.4",
"hawk": "^7.0.7",
"hoek": "^5.0.3",
"i18next": "^11.5.0",
"i18next-node-fs-backend": "^1.2.1",
"i18next-sync-fs-backend": "^1.1.0",
"is-empty": "^1.2.0",
"lodash": "^4.17.10",
"megalodon": "^0.3.0",

23
src/config/i18n.js Normal file
View File

@ -0,0 +1,23 @@
import path from 'path'
import i18next from 'i18next'
import Backend from 'i18next-sync-fs-backend'
const options = {
initImmediate: false,
backend: {
// path where resources get loaded from
loadPath: path.resolve(__dirname, './locales/{{lng}}/{{ns}}.json'),
// path to post missing resources
addPath: path.resolve(__dirname, './locales/{{lng}}/{{ns}}.missing.json'),
// jsonIndent to use when storing json files
jsonIndent: 2
}
}
i18next
.use(Backend)
.init(options)
export default i18next

View File

@ -0,0 +1,37 @@
{
"main_menu": {
"application": {
"name": "Whalebird",
"about": "About Whalebird",
"preferences": "Preferences...",
"services": "Services",
"hide": "Hide Whalebird",
"hide_others": "Hide Others",
"show_all": "Show All",
"quit": "Quit"
},
"toot": {
"name": "Toot",
"new": "New Toot"
},
"edit": {
"name": "Edit",
"undo": "Undo",
"redo": "Redo",
"cut": "Cut",
"copy": "Copy",
"paste": "Paste",
"select_all": "Select All"
},
"view": {
"name": "View",
"toggle_full_screen": "Toggle Full Screen"
},
"window": {
"name": "Window",
"close": "Close Window",
"minimize": "Minimize",
"jump_to": "Jump to"
}
}
}

View File

@ -0,0 +1,37 @@
{
"main_menu": {
"application": {
"name": "Whalebird",
"about": "Whalebirdについて",
"preferences": "設定...",
"services": "サービス",
"hide": "Whalebirdを隠す",
"hide_others": "ほかを隠す",
"show_all": "すべてを表示",
"quit": "終了"
},
"toot": {
"name": "トゥート",
"new": "トゥート"
},
"edit": {
"name": "編集",
"undo": "取り消す",
"redo": "やり直す",
"cut": "カット",
"copy": "コピー",
"paste": "ペースト",
"select_all": "すべてを選択"
},
"view": {
"name": "表示",
"toggle_full_screen": "フルスクリーンにする"
},
"window": {
"name": "ウィンドウ",
"close": "閉じる",
"minimize": "縮小",
"jump_to": "ジャンプ"
}
}
}

View File

@ -7,7 +7,6 @@ import log from 'electron-log'
import windowStateKeeper from 'electron-window-state'
import simplayer from 'simplayer'
import path from 'path'
import openAboutWindow from 'about-window'
import ContextMenu from 'electron-context-menu'
import * as Splashscreen from '@trodi/electron-splashscreen'
@ -16,6 +15,8 @@ import Account from './account'
import Streaming from './streaming'
import Preferences from './preferences'
import Hashtags from './hashtags'
import ApplicationMenu from './menu'
import i18n from '../config/i18n'
/**
* Context menu
@ -107,165 +108,12 @@ async function createWindow () {
click: () => changeAccount(a, index)
}
})
/**
* For mac menu
*/
const macGeneralMenu = process.platform !== 'darwin' ? [] : [
{
type: 'separator'
},
{
label: 'Services',
role: 'services',
submenu: []
},
{
type: 'separator'
},
{
label: 'Hide Whalebird',
role: 'hide'
},
{
label: 'Hide Others',
role: 'hideothers'
},
{
label: 'Show All',
role: 'unhide'
}
]
i18n.changeLanguage('ja')
/**
* Set application menu
*/
const template = [
{
label: 'Whalebird',
submenu: [
{
label: 'About Whalebird',
role: 'about',
click: () => {
openAboutWindow({
icon_path: path.resolve(__dirname, '../../build/icons/256x256.png'),
copyright: 'Copyright (c) 2018 AkiraFukushima',
package_json_dir: path.resolve(__dirname, '../../'),
open_devtools: process.env.NODE_ENV !== 'production'
})
}
},
{
type: 'separator'
},
{
label: 'Preferences...',
accelerator: 'CmdOrCtrl+,',
click: () => {
mainWindow.webContents.send('open-preferences')
}
},
...macGeneralMenu,
{
type: 'separator'
},
{
label: 'Quit',
accelerator: 'CmdOrCtrl+Q',
role: 'quit'
}
]
},
{
label: 'Toot',
submenu: [
{
label: 'New Toot',
accelerator: 'CmdOrCtrl+N',
click: () => {
mainWindow.webContents.send('CmdOrCtrl+N')
}
}
]
},
{
label: 'Edit',
submenu: [
{
label: 'Undo',
accelerator: 'CmdOrCtrl+Z',
role: 'undo'
},
{
label: 'Redo',
accelerator: 'Shift+CmdOrCtrl+Z',
role: 'redo'
},
{
type: 'separator'
},
{
label: 'Cut',
accelerator: 'CmdOrCtrl+X',
role: 'cut'
},
{
label: 'Copy',
accelerator: 'CmdOrCtrl+C',
role: 'copy'
},
{
label: 'Paste',
accelerator: 'CmdOrCtrl+V',
role: 'paste'
},
{
label: 'Select All',
accelerator: 'CmdOrCtrl+A',
role: 'selectall'
}
]
},
{
label: 'View',
submenu: [
{
label: 'Toggle Full Screen',
role: 'togglefullscreen'
}
]
},
{
label: 'Window',
submenu: [
{
label: 'Close Window',
role: 'close'
},
{
label: 'Minimize',
role: 'minimize'
},
{
type: 'separator'
},
{
label: 'Jump to',
accelerator: 'CmdOrCtrl+K',
enabled: true,
click: () => {
mainWindow.webContents.send('CmdOrCtrl+K')
}
},
{
type: 'separator'
},
...accountsChange
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
ApplicationMenu(mainWindow, accountsChange, i18n)
/**
* Set dock menu for mac

169
src/main/menu.js Normal file
View File

@ -0,0 +1,169 @@
import { Menu } from 'electron'
import path from 'path'
import openAboutWindow from 'about-window'
/**
* Set application menu
*/
const ApplicationMenu = (mainWindow, accountsChange, i18n) => {
/**
* For mac menu
*/
const macGeneralMenu = process.platform !== 'darwin' ? [] : [
{
type: 'separator'
},
{
label: i18n.t('main_menu.application.services'),
role: 'services',
submenu: []
},
{
type: 'separator'
},
{
label: i18n.t('main_menu.application.hide'),
role: 'hide'
},
{
label: i18n.t('main_menu.application.hide_others'),
role: 'hideothers'
},
{
label: i18n.t('main_menu.application.show_all'),
role: 'unhide'
}
]
const template = [
{
label: i18n.t('main_menu.application.name'),
submenu: [
{
label: i18n.t('main_menu.application.about'),
role: 'about',
click: () => {
openAboutWindow({
icon_path: path.resolve(__dirname, '../../build/icons/256x256.png'),
copyright: 'Copyright (c) 2018 AkiraFukushima',
package_json_dir: path.resolve(__dirname, '../../'),
open_devtools: process.env.NODE_ENV !== 'production'
})
}
},
{
type: 'separator'
},
{
label: i18n.t('main_menu.application.preferences'),
accelerator: 'CmdOrCtrl+,',
click: () => {
mainWindow.webContents.send('open-preferences')
}
},
...macGeneralMenu,
{
type: 'separator'
},
{
label: i18n.t('main_menu.application.quit'),
accelerator: 'CmdOrCtrl+Q',
role: 'quit'
}
]
},
{
label: i18n.t('main_menu.toot.name'),
submenu: [
{
label: i18n.t('main_menu.toot.new'),
accelerator: 'CmdOrCtrl+N',
click: () => {
mainWindow.webContents.send('CmdOrCtrl+N')
}
}
]
},
{
label: i18n.t('main_menu.edit.name'),
submenu: [
{
label: i18n.t('main_menu.edit.undo'),
accelerator: 'CmdOrCtrl+Z',
role: 'undo'
},
{
label: i18n.t('main_menu.edit.redo'),
accelerator: 'Shift+CmdOrCtrl+Z',
role: 'redo'
},
{
type: 'separator'
},
{
label: i18n.t('main_menu.edit.cut'),
accelerator: 'CmdOrCtrl+X',
role: 'cut'
},
{
label: i18n.t('main_menu.edit.copy'),
accelerator: 'CmdOrCtrl+C',
role: 'copy'
},
{
label: i18n.t('main_menu.edit.paste'),
accelerator: 'CmdOrCtrl+V',
role: 'paste'
},
{
label: i18n.t('main_menu.edit.select_all'),
accelerator: 'CmdOrCtrl+A',
role: 'selectall'
}
]
},
{
label: i18n.t('main_menu.view.name'),
submenu: [
{
label: i18n.t('main_menu.view.toggle_full_screen'),
role: 'togglefullscreen'
}
]
},
{
label: i18n.t('main_menu.window.name'),
submenu: [
{
label: i18n.t('main_menu.window.close'),
role: 'close'
},
{
label: i18n.t('main_menu.window.minimize'),
role: 'minimize'
},
{
type: 'separator'
},
{
label: i18n.t('main_menu.window.jump_to'),
accelerator: 'CmdOrCtrl+K',
enabled: true,
click: () => {
mainWindow.webContents.send('CmdOrCtrl+K')
}
},
{
type: 'separator'
},
...accountsChange
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
}
export default ApplicationMenu