Skip to content

Commit

Permalink
Merge pull request #887 from LiskHQ/830-add-network-switcher-to-settings
Browse files Browse the repository at this point in the history
Add network switcher to settings - Closes #830
  • Loading branch information
michaeltomasik committed Jun 11, 2018
2 parents 207c2e7 + 6236392 commit 2f79f44
Show file tree
Hide file tree
Showing 14 changed files with 60 additions and 30 deletions.
7 changes: 1 addition & 6 deletions README.md
Expand Up @@ -20,12 +20,7 @@ npm run dev

Open http://localhost:8080

For ease of development, you can `setItem` in `localStorage` to see network options in login page:
```
localStorage.setItem('showNetwork', true)
```

You can also pass the same key-value pair as query string:
For ease of development, you can set the following query string to see network options in login page:
```
http://localhost:8080/#/?showNetwork=true
```
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/en/common.json
Expand Up @@ -261,6 +261,7 @@
"Submit": "Submit",
"Success": "Success",
"Success!": "Success!",
"Switch networks (Main-/Testnet, Custom)": "Switch networks (Main-/Testnet, Custom)",
"Take a tour to see how it works. It should not take longer than 5 minutes": "Take a tour to see how it works. It should not take longer than 5 minutes",
"Testnet": "Testnet",
"Thank you": "Thank you",
Expand Down
1 change: 1 addition & 0 deletions src/components/login/index.js
Expand Up @@ -22,6 +22,7 @@ const mapStateToProps = state => ({
account: state.account,
peers: state.peers,
savedAccounts: state.savedAccounts,
settings: state.settings,
});

const mapDispatchToProps = dispatch => ({
Expand Down
6 changes: 4 additions & 2 deletions src/components/login/login.js
Expand Up @@ -57,7 +57,9 @@ class Login extends React.Component {

componentDidUpdate(prevProps) {
const params = parseSearchParams(prevProps.history.location.search);
const showNetworkParam = params.showNetwork || params.shownetwork;
const showNetworkParam = params.showNetwork
|| params.shownetwork
|| (this.props.settings && this.props.settings.showNetwork);

if (this.props.account &&
this.props.account.address && (showNetworkParam !== 'true' || this.secondIteration) &&
Expand Down Expand Up @@ -136,7 +138,7 @@ class Login extends React.Component {

// eslint-disable-next-line class-methods-use-this
showNetworkOptions() {
const showNetwork = localStorage.getItem('showNetwork') || localStorage.getItem('shownetwork');
const showNetwork = this.props.settings && this.props.settings.showNetwork;
const params = parseSearchParams(this.props.history.location.search);
const showNetworkParam = params.showNetwork || params.shownetwork;

Expand Down
1 change: 1 addition & 0 deletions src/components/login/login.test.js
Expand Up @@ -38,6 +38,7 @@ describe('Login', () => {
store = configureMockStore([])({
peers,
account,
settings: {},
});
history = {
location: {
Expand Down
2 changes: 1 addition & 1 deletion src/components/mainMenu/mainMenu.js
Expand Up @@ -110,7 +110,7 @@ class MainMenu extends React.Component {
}

const itemShouldBeDisabled = index =>
(isCurrent(history, index, tabs) || !account.address) && index !== 2;
(isCurrent(history, index, tabs) || !account.address) && index !== 2 && index !== 4;

return (
<Fragment>
Expand Down
2 changes: 1 addition & 1 deletion src/components/onboarding/index.js
Expand Up @@ -122,7 +122,7 @@ const mapDispatchToProps = dispatch => ({
const mapStateToProps = state => ({
isAuthenticated: !!state.account.publicKey,
showDelegates: state.settings.advancedMode,
start: state.settings.onBoarding,
start: Object.prototype.hasOwnProperty.call(state.settings, 'onBoarding') && state.settings.onBoarding,
});

export { Onboarding };
Expand Down
5 changes: 5 additions & 0 deletions src/components/setting/setting.css
Expand Up @@ -10,6 +10,11 @@
--check-box-font-size: 23px;
}

.disable {
pointer-events: none !important;
opacity: 0.5;
}

.wrapper {
position: relative;
display: flex;
Expand Down
35 changes: 23 additions & 12 deletions src/components/setting/setting.js
Expand Up @@ -48,17 +48,15 @@ class Setting extends React.Component {
settingsUpdated({ autoLog: !settings.autoLog });
}

showOnboardingSetting() {
return this.props.isAuthenticated && window.innerWidth > breakpoints.m;
}

render() {
this.language = (i18n.language === 'de');
const {
t, settings, settingsUpdated,
hasSecondPassphrase,
} = this.props;

const allowAuthClass = !this.props.isAuthenticated ? styles.disable : '';
const showOnboardingSetting = window.innerWidth > breakpoints.m;
const activeCurrency = settings.currency || settingsConst.currencies[0];

return (<Box className={styles.wrapper}>
Expand All @@ -67,7 +65,7 @@ class Setting extends React.Component {
<h4>{t('Settings')}</h4>
<p>{t('Set up Lisk Hub and your account.')}</p>
</header>
{this.showOnboardingSetting()
{showOnboardingSetting
? <div className={`${styles.item} onBoarding`}>
<label>{t('Start the onboarding')}</label>
<button className={`${styles.settingsButton} onboarding-setting`} onClick={() => {
Expand All @@ -82,12 +80,12 @@ class Setting extends React.Component {
}
</aside>
<section>
<h4>{t('Security')}</h4>
<h4 className={`${allowAuthClass}`}>{t('Security')}</h4>
<div className={styles.item}>
<label>{t('2nd passphrase (Fee: 5 LSK)')}</label>
<label className={`${allowAuthClass}`}>{t('2nd passphrase (Fee: 5 LSK)')}</label>
{!hasSecondPassphrase ?
<Link
className={`register-second-passphrase ${styles.secondPassphrase}`}
className={`register-second-passphrase ${styles.secondPassphrase} ${allowAuthClass}`}
to={`${routes.secondPassphrase.path}`}>
{t('Register')}
<FontIcon>arrow-right</FontIcon>
Expand All @@ -100,10 +98,11 @@ class Setting extends React.Component {
}
</div>
<div className={styles.item}>
<label>{t('Auto-Lock')}</label>
<label className={`${allowAuthClass}`}>{t('Auto-Lock')}</label>
<Checkbox
theme={styles}
className={`${styles.smallSlider} autoLog`}
disabled={!this.props.isAuthenticated}
className={`${styles.smallSlider} autoLog ${allowAuthClass}`}
onChange={() => this.toggleAutoLog(!settings.autoLog)}
input={{
value: true,
Expand All @@ -112,10 +111,22 @@ class Setting extends React.Component {
</div>
<h4>{t('Advanced features')}</h4>
<div className={styles.item}>
<label>{t('Delegate features')}</label>
<label>{t('Switch networks (Main-/Testnet, Custom)')}</label>
<Checkbox
theme={styles}
className={`${styles.smallSlider} showNetwork`}
onChange={() => settingsUpdated({ showNetwork: !settings.showNetwork })}
input={{
value: false,
checked: settings.showNetwork,
}}/>
</div>
<div className={styles.item}>
<label className={`${allowAuthClass}`}>{t('Delegate features')}</label>
<Checkbox
theme={styles}
className={`${styles.smallSlider} advancedMode`}
disabled={!this.props.isAuthenticated}
className={`${styles.smallSlider} advancedMode ${allowAuthClass}`}
onChange={() => settingsUpdated({ advancedMode: !settings.advancedMode })}
input={{
value: true,
Expand Down
15 changes: 13 additions & 2 deletions src/components/setting/setting.test.js
Expand Up @@ -21,6 +21,7 @@ describe('Setting', () => {
const settings = {
autoLog: true,
advancedMode: true,
showNetwork: false,
currency: settingsConst.currencies[0],
};

Expand Down Expand Up @@ -97,14 +98,14 @@ describe('Setting', () => {
expect(wrapper.find('.onBoarding')).to.have.length(0);
});

it('should not show the onboarding setting when not authenticated', () => {
it('should show the onboarding setting when not authenticated', () => {
props.isAuthenticated = false;
wrapper = mount(<Router>
<Setting
{...props}
/>
</Router>, options);
expect(wrapper.find('.onBoarding')).to.have.length(0);
expect(wrapper.find('.onBoarding')).to.have.length(1);
});

it.skip('should click on .autoLog update the setting', () => {
Expand All @@ -128,6 +129,16 @@ describe('Setting', () => {
expect(props.settingsUpdated).to.have.been.calledWith(expectedCallToSettingsUpdated);
});

it('should change showNetwork setting when clicking on checkbox', () => {
wrapper.find('.showNetwork').at(0).find('input').simulate('change', { target: { checked: true, value: true } });
clock.tick(300);
wrapper.update();
const expectedCallToSettingsUpdated = {
showNetwork: !settings.showNetwork,
};
expect(props.settingsUpdated).to.have.been.calledWith(expectedCallToSettingsUpdated);
});

it('should change active currency setting to EUR', () => {
wrapper.find('.currency').at(1).simulate('click');
wrapper.update();
Expand Down
2 changes: 1 addition & 1 deletion src/constants/routes.js
Expand Up @@ -44,7 +44,7 @@ export default {
setting: {
path: '/setting',
component: Setting,
isPrivate: true,
isPrivate: false,
},
secondPassphrase: {
path: '/second-passphrase',
Expand Down
1 change: 1 addition & 0 deletions src/store/reducers/settings.js
Expand Up @@ -5,6 +5,7 @@ const initialState = JSON.parse(localStorage.getItem('settings')) || {
advancedMode: false,
autoLog: true,
onBoarding: localStorage.getItem('onboarding') !== 'false',
showNetwork: false,
};

/**
Expand Down
8 changes: 5 additions & 3 deletions test/e2e/step_definitions/hooks.js
Expand Up @@ -47,11 +47,13 @@ defineSupportCode(({ Before, After, registerListener }) => {
.setSize(browser.params.screenWidth, browser.params.screenHeight);
browser.get(browser.params.baseURL);
localStorage.clear();

if (scenario.scenario.feature.name !== 'Login') {
localStorage.setItem('showNetwork', 'true');
localStorage.setItem('settings', '{ "showNetwork": true }');
}
if (scenario.scenario.feature.name !== 'Onboarding') {
localStorage.setItem('onboarding', 'false');

if (scenario.scenario.feature.name === 'Onboarding') {
localStorage.setItem('settings', '{ "showNetwork": true, "onBoarding": true }');
}
browser.get(browser.params.baseURL).then(callback);
});
Expand Down
4 changes: 2 additions & 2 deletions test/integration/login.test.js
Expand Up @@ -17,6 +17,7 @@ import accountMiddleware from '../../src/store/middlewares/account';
import peerMiddleware from '../../src/store/middlewares/peers';
import { activePeerSet } from '../../src/actions/peers';
import * as toasterActions from '../../src/actions/toaster';
import { settingsUpdated } from '../../src/actions/settings';
import Login from './../../src/components/login';
import accounts from '../constants/accounts';
import networks from './../../src/constants/networks';
Expand Down Expand Up @@ -64,7 +65,6 @@ describe('@integration: Login', () => {
netHashAPIStub = stub(netHash, 'getNethash').returnsPromise().rejects();
localStorageStub = stub(localStorage, 'getItem');
localStorageStub.withArgs('accounts').returns(JSON.stringify([{}, {}]));
localStorageStub.withArgs('showNetwork').returns(JSON.stringify(true));
accountAPIStub = stub(accountAPI, 'getAccount');
accountAPIStub.returnsPromise().resolves({
address: '6307319849853921018L',
Expand All @@ -85,7 +85,6 @@ describe('@integration: Login', () => {
const stubApisScenarioInvalidNode = () => {
localStorageStub = stub(localStorage, 'getItem');
localStorageStub.withArgs('accounts').returns(JSON.stringify([{}, {}]));
localStorageStub.withArgs('showNetwork').returns(JSON.stringify(true));
netHashAPIStub = stub(netHash, 'getNethash').returnsPromise().rejects();
accountAPIStub = stub(accountAPI, 'getAccount').returnsPromise().rejects();
delegateAPIStub = stub(delegateAPI, 'getDelegate').returnsPromise().rejects();
Expand Down Expand Up @@ -113,6 +112,7 @@ describe('@integration: Login', () => {
const setupStep = (stubApis) => {
const store = createStore();
stubApis();
store.dispatch(settingsUpdated({ showNetwork: true }));
wrapper = mount(renderWithRouter(Login, store, { location: { search: '' } }), { activePeerSet });
helper = new Helper(wrapper, store);
};
Expand Down

0 comments on commit 2f79f44

Please sign in to comment.