-
Notifications
You must be signed in to change notification settings - Fork 102
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
Conversation
064efd1
to
e0254f9
Compare
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.
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.
const setupWallet = tr.querySelector('#setupWallet') | ||
if (haveWallet) { | ||
setupWallet.innerText = intl.prep(intl.ID_CHOOSE_WALLET) | ||
Doc.bind(setupWallet, 'click', () => this.setWalletFee(fee.id)) |
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 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
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'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.
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.
client/webserver/locales/en-us.go
Outdated
@@ -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.", |
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 key name and text I think should 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.
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.
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:
When called like {{template "newWalletForm"}}
, as it is now:
The two differences are obviously this text at the top, but also the text about the wallet password goes into a tooltip:
So in forms.html where we have {{define "newWalletForm"}}
, there are a bunch of if
s 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.",
@@ -161,7 +140,7 @@ export default class RegistrationPage extends BasePage { | |||
this.auth() |
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.
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
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 would make sense if wallet was required when not restoring from seed, because pay fee.
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.
Well in any case, seems like this conditional message is no longer correct.
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.
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.
client/webserver/locales/en-us.go
Outdated
@@ -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.`, |
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 will spend from
How about , funds will be spent from ...
client/webserver/site/src/js/doc.js
Outdated
/* | ||
* assetById returns the asset string by its id. | ||
*/ | ||
static assetById (assetId) { |
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.
How about assetSymbol(assetID)
? But probably don't need this method anyway.
const feeAsset = Object.values(xc.regFees) | ||
feeAsset.forEach((fee) => { |
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.
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.
<button id="setupWallet" type="button" class="justify-content-center w-100 selected"></button> | ||
<span id="walletReady"></span> |
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.
Once there are two rows, these elements are no longer unique. Should not use the id
attribute here. Use data-tmpl
like the rest.
const setupWallet = tr.querySelector('#setupWallet') | ||
const walletReady = tr.querySelector('#walletReady') |
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 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) { |
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.
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 |
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 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) |
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.
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) { |
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.
Can just do if (assetID === null)
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). |
I went with graying the button cause I think it was a simpler solution |
33707c7
to
48421b7
Compare
whoops. mb |
48421b7
to
4db5fbf
Compare
fields.feeTableRows.removeChild(fields.feeTableRows.firstChild) | ||
} | ||
for (const [symbol, fee] of Object.entries(xc.regFees)) { | ||
const haveWallet = app.user.assets[fee.id].wallet |
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.
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).
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.
OK LGTM now. Will merge when @buck54321 circles back and it's ok.
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.
const haveWallet = app.user.assets[fee.id].wallet | ||
const tr = fields.feeRowTemplate.cloneNode(true) | ||
Doc.bind(tr, 'click', () => { | ||
this.setWalletFee(fee.id) |
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.
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) { |
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.
Don't need to pass in the assetID
. Get it from this.feeWallet
.
setWalletFee (assetID) { | ||
this.feeWallet = assetID | ||
} |
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.
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.
while (fields.marketsTableRows.firstChild) { | ||
fields.marketsTableRows.removeChild(fields.marketsTableRows.firstChild) | ||
} | ||
while (fields.feeTableRows.firstChild) { | ||
fields.feeTableRows.removeChild(fields.feeTableRows.firstChild) | ||
} |
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.
Can you change both of these to use Doc.empty
?
if (app.user.assets[fee.id] === undefined) { | ||
continue | ||
} |
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.
One line is good
if (app.user.assets[fee.id] === undefined) continue
rows.forEach(row => { | ||
row.classList.remove('selected') | ||
}) |
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.
One line is good
rows.forEach(row => { row.classList.remove('selected') })
this.walletForm.refresh() | ||
await this.changeForm(page.appPWForm, page.newWalletForm) | ||
await this.changeForm(page.appPWForm, page.dexAddrForm) |
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 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.
I was able to add a DCR wallet from the /markets page after registering with BTC |
This PR is the frontend part of (#1202)