From a659adfd33ecccac7474f8a76b92a4ca75472567 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 12 Dec 2016 15:43:24 +0100 Subject: [PATCH 01/10] Only ignore parity.* files in root --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e3bb529c4..f31145039 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,4 @@ out/ .vscode -parity.* +/parity.* From c784ab55d27f5de206f5aad7c21062496952dd45 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 12 Dec 2016 15:43:59 +0100 Subject: [PATCH 02/10] Extend jsapi interfaces with documentation --- js/src/api/rpc/parity/parity.js | 34 +++++++++++----------- js/src/jsonrpc/interfaces/parity.js | 45 +++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/js/src/api/rpc/parity/parity.js b/js/src/api/rpc/parity/parity.js index f00146d58..2605e41e5 100644 --- a/js/src/api/rpc/parity/parity.js +++ b/js/src/api/rpc/parity/parity.js @@ -54,6 +54,11 @@ export default class Parity { .execute('parity_checkRequest', inNumber16(requestId)); } + consensusCapability () { + return this._transport + .execute('parity_consensusCapability'); + } + dappsPort () { return this._transport .execute('parity_dappsPort') @@ -90,6 +95,11 @@ export default class Parity { .execute('parity_enode'); } + executeUpgrade () { + return this._transport + .execute('parity_executeUpgrade'); + } + extraData () { return this._transport .execute('parity_extraData'); @@ -243,6 +253,11 @@ export default class Parity { .then(outAddress); } + releasesInfo () { + return this._transport + .execute('parity_releasesInfo'); + } + removeReservedPeer (encode) { return this._transport .execute('parity_removeReservedPeer', encode); @@ -316,28 +331,13 @@ export default class Parity { .then(outNumber); } - consensusCapability () { + upgradeReady () { return this._transport - .execute('parity_consensusCapability'); + .execute('parity_upgradeReady'); } versionInfo () { return this._transport .execute('parity_versionInfo'); } - - releasesInfo () { - return this._transport - .execute('parity_releasesInfo'); - } - - upgradeReady () { - return this._transport - .execute('parity_upgradeReady'); - } - - executeUpgrade () { - return this._transport - .execute('parity_executeUpgrade'); - } } diff --git a/js/src/jsonrpc/interfaces/parity.js b/js/src/jsonrpc/interfaces/parity.js index bab9ad6e3..57fa791a8 100644 --- a/js/src/jsonrpc/interfaces/parity.js +++ b/js/src/jsonrpc/interfaces/parity.js @@ -100,6 +100,15 @@ export default { } }, + consensusCapability: { + desc: 'Returns an object or string detailing the state of parity capability of maintaining consensus', + params: [], + returns: [ + type: Object, + desc: 'Either "capable", {"capableUntil":N}, {"incapableSince":N} or "unknown" (N is a block number)' + ] + }, + dappsPort: { desc: 'Returns the port the dapps are running on, error if not enabled', params: [], @@ -163,6 +172,15 @@ export default { } }, + executeUpgrade: { + desc: 'Performs an upgrade', + params: [], + returns: [ + type: Boolean, + desc: 'returns true if the upgrade to the release specified in parity_upgradeReady was successfully executed, false if not' + ] + }, + extraData: { desc: 'Returns currently set extra data', params: [], @@ -468,6 +486,15 @@ export default { } }, + releasesInfo: { + desc: 'returns a ReleasesInfo object describing the current status of releases' + params: [], + returns: [ + type: Object, + desc: '"fork":N,"minor":null,"this_fork":MN,"track":R} (N is a block number representing the latest known fork of this chain which may be in the future, MN is a block number representing the latest known fork that the currently running binary can sync past or null if not known, R is a ReleaseInfo object describing the latest release in this release track)' + ] + }, + removeReservedPeer: { desc: '?', params: [ @@ -651,5 +678,23 @@ export default { type: Quantity, desc: 'Number of unsigned transactions' } + }, + + upgradeReady: { + desc: 'returns a ReleaseInfo object describing the release which is available for upgrade or null if none is available', + params: [], + returns: { + type: Object, + desc: '{"binary":H,"fork":15100,"is_critical":true,"version":V} where H is the Keccak-256 checksum of the release parity binary and V is a VersionInfo object describing the release' + } + }, + + versionInfo: { + desc: 'returns a VersionInfo object describing our current version', + params: [], + returns: { + type: Object, + desc: '{"hash":H,"track":T,"version":{"major":N,"minor":N,"patch":N}} (H is a 160-bit Git commit hash, T is a ReleaseTrack, either "stable", "beta", "nightly" or "unknown" and N is a version number)' + } } }; From 1135674eaa62f7f6845893cc05c28844924d67cf Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 12 Dec 2016 15:51:36 +0100 Subject: [PATCH 03/10] WIP UI (dialog available) --- js/src/modals/UpgradeParity/Info/index.js | 0 js/src/modals/UpgradeParity/Info/info.js | 31 +++++++ js/src/modals/UpgradeParity/Upgrade/index.js | 17 ++++ .../modals/UpgradeParity/Upgrade/upgrade.js | 33 +++++++ js/src/modals/UpgradeParity/store.js | 86 +++++++++++++++++++ js/src/modals/UpgradeParity/upgradeParity.js | 47 ++++++++++ js/src/modals/index.js | 10 ++- .../views/Application/Container/container.js | 13 +-- 8 files changed, 227 insertions(+), 10 deletions(-) create mode 100644 js/src/modals/UpgradeParity/Info/index.js create mode 100644 js/src/modals/UpgradeParity/Info/info.js create mode 100644 js/src/modals/UpgradeParity/Upgrade/index.js create mode 100644 js/src/modals/UpgradeParity/Upgrade/upgrade.js create mode 100644 js/src/modals/UpgradeParity/store.js create mode 100644 js/src/modals/UpgradeParity/upgradeParity.js diff --git a/js/src/modals/UpgradeParity/Info/index.js b/js/src/modals/UpgradeParity/Info/index.js new file mode 100644 index 000000000..e69de29bb diff --git a/js/src/modals/UpgradeParity/Info/info.js b/js/src/modals/UpgradeParity/Info/info.js new file mode 100644 index 000000000..539559710 --- /dev/null +++ b/js/src/modals/UpgradeParity/Info/info.js @@ -0,0 +1,31 @@ +// Copyright 2015, 2016 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 { observer } from 'mobx-react'; +import React, { Component, PropTypes } from 'react'; + +@observer +export default class Info extends Component { + static propTypes = { + store: PropTypes.object.isRequired + } + + render () { + return ( +
info
+ ); + } +} diff --git a/js/src/modals/UpgradeParity/Upgrade/index.js b/js/src/modals/UpgradeParity/Upgrade/index.js new file mode 100644 index 000000000..ff2da57b5 --- /dev/null +++ b/js/src/modals/UpgradeParity/Upgrade/index.js @@ -0,0 +1,17 @@ +// Copyright 2015, 2016 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 from './upgrade'; diff --git a/js/src/modals/UpgradeParity/Upgrade/upgrade.js b/js/src/modals/UpgradeParity/Upgrade/upgrade.js new file mode 100644 index 000000000..75637058c --- /dev/null +++ b/js/src/modals/UpgradeParity/Upgrade/upgrade.js @@ -0,0 +1,33 @@ +// Copyright 2015, 2016 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 { observer } from 'mobx-react'; +import React, { Component, PropTypes } from 'react'; + +import styles from './.css'; + +@observer +export default class Upgrade extends Component { + static propTypes = { + store: PropTypes.object.isRequired + } + + render () { + return ( +
hello
+ ); + } +} diff --git a/js/src/modals/UpgradeParity/store.js b/js/src/modals/UpgradeParity/store.js new file mode 100644 index 000000000..57446ead8 --- /dev/null +++ b/js/src/modals/UpgradeParity/store.js @@ -0,0 +1,86 @@ +// Copyright 2015, 2016 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 { action, observable, transaction } from 'mobx'; +import store from 'store'; + +const AN_HOUR = 60 * 60 * 1000; +const A_DAY = 24 * AN_HOUR; +const CHECK_INTERVAL = AN_HOUR; +const LS_UPDATE = '_parity::update'; + +export default class Store { + @observable availableUpgrade = null; + @observable remindAt = 0; + @observable showUpgrade = false; + + constructor (api) { + this._api = api; + + this.checkUpgrade(); + setInterval(this.pollUpgrade, CHECK_INTERVAL); + } + + @action loadStorage () { + const values = store.get(LS_UPDATE) || {}; + + this.remindAt = values.remindAt ? values.remindAt : 0; + + return values; + } + + @action setAvailableUpgrade (availableUpgrade, consensusCapability) { + transaction(() => { + this.setConsensusCapability(consensusCapability); + this.availableUpgrade = availableUpgrade; + + if (availableUpgrade && Date.now() >= this.remindAt) { + this.showUpgrade = true; + } + }); + } + + @action setConsensusCapability (consensusCapability) { + this.consensusCapability = consensusCapability; + } + + @action snoozeTillTomorrow () { + store.set(LS_UPDATE, Object.assign(this.loadStorage(), { + remindAt: Date.now() + A_DAY + })); + } + + checkUpgrade = () => { + this.loadStorage(); + + return Promise + .all([ + this._api.parity.upgradeReady(), + this._api.parity.consensusCapability() + ]) + .then(([availableUpgrade, consensusCapability]) => { + this.setAvailableUpgrade(availableUpgrade, consensusCapability); + }) + .catch((error) => { + console.warn('checkUpgrade', error); + }); + } + + executeUpgrade = () => { + return this._api.parity + .executeUpgrade(); + } +} diff --git a/js/src/modals/UpgradeParity/upgradeParity.js b/js/src/modals/UpgradeParity/upgradeParity.js new file mode 100644 index 000000000..41a28d666 --- /dev/null +++ b/js/src/modals/UpgradeParity/upgradeParity.js @@ -0,0 +1,47 @@ +// Copyright 2015, 2016 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 { observer } from 'mobx-react'; +import React, { Component, PropTypes } from 'react'; + +import { Button, Modal } from '~/ui'; + +import Store from './store'; + +@observer +export default class UpgradeParity extends Component { + static contextTypes = { + api: PropTypes.object.isRequired + }; + + store = new Store(this.context.api); + + render () { + if (!this.store.showUpgrade) { + return null; + } + + return ( + + ] } + visible> +
+ + ); + } +} diff --git a/js/src/modals/index.js b/js/src/modals/index.js index d3574fdc7..373772757 100644 --- a/js/src/modals/index.js +++ b/js/src/modals/index.js @@ -23,12 +23,13 @@ import DeployContract from './DeployContract'; import EditMeta from './EditMeta'; import ExecuteContract from './ExecuteContract'; import FirstRun from './FirstRun'; +import LoadContract from './LoadContract'; +import SaveContract from './SaveContract'; import Shapeshift from './Shapeshift'; import SMSVerification from './SMSVerification'; import Transfer from './Transfer'; import PasswordManager from './PasswordManager'; -import SaveContract from './SaveContract'; -import LoadContract from './LoadContract'; +import UpgradeParity from './UpgradeParity'; import WalletSettings from './WalletSettings'; export { @@ -41,11 +42,12 @@ export { EditMeta, ExecuteContract, FirstRun, + LoadContract, + SaveContract, Shapeshift, SMSVerification, Transfer, PasswordManager, - LoadContract, - SaveContract, + UpgradeParity, WalletSettings }; diff --git a/js/src/views/Application/Container/container.js b/js/src/views/Application/Container/container.js index c5cd529a5..275f8999c 100644 --- a/js/src/views/Application/Container/container.js +++ b/js/src/views/Application/Container/container.js @@ -16,7 +16,7 @@ import React, { Component, PropTypes } from 'react'; -import { FirstRun } from '~/modals'; +import { FirstRun, UpgradeParity } from '~/modals'; import { Errors, ParityBackground, Tooltips } from '~/ui'; import styles from '../application.css'; @@ -28,20 +28,21 @@ export default class Container extends Component { static propTypes = { children: PropTypes.node.isRequired, - showFirstRun: PropTypes.bool, - onCloseFirstRun: PropTypes.func + onCloseFirstRun: PropTypes.func, + showFirstRun: PropTypes.bool }; render () { - const { children, showFirstRun, onCloseFirstRun } = this.props; const { muiTheme } = this.context; + const { children, onCloseFirstRun, showFirstRun } = this.props; return ( + onClose={ onCloseFirstRun } + visible={ showFirstRun } /> + { children } From 9a26caf548271b9e1d1d210a5e7cec311ce540fb Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 12 Dec 2016 18:29:45 +0100 Subject: [PATCH 04/10] Build settings --- js/package.json | 2 +- js/webpack/dev.server.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/package.json b/js/package.json index 1e0ea8b68..2b5563f8c 100644 --- a/js/package.json +++ b/js/package.json @@ -36,7 +36,7 @@ "ci:build:npm": "NODE_ENV=production webpack --config webpack/npm", "start": "npm install && npm run build:lib && npm run build:dll && npm run start:app", "start:app": "node webpack/dev.server", - "clean": "rm -rf ./build ./coverage", + "clean": "rm -rf ./.build ./.coverage ./.happypack ./.npmjs ./build", "coveralls": "npm run testCoverage && coveralls < coverage/lcov.info", "lint": "eslint --ignore-path .gitignore ./src/", "lint:cached": "eslint --cache --ignore-path .gitignore ./src/", diff --git a/js/webpack/dev.server.js b/js/webpack/dev.server.js index 9e8bd1524..5ce285262 100644 --- a/js/webpack/dev.server.js +++ b/js/webpack/dev.server.js @@ -60,7 +60,7 @@ app.use(webpackHotMiddleware(compiler, { app.use(webpackDevMiddleware(compiler, { noInfo: false, - quiet: true, + quiet: false, progress: true, publicPath: webpackConfig.output.publicPath, stats: { From 7a0fccf4172e5a4d152b83356645b155f2ae1590 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 12 Dec 2016 18:30:05 +0100 Subject: [PATCH 05/10] Add shared icons --- js/src/ui/Icons/icons.js | 31 +++++++++++++++++++++++++++++++ js/src/ui/Icons/index.js | 17 +++++++++++++++++ js/src/ui/index.js | 2 ++ 3 files changed, 50 insertions(+) create mode 100644 js/src/ui/Icons/icons.js create mode 100644 js/src/ui/Icons/index.js diff --git a/js/src/ui/Icons/icons.js b/js/src/ui/Icons/icons.js new file mode 100644 index 000000000..b9cf70ba0 --- /dev/null +++ b/js/src/ui/Icons/icons.js @@ -0,0 +1,31 @@ +// Copyright 2015, 2016 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 AddIcon from 'material-ui/svg-icons/content/add'; +import CancelIcon from 'material-ui/svg-icons/content/clear'; +import DoneIcon from 'material-ui/svg-icons/action/done-all'; +import PrevIcon from 'material-ui/svg-icons/navigation/arrow-back'; +import NextIcon from 'material-ui/svg-icons/navigation/arrow-forward'; +import SnoozeIcon from 'material-ui/svg-icons/av/snooze'; + +export { + AddIcon, + CancelIcon, + DoneIcon, + PrevIcon, + NextIcon, + SnoozeIcon +}; diff --git a/js/src/ui/Icons/index.js b/js/src/ui/Icons/index.js new file mode 100644 index 000000000..3d68a7e6b --- /dev/null +++ b/js/src/ui/Icons/index.js @@ -0,0 +1,17 @@ +// Copyright 2015, 2016 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 * from './icons'; diff --git a/js/src/ui/index.js b/js/src/ui/index.js index e1ebb16a6..d7875b72b 100644 --- a/js/src/ui/index.js +++ b/js/src/ui/index.js @@ -33,6 +33,7 @@ import Errors from './Errors'; import Form, { AddressSelect, FormWrap, TypedInput, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select, RadioButtons } from './Form'; import GasPriceEditor from './GasPriceEditor'; import GasPriceSelector from './GasPriceSelector'; +import Icons from './Icons'; import IdentityIcon from './IdentityIcon'; import IdentityName from './IdentityName'; import LanguageSelector from './LanguageSelector'; @@ -72,6 +73,7 @@ export { FormWrap, GasPriceEditor, GasPriceSelector, + Icons, Input, InputAddress, InputAddressSelect, From a2a89f7e59fa6ef7d5a73ac9c32e62ed9fa22de6 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 12 Dec 2016 18:30:41 +0100 Subject: [PATCH 06/10] Basic UI structure in-place --- .../{Upgrade => Updating}/index.js | 2 +- .../upgrade.js => Updating/updating.js} | 6 +- js/src/modals/UpgradeParity/index.js | 17 ++++ js/src/modals/UpgradeParity/modalStore.js | 97 +++++++++++++++++++ js/src/modals/UpgradeParity/store.js | 86 ---------------- js/src/modals/UpgradeParity/upgradeParity.js | 83 ++++++++++++++-- js/src/modals/UpgradeParity/upgradeStore.js | 57 +++++++++++ js/src/ui/Modal/modal.js | 6 +- 8 files changed, 253 insertions(+), 101 deletions(-) rename js/src/modals/UpgradeParity/{Upgrade => Updating}/index.js (95%) rename js/src/modals/UpgradeParity/{Upgrade/upgrade.js => Updating/updating.js} (87%) create mode 100644 js/src/modals/UpgradeParity/index.js create mode 100644 js/src/modals/UpgradeParity/modalStore.js delete mode 100644 js/src/modals/UpgradeParity/store.js create mode 100644 js/src/modals/UpgradeParity/upgradeStore.js diff --git a/js/src/modals/UpgradeParity/Upgrade/index.js b/js/src/modals/UpgradeParity/Updating/index.js similarity index 95% rename from js/src/modals/UpgradeParity/Upgrade/index.js rename to js/src/modals/UpgradeParity/Updating/index.js index ff2da57b5..59e363f11 100644 --- a/js/src/modals/UpgradeParity/Upgrade/index.js +++ b/js/src/modals/UpgradeParity/Updating/index.js @@ -14,4 +14,4 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -export default from './upgrade'; +export default from './updating'; diff --git a/js/src/modals/UpgradeParity/Upgrade/upgrade.js b/js/src/modals/UpgradeParity/Updating/updating.js similarity index 87% rename from js/src/modals/UpgradeParity/Upgrade/upgrade.js rename to js/src/modals/UpgradeParity/Updating/updating.js index 75637058c..f1bbc722a 100644 --- a/js/src/modals/UpgradeParity/Upgrade/upgrade.js +++ b/js/src/modals/UpgradeParity/Updating/updating.js @@ -17,17 +17,15 @@ import { observer } from 'mobx-react'; import React, { Component, PropTypes } from 'react'; -import styles from './.css'; - @observer -export default class Upgrade extends Component { +export default class Updating extends Component { static propTypes = { store: PropTypes.object.isRequired } render () { return ( -
hello
+
hello
); } } diff --git a/js/src/modals/UpgradeParity/index.js b/js/src/modals/UpgradeParity/index.js new file mode 100644 index 000000000..523e372fa --- /dev/null +++ b/js/src/modals/UpgradeParity/index.js @@ -0,0 +1,17 @@ +// Copyright 2015, 2016 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 from './upgradeParity'; diff --git a/js/src/modals/UpgradeParity/modalStore.js b/js/src/modals/UpgradeParity/modalStore.js new file mode 100644 index 000000000..d677aa01d --- /dev/null +++ b/js/src/modals/UpgradeParity/modalStore.js @@ -0,0 +1,97 @@ +// Copyright 2015, 2016 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 { action, computed, observable, transaction } from 'mobx'; +import store from 'store'; + +const LS_UPDATE = '_parity::update'; + +const A_DAY = 24 * 60 * 60 * 1000; + +const STEP_INFO = 1; +const STEP_UPDATING = 2; +const STEP_COMPLETED = 3; +const STEP_ERROR = 4; + +export default class ModalStore { + @observable closed = false; + @observable error = null; + @observable step = 0; + @observable upgrade = null; + + constructor (upgradeStore) { + this.upgrade = upgradeStore; + + this.loadStorage(); + } + + @computed get showUpgrade () { + return !closed && Date.now() >= this.remindAt; + } + + @action closeModal = () => { + transaction(() => { + this.closed = true; + this.setStep(STEP_INFO); + }); + } + + @action loadStorage = () => { + const values = store.get(LS_UPDATE) || {}; + + this.remindAt = values.remindAt ? values.remindAt : 0; + + return values; + } + + @action setStep = (step, error = null) => { + transaction(() => { + this.error = error; + this.setp = step; + }); + } + + @action snoozeTillTomorrow = () => { + this.remindAt = Date.now() + A_DAY; + store.set(LS_UPDATE, Object.assign(this.loadStorage(), { remindAt: this.remindAt })); + } + + @action upgradeNow = () => { + this.setStep(STEP_UPDATING); + + this.upgrade + .executeUpgrade() + .then((result) => { + if (!result) { + throw new Error('Unable to complete update'); + } + + this.setStep(STEP_COMPLETED); + }) + .catch((error) => { + console.error('upgradeNow', error); + + this.setStep(STEP_ERROR, error); + }); + } +} + +export { + STEP_COMPLETED, + STEP_ERROR, + STEP_INFO, + STEP_UPDATING +}; diff --git a/js/src/modals/UpgradeParity/store.js b/js/src/modals/UpgradeParity/store.js deleted file mode 100644 index 57446ead8..000000000 --- a/js/src/modals/UpgradeParity/store.js +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2015, 2016 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 { action, observable, transaction } from 'mobx'; -import store from 'store'; - -const AN_HOUR = 60 * 60 * 1000; -const A_DAY = 24 * AN_HOUR; -const CHECK_INTERVAL = AN_HOUR; -const LS_UPDATE = '_parity::update'; - -export default class Store { - @observable availableUpgrade = null; - @observable remindAt = 0; - @observable showUpgrade = false; - - constructor (api) { - this._api = api; - - this.checkUpgrade(); - setInterval(this.pollUpgrade, CHECK_INTERVAL); - } - - @action loadStorage () { - const values = store.get(LS_UPDATE) || {}; - - this.remindAt = values.remindAt ? values.remindAt : 0; - - return values; - } - - @action setAvailableUpgrade (availableUpgrade, consensusCapability) { - transaction(() => { - this.setConsensusCapability(consensusCapability); - this.availableUpgrade = availableUpgrade; - - if (availableUpgrade && Date.now() >= this.remindAt) { - this.showUpgrade = true; - } - }); - } - - @action setConsensusCapability (consensusCapability) { - this.consensusCapability = consensusCapability; - } - - @action snoozeTillTomorrow () { - store.set(LS_UPDATE, Object.assign(this.loadStorage(), { - remindAt: Date.now() + A_DAY - })); - } - - checkUpgrade = () => { - this.loadStorage(); - - return Promise - .all([ - this._api.parity.upgradeReady(), - this._api.parity.consensusCapability() - ]) - .then(([availableUpgrade, consensusCapability]) => { - this.setAvailableUpgrade(availableUpgrade, consensusCapability); - }) - .catch((error) => { - console.warn('checkUpgrade', error); - }); - } - - executeUpgrade = () => { - return this._api.parity - .executeUpgrade(); - } -} diff --git a/js/src/modals/UpgradeParity/upgradeParity.js b/js/src/modals/UpgradeParity/upgradeParity.js index 41a28d666..4c4d9f1ef 100644 --- a/js/src/modals/UpgradeParity/upgradeParity.js +++ b/js/src/modals/UpgradeParity/upgradeParity.js @@ -16,10 +16,16 @@ import { observer } from 'mobx-react'; import React, { Component, PropTypes } from 'react'; +import { FormattedMessage } from 'react-intl'; import { Button, Modal } from '~/ui'; +import { CancelIcon, DoneIcon, NextIcon, SnoozeIcon } from '~/ui/Icons'; -import Store from './store'; +import Info from './Info'; +import Updating from './Updating'; + +import ModalStore, { STEP_COMPLETED, STEP_ERROR, STEP_INFO, STEP_UPDATING } from './modalStore'; +import UpgradeStore from './upgradeStore'; @observer export default class UpgradeParity extends Component { @@ -27,21 +33,84 @@ export default class UpgradeParity extends Component { api: PropTypes.object.isRequired }; - store = new Store(this.context.api); + store = new ModalStore(new UpgradeStore(this.context.api)); render () { - if (!this.store.showUpgrade) { + if (!this.store.upgrade.available || !this.store.showUpgrade) { return null; } return ( - ] } + actions={ this.renderActions() } visible> -
+ { this.renderStep() } ); } + + renderActions () { + const closeButton = +