Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Onboarding: add time remaining and progress ring #1210

Closed
wants to merge 6 commits into from

Conversation

e18r
Copy link
Contributor

@e18r e18r commented Dec 9, 2019

Fixes AutarkLabs#29
Fixes AutarkLabs#30
Fixes AutarkLabs#31
Fixes #1064

  • Adds a loading state for transactions by subscribing to the transactionHash web3 event.
  • Consumes EthGasStation API to obtain an estimate of the confirmation delay for each transaction.
  • Shows the time remaining in hours, minutes or seconds when the transaction is broadcasted.
  • Created a new Progress Ring component to show the progress using the remaining time estimation.

Peek 2019-12-18 18-51
Note: The estimaton times are only available for mainnet, so they are also used in other environments, creating very wrong estimates in these environments, as can be seen in the animated GIF above (it lasts like 8 minutes)

Progress ring inspired by http://firchow.net/css3-prozentanzeige-kreis/

@vercel vercel bot temporarily deployed to staging December 9, 2019 16:31 Inactive
Copy link
Contributor

@ottodevs ottodevs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job @e18r !!! The PR seems really promising!!

I just found some inconsistencies and I experienced several potential issues during my initial tests locally and using the automated now.sh deployment, could you please take a look to the following?

  • The template deployment fails on first transaction when using Fundraising or OpenEnterprise templates, on the other hand, it completes the single transaction for the rest of templates.
  • The gas estimation fallback is wrong locally, so metamask confirmation shows up with an empty Gas Limit field, this is maybe related to an small typo on the ethgasstation fetch line.
  • It does not show the "Organization Ready" banner after successfully approve the tx
  • It does not redirect to the new DAO as expected after that step as well
  • No animation on the progress ring (maybe related to the ethgasstation bug I mentioned)
  • The Info panel should be a Warning message; it is not implemented with the correct style (yellow bg) as Javier and Paty suggested in Animate signature progress and add time remaining AutarkLabs/aragon#29 I am missing some newer directions on that?
  • It does not show any kind of time estimation (again, maybe this is result of failing to fetch estimations because of wrong URL in the fetch request).

Please don't hesitate to ask if you need further clarification on any of the items 👍🍀

Comment on lines 347 to 355
return deployTransactions.map(({ name }, index) => ({
name,
status: status(index),
dateStart: submittedTransactions[index]
? submittedTransactions[index].dateStart
: undefined,
gasPrice: submittedTransactions[index]
? submittedTransactions[index].gasPrice
: undefined,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems much more clear way to express the same logic, and seems a bit less cumbersome and readable, also notably shorter :

const result = deployTransactions.map(({name}, index) => {
    const { dateStart, gasPrice } = submittedTransactions[index]
    const status = status(index)

    return {dateStart, gasPrice, name, status}
}

return result

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, I was struggling with that part.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up doing something different:

let deployment = {
  name,
  status: status(index),
}
if (submittedTransactions[index]) {
  const { dateStart, gasPrice } = submittedTransactions[index]
  deployment = { ...deployment, dateStart, gasPrice }
}
return deployment

Comment on lines 315 to 352
const { signed, errored } = transactionProgress
const { submitted, signed, errored } = transactionProgress
const status = index => {
if (errored !== -1 && index >= errored) {
return TRANSACTION_STATUS_ERROR
}
if (index === signed) {
return TRANSACTION_STATUS_PENDING
}
if (index < signed) {
if (index <= signed) {
return TRANSACTION_STATUS_SUCCESS
}
if (index <= submitted) {
return TRANSACTION_STATUS_PENDING
}
return TRANSACTION_STATUS_UPCOMING
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These conditions seem a bit convoluted and hard to follow/read, I suggest coming up with a more readable way to ease debugging or maintaining it in case of errors or future modifications

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this a lot. The underlying problem is the way these indexes work, and that's something that was there before I arrived. I'm merely extending that functionality (and making it probably more complex along the way).

I thought about changing this to an object where the keys were the transaction IDs and the values were the status of each transaction. However, it seemed hard to make sure I wasn't breaking anything in the process, and that's why I backed off.

But I'm gonna think about this more. Any suggestions welcome.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've decided to leave them like that for now. It really would require a level of refactoring that exceeds this PR.

...prev,
[i]: {
dateStart: new Date(),
gasPrice: submittedTransaction.gasPrice / 1000000000,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest using 1e9 instead of 1000000000, for readability and even using a constant instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or even better: fromWei


useMemo(() => {
if (gasPrice === undefined) return
fetch('https:ethgasstation.info/json/predictTable.json')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems we are missing the slashes after https: protocol, causing errors in runtime, because the URL ends up being added to the deployment address:
https://aragon-g00c0o0hh.now.sh/ethgasstation.info/json/predictTable.json

Suggested change
fetch('https:ethgasstation.info/json/predictTable.json')
fetch('https://ethgasstation.info/json/predictTable.json')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😕 Thank you

)

useMemo(() => {
if (gasPrice === undefined) return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add here an extra check as a fallback mechanism for rinkeby, localhost or anything different from mainnet, to set a different remaining time for those cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would that be? I feel like the mainnet estimate is still the best prediction available, even for Rinkeby or local.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I guess local network is not considered that important in the client, as it is for example tagged as "wrong network" when selected in metamask, so it is probably not worth the effort to reach accurate times there.

Comment on lines 28 to 33
const time = (dateEnd - now) / 1000
const unit = time < 60 ? 'sec' : time < 3600 ? 'min' : 'hr'
const amount = Math.floor(
unit === 'sec' ? time : unit === 'min' ? 1 + time / 60 : 1 + time / 3600
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure this is really needed if we are using date-fns? Maybe you might want to use some of these methods

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These methods still seem in development, but I'm gonna take a look. Thanks for the suggestion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may also want to take a look at dayjs to see if they have something similar. We're trying to move away from date-fns.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't found any methods in DayJS that give us what we want. I'm leaving this like this for now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems straightforward by enabling dayjs embedded plugin for that, we were talking about this the other day, but the change seems still pending

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The result differs a bit from the design - and it looks OK, so I think it can work. However, now the transaction status line is prone to occupying two lines:
Screenshot from 2020-01-02 12-28-29

What say you, @javieralaves?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@e18r Green light on my end, this is fine

@e18r e18r force-pushed the onboarding-time-remaining branch from ccdf731 to 994b25c Compare December 17, 2019 15:58
@vercel vercel bot temporarily deployed to staging December 17, 2019 15:58 Inactive
@e18r e18r force-pushed the onboarding-time-remaining branch from 994b25c to 48d812b Compare December 18, 2019 16:14
@vercel vercel bot temporarily deployed to staging December 18, 2019 16:14 Inactive
@e18r e18r changed the title Onboarding: add time remaining and progress ring [WIP] Onboarding: add time remaining and progress ring Dec 18, 2019
@vercel vercel bot temporarily deployed to staging December 18, 2019 21:26 Inactive
@e18r
Copy link
Contributor Author

e18r commented Dec 18, 2019

Hi @ottodevs, thank you so much for your review. Answering to your general remarks:

  • The template deployment fails on first transaction when using Fundraising or OpenEnterprise templates, on the other hand, it completes the single transaction for the rest of templates.

solved!

  • The gas estimation fallback is wrong locally, so metamask confirmation shows up with an empty Gas Limit field, this is maybe related to an small typo on the ethgasstation fetch line.

yes, it was that typo.

  • It does not show the "Organization Ready" banner after successfully approve the tx

solved!

  • It does not redirect to the new DAO as expected after that step as well

solved!

  • No animation on the progress ring (maybe related to the ethgasstation bug I mentioned)

yes

  • The Info panel should be a Warning message; it is not implemented with the correct style (yellow bg) as Javier and Paty suggested in AutarkLabs#29 I am missing some newer directions on that?

See #1211

  • It does not show any kind of time estimation (again, maybe this is result of failing to fetch estimations because of wrong URL in the fetch request).

yes

Please don't re-review yet; I still have to address your code-oriented remarks.

@e18r e18r force-pushed the onboarding-time-remaining branch from 0cbfa63 to 34f4d7f Compare December 18, 2019 22:54
@vercel vercel bot temporarily deployed to staging December 18, 2019 22:54 Inactive
e18r added 2 commits December 18, 2019 17:55
Fixes #29

* Adds a loading state for transactions by subscribing to the
'transactionHash' web3 event.
* Consumes EthGasStation API to obtain an estimate of the
confirmation delay for each transaction.
* Shows the time remaining when the transaction is broadcasted
* Created a new Progress Ring component to show the progress using the
remaining time estimation

**Note**: this PR was not tested for templates with multiple transactions.
Tested with the Open Enterprise template and addressed comments by @ottodevs:
* Transactions don't fail anymore
* The DAO gets created at the end
* Added a new state, "signig", which corresponds to the "waiting for
signature" state
* Used `fromWei(value, 'gwei')` instead of dividing by 1000000000
* Made more readable some parts of the code
* Solved weird typo on the EthGasStation URL
* Used `.attrs` in the HalfRing styled component to make it more
performant
@e18r e18r force-pushed the onboarding-time-remaining branch from 34f4d7f to b795801 Compare December 18, 2019 22:55
@vercel vercel bot temporarily deployed to staging December 18, 2019 22:55 Inactive
@e18r e18r changed the title [WIP] Onboarding: add time remaining and progress ring Onboarding: add time remaining and progress ring Dec 19, 2019
@e18r e18r requested a review from sohkai December 19, 2019 00:01
Copy link
Contributor

@ottodevs ottodevs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @e18r some minor comments, mostly conventions that may not apply to this repo, but good to know, it was not clear by your last comment if that was ready for re-review, please ping me when it is 👍 🥇

export const TRANSACTION_STATUS_PENDING = Symbol('TRANSACTION_STATUS_PENDING')
export const TRANSACTION_STATUS_SUCCESS = Symbol('TRANSACTION_STATUS_SUCCESS')
export const TRANSACTION_STATUS_UPCOMING = Symbol('TRANSACTION_STATUS_UPCOMING')
export const TRANSACTION_STATUS_ERROR = Symbol('TRANSACTION_STATUS_ERROR')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These symbols were alphabetically sorted, is there a good reason to change that sort?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to sort these symbols according to the order in which they occur in the transaction lifecycle. This helps understand what each of these symbols stands for:

  1. Upcoming - Waiting for a previous transaction to finish
  2. Signing - Waiting for the user to sign the transaction through the Web3 provider
  3. Pending - Waiting for the transaction to be mined in the blockchain
  4. Success - The transaction was mined
  5. Error - There was an error

TRANSACTION_STATUS_PENDING,
TRANSACTION_STATUS_SUCCESS,
TRANSACTION_STATUS_UPCOMING,
TRANSACTION_STATUS_ERROR,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These array members were alphabetically sorted, is there a good reason to change that sort?

Copy link
Contributor Author

@e18r e18r Jan 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my answer to your similar question at #1210 (comment)

TRANSACTION_STATUS_PENDING,
TRANSACTION_STATUS_SUCCESS,
TRANSACTION_STATUS_UPCOMING,
TRANSACTION_STATUS_ERROR,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this change is relevant for the purpose of the PR, but if there is a good reason for this, I'd love some help to understand it

Copy link
Contributor Author

@e18r e18r Jan 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my answer to your similar question at #1210 (comment)

height: ${({ diameter }) => diameter}px;
border: 2px solid ${({ theme }) => theme.selected};
border-radius: 50%;
clip-path: inset(0px ${({ diameter }) => diameter / 2}px 0px 0px);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is considered a standard convention to remove the unit for zero values:

Suggested change
clip-path: inset(0px ${({ diameter }) => diameter / 2}px 0px 0px);
clip-path: inset(0 ${({ diameter }) => diameter / 2}px 0 0);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for lines 235, 241, 242, 252

{transactionsStatus.map(
({ name, status, dateStart, gasPrice }, index) => (
<DeploymentStepsItem
key={index}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would improve the readability if the props are ordered alphabetically, it is also considered a good convention, feel free to skip this change if you think the oposite way

)

useMemo(() => {
if (gasPrice === undefined) return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I guess local network is not considered that important in the client, as it is for example tagged as "wrong network" when selected in metamask, so it is probably not worth the effort to reach accurate times there.

Comment on lines 28 to 33
const time = (dateEnd - now) / 1000
const unit = time < 60 ? 'sec' : time < 3600 ? 'min' : 'hr'
const amount = Math.floor(
unit === 'sec' ? time : unit === 'min' ? 1 + time / 60 : 1 + time / 3600
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems straightforward by enabling dayjs embedded plugin for that, we were talking about this the other day, but the change seems still pending

TRANSACTION_STATUS_PENDING,
TRANSACTION_STATUS_SUCCESS,
TRANSACTION_STATUS_UPCOMING,
TRANSACTION_STATUS_ERROR,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not seem a big deal, but why breaking the alphabetic sort here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my answer to your similar question at #1210 (comment)

@e18r
Copy link
Contributor Author

e18r commented Jan 2, 2020

@ottodevs Thank you for your second feedback. I will address your comments, as well as the DayJS comment from the last review. I'll let you know as soon as I'm done.

e18r added 3 commits January 2, 2020 12:43
Now using the `dayjs` library instead of `date-fns`, both for adding
minutes to a date, and for displaying the remaining time.
Removed the units from zeroes in CSS values
@e18r
Copy link
Contributor Author

e18r commented Jan 2, 2020

@ottodevs this PR is ready for a further review. Thank you.

@stale stale bot added the abandoned label Mar 3, 2020
@aragon aragon deleted a comment from stale bot Mar 3, 2020
@stale stale bot removed the abandoned label Mar 3, 2020
@stale stale bot added the abandoned label Apr 2, 2020
@sohkai sohkai removed the abandoned label Apr 8, 2020
@stale stale bot added the abandoned label May 12, 2020
@aragon aragon deleted a comment from stale bot May 12, 2020
@stale stale bot removed the abandoned label May 12, 2020
@aragon aragon deleted a comment from stale bot May 12, 2020
@stale stale bot added the abandoned label Jun 12, 2020
@aragon aragon deleted a comment from stale bot Jun 12, 2020
@stale stale bot removed the abandoned label Jun 12, 2020
@sohkai sohkai requested a review from bpierre July 1, 2020 16:07
@stale
Copy link

stale bot commented Jul 31, 2020

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for contributing to Aragon! 🦅

@stale stale bot added the abandoned label Jul 31, 2020
@sohkai
Copy link
Contributor

sohkai commented Aug 3, 2020

Hi @e18r @ottodevs, sorry for taking an incredibly long time to review this change.

Given the current gas market and how wildly it fluctuates (as well as the general amount of network congestion), we've decided to leave this responsibility out to wallets.

Sorry again for not being able to merge this sooner, when it would have been much more useful!

@sohkai sohkai closed this Aug 3, 2020
@sohkai sohkai deleted the onboarding-time-remaining branch August 3, 2020 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants