feat(translations): basic translations support

This commit is contained in:
Alexey Kasyanchuk 2018-05-17 02:09:43 +03:00
parent 57c1d0d322
commit feff322592
7 changed files with 113 additions and 16 deletions

View File

@ -5,10 +5,13 @@ import PagesPie from './pages-pie.js';
//import registerServiceWorker from './registerServiceWorker'; //import registerServiceWorker from './registerServiceWorker';
import injectTapEventPlugin from 'react-tap-event-plugin'; import injectTapEventPlugin from 'react-tap-event-plugin';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import __, { changeLanguage } from './translation'
import {Header} from './header' import {Header} from './header'
import Footer from './footer' import Footer from './footer'
window.__ = __
if(typeof WEB !== 'undefined') if(typeof WEB !== 'undefined')
{ {
@ -130,6 +133,10 @@ class App extends Component {
window.p2pStatus = status window.p2pStatus = status
this.forceUpdate() this.forceUpdate()
}) })
window.torrentSocket.on('changeLanguage', (lang) => {
changeLanguage(lang, () => this.forceUpdate())
})
} }
componentWillUnmount() { componentWillUnmount() {
appReady = false; appReady = false;
@ -138,6 +145,7 @@ class App extends Component {
return ( return (
<MuiThemeProvider> <MuiThemeProvider>
<div> <div>
{ __('welcome') }
{ {
((window.currentWindow && !window.currentWindow.isModal()) || typeof WEB !== 'undefined') ((window.currentWindow && !window.currentWindow.isModal()) || typeof WEB !== 'undefined')
&& &&

41
src/app/translation.js Normal file
View File

@ -0,0 +1,41 @@
const fs = require('fs')
let dictionary = {}
function loadJSON(file, callback) {
if(fs)
{
callback(JSON.parse(fs.readFileSync(file, 'utf8')))
}
else
{
const xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', file, true);
xobj.onreadystatechange = function() {
if (xobj.readyState == 4 && xobj.status == 200) {
// .open will NOT return a value but simply returns undefined in async mode so use a callback
callback(JSON.parse(xobj.responseText));
}
}
xobj.send(null);
}
}
const changeLanguage = (lang, callback) => {
loadJSON(`translations/${lang}.json`, (data) => {
dictionary = data.translations
if(callback)
callback()
})
}
export { changeLanguage }
export default (word) => {
const translation = dictionary[word]
if(translation === undefined)
{
return word
}
return translation
}

View File

@ -12,7 +12,7 @@ import { autoUpdater } from 'electron-updater'
import { devMenuTemplate } from "./menu/dev_menu_template"; import { devMenuTemplate } from "./menu/dev_menu_template";
import { editMenuTemplate } from "./menu/edit_menu_template"; import { editMenuTemplate } from "./menu/edit_menu_template";
import { settingsMenuTemplate } from "./menu/config_menu_template"; import { settingsMenuTemplateFunc } from "./menu/config_menu_template";
import { aboutMenuTemplate } from "./menu/about_menu_template"; import { aboutMenuTemplate } from "./menu/about_menu_template";
import { manageMenuTemplate } from "./menu/manage_menu_template"; import { manageMenuTemplate } from "./menu/manage_menu_template";
@ -24,18 +24,6 @@ import fs from 'fs';
// plugins and dev tool // plugins and dev tool
require('electron-context-menu')({}) require('electron-context-menu')({})
const setApplicationMenu = () => {
const menus = [editMenuTemplate, manageMenuTemplate, settingsMenuTemplate, aboutMenuTemplate];
if (env.name !== "production") {
menus.push(devMenuTemplate);
}
// append version as disabled menu item
menus.push({
label: app.getVersion()
})
Menu.setApplicationMenu(Menu.buildFromTemplate(menus));
};
// Save userData in separate folders for each environment. // Save userData in separate folders for each environment.
// Thanks to this you can use production and development versions of the app // Thanks to this you can use production and development versions of the app
// on same machine like those are two separate apps. // on same machine like those are two separate apps.
@ -59,11 +47,29 @@ const appConfig = require('./config')
const spiderCall = require('./spider') const spiderCall = require('./spider')
const dbPatcher = require('./dbPatcher') const dbPatcher = require('./dbPatcher')
const startSphinx = require('./sphinx') const startSphinx = require('./sphinx')
const { changeLanguage } = require('../app/translation')
let mainWindow = undefined let mainWindow = undefined
let sphinx = undefined let sphinx = undefined
let spider = undefined let spider = undefined
const setApplicationMenu = () => {
const settingsMenuTemplate = settingsMenuTemplateFunc(appConfig, (lang) => {
// update menu translation
changeLanguage(lang, () => setApplicationMenu())
})
const menus = [editMenuTemplate, manageMenuTemplate, settingsMenuTemplate, aboutMenuTemplate];
if (env.name !== "production") {
menus.push(devMenuTemplate);
}
// append version as disabled menu item
menus.push({
label: app.getVersion()
})
Menu.setApplicationMenu(Menu.buildFromTemplate(menus));
};
const util = require('util'); const util = require('util');
if (!fs.existsSync(app.getPath("userData"))){ if (!fs.existsSync(app.getPath("userData"))){
fs.mkdirSync(app.getPath("userData")); fs.mkdirSync(app.getPath("userData"));
@ -144,7 +150,7 @@ app.on("ready", () => {
}); });
dbPatcher(() => { dbPatcher(() => {
setApplicationMenu(); changeLanguage(appConfig.language, () => setApplicationMenu())
mainWindow.loadURL( mainWindow.loadURL(
url.format({ url.format({

View File

@ -10,6 +10,7 @@ let config = {
udpTrackersPort: 4446, udpTrackersPort: 4446,
udpTrackersTimeout: 3 * 60 * 1000, udpTrackersTimeout: 3 * 60 * 1000,
peerId: undefined, peerId: undefined,
language: 'en',
p2p: true, p2p: true,
p2pConnections: 10, p2pConnections: 10,

View File

@ -1,6 +1,9 @@
import { app, BrowserWindow } from "electron"; import { app, BrowserWindow } from "electron";
import fs from 'fs'
import path from 'path'
import __ from '../../app/translation'
export const settingsMenuTemplate = { export const settingsMenuTemplateFunc = (config, onLanguageChange) => ({
label: "Settings", label: "Settings",
submenu: [ submenu: [
{ {
@ -16,6 +19,27 @@ export const settingsMenuTemplate = {
click: () => { click: () => {
BrowserWindow.getFocusedWindow().webContents.send('url', '/filters') BrowserWindow.getFocusedWindow().webContents.send('url', '/filters')
} }
},
{
label: __("Language"),
submenu: (() => {
const translations = []
fs.readdirSync('translations').forEach(translation => {
const translationJson = JSON.parse(fs.readFileSync(`translations/${translation}`, 'utf8'))
translations.push({
label: translationJson.nameOriginal,
click: () => {
const lang = path.basename(translation, '.json')
BrowserWindow.getFocusedWindow().webContents.send('changeLanguage', lang)
config.language = lang
if(onLanguageChange)
onLanguageChange(lang)
console.log('changed translation to:', lang)
}
})
})
return translations
})()
} }
] ]
}; });

8
translations/en.json Normal file
View File

@ -0,0 +1,8 @@
{
"name": "English",
"nameOriginal": "English",
"translations":
{
"welcome": "welcome"
}
}

9
translations/ru.json Normal file
View File

@ -0,0 +1,9 @@
{
"name": "Russian",
"nameOriginal": "Русский",
"translations":
{
"welcome": "приветствие",
"Language": "Язык"
}
}