+ )}
+ />
+);
export default connect(mapStateToProps, mapDispatchToProps)(Root);
diff --git a/src/WebSocketHandler.js b/src/WebSocketHandler.js
index eff392a9..2ae93162 100644
--- a/src/WebSocketHandler.js
+++ b/src/WebSocketHandler.js
@@ -8,11 +8,10 @@
import EventEmitter from 'events';
import { WS_URL } from './constants';
-const HEARTBEAT_TMO = 30000; // 30s
-
+const HEARTBEAT_TMO = 30000; // 30s
class WS extends EventEmitter {
- constructor(){
+ constructor() {
if (!WS.instance) {
super();
this.connected = false;
@@ -33,45 +32,44 @@ class WS extends EventEmitter {
this.ws.onmessage = this.onMessage;
this.ws.onerror = this.onError;
this.ws.onclose = this.onClose;
- }
+ };
onMessage = evt => {
- const message = JSON.parse(evt.data)
- const _type = message.type.split(':')[0]
- this.emit(_type, message)
- }
+ const message = JSON.parse(evt.data);
+ const _type = message.type.split(':')[0];
+ this.emit(_type, message);
+ };
onOpen = () => {
this.connected = true;
console.log('ws connection established');
this.heartbeat = setInterval(this.sendPing, HEARTBEAT_TMO);
- }
+ };
onClose = () => {
this.connected = false;
setTimeout(this.setup, 500);
clearInterval(this.heartbeat);
console.log('ws connection closed');
- }
+ };
onError = evt => {
console.log('ws error', evt);
- }
+ };
- sendMessage = (msg) => {
+ sendMessage = msg => {
if (!this.connected) {
console.log('ws not connected, cannot send message');
return;
}
-
+
this.ws.send(msg);
- }
+ };
sendPing = () => {
- const msg = JSON.stringify({'type': 'ping'})
- this.sendMessage(msg)
- }
-
+ const msg = JSON.stringify({ type: 'ping' });
+ this.sendMessage(msg);
+ };
}
const instance = new WS();
diff --git a/src/actions/index.js b/src/actions/index.js
index e2c3021b..8cf6abb8 100644
--- a/src/actions/index.js
+++ b/src/actions/index.js
@@ -5,9 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/
-export const dashboardUpdate = data => ({ type: "dashboard_update", payload: data });
+export const dashboardUpdate = data => ({ type: 'dashboard_update', payload: data });
-export const isVersionAllowedUpdate = data => ({ type: "is_version_allowed_update", payload: data });
+export const isVersionAllowedUpdate = data => ({
+ type: 'is_version_allowed_update',
+ payload: data,
+});
export const apiLoadErrorUpdate = data => ({ type: 'api_load_error_update', payload: data });
diff --git a/src/api/addressApi.js b/src/api/addressApi.js
index 30896260..6c7c075d 100644
--- a/src/api/addressApi.js
+++ b/src/api/addressApi.js
@@ -15,27 +15,29 @@ const addressApi = {
offset (optional): int -> offset this many transactions before fetching
*/
- const data = {address};
+ const data = { address };
if (limit) {
- data['limit'] = limit;
+ data.limit = limit;
}
if (offset) {
- data['offset'] = offset;
+ data.offset = offset;
}
- return requestExplorerServiceV1.get(`address/tokens`, {params: data}).then((res) => {
+ return requestExplorerServiceV1.get(`address/tokens`, { params: data }).then(res => {
if (res && res.data) {
- return res.data
+ return res.data;
}
});
},
getBalance(address, token) {
- return requestExplorerServiceV1.get(`address/balance`, {params: {address, token}}).then((res) => {
- if (res && res.data) {
- return res.data
- }
- });
+ return requestExplorerServiceV1
+ .get(`address/balance`, { params: { address, token } })
+ .then(res => {
+ if (res && res.data) {
+ return res.data;
+ }
+ });
},
getHistory(address, token, limit, lastTx, lastTs) {
@@ -47,22 +49,22 @@ const addressApi = {
lastTs (optional): int -> last timestamp of the page, so we can retrieve the next page
*/
- const data = {address, token};
+ const data = { address, token };
if (limit) {
- data['limit'] = limit;
+ data.limit = limit;
}
if (lastTx) {
- data['last_tx'] = lastTx;
+ data.last_tx = lastTx;
}
if (lastTs) {
- data['last_ts'] = lastTs;
+ data.last_ts = lastTs;
}
- return requestExplorerServiceV1.get(`address/history`, {params: data}).then((res) => {
+ return requestExplorerServiceV1.get(`address/history`, { params: data }).then(res => {
if (res && res.data) {
- return res.data
+ return res.data;
}
});
},
diff --git a/src/api/addressApiLegacy.js b/src/api/addressApiLegacy.js
index 12688881..92d0b926 100644
--- a/src/api/addressApiLegacy.js
+++ b/src/api/addressApiLegacy.js
@@ -9,13 +9,16 @@ import requestExplorerServiceV1 from './axiosInstance';
const addressApi = {
getBalance(address) {
- return requestExplorerServiceV1.get(`node_api/address_balance`, {params: {address}}).then((res) => {
- if (res && res.data) {
- return res.data
- }
- }).catch((error) => {
- // something wrong with request
- });
+ return requestExplorerServiceV1
+ .get(`node_api/address_balance`, { params: { address } })
+ .then(res => {
+ if (res && res.data) {
+ return res.data;
+ }
+ })
+ .catch(error => {
+ // something wrong with request
+ });
},
search(address, count, hash, page, token) {
@@ -27,23 +30,26 @@ const addressApi = {
if 'next', we get the objects after the hash reference
token (optional): str -> only fetch txs related to this token uid
*/
-
- const data = {address, count};
+
+ const data = { address, count };
if (hash) {
- data['hash'] = hash;
- data['page'] = page;
+ data.hash = hash;
+ data.page = page;
}
if (token) {
- data['token'] = token;
+ data.token = token;
}
- return requestExplorerServiceV1.get(`node_api/address_search`, {params: data}).then((res) => {
- if (res && res.data) {
- return res.data
- }
- }).catch((error) => {
- // something wrong with request
- });
+ return requestExplorerServiceV1
+ .get(`node_api/address_search`, { params: data })
+ .then(res => {
+ if (res && res.data) {
+ return res.data;
+ }
+ })
+ .catch(error => {
+ // something wrong with request
+ });
},
};
diff --git a/src/api/axiosInstance.js b/src/api/axiosInstance.js
index be836100..d380f5f7 100644
--- a/src/api/axiosInstance.js
+++ b/src/api/axiosInstance.js
@@ -5,12 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/
-import { EXPLORER_SERVICE_BASE_URL } from '../constants.js';
import axios from 'axios';
+import { EXPLORER_SERVICE_BASE_URL } from '../constants.js';
-const errorHandler = (error) => {
- console.log("ERROR RESPONSE", error);
-}
+const errorHandler = error => {
+ console.log('ERROR RESPONSE', error);
+};
const requestExplorerServiceV1 = () => {
const defaultOptions = {
@@ -18,13 +18,13 @@ const requestExplorerServiceV1 = () => {
headers: {
'Content-Type': 'application/json',
},
- }
+ };
- let instance = axios.create(defaultOptions);
- instance.interceptors.response.use((response) => {
+ const instance = axios.create(defaultOptions);
+ instance.interceptors.response.use(response => {
return response;
}, errorHandler);
return instance;
-}
+};
export default requestExplorerServiceV1();
diff --git a/src/api/blockApi.js b/src/api/blockApi.js
index 9e43e97a..a6808438 100644
--- a/src/api/blockApi.js
+++ b/src/api/blockApi.js
@@ -9,20 +9,20 @@ import helpers from '../utils/helpers';
import requestExplorerServiceV1 from './axiosInstance';
-
const BLOCK_API_DEFAULT_TIMEOUT = 35000; // ms
const blockApi = {
+ /**
+ * Get the best chain height available on ElasticSearch
+ *
+ * @returns {Promise}
+ */
+ async getBestChainHeight() {
+ const response = await requestExplorerServiceV1.get('blocks/best_chain_height', {
+ timeout: BLOCK_API_DEFAULT_TIMEOUT,
+ });
+ return helpers.handleExplorerServiceResponse(response);
+ },
+};
- /**
- * Get the best chain height available on ElasticSearch
- *
- * @returns {Promise}
- */
- async getBestChainHeight() {
- const response = await requestExplorerServiceV1.get('blocks/best_chain_height', { timeout: BLOCK_API_DEFAULT_TIMEOUT });
- return helpers.handleExplorerServiceResponse(response);
- }
-}
-
-export default blockApi;
\ No newline at end of file
+export default blockApi;
diff --git a/src/api/customAxiosInstance.js b/src/api/customAxiosInstance.js
index bad77fb8..0c7d4751 100644
--- a/src/api/customAxiosInstance.js
+++ b/src/api/customAxiosInstance.js
@@ -23,6 +23,6 @@ const createRequestInstance = (resolve, timeout) => {
// Will override lib axios instance increasing the default request timeout
const instance = hathorLib.axios.defaultCreateRequestInstance(resolve, 30000);
return instance;
-}
+};
export default createRequestInstance;
diff --git a/src/api/featureApi.js b/src/api/featureApi.js
index 6eb94b82..fd72e093 100644
--- a/src/api/featureApi.js
+++ b/src/api/featureApi.js
@@ -8,20 +8,17 @@
import requestExplorerServiceV1 from './axiosInstance';
const featureApi = {
-
async getFeatures(block = null) {
return requestExplorerServiceV1.get(`node_api/feature`, { params: { block } }).then(res => {
- return res.data
+ return res.data;
});
},
async getSignalBits(block) {
return this.getFeatures(block).then(data => {
- return data.signal_bits
+ return data.signal_bits;
});
- }
-
-
+ },
};
export default featureApi;
diff --git a/src/api/graphvizApi.js b/src/api/graphvizApi.js
index 20dc52af..611723d0 100644
--- a/src/api/graphvizApi.js
+++ b/src/api/graphvizApi.js
@@ -10,12 +10,15 @@ import { MAX_GRAPH_LEVEL } from '../constants';
const graphvizApi = {
dotNeighbors(tx, graphType) {
- const data = {tx, "graph_type": graphType, "max_level": MAX_GRAPH_LEVEL}
- return requestExplorerServiceV1.get(`node_api/graphviz/neighbours.dot`, {params: data}).then((res) => {
- return res.data
- }, (res) => {
- throw new Error(res.data.message);
- });
+ const data = { tx, graph_type: graphType, max_level: MAX_GRAPH_LEVEL };
+ return requestExplorerServiceV1.get(`node_api/graphviz/neighbours.dot`, { params: data }).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ throw new Error(res.data.message);
+ }
+ );
},
};
diff --git a/src/api/metadataApi.js b/src/api/metadataApi.js
index d4a43497..07513262 100644
--- a/src/api/metadataApi.js
+++ b/src/api/metadataApi.js
@@ -9,14 +9,17 @@ import requestExplorerServiceV1 from './axiosInstance';
const metadataApi = {
getDagMetadata(id) {
- return requestExplorerServiceV1.get(`metadata/dag`, {params: {id}}).then((res) => {
- if (res && id in res.data) {
- return res.data[id]
- }
- }).catch((error) => {
- // something wrong with request
- });
- }
+ return requestExplorerServiceV1
+ .get(`metadata/dag`, { params: { id } })
+ .then(res => {
+ if (res && id in res.data) {
+ return res.data[id];
+ }
+ })
+ .catch(error => {
+ // something wrong with request
+ });
+ },
};
export default metadataApi;
diff --git a/src/api/nanoApi.js b/src/api/nanoApi.js
index ac47b34a..d0d2d151 100644
--- a/src/api/nanoApi.js
+++ b/src/api/nanoApi.js
@@ -20,11 +20,14 @@ const nanoApi = {
*/
getState(id, fields, balances, calls) {
const data = { id, fields, balances, calls };
- return requestExplorerServiceV1.get(`node_api/nc_state`, {params: data}).then((res) => {
- return res.data
- }, (res) => {
- throw new Error(res.data.message);
- });
+ return requestExplorerServiceV1.get(`node_api/nc_state`, { params: data }).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ throw new Error(res.data.message);
+ }
+ );
},
/**
@@ -36,11 +39,14 @@ const nanoApi = {
*/
getHistory(id) {
const data = { id };
- return requestExplorerServiceV1.get(`node_api/nc_history`, {params: data}).then((res) => {
- return res.data
- }, (res) => {
- throw new Error(res.data.message);
- });
+ return requestExplorerServiceV1.get(`node_api/nc_history`, { params: data }).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ throw new Error(res.data.message);
+ }
+ );
},
/**
@@ -52,12 +58,15 @@ const nanoApi = {
*/
getBlueprintInformation(blueprintId) {
const data = { blueprint_id: blueprintId };
- return requestExplorerServiceV1.get(`node_api/nc_blueprint_information`, {params: data}).then((res) => {
- return res.data
- }, (res) => {
- throw new Error(res.data.message);
- });
+ return requestExplorerServiceV1.get(`node_api/nc_blueprint_information`, { params: data }).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ throw new Error(res.data.message);
+ }
+ );
},
};
-export default nanoApi;
\ No newline at end of file
+export default nanoApi;
diff --git a/src/api/networkApi.js b/src/api/networkApi.js
index c7336829..fb05fbe5 100644
--- a/src/api/networkApi.js
+++ b/src/api/networkApi.js
@@ -9,25 +9,31 @@ import requestExplorerServiceV1 from './axiosInstance';
const networkApi = {
getPeerList() {
- return requestExplorerServiceV1.get(`node`).then((res) => {
- if (!res.data) {
- throw new Error("unknown_error");
- }
- return res.data
- }).catch((res) => {
- throw new Error(res.data.message);
- });
+ return requestExplorerServiceV1
+ .get(`node`)
+ .then(res => {
+ if (!res.data) {
+ throw new Error('unknown_error');
+ }
+ return res.data;
+ })
+ .catch(res => {
+ throw new Error(res.data.message);
+ });
},
getPeer(hash) {
- return requestExplorerServiceV1.get(`node/${hash}`).then((res) => {
- if (!res.data) {
- throw new Error("unknown_error");
- }
- return res.data
- }).catch((res) => {
- throw new Error(res.data.message);
- });
- }
+ return requestExplorerServiceV1
+ .get(`node/${hash}`)
+ .then(res => {
+ if (!res.data) {
+ throw new Error('unknown_error');
+ }
+ return res.data;
+ })
+ .catch(res => {
+ throw new Error(res.data.message);
+ });
+ },
};
export default networkApi;
diff --git a/src/api/tokenApi.js b/src/api/tokenApi.js
index c63f7106..efd2e93d 100644
--- a/src/api/tokenApi.js
+++ b/src/api/tokenApi.js
@@ -10,29 +10,38 @@ import { TX_COUNT } from '../constants';
const tokenApi = {
getList() {
- return requestExplorerServiceV1.get(`node_api/tokens`).then((res) => {
- return res.data
- }, (res) => {
- throw new Error(res.data.message);
- });
+ return requestExplorerServiceV1.get(`node_api/tokens`).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ throw new Error(res.data.message);
+ }
+ );
},
get(id) {
- const data = {id};
- return requestExplorerServiceV1.get(`node_api/token`, {params: data}).then((res) => {
- return res.data
- }, (res) => {
- throw new Error(res.data.message);
- });
+ const data = { id };
+ return requestExplorerServiceV1.get(`node_api/token`, { params: data }).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ throw new Error(res.data.message);
+ }
+ );
},
getHistory(id, timestamp, hash, page) {
- const data = {id, timestamp, hash, page, count: TX_COUNT};
- return requestExplorerServiceV1.get(`node_api/token_history`, {params: data}).then((res) => {
- return res.data
- }, (res) => {
- throw new Error(res.data.message);
- });
+ const data = { id, timestamp, hash, page, count: TX_COUNT };
+ return requestExplorerServiceV1.get(`node_api/token_history`, { params: data }).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ throw new Error(res.data.message);
+ }
+ );
},
};
diff --git a/src/api/tokensApi.js b/src/api/tokensApi.js
index 8bea9c11..ce7d61e4 100644
--- a/src/api/tokensApi.js
+++ b/src/api/tokensApi.js
@@ -24,13 +24,16 @@ const tokensApi = {
*/
async getList(searchText, sortBy, order, searchAfter) {
const data = {
- 'search_text': searchText,
- 'sort_by': sortBy,
- 'order': order,
- 'search_after': searchAfter.join(','),
+ search_text: searchText,
+ sort_by: sortBy,
+ order,
+ search_after: searchAfter.join(','),
};
- const response = await requestExplorerServiceV1.get('tokens', { params: data, timeout: TOKENS_API_DEFAULT_TIMEOUT });
+ const response = await requestExplorerServiceV1.get('tokens', {
+ params: data,
+ timeout: TOKENS_API_DEFAULT_TIMEOUT,
+ });
return helpers.handleExplorerServiceResponse(response);
},
@@ -43,7 +46,9 @@ const tokensApi = {
* @return {Promise}
*/
async getToken(tokenId) {
- const response = await requestExplorerServiceV1.get(`tokens/${tokenId}`, { timeout: TOKENS_API_DEFAULT_TIMEOUT });
+ const response = await requestExplorerServiceV1.get(`tokens/${tokenId}`, {
+ timeout: TOKENS_API_DEFAULT_TIMEOUT,
+ });
return helpers.handleExplorerServiceResponse(response);
},
@@ -61,13 +66,16 @@ const tokensApi = {
*/
async getBalances(tokenId, sortBy, order, searchAfter) {
const data = {
- 'token_id': tokenId,
- 'sort_by': sortBy,
- 'order': order,
- 'search_after': searchAfter.join(',')
+ token_id: tokenId,
+ sort_by: sortBy,
+ order,
+ search_after: searchAfter.join(','),
};
- const response = await requestExplorerServiceV1.get('token_balances', { params: data, timeout: TOKENS_API_DEFAULT_TIMEOUT });
+ const response = await requestExplorerServiceV1.get('token_balances', {
+ params: data,
+ timeout: TOKENS_API_DEFAULT_TIMEOUT,
+ });
return helpers.handleExplorerServiceResponse(response);
},
@@ -81,10 +89,13 @@ const tokensApi = {
*/
async getBalanceInformation(tokenId) {
const data = {
- 'token_id': tokenId,
+ token_id: tokenId,
};
- const response = await requestExplorerServiceV1.get('token_balances/information', { params: data, timeout: TOKENS_API_DEFAULT_TIMEOUT});
+ const response = await requestExplorerServiceV1.get('token_balances/information', {
+ params: data,
+ timeout: TOKENS_API_DEFAULT_TIMEOUT,
+ });
return helpers.handleExplorerServiceResponse(response);
},
diff --git a/src/api/txApi.js b/src/api/txApi.js
index 9d817487..523145a8 100644
--- a/src/api/txApi.js
+++ b/src/api/txApi.js
@@ -17,52 +17,67 @@ const txApi = {
page (optional): 'previous' or 'next' -> if 'previous', we get the objects before the hash reference
if 'next', we get the objects after the hash reference
*/
- const data = {type, count};
+ const data = { type, count };
if (hash) {
- data['hash'] = hash;
- data['timestamp'] = timestamp;
- data['page'] = page;
+ data.hash = hash;
+ data.timestamp = timestamp;
+ data.page = page;
}
- return requestExplorerServiceV1.get(`node_api/transactions`, {params: data}).then(res => {
- return res.data
- }).catch(e => {
- throw new Error(e);
- });
+ return requestExplorerServiceV1
+ .get(`node_api/transactions`, { params: data })
+ .then(res => {
+ return res.data;
+ })
+ .catch(e => {
+ throw new Error(e);
+ });
},
getTransaction(id) {
- return requestExplorerServiceV1.get(`node_api/transaction`, {params: {id}}).then(res => {
- return res.data
- }).catch(e => {
- throw new Error(e);
- });
+ return requestExplorerServiceV1
+ .get(`node_api/transaction`, { params: { id } })
+ .then(res => {
+ return res.data;
+ })
+ .catch(e => {
+ throw new Error(e);
+ });
},
decodeTx(hex_tx) {
- const data = {hex_tx}
- return requestExplorerServiceV1.get(`node_api/decode_tx`, {params: data}).then((res) => {
- return res.data
- }, (res) => {
- throw new Error(res.data.message);
- });
+ const data = { hex_tx };
+ return requestExplorerServiceV1.get(`node_api/decode_tx`, { params: data }).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ throw new Error(res.data.message);
+ }
+ );
},
pushTx(hex_tx, force) {
- const data = {hex_tx, force}
- return requestExplorerServiceV1.post(`node_api/push_tx`, data).then((res) => {
- return res.data
- }, (res) => {
- throw new Error(res.data.message);
- });
+ const data = { hex_tx, force };
+ return requestExplorerServiceV1.post(`node_api/push_tx`, data).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ throw new Error(res.data.message);
+ }
+ );
},
getDashboardTx(block, tx) {
- const data = {block, tx}
- return requestExplorerServiceV1.get(`node_api/dashboard_tx`, {params: data}).then((res) => {
- return res.data
- }, (res) => {
- throw new Error(res.data.message);
- });
+ const data = { block, tx };
+ return requestExplorerServiceV1.get(`node_api/dashboard_tx`, { params: data }).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ throw new Error(res.data.message);
+ }
+ );
},
/*
@@ -75,12 +90,15 @@ const txApi = {
* @inner
*/
getConfirmationData(id) {
- const data = {id};
- return requestExplorerServiceV1.get(`node_api/transaction_acc_weight`, {params: data}).then((res) => {
- return res.data;
- }, (res) => {
- return Promise.reject(res);
- });
+ const data = { id };
+ return requestExplorerServiceV1.get(`node_api/transaction_acc_weight`, { params: data }).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ return Promise.reject(res);
+ }
+ );
},
};
diff --git a/src/api/version.js b/src/api/version.js
index 51572a83..58c75b50 100644
--- a/src/api/version.js
+++ b/src/api/version.js
@@ -9,12 +9,15 @@ import requestExplorerServiceV1 from './axiosInstance';
const versionApi = {
getVersion() {
- return requestExplorerServiceV1.get(`node_api/version`).then((res) => {
- return res.data
- }, (res) => {
- throw new Error(res.data.message);
- });
- }
+ return requestExplorerServiceV1.get(`node_api/version`).then(
+ res => {
+ return res.data;
+ },
+ res => {
+ throw new Error(res.data.message);
+ }
+ );
+ },
};
export default versionApi;
diff --git a/src/components/AddressDetailExplorer.js b/src/components/AddressDetailExplorer.js
index 7d622d2c..d1e861f0 100644
--- a/src/components/AddressDetailExplorer.js
+++ b/src/components/AddressDetailExplorer.js
@@ -18,12 +18,11 @@ import { isEqual, find } from 'lodash';
import metadataApi from '../api/metadataApi';
import addressApi from '../api/addressApi';
import txApi from '../api/txApi';
-import ErrorMessageWithIcon from '../components/error/ErrorMessageWithIcon'
-
+import ErrorMessageWithIcon from '../components/error/ErrorMessageWithIcon';
class AddressDetailExplorer extends React.Component {
pagination = new PaginationURL({
- 'token': {required: true},
+ token: { required: true },
});
addressSummaryRef = React.createRef();
@@ -69,14 +68,16 @@ class AddressDetailExplorer extends React.Component {
txCache: {},
showReloadDataButton: false,
showReloadTokenButton: false,
- pageSearchAfter: [{
- page: 0,
- searchAfter: {
- lastTx: null,
- lastTs: null,
+ pageSearchAfter: [
+ {
+ page: 0,
+ searchAfter: {
+ lastTx: null,
+ lastTs: null,
+ },
},
- }]
- }
+ ],
+ };
componentDidMount() {
// Expects address on URL
@@ -126,14 +127,14 @@ class AddressDetailExplorer extends React.Component {
*
* @param {Object} wsData Data from websocket
*/
- handleWebsocket = (wsData) => {
+ handleWebsocket = wsData => {
if (wsData.type === 'network:new_tx_accepted') {
if (this.shouldUpdate(wsData, false) && !this.state.warningRefreshPage) {
// If the search address is in one of the inputs or outputs
this.setState({ warningRefreshPage: true });
}
}
- }
+ };
/**
* Check if address is valid and then update the state and fetch data
@@ -141,36 +142,39 @@ class AddressDetailExplorer extends React.Component {
*
* @param {Object} address New searched address to update state
*/
- updateAddress = (address) => {
+ updateAddress = address => {
this.setState({ queryParams: this.pagination.obtainQueryParams() }, () => {
const network = hathorLib.config.getNetwork();
const addressObj = new hathorLib.Address(address, { network });
if (addressObj.isValid()) {
- this.setState({
- address,
- loadingTokens: true,
- loadingSummary: true,
- loadingHistory: true,
- addressTokens: {},
- transactions: [],
- balance: {},
- errorMessage: '',
- }, () => {
- const queryParams = this.pagination.obtainQueryParams();
- if (queryParams.token !== null) {
- // User already have a token selected on the URL
- this.setState({ selectedToken: queryParams.token }, () => {
+ this.setState(
+ {
+ address,
+ loadingTokens: true,
+ loadingSummary: true,
+ loadingHistory: true,
+ addressTokens: {},
+ transactions: [],
+ balance: {},
+ errorMessage: '',
+ },
+ () => {
+ const queryParams = this.pagination.obtainQueryParams();
+ if (queryParams.token !== null) {
+ // User already have a token selected on the URL
+ this.setState({ selectedToken: queryParams.token }, () => {
+ this.reloadData();
+ });
+ } else {
this.reloadData();
- });
- } else {
- this.reloadData();
+ }
}
- });
+ );
} else {
this.setState({ errorMessage: 'Invalid address.' });
}
});
- }
+ };
/**
* Update transactions data state after requesting data from the server
@@ -178,188 +182,214 @@ class AddressDetailExplorer extends React.Component {
* @param {Object} queryParams URL parameters
*/
getHistoryData = (lastTx, lastTs) => {
- return addressApi.getHistory(this.state.address, this.state.selectedToken, TX_COUNT, lastTx, lastTs).then((response) => {
- if (!response) {
- // An error happened with the API call
- this.setState({
- showReloadTokenButton: true,
- });
- return;
- }
-
- const { has_next, history } = response;
- this.setState({
- transactions: history,
- hasAfter: has_next,
- }, () => {
- const promises = [];
- for (const tx of history) {
- if (!this.state.txCache[tx.tx_id]) {
- /**
- * The explorer-service address api does not retrieve all metadata of the transactions
- * So there are some information that are not retrieved, e.g. whether the transaction only has authorities
- * We fetch the transaction with all it's metadata to make this assertions.
- */
- promises.push(txApi.getTransaction(tx.tx_id));
- }
- }
-
- Promise.all(promises).then(results => {
- const cache = {...this.state.txCache};
- for (const result of results) {
- const tx = {...result.tx, meta: result.meta};
- cache[tx.hash] = tx;
- }
- this.setState({txCache: cache});
- });
- });
- return history;
- }).finally(() => {
- this.setState({ loadingHistory: false });
- });
- }
-
- reloadData = () => {
- this.setState({
- loadingTokens: true,
- }, () => {
- addressApi.getTokens(this.state.address, TOKEN_COUNT).then(response => {
+ return addressApi
+ .getHistory(this.state.address, this.state.selectedToken, TX_COUNT, lastTx, lastTs)
+ .then(response => {
if (!response) {
// An error happened with the API call
- this.setState({ showReloadDataButton: true });
+ this.setState({
+ showReloadTokenButton: true,
+ });
return;
}
- let selectedToken = '';
-
- const tokens = response.tokens || {};
- const total = response.total || 0;
+ const { has_next, history } = response;
+ this.setState(
+ {
+ transactions: history,
+ hasAfter: has_next,
+ },
+ () => {
+ const promises = [];
+ for (const tx of history) {
+ if (!this.state.txCache[tx.tx_id]) {
+ /**
+ * The explorer-service address api does not retrieve all metadata of the transactions
+ * So there are some information that are not retrieved, e.g. whether the transaction only has authorities
+ * We fetch the transaction with all it's metadata to make this assertions.
+ */
+ promises.push(txApi.getTransaction(tx.tx_id));
+ }
+ }
- if (total > Object.keys(tokens).length) {
- // There were unfetched tokens
- this.setState({ warnMissingTokens: total });
- } else {
- // This will turn off the missing tokens alert
- this.setState({ warnMissingTokens: 0 });
- }
+ Promise.all(promises).then(results => {
+ const cache = { ...this.state.txCache };
+ for (const result of results) {
+ const tx = { ...result.tx, meta: result.meta };
+ cache[tx.hash] = tx;
+ }
+ this.setState({ txCache: cache });
+ });
+ }
+ );
+ return history;
+ })
+ .finally(() => {
+ this.setState({ loadingHistory: false });
+ });
+ };
- if (this.state.selectedToken && tokens[this.state.selectedToken]) {
- // use has a selected token, we will keep the selected token
- selectedToken = this.state.selectedToken;
- } else {
- const hathorUID = hathorLib.constants.NATIVE_TOKEN_UID
- if (tokens[hathorUID]) {
- // If HTR is in the token list of this address, it's the default selection
- selectedToken = hathorUID;
- } else {
- // Otherwise we get the first element, if there is one
- const keys = Object.keys(tokens);
- if (keys.length === 0) {
- // In case the length is 0, we have no transactions for this address
- this.setState({
- loadingTokens: false,
- loadingSummary: false,
- loadingHistory: false,
- });
+ reloadData = () => {
+ this.setState(
+ {
+ loadingTokens: true,
+ },
+ () => {
+ addressApi
+ .getTokens(this.state.address, TOKEN_COUNT)
+ .then(response => {
+ if (!response) {
+ // An error happened with the API call
+ this.setState({ showReloadDataButton: true });
return;
}
- selectedToken = keys[0];
- }
- }
- const tokenDidChange = selectedToken !== this.state.selectedToken || this.state.selectedToken === '';
+ let selectedToken = '';
- this.setState({
- addressTokens: tokens,
- loadingTokens: false,
- selectedToken,
- }, () => {
- if (tokenDidChange || !this.state.metadataLoaded) {
- this.getSelectedTokenMetadata(selectedToken);
- }
+ const tokens = response.tokens || {};
+ const total = response.total || 0;
- // Update token in the URL
- this.updateTokenURL(selectedToken);
- this.reloadTokenData(selectedToken);
- });
+ if (total > Object.keys(tokens).length) {
+ // There were unfetched tokens
+ this.setState({ warnMissingTokens: total });
+ } else {
+ // This will turn off the missing tokens alert
+ this.setState({ warnMissingTokens: 0 });
+ }
- }).catch(error => {
- this.setState({
- loadingTokens: false,
- errorMessage: error.toString(),
- });
- });
- });
- }
+ if (this.state.selectedToken && tokens[this.state.selectedToken]) {
+ // use has a selected token, we will keep the selected token
+ selectedToken = this.state.selectedToken;
+ } else {
+ const hathorUID = hathorLib.constants.NATIVE_TOKEN_UID;
+ if (tokens[hathorUID]) {
+ // If HTR is in the token list of this address, it's the default selection
+ selectedToken = hathorUID;
+ } else {
+ // Otherwise we get the first element, if there is one
+ const keys = Object.keys(tokens);
+ if (keys.length === 0) {
+ // In case the length is 0, we have no transactions for this address
+ this.setState({
+ loadingTokens: false,
+ loadingSummary: false,
+ loadingHistory: false,
+ });
+ return;
+ }
+ selectedToken = keys[0];
+ }
+ }
- reloadTokenData = (token) => {
- this.setState({
- loadingSummary: true,
- loadingHistory: true,
- }, () => {
- addressApi.getBalance(this.state.address, token).then(response => {
- if (!response) {
- // An error happened with the API call
- this.setState({ showReloadTokenButton: true });
- return;
- }
- const balance = response;
- this.setState({ balance });
- return balance;
- }).then(balance => {
- return this.getHistoryData().then(txhistory => {
- if (!this.state.metadataLoaded) {
- this.getSelectedTokenMetadata(token);
- }
- });
- }).catch(error => {
- this.setState({ errorMessage: error });
- }).finally(() => {
- this.setState({ loadingSummary: false });
- });
- });
- }
+ const tokenDidChange =
+ selectedToken !== this.state.selectedToken || this.state.selectedToken === '';
- getSelectedTokenMetadata = (selectedToken) => {
+ this.setState(
+ {
+ addressTokens: tokens,
+ loadingTokens: false,
+ selectedToken,
+ },
+ () => {
+ if (tokenDidChange || !this.state.metadataLoaded) {
+ this.getSelectedTokenMetadata(selectedToken);
+ }
+
+ // Update token in the URL
+ this.updateTokenURL(selectedToken);
+ this.reloadTokenData(selectedToken);
+ }
+ );
+ })
+ .catch(error => {
+ this.setState({
+ loadingTokens: false,
+ errorMessage: error.toString(),
+ });
+ });
+ }
+ );
+ };
+
+ reloadTokenData = token => {
+ this.setState(
+ {
+ loadingSummary: true,
+ loadingHistory: true,
+ },
+ () => {
+ addressApi
+ .getBalance(this.state.address, token)
+ .then(response => {
+ if (!response) {
+ // An error happened with the API call
+ this.setState({ showReloadTokenButton: true });
+ return;
+ }
+ const balance = response;
+ this.setState({ balance });
+ return balance;
+ })
+ .then(balance => {
+ return this.getHistoryData().then(txhistory => {
+ if (!this.state.metadataLoaded) {
+ this.getSelectedTokenMetadata(token);
+ }
+ });
+ })
+ .catch(error => {
+ this.setState({ errorMessage: error });
+ })
+ .finally(() => {
+ this.setState({ loadingSummary: false });
+ });
+ }
+ );
+ };
+
+ getSelectedTokenMetadata = selectedToken => {
if (selectedToken === hathorLib.constants.NATIVE_TOKEN_UID) {
this.setState({ metadataLoaded: true });
return;
}
- metadataApi.getDagMetadata(selectedToken).then((data) => {
+ metadataApi.getDagMetadata(selectedToken).then(data => {
if (data) {
this.setState({ selectedTokenMetadata: data });
}
this.setState({ metadataLoaded: true });
});
- }
+ };
/**
* Callback to be executed when user changes token on select input
*
* @param {String} Value of the selected item
*/
- onTokenSelectChanged = (value) => {
- this.setState({
- selectedToken: value,
- metadataLoaded: false,
- selectedTokenMetadata: null,
- balance: {},
- transactions: [],
- }, () => {
- this.updateTokenURL(value);
- this.reloadTokenData(value);
- });
- }
+ onTokenSelectChanged = value => {
+ this.setState(
+ {
+ selectedToken: value,
+ metadataLoaded: false,
+ selectedTokenMetadata: null,
+ balance: {},
+ transactions: [],
+ },
+ () => {
+ this.updateTokenURL(value);
+ this.reloadTokenData(value);
+ }
+ );
+ };
/**
* Update URL with new selected token and trigger didUpdate
*
* @param {String} New token selected
*/
- updateTokenURL = (token) => {
+ updateTokenURL = token => {
const newURL = this.pagination.setURLParameters({ token });
this.props.history.push(newURL);
- }
+ };
/**
* Check if the searched address is on the inputs or outputs of the new tx
@@ -384,57 +414,60 @@ class AddressDetailExplorer extends React.Component {
}
return false;
- }
+ };
/**
* Redirects to transaction detail screen after clicking on a table row
*
* @param {String} hash Hash of tx clicked
*/
- onRowClicked = (hash) => {
+ onRowClicked = hash => {
this.props.history.push(`/transaction/${hash}`);
- }
+ };
/**
* Refresh all data for the selected token
*
* @param {Event} e Click event
*/
- refreshTokenData = (e) => {
+ refreshTokenData = e => {
e.preventDefault();
this.setState({ showReloadTokenButton: false }, () => {
- this.reloadTokenData();
- })
- }
+ this.reloadTokenData();
+ });
+ };
/**
* Refresh all data.
*
* @param {Event} e Click event
*/
- refreshPageData = (e) => {
+ refreshPageData = e => {
e.preventDefault();
- this.setState({
- showReloadDataButton: false,
- warningRefreshPage: false
- }, () => {
- this.reloadData();
- })
- }
+ this.setState(
+ {
+ showReloadDataButton: false,
+ warningRefreshPage: false,
+ },
+ () => {
+ this.reloadData();
+ }
+ );
+ };
/**
* Reset query params then refresh data.
*
* @param {Event} e Click event
*/
- reloadPage = (e) => {
+ reloadPage = e => {
this.pagination.clearOptionalQueryParams();
this.refreshPageData(e);
- }
+ };
lastPage = () => {
return Math.ceil(this.state.balance.transactions / TX_COUNT);
- }
+ };
onNextPageClicked = async () => {
this.setState({ loadingPagination: true });
@@ -453,11 +486,12 @@ class AddressDetailExplorer extends React.Component {
lastTs,
};
- const newPageSearchAfter = [
- ...this.state.pageSearchAfter, {
+ const newPageSearchAfter = [
+ ...this.state.pageSearchAfter,
+ {
page: nextPage,
searchAfter,
- }
+ },
];
await this.getHistoryData(searchAfter.lastTx, searchAfter.lastTs);
@@ -468,7 +502,7 @@ class AddressDetailExplorer extends React.Component {
loadingPagination: false,
page: nextPage,
});
- }
+ };
onPreviousPageClicked = async () => {
this.setState({ loadingPagination: true });
@@ -484,78 +518,89 @@ class AddressDetailExplorer extends React.Component {
});
this.setState({ loadingPagination: false });
- }
+ };
render() {
const renderWarningAlert = () => {
if (this.state.warningRefreshPage) {
return (
- There is a new transaction for this address. Please refresh the page to see the newest data.
+ There is a new transaction for this address. Please{' '}
+
+ refresh
+ {' '}
+ the page to see the newest data.
- This address has {this.state.warnMissingTokens} tokens but we are showing only the {TOKEN_COUNT} with the most recent activity.
+ This address has {this.state.warnMissingTokens} tokens but we are showing only the{' '}
+ {TOKEN_COUNT} with the most recent activity.
;
}
}
diff --git a/src/components/AddressDetailLegacy.js b/src/components/AddressDetailLegacy.js
index 9c73f676..4fdc5900 100644
--- a/src/components/AddressDetailLegacy.js
+++ b/src/components/AddressDetailLegacy.js
@@ -19,12 +19,11 @@ import helpers from '../utils/helpers';
import metadataApi from '../api/metadataApi';
import addressApiLegacy from '../api/addressApiLegacy';
-
class AddressDetailLegacy extends React.Component {
pagination = new PaginationURL({
- 'hash': {required: false},
- 'page': {required: false},
- 'token': {required: true}
+ hash: { required: false },
+ page: { required: false },
+ token: { required: true },
});
addressSummaryRef = React.createRef();
@@ -60,7 +59,7 @@ class AddressDetailLegacy extends React.Component {
warningRefreshPage: false,
selectedTokenMetadata: null,
metadataLoaded: false,
- }
+ };
componentDidMount() {
// Expects address on URL
@@ -111,14 +110,14 @@ class AddressDetailLegacy extends React.Component {
*
* @param {Object} wsData Data from websocket
*/
- handleWebsocket = (wsData) => {
+ handleWebsocket = wsData => {
if (wsData.type === 'network:new_tx_accepted') {
if (this.shouldUpdate(wsData, false) && !this.state.warningRefreshPage) {
// If the search address is in one of the inputs or outputs
this.setState({ warningRefreshPage: true });
}
}
- }
+ };
/**
* Update the list with a new tx arrived in a ws message
@@ -127,7 +126,7 @@ class AddressDetailLegacy extends React.Component {
*
* @param {Object} tx Data of a newly arrived tx
*/
- updateListWs = (tx) => {
+ updateListWs = tx => {
// We only add new tx/blocks if it's the first page
if (!this.state.hasBefore) {
if (this.shouldUpdate(tx, true)) {
@@ -141,7 +140,7 @@ class AddressDetailLegacy extends React.Component {
this.setState({ transactions, hasAfter, numberOfTransactions: newNumberOfTransactions });
}
}
- }
+ };
/**
* Check if address is valid and then update the state and get data from full node
@@ -149,7 +148,7 @@ class AddressDetailLegacy extends React.Component {
*
* @param {Object} address New searched address to update state
*/
- updateAddress = (address) => {
+ updateAddress = address => {
this.setState({ queryParams: this.pagination.obtainQueryParams() }, () => {
const network = hathorLib.config.getNetwork();
const addressObj = new hathorLib.Address(address, { network });
@@ -173,23 +172,24 @@ class AddressDetailLegacy extends React.Component {
this.setState({ errorMessage: 'Invalid address.' });
}
});
- }
+ };
/**
* Update transactions data state after requesting data from the server
*
* @param {Object} queryParams URL parameters
*/
- getHistoryData = (queryParams) => {
- addressApiLegacy.search(this.state.address, TX_COUNT, queryParams.hash, queryParams.page, queryParams.token).then((response) => {
- if (response.success) {
- this.handleFetchedData(response, queryParams);
- }
- // fetch metadata for selected token
- this.getSelectedTokenMetadata(queryParams.token);
- });
- }
-
+ getHistoryData = queryParams => {
+ addressApiLegacy
+ .search(this.state.address, TX_COUNT, queryParams.hash, queryParams.page, queryParams.token)
+ .then(response => {
+ if (response.success) {
+ this.handleFetchedData(response, queryParams);
+ }
+ // fetch metadata for selected token
+ this.getSelectedTokenMetadata(queryParams.token);
+ });
+ };
/**
* Update component state when new list data arrives
@@ -227,20 +227,20 @@ class AddressDetailLegacy extends React.Component {
queryParams,
numberOfTransactions: data.total,
});
- }
+ };
/**
* Request data from server and update state balance
*/
getSummaryData = () => {
- addressApiLegacy.getBalance(this.state.address).then((response) => {
+ addressApiLegacy.getBalance(this.state.address).then(response => {
if (response.success) {
let selectedToken = '';
if (this.state.selectedToken && this.state.selectedToken in response.tokens_data) {
// If user had selected a token already, should continue the same
selectedToken = this.state.selectedToken;
} else {
- const hathorUID = hathorLib.constants.NATIVE_TOKEN_UID
+ const hathorUID = hathorLib.constants.NATIVE_TOKEN_UID;
if (hathorUID in response.tokens_data) {
// If HTR is in the token list of this address, it's the default selection
selectedToken = hathorUID;
@@ -273,38 +273,38 @@ class AddressDetailLegacy extends React.Component {
});
}
});
- }
+ };
- getSelectedTokenMetadata = (selectedToken) => {
- metadataApi.getDagMetadata(selectedToken).then((data) => {
+ getSelectedTokenMetadata = selectedToken => {
+ metadataApi.getDagMetadata(selectedToken).then(data => {
if (data) {
this.setState({ selectedTokenMetadata: data });
}
this.setState({ metadataLoaded: true });
});
- }
+ };
/**
* Callback to be executed when user changes token on select input
*
* @param {String} Value of the selected item
*/
- onTokenSelectChanged = (value) => {
+ onTokenSelectChanged = value => {
this.setState({ selectedToken: value, metadataLoaded: false, selectedTokenMetadata: null });
this.updateTokenURL(value);
- }
+ };
/**
* Update URL with new selected token and trigger didUpdate
*
* @param {String} New token selected
*/
- updateTokenURL = (token) => {
+ updateTokenURL = token => {
const queryParams = this.pagination.obtainQueryParams();
queryParams.token = token;
const newURL = this.pagination.setURLParameters(queryParams);
this.props.history.push(newURL);
- }
+ };
/**
* Check if the searched address is on the inputs or outputs of the new tx
@@ -329,54 +329,56 @@ class AddressDetailLegacy extends React.Component {
}
return false;
- }
+ };
/**
* Redirects to transaction detail screen after clicking on a table row
*
* @param {String} hash Hash of tx clicked
*/
- onRowClicked = (hash) => {
+ onRowClicked = hash => {
this.props.history.push(`/transaction/${hash}`);
- }
+ };
/**
* Refresh web page
*
* @param {Event} e Click event
*/
- refreshPage = (e) => {
+ refreshPage = e => {
e.preventDefault();
window.location.reload();
- }
+ };
render() {
const renderWarningAlert = () => {
if (this.state.warningRefreshPage) {
return (
- There is a new transaction for this address. Please refresh the page to see the newest data.
+ There is a new transaction for this address. Please{' '}
+
+ refresh
+ {' '}
+ the page to see the newest data.
+ ) : null;
+};
/**
* featureToggle: The feature flag that will be evaluated to check if this component must be rendered
@@ -18,9 +25,9 @@ const ConditionalNavigation = ({ featureToggle, to, label }) => {
* to: Where this navigation link will point to
*/
ConditionalNavigation.propTypes = {
- featureToggle: PropTypes.string.isRequired,
- label: PropTypes.string.isRequired,
- to: PropTypes.string.isRequired
-}
+ featureToggle: PropTypes.string.isRequired,
+ label: PropTypes.string.isRequired,
+ to: PropTypes.string.isRequired,
+};
export default ConditionalNavigation;
diff --git a/src/components/DagComponent.js b/src/components/DagComponent.js
index ab85a35f..f79d725e 100644
--- a/src/components/DagComponent.js
+++ b/src/components/DagComponent.js
@@ -17,19 +17,18 @@ import { zoom, zoomIdentity } from 'd3-zoom';
// When we have a better control of timestamp in the graph we should change
// the throttle background to cover a timestamp region and not a tx/block
-
class DagComponent extends React.Component {
constructor(props) {
super(props);
// Tx circle radius and color
this.txRadius = 8;
- this.txColor = "steelblue";
+ this.txColor = 'steelblue';
// Block rectangle width, height and color
this.blockWidth = 20;
this.blockHeight = 10;
- this.blockColor = "darkgoldenrod";
+ this.blockColor = 'darkgoldenrod';
// X distance between txs and blocks
this.txMargin = 40;
@@ -62,7 +61,7 @@ class DagComponent extends React.Component {
this.lastZoomScale = 1;
// Throttle background
- this.throttleBackground = {'size': 2*this.txRadius + this.txMargin, 'color': '#eee'};
+ this.throttleBackground = { size: 2 * this.txRadius + this.txMargin, color: '#eee' };
this.newTxs = this.newTxs.bind(this);
this.newBlocks = this.newBlocks.bind(this);
@@ -78,16 +77,15 @@ class DagComponent extends React.Component {
}
componentDidMount() {
- this.tooltip = select(".tooltip")
- .style("opacity", 0);
+ this.tooltip = select('.tooltip').style('opacity', 0);
this.drawGraph();
}
getTxY() {
// We show same timestamp tx in a vertical axis alternating top and bottom from the block line
- let signal = this.currentTimestampIndex % 2 === 0 ? -1 : 1;
- let multiplier = Math.floor(this.currentTimestampIndex / 2) + 1;
+ const signal = this.currentTimestampIndex % 2 === 0 ? -1 : 1;
+ const multiplier = Math.floor(this.currentTimestampIndex / 2) + 1;
return this.height / 2 + signal * multiplier * this.txMargin;
}
@@ -103,36 +101,36 @@ class DagComponent extends React.Component {
if (isBlock) {
// Calculate new x value to add this block
x = this.startBlockX + this.indexBlock * this.txMargin;
- let graphData = {
- "id": data.tx_id,
- "isBlock": true,
- "x": x,
- "y": this.blockY,
- "links": [],
- "timestamp": data.timestamp
+ const graphData = {
+ id: data.tx_id,
+ isBlock: true,
+ x,
+ y: this.blockY,
+ links: [],
+ timestamp: data.timestamp,
};
this.graph[data.tx_id] = graphData;
- let newLinks = [];
- for (let parent of parents) {
+ const newLinks = [];
+ for (const parent of parents) {
// Validate if parent is in the data, otherwise no need to add a link
if (this.graph.hasOwnProperty(parent)) {
// Creating link for each parent
- let linkData = {
- "source": {
- "id": data.tx_id,
- "x": x + this.blockWidth / 2,
- "y": this.blockY + this.blockHeight / 2
+ const linkData = {
+ source: {
+ id: data.tx_id,
+ x: x + this.blockWidth / 2,
+ y: this.blockY + this.blockHeight / 2,
+ },
+ target: {
+ id: parent,
+ x: this.graph[parent].x + (this.graph[parent].isBlock ? this.blockWidth / 2 : 0),
+ y: this.graph[parent].y + (this.graph[parent].isBlock ? this.blockHeight / 2 : 0),
},
- "target": {
- "id": parent,
- "x": this.graph[parent].x + (this.graph[parent].isBlock ? this.blockWidth / 2 : 0),
- "y": this.graph[parent].y + (this.graph[parent].isBlock ? this.blockHeight / 2 : 0)
- }
};
this.links.push(linkData);
newLinks.push(linkData);
- this.graph[parent]["links"].push(data.tx_id);
- this.graph[data.tx_id]["links"].push(parent);
+ this.graph[parent].links.push(data.tx_id);
+ this.graph[data.tx_id].links.push(parent);
}
}
// Add new links to graph
@@ -151,35 +149,35 @@ class DagComponent extends React.Component {
}
// Calculate new x value to add this tx
x = this.startTxX + this.indexTx * this.txMargin;
- let graphData = {
- "id": data.tx_id,
- "isBlock": false,
- "x": x,
- "y": this.getTxY(),
- "links": [],
- "timestamp": data.timestamp
+ const graphData = {
+ id: data.tx_id,
+ isBlock: false,
+ x,
+ y: this.getTxY(),
+ links: [],
+ timestamp: data.timestamp,
};
this.graph[data.tx_id] = graphData;
- let newLinks = [];
- for (let parent of parents) {
+ const newLinks = [];
+ for (const parent of parents) {
// Validate if parent is in the data, otherwise no need to add a link
if (this.graph.hasOwnProperty(parent)) {
// Creating link for each parent
- let linkData = {
- "source": {
- "id": data.tx_id,
- "x": x,
- "y": this.getTxY()
+ const linkData = {
+ source: {
+ id: data.tx_id,
+ x,
+ y: this.getTxY(),
+ },
+ target: {
+ id: parent,
+ x: this.graph[parent].x,
+ y: this.graph[parent].y,
},
- "target": {
- "id": parent,
- "x": this.graph[parent].x,
- "y": this.graph[parent].y
- }
};
this.links.push(linkData);
- this.graph[parent]["links"].push(data.tx_id);
- this.graph[data.tx_id]["links"].push(parent);
+ this.graph[parent].links.push(data.tx_id);
+ this.graph[data.tx_id].links.push(parent);
newLinks.push(linkData);
}
}
@@ -204,13 +202,18 @@ class DagComponent extends React.Component {
translateGraph(x) {
// Translate the graph to show the last added element
// Get diff from last x to the one that is being added
- let diff = x - ((this.width - this.txMargin) / this.lastZoomScale - this.lastZoomX);
+ const diff = x - ((this.width - this.txMargin) / this.lastZoomScale - this.lastZoomX);
if (diff > 0) {
// If diff > 0, means that it's not appearing, so we translate the graph
this.gDraw
- .transition()
- .duration(300)
- .call( this.zoomCall.transform, zoomIdentity.scale(this.lastZoomScale).translate(this.lastZoomX - diff, this.lastZoomY / this.lastZoomScale) );
+ .transition()
+ .duration(300)
+ .call(
+ this.zoomCall.transform,
+ zoomIdentity
+ .scale(this.lastZoomScale)
+ .translate(this.lastZoomX - diff, this.lastZoomY / this.lastZoomScale)
+ );
// Save new X zoom
this.lastZoomX -= diff;
}
@@ -221,13 +224,22 @@ class DagComponent extends React.Component {
this.gLinks
.selectAll()
.data(links)
- .enter().append("g")
- .attr("class", "link")
- .append("line")
- .attr("x1", function(d) { return d.source.x; })
- .attr("y1", function(d) { return d.source.y; })
- .attr("x2", function(d) { return d.target.x; })
- .attr("y2", function(d) { return d.target.y; });
+ .enter()
+ .append('g')
+ .attr('class', 'link')
+ .append('line')
+ .attr('x1', function(d) {
+ return d.source.x;
+ })
+ .attr('y1', function(d) {
+ return d.source.y;
+ })
+ .attr('x2', function(d) {
+ return d.target.x;
+ })
+ .attr('y2', function(d) {
+ return d.target.y;
+ });
this.link = this.gLinks.selectAll('line');
}
@@ -236,44 +248,55 @@ class DagComponent extends React.Component {
// Add new txs to the svg
// Add g auxiliar element
- var tx = this.gTxs
+ const tx = this.gTxs
.selectAll()
.data(txs)
.enter()
- .filter(function(d){ return !d.isBlock; })
- .append("g")
- .attr("class", "tx")
+ .filter(function(d) {
+ return !d.isBlock;
+ })
+ .append('g')
+ .attr('class', 'tx');
// Add circle with tx data
- tx.append("circle")
- .attr("r", this.txRadius)
- .attr("fill", this.txColor)
- .attr("cx", (d) => { return d.x})
- .attr("cy", (d) => { return d.y})
+ tx.append('circle')
+ .attr('r', this.txRadius)
+ .attr('fill', this.txColor)
+ .attr('cx', d => {
+ return d.x;
+ })
+ .attr('cy', d => {
+ return d.y;
+ });
// Mouseover event to show/move/remove tooltip
- tx.on('mouseover.tooltip', (d) => {
+ tx.on('mouseover.tooltip', d => {
this.createTooltip(d);
})
- .on('mouseover.fade', this.fade(0.1))
- .on("mouseout.tooltip", (e) => {
- this.removeTooltip(e);
- })
- .on('mouseout.fade', this.fade(1))
- .on("mousemove", (e) => {
- this.moveTooltip(e);
- })
+ .on('mouseover.fade', this.fade(0.1))
+ .on('mouseout.tooltip', e => {
+ this.removeTooltip(e);
+ })
+ .on('mouseout.fade', this.fade(1))
+ .on('mousemove', e => {
+ this.moveTooltip(e);
+ });
// Add text to show tx info
- tx
- .append("text")
- .append("tspan")
- .attr("class", "tx-text")
- .attr("text-anchor", "middle")
- .attr("alignment-baseline", "central")
- .attr("x", (d) => { return d.x})
- .attr("y", (d) => { return d.y})
- .text(function(d) { return d.id.substring(0,4); });
+ tx.append('text')
+ .append('tspan')
+ .attr('class', 'tx-text')
+ .attr('text-anchor', 'middle')
+ .attr('alignment-baseline', 'central')
+ .attr('x', d => {
+ return d.x;
+ })
+ .attr('y', d => {
+ return d.y;
+ })
+ .text(function(d) {
+ return d.id.substring(0, 4);
+ });
this.tx = this.gTxs.selectAll('circle');
}
@@ -282,45 +305,62 @@ class DagComponent extends React.Component {
// Add new blocks to the svg
// Create g auxiliar element
- var block = this.gBlocks
+ const block = this.gBlocks
.selectAll()
.data(blocks)
.enter()
- .filter(function(d){ return d.isBlock; })
- .append("g")
- .attr("class", "block")
+ .filter(function(d) {
+ return d.isBlock;
+ })
+ .append('g')
+ .attr('class', 'block');
// Add tooltip events
- block.on('mouseover.tooltip', (d) => {
- this.createTooltip(d);
- })
- .on('mouseover.fade', this.fade(0.1))
- .on("mouseout.tooltip", (e) => {
- this.removeTooltip(e);
- })
- .on('mouseout.fade', this.fade(1))
- .on("mousemove", (e) => {
- this.moveTooltip(e);
- })
+ block
+ .on('mouseover.tooltip', d => {
+ this.createTooltip(d);
+ })
+ .on('mouseover.fade', this.fade(0.1))
+ .on('mouseout.tooltip', e => {
+ this.removeTooltip(e);
+ })
+ .on('mouseout.fade', this.fade(1))
+ .on('mousemove', e => {
+ this.moveTooltip(e);
+ });
// Add rectangle with block data
- block.append("rect")
- .attr("fill", this.blockColor)
- .attr("width", this.blockWidth)
- .attr("height", this.blockHeight)
- .attr("x", (d) => {return d.x})
- .attr("y", (d) => {return d.y})
+ block
+ .append('rect')
+ .attr('fill', this.blockColor)
+ .attr('width', this.blockWidth)
+ .attr('height', this.blockHeight)
+ .attr('x', d => {
+ return d.x;
+ })
+ .attr('y', d => {
+ return d.y;
+ });
// Add text to show block info
- block.filter(function(d){return d.isBlock; })
- .append("text")
- .append("tspan")
- .attr("class", "block-text")
- .attr("text-anchor", "middle")
- .attr("alignment-baseline", "central")
- .attr("x", (d) => { return d.x + this.blockWidth / 2})
- .attr("y", (d) => { return d.y + this.blockHeight / 2})
- .text(function(d) { return d.id.substring(0,4); });
+ block
+ .filter(function(d) {
+ return d.isBlock;
+ })
+ .append('text')
+ .append('tspan')
+ .attr('class', 'block-text')
+ .attr('text-anchor', 'middle')
+ .attr('alignment-baseline', 'central')
+ .attr('x', d => {
+ return d.x + this.blockWidth / 2;
+ })
+ .attr('y', d => {
+ return d.y + this.blockHeight / 2;
+ })
+ .text(function(d) {
+ return d.id.substring(0, 4);
+ });
this.block = this.gBlocks.selectAll('rect');
}
@@ -329,14 +369,19 @@ class DagComponent extends React.Component {
this.gThrottleBg
.selectAll()
.data(data)
- .enter().append("g")
- .attr("class", "throttle-bg")
- .append("rect")
- .attr("fill", this.throttleBackground.color)
- .attr("width", this.throttleBackground.size)
- .attr("height", this.throttleBackground.size)
- .attr("x", (d) => {return d.x - this.throttleBackground.size / 2})
- .attr("y", (d) => {return d.y - this.throttleBackground.size / 2})
+ .enter()
+ .append('g')
+ .attr('class', 'throttle-bg')
+ .append('rect')
+ .attr('fill', this.throttleBackground.color)
+ .attr('width', this.throttleBackground.size)
+ .attr('height', this.throttleBackground.size)
+ .attr('x', d => {
+ return d.x - this.throttleBackground.size / 2;
+ })
+ .attr('y', d => {
+ return d.y - this.throttleBackground.size / 2;
+ });
}
drawGraph() {
@@ -348,10 +393,10 @@ class DagComponent extends React.Component {
.attr('width', this.width)
.attr('height', this.height);
- this.gMain = this.svg.append('g')
- .classed('g-main', true);
+ this.gMain = this.svg.append('g').classed('g-main', true);
- this.gMain.append('rect')
+ this.gMain
+ .append('rect')
.attr('width', this.width)
.attr('height', this.height)
.style('fill', 'white');
@@ -364,21 +409,20 @@ class DagComponent extends React.Component {
this.gBlocks = this.gDraw.append('g');
// Adding zoom handler
- this.zoomCall = zoom()
- .on('zoom', this.zoomed)
+ this.zoomCall = zoom().on('zoom', this.zoomed);
this.gMain.call(this.zoomCall);
// Handle initial data translating in the end to last X
let maxX = 0;
- for(let tx of this.props.txs) {
- let newX = this.newData(tx, false, true);
+ for (const tx of this.props.txs) {
+ const newX = this.newData(tx, false, true);
maxX = Math.max(maxX, newX);
}
- for(let block of this.props.blocks) {
- let newX = this.newData(block, true, true);
+ for (const block of this.props.blocks) {
+ const newX = this.newData(block, true, true);
maxX = Math.max(maxX, newX);
}
@@ -391,24 +435,26 @@ class DagComponent extends React.Component {
/** Data from the tx being hovered */
const d = mouseEvent.currentTarget.__data__;
if (this.tx) {
- this.tx.style('stroke-opacity', function (o) {
- const thisOpacity = (d.links.indexOf(o.id) > -1 || d.id === o.id) ? 1 : opacity;
+ this.tx.style('stroke-opacity', function(o) {
+ const thisOpacity = d.links.indexOf(o.id) > -1 || d.id === o.id ? 1 : opacity;
this.setAttribute('fill-opacity', thisOpacity);
return thisOpacity;
});
}
if (this.block) {
- this.block.style('stroke-opacity', function (o) {
- const thisOpacity = (d.links.indexOf(o.id) > -1 || d.id === o.id) ? 1 : opacity;
+ this.block.style('stroke-opacity', function(o) {
+ const thisOpacity = d.links.indexOf(o.id) > -1 || d.id === o.id ? 1 : opacity;
this.setAttribute('fill-opacity', thisOpacity);
return thisOpacity;
});
}
if (this.link) {
- let linkOpacity = opacity === 1 ? 1 : 0;
- this.link.style('stroke-opacity', o => {return ((o.source.id === d.id) || (o.target.id === d.id) ? 1 : linkOpacity)});
+ const linkOpacity = opacity === 1 ? 1 : 0;
+ this.link.style('stroke-opacity', o => {
+ return o.source.id === d.id || o.target.id === d.id ? 1 : linkOpacity;
+ });
}
};
}
@@ -436,25 +482,27 @@ class DagComponent extends React.Component {
const data = mouseEvent.currentTarget.__data__;
// Create tooltip on mouse over in a block or tx to show their info
- this.tooltip.transition()
+ this.tooltip
+ .transition()
.duration(300)
- .style("opacity", 1);
- this.tooltip.html(`Hash:${ data.id } Timestamp: ${ data.timestamp }`)
- .style("left", (mouseEvent.pageX) + "px")
- .style("top", (mouseEvent.pageY + 10) + "px");
+ .style('opacity', 1);
+ this.tooltip
+ .html(`Hash:${data.id} Timestamp: ${data.timestamp}`)
+ .style('left', `${mouseEvent.pageX}px`)
+ .style('top', `${mouseEvent.pageY + 10}px`);
}
removeTooltip() {
// Remove tooltip when mouse out in a block or tx
- this.tooltip.transition()
+ this.tooltip
+ .transition()
.duration(100)
- .style("opacity", 0);
+ .style('opacity', 0);
}
moveTooltip(event) {
// Move tooltip when mouse move in a block or tx
- this.tooltip.style("left", (event.pageX) + "px")
- .style("top", (event.pageY + 10) + "px");
+ this.tooltip.style('left', `${event.pageX}px`).style('top', `${event.pageY + 10}px`);
}
render() {
diff --git a/src/components/GDPRConsent.js b/src/components/GDPRConsent.js
index dbac9617..6f949f47 100644
--- a/src/components/GDPRConsent.js
+++ b/src/components/GDPRConsent.js
@@ -7,13 +7,11 @@
import React, { useEffect } from 'react';
-import { GTM_ID } from '../constants';
-import CookieConsent from "react-cookie-consent";
+import CookieConsent from 'react-cookie-consent';
import TagManager from 'react-gtm-module';
-
+import { GTM_ID } from '../constants';
const GDPRConsent = () => {
-
useEffect(() => {
// Just to ensure that when we initialize GTM, the message on this component will be shown
TagManager.initialize({ gtmId: GTM_ID });
@@ -28,9 +26,17 @@ const GDPRConsent = () => {
buttonClasses="btn btn-hathor m-3"
>
This website uses cookies to ensure you get the best experience on our website.
- Learn more.
+
+ {' '}
+ Learn more
+
+ .
- )
-}
+ );
+};
export default GDPRConsent;
diff --git a/src/components/HathorAlert.js b/src/components/HathorAlert.js
index d69ca07e..6d55ca25 100644
--- a/src/components/HathorAlert.js
+++ b/src/components/HathorAlert.js
@@ -7,7 +7,6 @@
import React from 'react';
-
class HathorAlert extends React.Component {
show(duration) {
const el = this.refs.alertDiv;
@@ -19,7 +18,11 @@ class HathorAlert extends React.Component {
render() {
return (
-
+
{this.props.text}
);
- }
+ };
const renderAttributeValue = (name, data) => {
// If the attribute is a dict, it won't return the value of it
@@ -201,7 +207,7 @@ function NanoContractDetail(props) {
// In the future, we plan to have a query feature, so the user can
// query these attributes until they get the value they need
return 'value' in data ? data.value : blueprintInformation.attributes[name];
- }
+ };
const renderAttributes = () => {
return Object.entries(ncState.fields).map(([name, data]) => {
@@ -212,17 +218,24 @@ function NanoContractDetail(props) {
);
});
- }
+ };
return (