-
Notifications
You must be signed in to change notification settings - Fork 55
feat(frontend): Implementation of new design on Nodes page #613
Conversation
Your Render PR Server URL is https://near-explorer-frontend-with-indexer-pr.onrender.com. Follow its progress at https://dashboard.render.com/web/srv-c20nv6bs1gh9plsflk9g. |
7e1afc0
to
256eb68
Compare
@frol, currently I don't know how to get some data. But I have some thoughts of how to do it |
4a3e2a4
to
5fd1044
Compare
42c0105
to
0237158
Compare
<div className="total-value" style={{ width: `${value.total}%` }} /> | ||
<div className="current-value" /> | ||
<div className="cumulative-stake-label">{value.current}%</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is just a coincidence that the width of the dark blue chunk has a constant size
On the second line the light-blue block on the left represents 27% of the width, and the width of the dark blue line is the % of the current stake out of the total stake (8% in that case). In other words, 27%+8% = 35%
Number( | ||
utils.format.formatNearAmount(amount.toString(), 0).replace(/,/g, "") | ||
) / | ||
10 ** 6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You do not need to format the amount and then convert it back to Number. If amount
is BN
, just divide it by 10 ** (24 + 9)
const currentTimestamp = moment() as moment.Moment; | ||
const endEpochTimestamp = moment( | ||
this.props.epochStartBlock.timestamp | ||
).add(12, "h"); | ||
const duration = moment | ||
.duration( | ||
endEpochTimestamp.diff(moment(this.props.epochStartBlock.timestamp)) | ||
) | ||
.asSeconds(); | ||
const durationProseed = moment | ||
.duration( | ||
currentTimestamp.diff(moment(this.props.epochStartBlock.timestamp)) | ||
) | ||
.asSeconds(); | ||
const durationValue = (durationProseed / duration) * 100; | ||
this.setState({ | ||
timeRemaining: moment | ||
.duration(endEpochTimestamp.diff(currentTimestamp)) | ||
.asMilliseconds(), | ||
epochProseed: Number(durationValue.toFixed(2)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
epochProgress = (latestBlock.height - epochStartBlock.height) / epochLength * 100
timeRemaining = (latestBlock.timestamp - epochStartBlock.timestamp) / epochProgress * (100 - epochProgress)
( | ||
{timeRemaining | ||
? moment(timeRemaining)?.format("HH:mm:ss") | ||
: "00:00:00"}{" "} | ||
remaining) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel this is easier to read:
( | |
{timeRemaining | |
? moment(timeRemaining)?.format("HH:mm:ss") | |
: "00:00:00"}{" "} | |
remaining) | |
{`({timeRemaining | |
? moment(timeRemaining)?.format("HH:mm:ss") | |
: "00:00:00"} remaining)`} |
render() { | ||
const { node } = this.props; | ||
const { node, index, cellCount, validatorType } = this.props; | ||
let persntStake = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming looks odd to me O_o
class ValidatorsList extends React.PureComponent<Props> { | ||
calculateStake = (nodeIndex: number, totalStake: BN) => { | ||
let total = new BN(0); | ||
let networkHolderIndex = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need an array here, you only care about the very first value. Just initialize it as null and only set it if the accumulated stake is over 33% and also this variable is still null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could not figure out of how to do it differently here
for (let i = 0; i <= nodeIndex; i++) { | ||
total = total.add(new BN(this.props.validators[i].stake)); | ||
|
||
if (total.gt(totalStake.div(new BN(3)))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Precompute the totalStake.divn(3)
in a const before the loop, so you don't need to re-compute it over and over again in the loop.
@@ -5,19 +5,23 @@ import { OverlayTrigger, Tooltip } from "react-bootstrap"; | |||
|
|||
const FRAC_DIGITS = 5; | |||
|
|||
const Balance = ({ amount }) => { | |||
const Balance = ({ amount, label = null, className = "" }) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It think it is better to leave className undefined if it was not defined
const Balance = ({ amount, label = null, className = "" }) => { | |
const Balance = ({ amount, label = null, className }) => { |
return () => { | ||
explorerApi.unsubscribe("node-stats"); | ||
}; | ||
}, []); | ||
}, [epochStartHeight]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a separate useEffect
since otherwise, this code will re-subscribe to node-stats
for no good reason.
backend/src/index.js
Outdated
@@ -285,6 +319,24 @@ async function main() { | |||
}; | |||
setTimeout(regularCheckNodeStatus, 0); | |||
|
|||
// Periodic check of validator's fee and delegators | |||
const regularCheckValidatorsExtraInfo = async (validators) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a dedicated setTimeout
for this regularCheckValidatorsExtraInfo
, and don't call it from regularCheckNodeStatus
. Fetch the validators (current validators and current proposals) inside this regular job, so you do not need to call it from regularCheckNodeStatus
.
backend/src/index.js
Outdated
const regularCheckValidatorsExtraInfo = async () => { | ||
if (validators) { | ||
validatorsExtraInfo = validatorsExtraInfo || validators; | ||
|
||
for (let i = 0; i < validatorsExtraInfo.length; i++) { | ||
const { account_id } = validatorsExtraInfo[i]; | ||
validatorsExtraInfo[i].fee = await nearRpc.callViewMethod( | ||
account_id, | ||
"get_reward_fee_fraction", | ||
{} | ||
); | ||
validatorsExtraInfo[i].delegators = await nearRpc.callViewMethod( | ||
account_id, | ||
"get_number_of_accounts", | ||
{} | ||
); | ||
} | ||
} | ||
return validators; | ||
|
||
if (proposals) { | ||
proposalsExtraInfo = proposalsExtraInfo || proposals; | ||
|
||
for (let i = 0; i < proposalsExtraInfo.length; i++) { | ||
const { account_id } = proposalsExtraInfo[i]; | ||
proposalsExtraInfo[i].fee = await nearRpc.callViewMethod( | ||
account_id, | ||
"get_reward_fee_fraction", | ||
{} | ||
); | ||
proposalsExtraInfo[i].delegators = await nearRpc.callViewMethod( | ||
account_id, | ||
"get_number_of_accounts", | ||
{} | ||
); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@frol , I don't know is it a good idea or not... Could you please look at it and tell me your mind?
value = (Number(amount) / 10 ** (24 + 6)).toFixed(1); | ||
} else if (type === "totalStakeAmount") { | ||
value = | ||
( | ||
Number( | ||
utils.format.formatNearAmount(amount.toString(), 0).replace(/,/g, "") | ||
) / | ||
10 ** 3 | ||
).toFixed(1) + "M"; | ||
value = (Number(amount) / 10 ** (24 + 3)).toFixed(1); | ||
} else if (type === "seatPriceAmount") { | ||
value = (Number(amount) / 10 ** 24).toFixed(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@frol , also this looks strange but with BN it fails
@shelegdmitriy I had to move a lot of things around to hopefully name things a little bit better. There are lots of things that remain to be named in a way that is hard to reason about, but I did not want to block this PR even more. Please, go over the Figma design and especially font sizes as it seems that they might be off. Bug report:
|
ecb0a96
to
fb7ba55
Compare
…g at least somewhat sane
12360ad
to
2075cf5
Compare
2075cf5
to
c3c092d
Compare
Resolves #370
Test plan