1
0
mirror of https://github.com/pavlobu/deskreen.git synced 2025-05-18 08:20:10 -07:00

working locales on dev environment only

This commit is contained in:
Pavlo Buidenkov 2020-08-11 20:20:09 +03:00
parent 763c13c854
commit a12b323e5a
13 changed files with 285 additions and 10 deletions

View File

@ -1,4 +1,5 @@
import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { ipcRenderer } from 'electron';
import routes from '../constants/routes.json';
@ -8,22 +9,30 @@ import styles from './Home.css';
export default function Home(): JSX.Element {
const [signalingServerPort, setSignalingServerPort] = useState('0000');
const { t, i18n } = useTranslation();
// Example of how to get signaling server port from main process in renderer process
// following this practice, you can also get local server ip address
useEffect(() => {
ipcRenderer.on('sending-port-from-main', (event, message) => {
console.log(message);
setSignalingServerPort(message);
});
ipcRenderer.invoke('get-signaling-server-port');
}, []);
const onButtonClick = () => {
console.log(t('Language'));
};
return (
<div className={styles.container} data-tid="container">
<h2>Home</h2>
<Link to={routes.COUNTER}>to Counter</Link>
<h3>{`Signaling server is running on port: ${signalingServerPort}`}</h3>
<h3>{`Locales test ${t('Language')}`}</h3>
<button type="button" onClick={onButtonClick}>
CLICK ME!
</button>
</div>
);
}

View File

@ -0,0 +1,5 @@
export default {
languages: ['ru', 'en'],
fallbackLng: 'en',
namespace: 'translation',
};

View File

@ -0,0 +1,40 @@
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import SyncBackend from 'i18next-sync-fs-backend';
import { join } from 'path';
import isDev from 'electron-is-dev';
import config from './app.config';
const i18nextOptions = {
interpolation: {
escapeValue: false,
},
backend: {
// path where resources get loaded from
loadPath: isDev
? join(__dirname, './locales/{{lng}}/{{ns}}.json')
: 'locales/{{lng}}/{{ns}}.json',
// path to post missing resources
addPath: isDev
? join(__dirname, './locales/{{lng}}/{{ns}}.missing.json')
: 'locales/{{lng}}/{{ns}}.json',
// jsonIndent to use when storing json files
jsonIndent: 2,
},
saveMissing: true,
lng: 'en',
fallbackLng: config.fallbackLng,
whitelist: config.languages,
react: {
wait: false,
},
};
i18n.use(SyncBackend);
i18n.use(initReactI18next);
// initialize if not already initialized
if (!i18n.isInitialized) {
i18n.init(i18nextOptions);
}
export default i18n;

View File

@ -0,0 +1,58 @@
// const i18n = require('i18next');
// const i18nextBackend = require('i18next-fs-backend');
// const { join } = require('path');
// const config = require('./app.config');
import i18n from 'i18next';
import i18nextBackend from 'i18next-node-fs-backend';
import { join } from 'path';
import isDev from 'electron-is-dev';
import config from './app.config';
const i18nextOptions = {
fallbackLng: config.fallbackLng,
lng: 'en',
ns: 'translation',
defaultNS: 'translation',
backend: {
// path where resources get loaded from
loadPath: isDev
? join(__dirname, '../locales/{{lng}}/{{ns}}.json')
: 'locales/{{lng}}/{{ns}}.json',
// path to post missing resources
addPath: isDev
? join(__dirname, '../locales/{{lng}}/{{ns}}.missing.json')
: 'locales/{{lng}}/{{ns}}.json',
// jsonIndent to use when storing json files
jsonIndent: 2,
},
interpolation: {
escapeValue: false,
},
saveMissing: true,
whitelist: config.languages,
react: {
wait: false,
},
};
i18n.use(i18nextBackend);
// initialize if not already initialized
if (!i18n.isInitialized) {
i18n.init(i18nextOptions);
// i18n.init({
// lng: 'en',
// debug: true,
// resources: {
// en: {
// translation: {
// Language: 'Jjdjjdjd',
// },
// },
// },
// });
console.log('\n\n\n\n INTITIALIZING I18N ----');
}
console.log(i18n.t('Language'));
export default i18n;

View File

@ -1,6 +1,10 @@
import React, { Fragment } from 'react';
import React, { Fragment, Suspense } from 'react';
import { render } from 'react-dom';
import { AppContainer as ReactHotAppContainer } from 'react-hot-loader';
// import { ipcRenderer } from 'electron';
// import { I18nextProvider } from 'react-i18next';
// import i18n from './configs/i18next.config.client';
import './configs/i18next.config.client';
import { history, configuredStore } from './store';
import './app.global.css';
@ -8,12 +12,16 @@ const store = configuredStore();
const AppContainer = process.env.PLAIN_HMR ? Fragment : ReactHotAppContainer;
// let initialI18nStore = ipcRenderer.sendSync('get-initial-translations');
document.addEventListener('DOMContentLoaded', () => {
// eslint-disable-next-line global-require
const Root = require('./containers/Root').default;
render(
<AppContainer>
<Root store={store} history={history} />
<Suspense fallback="loading">
<Root store={store} history={history} />
</Suspense>
</AppContainer>,
document.getElementById('root')
);

View File

@ -0,0 +1,5 @@
{
"Language": "🌐 Language",
"ru": "Русский",
"en": "English"
}

View File

@ -0,0 +1,4 @@
{
"ru": "ru",
"en": "en"
}

View File

@ -0,0 +1,5 @@
{
"Language": "🌐 Язык",
"ru": "Русский",
"en": "English"
}

View File

View File

@ -11,14 +11,19 @@
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import path from 'path';
import { app, BrowserWindow, ipcMain } from 'electron';
import { app, BrowserWindow, ipcMain, Menu } from 'electron';
import { autoUpdater } from 'electron-updater';
import log from 'electron-log';
import config from './configs/app.config';
import i18n from './configs/i18next.config';
import signalingServer from './server/signalingServer';
import MenuBuilder from './menu';
signalingServer.start();
console.log('\n\n\n\n\n APP PATH');
console.log(app.getPath('app/locales'));
export default class AppUpdater {
constructor() {
log.transports.file.level = 'info';
@ -28,6 +33,7 @@ export default class AppUpdater {
}
let mainWindow: BrowserWindow | null = null;
let menuBuilder: MenuBuilder | null = null;
if (process.env.NODE_ENV === 'production') {
const sourceMapSupport = require('source-map-support');
@ -95,9 +101,20 @@ const createWindow = async () => {
mainWindow = null;
});
const menuBuilder = new MenuBuilder(mainWindow);
menuBuilder = new MenuBuilder(mainWindow, i18n);
menuBuilder.buildMenu();
i18n.on('loaded', (loaded) => {
i18n.changeLanguage('en');
i18n.off('loaded');
});
i18n.on('languageChanged', (lng) => {
menuBuilder = new MenuBuilder(mainWindow, i18n);
menuBuilder.buildMenu();
console.log(`Language changed! ${lng}`);
});
// Remove this if your app does not use auto updates
// eslint-disable-next-line
new AppUpdater();
@ -130,10 +147,21 @@ app.on('activate', () => {
// TODO: get locale of app and load appropriate menu texts and app texts( ISO 3166 COUNTRY CODES )
console.log('\n\n\n\n\n\n GETTING OS LOCALE: ');
console.log(app.getLocaleCountryCode());
console.log(app.getLocale());
ipcMain.handle('get-signaling-server-port', () => {
console.log('printing port');
console.log(signalingServer.port);
mainWindow.webContents.send('sending-port-from-main', signalingServer.port);
});
ipcMain.on('get-initial-translations', (event, arg) => {
i18n.loadLanguages('en', (err, t) => {
const initial = {
en: {
translation: i18n.getResourceBundle('en', config.namespace),
},
};
event.returnValue = initial;
});
});

View File

@ -6,6 +6,8 @@ import {
MenuItemConstructorOptions,
} from 'electron';
import config from './configs/app.config';
import signalingServer from './server/signalingServer';
interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions {
@ -16,8 +18,11 @@ interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions {
export default class MenuBuilder {
mainWindow: BrowserWindow;
constructor(mainWindow: BrowserWindow) {
i18n: any;
constructor(mainWindow: BrowserWindow, i18n: any) {
this.mainWindow = mainWindow;
this.i18n = i18n;
}
buildMenu(): Menu {
@ -192,7 +197,33 @@ export default class MenuBuilder {
? subMenuViewDev
: subMenuViewProd;
return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow, subMenuHelp];
const languageSubmenu = config.languages.map((languageCode) => {
return {
label: this.i18n.t(languageCode),
type: 'radio',
checked: this.i18n.language === languageCode,
click: () => {
this.i18n.changeLanguage(languageCode);
},
};
});
const languageMenu: MenuItemConstructorOptions = {
label: this.i18n.t('Language'),
submenu: languageSubmenu,
};
console.log('\n\n\n\n\nprinting stufff!!!!!');
console.log(this.i18n.t('Language'));
return [
subMenuAbout,
subMenuEdit,
subMenuView,
subMenuWindow,
subMenuHelp,
languageMenu,
];
}
buildDefaultTemplate() {

View File

@ -195,6 +195,7 @@
"@types/enzyme-adapter-react-16": "^1.0.6",
"@types/express": "^4.17.7",
"@types/history": "^4.7.6",
"@types/i18next-node-fs-backend": "^2.1.0",
"@types/jest": "^26.0.5",
"@types/node": "12",
"@types/react": "^16.9.44",
@ -281,14 +282,20 @@
"axios": "^0.19.2",
"connected-react-router": "^6.6.1",
"electron-debug": "^3.1.0",
"electron-is-dev": "^1.2.0",
"electron-log": "^4.2.2",
"electron-updater": "^4.3.1",
"express": "^4.17.1",
"get-port": "^5.1.1",
"history": "^4.7.2",
"i18next": "^19.6.3",
"i18next-fs-backend": "^1.0.7",
"i18next-node-fs-backend": "^2.1.3",
"i18next-sync-fs-backend": "^1.1.1",
"react": "^16.13.1",
"react-dom": "^16.12.0",
"react-hot-loader": "^4.12.21",
"react-i18next": "^11.7.0",
"react-redux": "^7.2.0",
"react-router-dom": "^5.2.0",
"redux": "^4.0.5",

View File

@ -1085,7 +1085,7 @@
core-js-pure "^3.0.0"
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4":
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4":
version "7.11.2"
resolved "https://registry.npm.taobao.org/@babel/runtime/download/@babel/runtime-7.11.2.tgz?cache=0&sync_timestamp=1596637793207&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736"
integrity sha1-9UnBPHVMxAuHZEufqfCaapX+BzY=
@ -1620,6 +1620,13 @@
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
"@types/i18next-node-fs-backend@^2.1.0":
version "2.1.0"
resolved "https://registry.npm.taobao.org/@types/i18next-node-fs-backend/download/@types/i18next-node-fs-backend-2.1.0.tgz#83616bc8589f155438f150b83ec59b92e5347668"
integrity sha1-g2FryFifFVQ48VC4PsWbkuU0dmg=
dependencies:
i18next ">=17.0.11"
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
version "2.0.3"
resolved "https://registry.npm.taobao.org/@types/istanbul-lib-coverage/download/@types/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
@ -5475,7 +5482,7 @@ electron-is-accelerator@^0.1.0:
resolved "https://registry.npm.taobao.org/electron-is-accelerator/download/electron-is-accelerator-0.1.2.tgz#509e510c26a56b55e17f863a4b04e111846ab27b"
integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=
electron-is-dev@^1.1.0:
electron-is-dev@^1.1.0, electron-is-dev@^1.2.0:
version "1.2.0"
resolved "https://registry.npm.taobao.org/electron-is-dev/download/electron-is-dev-1.2.0.tgz#2e5cea0a1b3ccf1c86f577cee77363ef55deb05e"
integrity sha1-LlzqChs8zxyG9XfO53Nj71XesF4=
@ -7275,6 +7282,13 @@ html-escaper@^2.0.0:
resolved "https://registry.npm.taobao.org/html-escaper/download/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
integrity sha1-39YAJ9o2o238viNiYsAKWCJoFFM=
html-parse-stringify2@2.0.1:
version "2.0.1"
resolved "https://registry.npm.taobao.org/html-parse-stringify2/download/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a"
integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=
dependencies:
void-elements "^2.0.1"
html-tags@^3.1.0:
version "3.1.0"
resolved "https://registry.npm.taobao.org/html-tags/download/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
@ -7377,6 +7391,34 @@ husky@^4.2.5:
slash "^3.0.0"
which-pm-runs "^1.0.0"
i18next-fs-backend@^1.0.7:
version "1.0.7"
resolved "https://registry.npm.taobao.org/i18next-fs-backend/download/i18next-fs-backend-1.0.7.tgz#00ca4587e306f8948740408389dda73461a5d07f"
integrity sha1-AMpFh+MG+JSHQECDid2nNGGl0H8=
i18next-node-fs-backend@^2.1.3:
version "2.1.3"
resolved "https://registry.npm.taobao.org/i18next-node-fs-backend/download/i18next-node-fs-backend-2.1.3.tgz#483fa9eda4c152d62a3a55bcae2a5727ba887559"
integrity sha1-SD+p7aTBUtYqOlW8ripXJ7qIdVk=
dependencies:
js-yaml "3.13.1"
json5 "2.0.0"
i18next-sync-fs-backend@^1.1.1:
version "1.1.1"
resolved "https://registry.npm.taobao.org/i18next-sync-fs-backend/download/i18next-sync-fs-backend-1.1.1.tgz#d1fb28545918e899b59feccc61adb4b9f5593a04"
integrity sha1-0fsoVFkY6Jm1n+zMYa20ufVZOgQ=
dependencies:
js-yaml "3.13.1"
json5 "0.5.0"
i18next@>=17.0.11, i18next@^19.6.3:
version "19.6.3"
resolved "https://registry.npm.taobao.org/i18next/download/i18next-19.6.3.tgz#ce2346161b35c4c5ab691b0674119c7b349c0817"
integrity sha1-ziNGFhs1xMWraRsGdBGcezScCBc=
dependencies:
"@babel/runtime" "^7.10.1"
iconv-lite@0.4.24:
version "0.4.24"
resolved "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz?cache=0&sync_timestamp=1594184266261&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@ -8549,6 +8591,14 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
resolved "https://registry.npm.taobao.org/js-tokens/download/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha1-GSA/tZmR35jjoocFDUZHzerzJJk=
js-yaml@3.13.1:
version "3.13.1"
resolved "https://registry.npm.taobao.org/js-yaml/download/js-yaml-3.13.1.tgz?cache=0&sync_timestamp=1593091110355&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjs-yaml%2Fdownload%2Fjs-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha1-r/FRswv9+o5J4F2iLnQV6d+jeEc=
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^3.13.1, js-yaml@^3.14.0:
version "3.14.0"
resolved "https://registry.npm.taobao.org/js-yaml/download/js-yaml-3.14.0.tgz?cache=0&sync_timestamp=1593091110355&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjs-yaml%2Fdownload%2Fjs-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482"
@ -8644,6 +8694,18 @@ json3@^3.3.2:
resolved "https://registry.npm.taobao.org/json3/download/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
integrity sha1-f8EON1/FrkLEcFpcwKpvYr4wW4E=
json5@0.5.0:
version "0.5.0"
resolved "https://registry.npm.taobao.org/json5/download/json5-0.5.0.tgz#9b20715b026cbe3778fd769edccd822d8332a5b2"
integrity sha1-myBxWwJsvjd4/Xae3M2CLYMypbI=
json5@2.0.0:
version "2.0.0"
resolved "https://registry.npm.taobao.org/json5/download/json5-2.0.0.tgz#b61abf97aa178c4b5853a66cc8eecafd03045d78"
integrity sha1-thq/l6oXjEtYU6ZsyO7K/QMEXXg=
dependencies:
minimist "^1.2.0"
json5@2.x, json5@^2.1.0, json5@^2.1.2:
version "2.1.3"
resolved "https://registry.npm.taobao.org/json5/download/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
@ -11175,6 +11237,14 @@ react-hot-loader@^4.12.21:
shallowequal "^1.1.0"
source-map "^0.7.3"
react-i18next@^11.7.0:
version "11.7.0"
resolved "https://registry.npm.taobao.org/react-i18next/download/react-i18next-11.7.0.tgz#f27c4c237a274e007a48ac1210db83e33719908b"
integrity sha1-8nxMI3onTgB6SKwSENuD4zcZkIs=
dependencies:
"@babel/runtime" "^7.3.1"
html-parse-stringify2 "2.0.1"
react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0:
version "16.13.1"
resolved "https://registry.npm.taobao.org/react-is/download/react-is-16.13.1.tgz?cache=0&sync_timestamp=1596207163827&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-is%2Fdownload%2Freact-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@ -13882,6 +13952,11 @@ vm-browserify@^1.0.1:
resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha1-eGQcSIuObKkadfUR56OzKobl3aA=
void-elements@^2.0.1:
version "2.0.1"
resolved "https://registry.npm.taobao.org/void-elements/download/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
w3c-hr-time@^1.0.2:
version "1.0.2"
resolved "https://registry.npm.taobao.org/w3c-hr-time/download/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"