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

re-work register flow to accept new assets fee #1223

Merged
merged 6 commits into from
Oct 11, 2021

Conversation

vctt94
Copy link
Member

@vctt94 vctt94 commented Sep 28, 2021

This PR is the frontend part of (#1202)

@chappjc chappjc added this to the 0.3 milestone Sep 28, 2021
@vctt94 vctt94 changed the title [wip] re-work register flow to accept new assets fee re-work register flow to accept new assets fee Sep 29, 2021
@vctt94 vctt94 marked this pull request as ready for review September 29, 2021 15:30
@vctt94 vctt94 force-pushed the multi-fee-payment-front branch from 064efd1 to e0254f9 Compare September 29, 2021 15:52
Copy link
Member

@chappjc chappjc left a comment

Choose a reason for hiding this comment

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

Thanks for taking this on @vctt94!

Here's a quick first pass with some change I think can be made, but I've not actually tested it yet.
Overall, looking nice.

client/webserver/site/src/html/register.tmpl Outdated Show resolved Hide resolved
client/webserver/locales/en-us.go Show resolved Hide resolved
client/webserver/http.go Show resolved Hide resolved
client/webserver/http.go Outdated Show resolved Hide resolved
client/webserver/locales/en-us.go Outdated Show resolved Hide resolved
client/webserver/site/src/html/forms.tmpl Outdated Show resolved Hide resolved
client/webserver/site/src/html/forms.tmpl Outdated Show resolved Hide resolved
const setupWallet = tr.querySelector('#setupWallet')
if (haveWallet) {
setupWallet.innerText = intl.prep(intl.ID_CHOOSE_WALLET)
Doc.bind(setupWallet, 'click', () => this.setWalletFee(fee.id))
Copy link
Member

@chappjc chappjc Sep 29, 2021

Choose a reason for hiding this comment

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

I think this action should also update something to indicate the selection was made and that clicking "Register" will in fact use the intended asset and amount.

For this I had envisioned either or both of: (1) modify the table row's style or just the clicked this button to show it is selected (sorry if this is already done, I haven't tested), which would obviously require undoing this styling change if the user clicks another row, or (2) Update a new sentence just above the Password field to say something like "This will pay a fee of [X amount] [Y asset symbol]."

Also, the styling of the button would ideally be different (perhaps color) between Choose and Setup

Copy link
Member

Choose a reason for hiding this comment

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

I'm pretty happy now with how solution (1) is implemented. With a boundary around the selected asset's row, it's quite clear what is going to happen when you submit the form.

Maybe another reviewer will think the text proposed in (2) is also valuable, but I can live without it.

@vctt94
Copy link
Member Author

vctt94 commented Sep 29, 2021

Thanks for your review chapp.

I changed the table row now for being clickable instead of the button, and made them with low oppacity, so when they are selected they fade in.

image

image

@chappjc chappjc linked an issue Sep 29, 2021 that may be closed by this pull request
Copy link
Member

@chappjc chappjc left a comment

Choose a reason for hiding this comment

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

I like the direction this is going. I think it could look more like this:

image

Selected:

image

Note also the text edits.

client/webserver/locales/en-us.go Outdated Show resolved Hide resolved
@@ -131,8 +131,7 @@ var EnUS = map[string]string{
"Set App Password": "Set App Password",
"reg_set_app_pw_msg": "Set your app password. This password will protect your DEX account keys and connected wallets.",
"Password Again": "Password Again",
"reg_dcr_required": "Your Decred wallet is required to pay registration fees.", // TODO
"reg_dcr_unlocked": "Unlock your Decred wallet to pay registration fees.", // TODO
"reg_dcr_required": "A wallet is required to pay registration fees. You can set one with this form.",
Copy link
Member

@chappjc chappjc Sep 29, 2021

Choose a reason for hiding this comment

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

The key name and text I think should change.

Suggested change
"reg_dcr_required": "A wallet is required to pay registration fees. You can set one with this form.",
"reg_wallet_required": "A wallet is required to pay registration fees.",

Although I'm thinking this text is not even required on the form at all since the user just got here from the register form by clicking the Setup button, so they know why they are on this form. Before this PR the form came up on its own and it wasn't obvious why, but that's changed.

Copy link
Member

Choose a reason for hiding this comment

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

Since we went with getting rid of this as an argument to the "newWalletForm" template, it's the right time to clean up that template definition because it no longer gets an input from any callers and the template only has one possible rendering now.

That is, when called like {{template "newWalletForm" "reg reg reg"}}, we see:

image

When called like {{template "newWalletForm"}}, as it is now:

image

The two differences are obviously this text at the top, but also the text about the wallet password goes into a tooltip:

image

So in forms.html where we have {{define "newWalletForm"}}, there are a bunch of ifs using . that will never be true anymore since only this register form was ever executing this template with an arg.

Regarding the wallet password texts, we could just go with the existing w_password_tooltip, or combine it with the text from w_password_helper. i.e. "w_password_tooltip": "This is the password you have configured with your wallet software. Leave the password empty if there is no password required for the wallet.",

image

client/webserver/site/src/css/forms.scss Outdated Show resolved Hide resolved
client/webserver/site/src/html/forms.tmpl Outdated Show resolved Hide resolved
client/webserver/site/src/html/forms.tmpl Outdated Show resolved Hide resolved
client/webserver/site/src/html/register.tmpl Show resolved Hide resolved
client/webserver/site/src/js/forms.js Outdated Show resolved Hide resolved
client/webserver/site/src/html/register.tmpl Outdated Show resolved Hide resolved
@@ -161,7 +140,7 @@ export default class RegistrationPage extends BasePage {
this.auth()
Copy link
Member

@chappjc chappjc Sep 30, 2021

Choose a reason for hiding this comment

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

A couple lines up there is if (seed) this.walletForm.setRegMsg('Your Decred wallet is required').
I'm struggling to recall why restoring from seed means the Decred wallet is required. Does that basically just mean "don't forget your Decred wallet, because you had it setup before"? In which case we could remove that line now.
@buck54321

Copy link
Member

Choose a reason for hiding this comment

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

It would make sense if wallet was required when not restoring from seed, because pay fee.

Copy link
Member

Choose a reason for hiding this comment

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

Well in any case, seems like this conditional message is no longer correct.

Copy link
Member

@buck54321 buck54321 left a comment

Choose a reason for hiding this comment

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

First pass. Looking pretty good.


When I register from scratch, and choose to "remember password", the DEX address form shows the app password input.

That input used to be shown only when landing on the registration page with the app already initialized and a Decred wallet already connected, and no password cached.


If I select an asset with no wallet, and click the "Register" button, I just get an error that says "no wallet".

Maybe in this case we should just show the wallet setup form for the selected asset, as if they'd clicked the "Setup" button.

@@ -27,8 +27,9 @@ var EnUS = map[string]string{
"Submit": "Submit",
"Confirm Registration": "Confirm Registration",
"app_pw_reg": "Enter your app password to confirm DEX registration.",
"reg_confirm_submit": `When you submit this form, <span id="feeDisplay"></span> DCR will be spent from your Decred wallet to pay registration fees.`, // TODO for multi-asset reg
"reg_confirm_submit": `When you submit this form, it will spend from your chosen wallet to pay the registration fee.`,
Copy link
Member

Choose a reason for hiding this comment

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

it will spend from

How about , funds will be spent from ...

/*
* assetById returns the asset string by its id.
*/
static assetById (assetId) {
Copy link
Member

Choose a reason for hiding this comment

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

How about assetSymbol(assetID)? But probably don't need this method anyway.

Comment on lines 345 to 346
const feeAsset = Object.values(xc.regFees)
feeAsset.forEach((fee) => {
Copy link
Member

Choose a reason for hiding this comment

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

for (const [symbol, fee] of Object.entries(xc.regFees)) {
  ...
  Doc.tmplElement(tr, 'asseticon').src = Doc.logoPath(symbol)
  Doc.tmplElement(tr, 'asset').innerText = symbol.toUpperCase()

And then you don't need the assetById method.

Comment on lines 178 to 179
<button id="setupWallet" type="button" class="justify-content-center w-100 selected"></button>
<span id="walletReady"></span>
Copy link
Member

Choose a reason for hiding this comment

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

Once there are two rows, these elements are no longer unique. Should not use the id attribute here. Use data-tmpl like the rest.

Comment on lines 364 to 365
const setupWallet = tr.querySelector('#setupWallet')
const walletReady = tr.querySelector('#walletReady')
Copy link
Member

Choose a reason for hiding this comment

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

Use data-tmpl attributes instead of id.

@@ -60,8 +67,9 @@ export class NewWalletForm {
else Doc.show(this.fields.newWalletAppPWBox)
}

async setAsset (asset) {
async setAsset (assetId) {
Copy link
Member

Choose a reason for hiding this comment

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

Please use assetID instead of assetId. We're not perfectly consistent, but we try to use either id or ID, not Id. You'll find many instances of marketID and assetID around.

Doc.tmplElement(tr, 'confs').innerText = fee.confs
Doc.tmplElement(tr, 'fee').innerText = fee.amount / 1e8

const haveWallet = app.user.assets[fee.id] ? app.user.assets[fee.id].wallet : null
Copy link
Member

Choose a reason for hiding this comment

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

I would think you'd want to check that we support the asset earlier, and bail on this row if we don't. Also, the app.user.assets -> SupportedAsset gives you the symbol, which is another reason we don't need Doc.assetById.

})
tr.classList.add('selected')
})
const asset = Doc.assetById(fee.id)
Copy link
Member

Choose a reason for hiding this comment

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

As mentioned, you don't need this method to get the asset ID.

const fields = this.fields
const symbol = Doc.assetById(assetId)
if (!assetId || !symbol) {
Copy link
Member

Choose a reason for hiding this comment

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

Can just do if (assetID === null)

@chappjc
Copy link
Member

chappjc commented Oct 5, 2021

Maybe in this case we should just show the wallet setup form for the selected asset, as if they'd clicked the "Setup" button

Or even gray out the Register button if a row is highlighted that is not a set up wallet? Otherwise then you have to handle the completion of wallet setup differently depending on how you got to there (from the Setup button or from the Register button).

@vctt94
Copy link
Member Author

vctt94 commented Oct 5, 2021

I went with graying the button cause I think it was a simpler solution

@vctt94 vctt94 force-pushed the multi-fee-payment-front branch 2 times, most recently from 33707c7 to 48421b7 Compare October 5, 2021 15:55
@vctt94
Copy link
Member Author

vctt94 commented Oct 5, 2021

whoops. mb

@vctt94 vctt94 force-pushed the multi-fee-payment-front branch from 48421b7 to 4db5fbf Compare October 5, 2021 16:05
fields.feeTableRows.removeChild(fields.feeTableRows.firstChild)
}
for (const [symbol, fee] of Object.entries(xc.regFees)) {
const haveWallet = app.user.assets[fee.id].wallet
Copy link
Member

@chappjc chappjc Oct 5, 2021

Choose a reason for hiding this comment

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

This is not easy to test, but if the user's dexc does not support an asset that the server does and does for fees, this will be an error of the sort "can't access property "wallet", ...user.assets[l.id] is undefined".

If app.user.assets[fee.id] is undefined, this loop could either: (1) continue to next entry in regFee and not show the row, or (2) show the row somehow with "N/A" and "unsupported" in appropriate places. For this iteration, let's go with (1).

Copy link
Member

@chappjc chappjc left a comment

Choose a reason for hiding this comment

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

OK LGTM now. Will merge when @buck54321 circles back and it's ok.

@chappjc chappjc requested a review from buck54321 October 6, 2021 17:14
Copy link
Member

@buck54321 buck54321 left a comment

Choose a reason for hiding this comment

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

When trying to create a wallet from the markets view, I'm getting some errors

image

Same thing from the wallets view.

const haveWallet = app.user.assets[fee.id].wallet
const tr = fields.feeRowTemplate.cloneNode(true)
Doc.bind(tr, 'click', () => {
this.setWalletFee(fee.id)
Copy link
Member

Choose a reason for hiding this comment

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

See other comment about setFeeWallet, but here you can just do this.feeWallet = assetID, or this.feeAssetID = assetID if you go with my naming suggestion.

@@ -350,12 +414,22 @@ export class ConfirmRegistrationForm {
/*
* submitForm is called when the form is submitted.
*/
async submitForm () {
async submitForm (assetID) {
Copy link
Member

Choose a reason for hiding this comment

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

Don't need to pass in the assetID. Get it from this.feeWallet.

Comment on lines 322 to 324
setWalletFee (assetID) {
this.feeWallet = assetID
}
Copy link
Member

Choose a reason for hiding this comment

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

Lots going on with the naming here. Is it a fee or a wallet or an asset ID? How about renaming feeWallet to feeAssetID or similar, and getting rid of setWalletFee and just set the field directly.

Comment on lines 335 to 340
while (fields.marketsTableRows.firstChild) {
fields.marketsTableRows.removeChild(fields.marketsTableRows.firstChild)
}
while (fields.feeTableRows.firstChild) {
fields.feeTableRows.removeChild(fields.feeTableRows.firstChild)
}
Copy link
Member

Choose a reason for hiding this comment

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

Can you change both of these to use Doc.empty?

Comment on lines 343 to 345
if (app.user.assets[fee.id] === undefined) {
continue
}
Copy link
Member

Choose a reason for hiding this comment

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

One line is good

if (app.user.assets[fee.id] === undefined) continue

Comment on lines 352 to 354
rows.forEach(row => {
row.classList.remove('selected')
})
Copy link
Member

Choose a reason for hiding this comment

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

One line is good

rows.forEach(row => { row.classList.remove('selected') })

Comment on lines 139 to 140
this.walletForm.refresh()
await this.changeForm(page.appPWForm, page.newWalletForm)
await this.changeForm(page.appPWForm, page.dexAddrForm)
Copy link
Member

Choose a reason for hiding this comment

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

I think you need a this.dexAddrForm.refresh() here too. If I choose the "remember password" option, the password field is still shown on the dex address form.

@chappjc
Copy link
Member

chappjc commented Oct 8, 2021

I was able to add a DCR wallet from the /markets page after registering with BTC

@chappjc chappjc merged commit 0d4075a into decred:master Oct 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ui: update for different reg fee assets
4 participants