diff --git a/js/src/redux/providers/balances.js b/js/src/redux/providers/balances.js
index cc7df73dd..a2f49cfa8 100644
--- a/js/src/redux/providers/balances.js
+++ b/js/src/redux/providers/balances.js
@@ -241,7 +241,7 @@ export default class Balances {
// If syncing, only retrieve balances once every
// few seconds
- if (syncing) {
+ if (syncing || syncing === null) {
this.shortThrottledFetch.cancel();
this.longThrottledFetch(skipNotifications);
diff --git a/js/src/redux/providers/statusReducer.js b/js/src/redux/providers/statusReducer.js
index 12fe9654d..3a6968548 100644
--- a/js/src/redux/providers/statusReducer.js
+++ b/js/src/redux/providers/statusReducer.js
@@ -33,7 +33,7 @@ const initialState = {
netVersion: '0',
nodeKind: null,
nodeKindFull: null,
- syncing: true,
+ syncing: null,
isConnected: false,
isConnecting: false,
isTest: undefined,
diff --git a/js/src/views/Application/application.js b/js/src/views/Application/application.js
index 2fac18c6f..73f0cdda8 100644
--- a/js/src/views/Application/application.js
+++ b/js/src/views/Application/application.js
@@ -22,6 +22,7 @@ import UpgradeStore from '~/modals/UpgradeParity/store';
import Connection from '../Connection';
import ParityBar from '../ParityBar';
+import SyncWarning, { showSyncWarning } from '../SyncWarning';
import Snackbar from './Snackbar';
import Container from './Container';
@@ -36,6 +37,7 @@ import Requests from './Requests';
import styles from './application.css';
const inFrame = window.parent !== window && window.parent.frames.length !== 0;
+const doShowSyncWarning = showSyncWarning();
@observer
class Application extends Component {
@@ -78,6 +80,11 @@ class Application extends Component {
? this.renderMinimized()
: this.renderApp()
}
+ {
+ doShowSyncWarning
+ ? ()
+ : null
+ }
diff --git a/js/src/views/SyncWarning/index.js b/js/src/views/SyncWarning/index.js
new file mode 100644
index 000000000..098605b2a
--- /dev/null
+++ b/js/src/views/SyncWarning/index.js
@@ -0,0 +1,17 @@
+// Copyright 2015-2017 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+export default, { showSyncWarning } from './syncWarning';
diff --git a/js/src/views/SyncWarning/syncWarning.css b/js/src/views/SyncWarning/syncWarning.css
new file mode 100644
index 000000000..828036499
--- /dev/null
+++ b/js/src/views/SyncWarning/syncWarning.css
@@ -0,0 +1,60 @@
+/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
+/* This file is part of Parity.
+/*
+/* Parity is free software: you can redistribute it and/or modify
+/* it under the terms of the GNU General Public License as published by
+/* the Free Software Foundation; either version 3 of the License; or
+/* (at your option) any later version.
+/*
+/* Parity is distributed in the hope that it will be useful;
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+/* GNU General Public License for more details.
+/*
+/* You should have received a copy of the GNU General Public License
+/* along with Parity. If not; see .
+*/
+
+.overlay {
+ background: rgba(255, 255, 255, 0.75);
+ bottom: 0;
+ left: 0;
+ position: fixed;
+ right: 0;
+ top: 0;
+ z-index: 10000;
+}
+
+.modal {
+ align-items: flex-start;
+ bottom: 0;
+ display: flex;
+ left: 0;
+ position: fixed;
+ right: 0;
+ top: 0;
+ z-index: 10001;
+}
+
+.body {
+ background: rgba(25, 25, 25, 0.75);
+ box-shadow: rgba(0, 0, 0, 0.25) 0 14px 45px, rgba(0, 0, 0, 0.22) 0 10px 18px;
+ color: rgb(208, 208, 208);
+ display: flex;
+ flex-direction: column;
+ margin: 0 auto;
+ max-width: 20em;
+ padding: 2em 4em;
+ text-align: center;
+}
+
+.button {
+ margin-top: 1em;
+}
+
+.body,
+.button {
+ > * {
+ margin: 0.5em 0;
+ }
+}
diff --git a/js/src/views/SyncWarning/syncWarning.js b/js/src/views/SyncWarning/syncWarning.js
new file mode 100644
index 000000000..67deff075
--- /dev/null
+++ b/js/src/views/SyncWarning/syncWarning.js
@@ -0,0 +1,130 @@
+// Copyright 2015-2017 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+import { Checkbox } from 'material-ui';
+import React, { Component, PropTypes } from 'react';
+import { FormattedMessage } from 'react-intl';
+import { connect } from 'react-redux';
+import store from 'store';
+
+import { Button } from '~/ui';
+
+import styles from './syncWarning.css';
+
+const LS_DONT_SHOW_AGAIN = '_parity::syncWarning::dontShowAgain';
+
+export const showSyncWarning = () => {
+ const dontShowAgain = store.get(LS_DONT_SHOW_AGAIN);
+
+ if (dontShowAgain === undefined || dontShowAgain === null) {
+ return true;
+ }
+
+ return !dontShowAgain;
+};
+
+class SyncWarning extends Component {
+ static propTypes = {
+ isSyncing: PropTypes.bool
+ };
+
+ state = {
+ dontShowAgain: false,
+ show: true
+ };
+
+ render () {
+ const { isSyncing } = this.props;
+ const { dontShowAgain, show } = this.state;
+
+ if (!isSyncing || isSyncing === null || !show) {
+ return null;
+ }
+
+ return (
+
+ );
+ }
+
+ handleCheck = () => {
+ this.setState({ dontShowAgain: !this.state.dontShowAgain });
+ }
+
+ handleAgreeClick = () => {
+ if (this.state.dontShowAgain) {
+ store.set(LS_DONT_SHOW_AGAIN, true);
+ }
+
+ this.setState({ show: false });
+ }
+}
+
+function mapStateToProps (state) {
+ const { syncing } = state.nodeStatus;
+ // syncing could be an Object, false, or null
+ const isSyncing = syncing
+ ? true
+ : syncing;
+
+ return {
+ isSyncing
+ };
+}
+
+export default connect(
+ mapStateToProps,
+ null
+)(SyncWarning);
diff --git a/js/src/views/SyncWarning/syncWarning.spec.js b/js/src/views/SyncWarning/syncWarning.spec.js
new file mode 100644
index 000000000..36c3c2436
--- /dev/null
+++ b/js/src/views/SyncWarning/syncWarning.spec.js
@@ -0,0 +1,57 @@
+// Copyright 2015-2017 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+import { shallow } from 'enzyme';
+import React from 'react';
+
+import SyncWarning from './';
+
+let component;
+
+function createRedux (syncing = null) {
+ return {
+ getState: () => {
+ return {
+ nodeStatus: {
+ syncing
+ }
+ };
+ }
+ };
+}
+
+function render (store) {
+ component = shallow(
+ ,
+ { context: { store: store || createRedux() } }
+ ).find('SyncWarning').shallow();
+
+ return component;
+}
+
+describe('views/SyncWarning', () => {
+ it('renders defaults', () => {
+ expect(render()).to.be.ok;
+ });
+
+ it('does render when syncing', () => {
+ expect(render(createRedux({})).find('div')).to.have.length.gte(1);
+ });
+
+ it('does not render when not syncing', () => {
+ expect(render(createRedux(false)).find('div')).to.have.length(0);
+ });
+});