diff --git a/package.json b/package.json
index 92579d96d6a80dc8934401d7d2232688f68b43c2..a7c6f97f46b6d5c0725b7210eb462002ada0595f 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,7 @@
},
"dependencies": {
"@parity/api": "^2.1.22",
- "@parity/light.js": "https://github.com/parity-js/light.js#0c57c29de42122b0f07ff82dfaf38b48863d8d2e",
+ "@parity/light.js": "https://github.com/parity-js/light.js#aa03e7f2956718bf91f6f82771eee3b81d260a18",
"async-retry": "^1.2.1",
"axios": "^0.18.0",
"checksum": "^0.1.1",
diff --git a/src/Health/Health.js b/src/Health/Health.js
index a4793bd2d984aa4da4cbe32202872f259c4e536a..8b4b3f9f60fbd783fbcae3bc3b6ae28d1dc53bd2 100644
--- a/src/Health/Health.js
+++ b/src/Health/Health.js
@@ -3,21 +3,69 @@
//
// SPDX-License-Identifier: MIT
-import React, { PureComponent } from 'react';
+import React, { Component } from 'react';
+import { inject, observer } from 'mobx-react';
-class Health extends PureComponent {
+import { STATUS } from '../stores/healthStore';
+
+@inject('healthStore')
+@observer
+class Health extends Component {
render () {
return (
+
This is the Loading page.
-
+
+
);
}
-
- renderStatus = () => {
- const { parityStore: { downloadProgress, isParityRunning } } = this.props;
-
- if (isParityRunning) {
- return 'Connecting to API...';
- } else if (downloadProgress) {
- return 'Downloading...';
- } else {
- // We should be in browser now
- return 'Please run:\nparity --light --ws-origins all';
- }
- };
}
export default Loading;
diff --git a/src/stores/healthStore.js b/src/stores/healthStore.js
new file mode 100644
index 0000000000000000000000000000000000000000..afae19ecef4a4588706ccb5979b54589fee64e4f
--- /dev/null
+++ b/src/stores/healthStore.js
@@ -0,0 +1,152 @@
+// Copyright 2015-2018 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+//
+// SPDX-License-Identifier: MIT
+
+import { action, computed, observable } from 'mobx';
+import { nodeHealth$, syncing$ } from '@parity/light.js';
+
+import parityStore from './parityStore';
+
+// List here all possible states of our health store. Each state can have a
+// payload.
+export const STATUS = {
+ CANTCONNECT: 'CANTCONNECT', // Can't connect to Parity's api
+ CLOCKNOTSYNC: 'CLOCKNOTSYNC', // Local clock is not sync
+ DOWNLOADING: 'DOWNLOADING', // Currently downloading Parity
+ GOOD: 'GOOD', // Everything's fine
+ NOINTERNET: 'NOINTERNET', // No network connection
+ OTHER: 'OTHER', // Unknown state, might have a payload
+ RUNNING: 'RUNNING', // Currently try to launch Parity
+ SYNCING: 'SYNCING' // Obvious
+};
+
+class HealthStore {
+ @observable nodeHealth;
+ @observable syncing;
+
+ constructor () {
+ nodeHealth$().subscribe(this.setNodeHealth);
+ syncing$().subscribe(this.setSyncing);
+ }
+
+ /**
+ * Calculate the current status.
+ *
+ * @return [Object{ status: StatusEnum, payload: Any}] - An object which
+ * represents the current status, with a custom payload.
+ */
+ @computed
+ get health () {
+ // Check download progress
+ if (parityStore.downloadProgress > 0 && !parityStore.isParityRunning) {
+ return {
+ status: STATUS.DOWNLOADING,
+ payload: { percentage: Math.round(parityStore.downloadProgress * 100) }
+ };
+ }
+
+ // Check if we are currently launching
+ if (parityStore.isParityRunning && !parityStore.isApiConnected) {
+ return {
+ status: STATUS.RUNNING
+ };
+ }
+
+ // Check if we get responses from the WS server
+ if (
+ !parityStore.isApiConnected ||
+ !this.nodeHealth ||
+ !Object.keys(this.nodeHealth).length
+ ) {
+ return {
+ status: STATUS.CANTCONNECT
+ };
+ }
+
+ // At this point we have a successful connection to parity
+
+ // Check if we're syncing
+ if (this.syncing) {
+ const { currentBlock, highestBlock, startingBlock } = this.syncing;
+ const percentage = Math.round(
+ (currentBlock - startingBlock) * 100 / (highestBlock - startingBlock)
+ );
+ return {
+ status: STATUS.SYNCING,
+ payload: { currentBlock, highestBlock, percentage, startingBlock }
+ };
+ }
+
+ // Find out if there are bad statuses
+ const bad = Object.values(this.nodeHealth)
+ .filter(x => x)
+ .map(({ status }) => status)
+ .find(s => s === 'bad');
+ // Find out if there are needsAttention statuses
+ const needsAttention = Object.keys(this.nodeHealth)
+ .filter(key => key !== 'time')
+ .map(key => this.nodeHealth[key])
+ .filter(x => x)
+ .map(({ status }) => status)
+ .find(s => s === 'needsattention');
+
+ if (!bad && !needsAttention) {
+ return {
+ status: STATUS.GOOD
+ };
+ }
+
+ // Now we have a bad or a needsattention message
+
+ // Get all non-empty messages from all statuses
+ const details = Object.values(this.nodeHealth)
+ .map(({ message }) => message)
+ .filter(x => x);
+
+ // If status is bad or needsattention, there should be an associated
+ // message. Just in case, we do an additional test.
+ if (!details || !details.length) {
+ return { status: STATUS.OTHER };
+ }
+
+ const message = details[0];
+ console.log(message); // TODO WIP, to catch potential other messages
+
+ if (
+ message ===
+ "Your node is still syncing, the values you see might be outdated. Wait until it's fully synced."
+ ) {
+ return { status: STATUS.SYNCING };
+ }
+
+ if (
+ message ===
+ 'You are not connected to any peers. There is most likely some network issue. Fix connectivity.'
+ ) {
+ return { status: STATUS.NOINTERNET, payload: message };
+ }
+
+ if (
+ message.includes(
+ 'Your clock is not in sync. Detected difference is too big for the protocol to work.'
+ )
+ ) {
+ return { status: STATUS.CLOCKNOTSYNC, payload: message };
+ }
+
+ return { status: STATUS.OTHER, payload: message };
+ }
+
+ @action
+ setNodeHealth = nodeHealth => {
+ this.nodeHealth = nodeHealth;
+ };
+
+ @action
+ setSyncing = syncing => {
+ this.syncing = syncing;
+ };
+}
+
+export default new HealthStore();
diff --git a/src/stores/index.js b/src/stores/index.js
index 6e071f07b14accd358aa7b5904897602433be7ea..d2346d8aa89dccc2693799b4812c4127dc15620c 100644
--- a/src/stores/index.js
+++ b/src/stores/index.js
@@ -4,12 +4,14 @@
// SPDX-License-Identifier: MIT
import createAccountStore from './createAccountStore';
+import healthStore from './healthStore';
import parityStore from './parityStore';
import signerStore from './signerStore';
import tokensStore from './tokensStore';
export default {
createAccountStore,
+ healthStore,
parityStore,
signerStore,
tokensStore
diff --git a/src/stores/parityStore.js b/src/stores/parityStore.js
index a62c43780190a465e42e38fdf0c2048f28267030..daf392d429a6b6ec48af081c6e891f34df901c83 100644
--- a/src/stores/parityStore.js
+++ b/src/stores/parityStore.js
@@ -50,14 +50,15 @@ class ParityStore {
}
connectToApi = () => {
- let provider = 'ws://127.0.0.1:8546'; // Default provider to be used in localhost:3000
+ // Get the provider, optionally from --ws-interface and --ws-port flags
+ const [defaultInterface, defaultPort] = ['127.0.0.1', '8546'];
+ let provider = `ws://${defaultInterface}:${defaultPort}`;
if (electron) {
const { remote } = electron;
const wsInterface = remote.getGlobal('wsInterface');
const wsPort = remote.getGlobal('wsPort');
- if (wsInterface && wsPort) {
- provider = `ws://${wsInterface}:${wsPort}`;
- }
+ provider = `ws://${wsInterface || defaultInterface}:${wsPort ||
+ defaultPort}`;
}
const api = new Api(
diff --git a/yarn.lock b/yarn.lock
index d86a819ca3098ffa9a60e78e0313301bafe71a25..f86394648d3f0b88223a7e9d383df5882c576211 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -47,10 +47,10 @@
js-tokens "^3.0.0"
"@babel/runtime@^7.0.0-beta.46":
- version "7.0.0-beta.47"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.47.tgz#273f5e71629e80f6cbcd7507503848615e59f7e0"
+ version "7.0.0-beta.49"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.49.tgz#03b3bf07eb982072c8e851dd2ddd5110282e61bf"
dependencies:
- core-js "^2.5.3"
+ core-js "^2.5.6"
regenerator-runtime "^0.11.1"
"@babel/template@7.0.0-beta.44":
@@ -131,9 +131,9 @@
u2f-api "0.0.9"
u2f-api-polyfill "0.4.3"
-"@parity/light.js@https://github.com/parity-js/light.js#0c57c29de42122b0f07ff82dfaf38b48863d8d2e":
+"@parity/light.js@https://github.com/parity-js/light.js#aa03e7f2956718bf91f6f82771eee3b81d260a18":
version "1.0.0"
- resolved "https://github.com/parity-js/light.js#0c57c29de42122b0f07ff82dfaf38b48863d8d2e"
+ resolved "https://github.com/parity-js/light.js#aa03e7f2956718bf91f6f82771eee3b81d260a18"
dependencies:
"@babel/runtime" "^7.0.0-beta.46"
"@parity/api" "^2.1.22"
@@ -2212,9 +2212,9 @@ core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0:
version "2.5.5"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.5.tgz#b14dde936c640c0579a6b50cabcc132dd6127e3b"
-core-js@^2.5.3:
- version "2.5.6"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.6.tgz#0fe6d45bf3cac3ac364a9d72de7576f4eb221b9d"
+core-js@^2.5.6:
+ version "2.5.7"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"