Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

Commit

Permalink
Merge branch '768-electron-menu-i18n' of https://github.com/LiskHQ/li…
Browse files Browse the repository at this point in the history
…sk-nano into 768-electron-menu-i18n
  • Loading branch information
reyraa committed Oct 2, 2017
2 parents 92fb01b + 2860698 commit 0d7631a
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 81 deletions.
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ node('lisk-nano-01'){
stage ('Deploy and Set milestone') {
try {
sh '''
rsync -axl --delete "$WORKSPACE/app/dist/" "jenkins@master-01:/var/www/test/lisk-nano/$BRANCH_NAME/"
rsync -axl --delete --rsync-path="mkdir -p '/var/www/test/lisk-nano/$BRANCH_NAME/' && rsync" "$WORKSPACE/app/dist/" "jenkins@master-01:/var/www/test/lisk-nano/$BRANCH_NAME/"
# Cleanup - delete all files on success
rm -rf "$WORKSPACE/*"
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"postcss": "6.0.12",
"postcss-cssnext": "2.11.0",
"prop-types": "=15.5.10",
"qrcode.react": "=0.7.1",
"qrcode.react": "0.7.2",
"react": "=15.6.x",
"react-animate-on-change": "^1.0.0",
"react-circular-progressbar": "0.2.1",
Expand Down Expand Up @@ -78,9 +78,9 @@
"cucumber": "2.2.0",
"del-cli": "1.1.0",
"electron": "1.7.8",
"electron-builder": "19.30.2",
"electron-builder": "19.32.2",
"enzyme": "2.9.1",
"eslint": "4.7.2",
"eslint": "4.8.0",
"eslint-config-airbnb": "15.1.0",
"eslint-config-google": "0.9.1",
"eslint-loader": "1.9.0",
Expand All @@ -89,7 +89,7 @@
"eslint-plugin-react": "7.4.0",
"exports-loader": "0.6.4",
"extract-text-webpack-plugin": "3.0.0",
"file-loader": "0.11.2",
"file-loader": "1.1.0",
"glob": "=7.1.2",
"i18next-scanner": "=2.0.0",
"imports-loader": "0.7.1",
Expand All @@ -112,7 +112,7 @@
"postcss-reporter": "5.0.0",
"protractor": "5.1.2",
"protractor-cucumber-framework": "3.1.0",
"raw-loader": "=0.5.1",
"raw-loader": "1.0.0-beta.0",
"react-addons-test-utils": "=15.6.0",
"react-hot-loader": "^1.3.1",
"react-test-renderer": "=15.6.1",
Expand Down
29 changes: 4 additions & 25 deletions src/components/dialog/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,15 @@ import AppBar from 'react-toolbox/lib/app_bar';
import { IconButton } from 'react-toolbox/lib/button';
import styles from './dialog.css';
import getDialogs from './dialogs';
import routesReg from '../../utils/routes';

class DialogElement extends Component {
constructor() {
super();
this.state = {};
this.routesReg = [
{
regex: /\/main\/transactions(?:\/[^/]*)?$/,
path: '/main/transactions/',
params: 'dialog',
name: 'transactions',
}, {
regex: /\/main\/voting(?:\/[^/]*)?$/,
path: '/main/voting/',
params: 'dialog',
name: 'voting',
}, {
regex: /\/main\/forging(?:\/[^/]*)?$/,
path: '/main/forging/',
params: 'dialog',
name: 'forging',
}, {
regex: /\/(\w+)?$/,
path: '/',
params: 'dialog',
name: 'login',
},
];
this.current = {
pathname: '/',
reg: this.routesReg[3],
reg: routesReg[3],
list: [],
dialog: '',
};
Expand All @@ -50,8 +28,9 @@ class DialogElement extends Component {
}

checkForDialog() {
// if the dialog is wrong, show a toast
if (this.current.pathname !== this.props.history.location.pathname) {
this.current.reg = this.routesReg.find(item =>
this.current.reg = routesReg.find(item =>
item.regex.test(this.props.history.location.pathname));
this.current.pathname = this.props.history.location.pathname;
const dialogName = this.props.history.location.pathname.replace(this.current.reg.path, '');
Expand Down
37 changes: 37 additions & 0 deletions src/components/languageDropdown/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Dropdown } from 'react-toolbox';
import { translate } from 'react-i18next';
import React from 'react';

import i18n from '../../i18n';
import languages from '../../constants/languages';

const languagesSource = Object.keys(languages).map(key => ({
value: key,
label: languages[key].name,
flag: languages[key].flag,
}));

const handleChange = (value) => {
i18n.changeLanguage(value);
};

const customItem = item => (
<div>
<img src={item.flag}/> {item.label}
</div>
);

const LanguageDropdown = ({ t }) => (
<Dropdown
auto={false}
className='language'
label={t('Language')}
source={languagesSource}
value={i18n.language}
template={customItem}
onChange={handleChange}
/>
);

export default translate()(LanguageDropdown);

43 changes: 43 additions & 0 deletions src/components/languageDropdown/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import PropTypes from 'prop-types';
import React from 'react';

import { expect } from 'chai';
import { mount } from 'enzyme';
import sinon from 'sinon';

import LanguageDropdown from './index';
import i18n from '../../i18n';

// import * as accountApi from '../../utils/api/account';


describe('LanguageDropdown', () => {
let wrapper;
let props;

beforeEach(() => {
props = {
};
wrapper = mount(<LanguageDropdown {...props} />, {
context: { i18n },
childContextTypes: {
i18n: PropTypes.object.isRequired,
},
});
});

it('renders a Dropdown component', () => {
expect(wrapper.find('Dropdown')).to.have.length(1);
});

it('calls i18n.changeLanguage on chaning the value in the dropdown', () => {
const i18nSpy = sinon.spy(i18n, 'changeLanguage');

wrapper.find('Dropdown').simulate('click');
wrapper.find('Dropdown ul li').at(0).simulate('click');
expect(i18nSpy).to.have.been.calledWith('en');

i18nSpy.restore();
});
});

6 changes: 4 additions & 2 deletions src/components/login/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import getNetworks from './networks';
import PassphraseInput from '../passphraseInput';
import styles from './login.css';
import env from '../../constants/env';
import LanguageDropdown from '../languageDropdown';
import RelativeLink from '../relativeLink';

/**
Expand Down Expand Up @@ -163,9 +164,10 @@ class Login extends React.Component {
render() {
return (
<div className={`box ${styles.wrapper}`}>
<div className={`${grid.row} ${grid['center-xs']}`}>
<div className={`${grid['col-xs-12']} ${grid['col-sm-8']}`}>
<div className={grid.row}>
<div className={`${grid['col-xs-12']} ${grid['col-sm-8']} ${grid['col-sm-offset-2']}`}>
<form onSubmit={this.onFormSubmit.bind(this)}>
<LanguageDropdown />
<Dropdown
auto={false}
source={this.networks}
Expand Down
36 changes: 4 additions & 32 deletions src/components/settings/index.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,10 @@
import { Dropdown } from 'react-toolbox';
import { translate } from 'react-i18next';
import React from 'react';
import LanguageDropdown from '../languageDropdown';

import i18n from '../../i18n';
import languages from '../../constants/languages';

const languagesSource = Object.keys(languages).map(key => ({
value: key,
label: languages[key].name,
flag: languages[key].flag,
}));

const handleChange = (value) => {
i18n.changeLanguage(value);
};

const customItem = item => (
<div>
<img src={item.flag}/> {item.label}
</div>
);

const Settings = ({ t }) => (
const Settings = () => (
<form>
<Dropdown
auto={false}
className='language'
label={t('Language')}
source={languagesSource}
value={i18n.language}
template={customItem}
onChange={handleChange}
/>
<LanguageDropdown />
</form>
);

export default translate()(Settings);
export default Settings;
15 changes: 2 additions & 13 deletions src/components/settings/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React from 'react';

import { expect } from 'chai';
import { mount } from 'enzyme';
import sinon from 'sinon';

import Settings from './index';
import i18n from '../../i18n';
Expand All @@ -26,17 +25,7 @@ describe('Settings', () => {
});
});

it('renders a form and a Dropdown components', () => {
expect(wrapper.find('Dropdown')).to.have.length(1);
});

it('calls i18n.changeLanguage on chaning the value in the dropdown', () => {
const i18nSpy = sinon.spy(i18n, 'changeLanguage');

wrapper.find('Dropdown').simulate('click');
wrapper.find('Dropdown ul li').at(0).simulate('click');
expect(i18nSpy).to.have.been.calledWith('en');

i18nSpy.restore();
it('renders a LanguageDropdown component', () => {
expect(wrapper.find('LanguageDropdown')).to.have.length(1);
});
});
3 changes: 0 additions & 3 deletions src/i18n.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import i18n from 'i18next';
import languages from './constants/languages';
// import Cache from 'i18next-localstorage-cache';

const resources = Object.keys(languages).reduce((accumulator, key) => {
accumulator[key] = {
Expand All @@ -10,10 +9,8 @@ const resources = Object.keys(languages).reduce((accumulator, key) => {
}, {});

i18n
// .use(Cache)
.init({
fallbackLng: 'en',
lng: 'en',
resources,
react: {
// wait: true, // globally set to wait for loaded translations in translate hoc
Expand Down
2 changes: 2 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import App from './components/app';
import store from './store';
import i18n from './i18n'; // initialized i18next instance
import proxyLogin from './utils/proxyLogin';
import externalLinks from './utils/externalLinks';
import env from './constants/env';
import ipcLocale from './utils/ipcLocale';

if (env.production) {
proxyLogin.init();
ipcLocale.init(i18n);
externalLinks.init();
}

const rootElement = document.getElementById('app');
Expand Down
23 changes: 23 additions & 0 deletions src/utils/externalLinks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import history from '../history';
import routesReg from './routes';
import { errorToastDisplayed } from '../actions/toaster';
import store from '../store';

export default {
init: () => {
const { ipc } = window;

if (ipc) {
ipc.on('openUrl', (action, url) => {
const normalizedUrl = url.toLowerCase().replace('lisk://', '/');
const route = routesReg.find(item => item.regex.test(normalizedUrl));
if (route !== undefined) {
history.push(normalizedUrl);
} else {
store.dispatch(errorToastDisplayed({ label: 'The URL was invalid' }));
}
});
}
},
};

26 changes: 26 additions & 0 deletions src/utils/externalLinks.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { expect } from 'chai';
import { spy } from 'sinon';
import externalLinks from './externalLinks';

describe('externalLinks', () => {
const ipc = {
on: spy(),
};

describe('init', () => {
it('should be a function', () => {
expect(typeof externalLinks.init).to.be.equal('function');
});

it('calling init when ipc is not on window should do nothing', () => {
externalLinks.init();
expect(ipc.on).to.not.have.been.calledWith();
});

it('calling init when ipc is available on window should bind listeners', () => {
window.ipc = ipc;
externalLinks.init();
expect(ipc.on).to.have.been.calledWith();
});
});
});
28 changes: 28 additions & 0 deletions src/utils/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export default [
{
regex: /\/main\/transactions(?:\/[^/]*)?$/,
path: '/main/transactions/',
params: 'dialog',
name: 'transactions',
}, {
regex: /\/main\/voting(?:\/[^/]*)?$/,
path: '/main/voting/',
params: 'dialog',
name: 'voting',
}, {
regex: /\/main\/forging(?:\/[^/]*)?$/,
path: '/main/forging/',
params: 'dialog',
name: 'forging',
}, {
regex: /register(\/)?$/,
path: '/',
params: 'dialog',
name: 'login',
}, {
regex: /^\/$/,
path: '/',
params: 'dialog',
name: 'login',
},
];

0 comments on commit 0d7631a

Please sign in to comment.