-
Notifications
You must be signed in to change notification settings - Fork 990
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
Wallet: Password field contains saved data once user put it before while transaction confirmation #18447 #18899
Conversation
Jenkins BuildsClick to see older builds (20)
|
@@ -127,6 +127,7 @@ | |||
{:size :size-48 | |||
:track-text (i18n/label :t/slide-to-create-account) | |||
:customization-color @account-color | |||
:on-close #(rf/dispatch [:standard-auth/reset-login-password]) |
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 should be handled by authorize
, as I don't see scenarios where we wouldn't want to reset the password after the bottom-sheet is closed. @J-Son89 ?
... but I'd avoid adding it in this PR as authorize
is fully refactored already over here and the conflicts might be hard to fix if that ns would be touched 😨.
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.
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.
@clauxx Thanks man. I used your code
on-change-password (fn [value] | ||
(reset! password-value value) | ||
(when (not= value (security/safe-unmask-data password)) | ||
(rf/dispatch [:set-in [:profile/login :password] | ||
(security/mask-data value)]) | ||
(rf/dispatch [:set-in [:profile/login :error] ""])))] |
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.
might make sense to make a util for this inside standard-auth, as we're repeating it everywhere?
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 it's just better that we make a proper re-frame event, no?
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 we are supposed to move away from the :set-in
method it just sort of lingered around because no one took the time to update it.
No better time than now to do so :)
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.
hmm, then maybe it might be better to make an event inside standard-auth and call it from a single place - password-input
? This way the consumers of standard-auth/password-input
will only have to handle the ratom inside on-change
.
orrr, what about not exposing on-change
at all and handling the ratom inside password-input
as well?
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's a bit unclear of what you mean here @clauxx - can you expand this a bit further?
My point is rather straightforward, we just define an event that updates the db as normal.
so instead of this:
(rf/dispatch [:set-in [:profile/login :password]
(security/mask-data value)])
we have
(rf/reg-event-fx
:profile/update-login-password
(fn [{:keys [db]} [value]]
{:db (assoc-in db [:profile/login :password (security/mask-data value)]
))
and then used as
(rf/dispatch [:profile/update-login-password value])
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.
and similar events for updating the error and the key-uid
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.
Oh, I agree with your suggestion of handling the db updates inside an event. Maybe even a single event to update the password and reset the error together and put them inside standard-auth
like:
(rf/reg-event-fx
:standard-auth/update-password
(fn [{:keys [db]} [value]]
{:db (-> db
(assoc-in [:profile/login :password (security/mask-data value))
(assoc-in [:profile/login :error ""))]))
My suggestion though is more related to simplifying the password-input
use. Before this PR, to use the password-input
, you didn't have to care about the on-change-text
behaviour, it was handled implicitly. Now, you have to pass the on-change
and dispatch the event(s) to update the password/error and update a ratom. It was fine for a POC of the fix, but now it seems like a bit of a DX regression if the consumers of password-input
have to pass an extra prop with boilerplate. What do you think @J-Son89?
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.
Yeah sure, sounds good to me
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.
Regarding @J-Son89's comment about not using set-in
. Here it's also being used twice in a row, as if the app-db is a synchronous state that can be mutated. This is usually a smell in my experience because it leads to the view layer knowing too much about the app state.
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.
Done
When I've read the description "Password field contains saved data", I thought it is a feature and as a result, haven't understood the attached video) I'd suggest rephrasing the description to make it more clear. Like:
|
(rf/dispatch [:profile.login/verify-database-password password | ||
#(on-enter-password password)]))} | ||
button-label]]]])) | ||
[] |
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.
should be [_
]?
cc @ulisesmac wdyt
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.
Yeah, as a standard practice I think it'd be the best, although it's not needed for this component
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.
Done
container-style] | ||
:or {container-style {:flex 1}}}] | ||
:or {container-style {:flex 1} | ||
on-close #()}}] |
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.
Just a reminder that if a caller of view-internal
pass on-close
as nil for any reason (easy to happen with Clojure conditionals), then the destructring code to set a default on-close
won't be used and the app will break when :on-complete
runs because on-close
is called unchecked.
The pattern (when f (f))
is more robust here, and the default destructuring can be removed.
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's safer to do: (when (fn? f) (f))
, no?
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.
Done
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 like @J-Son89 's approach! too expressive and cheap to implement
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's safer to do: (when (fn? f) (f)), no?
Definitely safer, but I don't remember a case where we passed a string or other primitive instead of a function. As far as I've seen, it's either the value exists and it's a valid function instance or it's falsey.
(when (not= value | ||
(security/safe-unmask-data | ||
password)) | ||
(rf/dispatch [:set-in |
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.
These type of events :set-in
, :set-once
, etc are deprecated. Although not easy to realize that 🤷🏼
status-mobile/src/legacy/status_im/events.cljs
Lines 220 to 222 in bfed36d
;;TODO :replace by named events | |
(rf/defn set-in-event | |
{:events [:set-in]} |
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.
Done
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.
They are still being used here @mmilad75. Maybe you forgot to push?
{:keys [error processing password]} (rf/sub [:profile/login]) | ||
sign-in-enabled? (rf/sub [:sign-in-enabled?]) | ||
on-change-password (fn [value] | ||
(reset! password-value value) |
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 we could improve the naming of this atom. password-value
for an atom is kind of confusing, because usually when we refer to the "value" of an atom is the deref'ed result, not the atom itself. The name could be just password
or password-state
for added clarity (for some).
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.
Done
:on-success #(rf/dispatch [:standard-auth/on-biometric-success on-auth-success]) | ||
:on-fail #(rf/dispatch [:standard-auth/on-biometric-fail on-auth-fail %])}]]]})) | ||
|
||
(schema/=> authorize-with-biometric events-schema/?authorize-with-biometric) |
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 we don't need/want schema added here just yet 👍
let's keep it focused until quo is covered completely, you can remove from this pr
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 was added accidentally. I removed the codes
@@ -32,8 +32,7 @@ | |||
(rf/reg-event-fx :wallet/navigate-to-new-account | |||
(fn [{:keys [db]} [address]] | |||
{:db (assoc-in db [:wallet :current-viewing-account-address] address) | |||
:fx [[:dispatch [:hide-bottom-sheet]] |
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.
do we definitely need to move this to the other event?
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.
Yes, we agreed to close the bottom sheet before the navigation happens
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.
Right, but the original order did that no?
it now works for syncing and sending? |
(reset! password-state value) | ||
(rf/dispatch [:standard-auth/update-password | ||
value])))] | ||
[:<> |
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 fragment is wrapping a single view. Is this 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.
Removed
value])))] | ||
[:<> | ||
[rn/view {:style style/enter-password-container} | ||
[rn/view |
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 view
seems unnecessary.
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.
Removed
on-change-password (fn [value] | ||
(when (not= value @password-state) | ||
(reset! password-state value) | ||
(rf/dispatch [:standard-auth/update-password |
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 are talking more about performance these days, I'd like to mention a few things for this enter-password
component I deem significant and that appear in many of our PRs. In no order of importance:
- There's an unnecessary overhead to involve re-frame on every key press. Why are we committing to the app-db all the time?
- Because we dispatch
:standard-auth/update-password
on every key press, this forces the parentview
component to be rendered twice, for every key press. This problem cascades to its childrenpassword-input/view
andquo/button
.input/view
itself is quite heavy. We can save a bunch of CPU cycles if we process the parentview
component and its children only once on every key press. - The props passed to the
button
component are different on every Reagent pass because theon-press
function is recreated over and over. This forces the button component to be re-processed by Reagent on every pass of the parent component.
Things that would allow us to render all components in enter-password
once on every key press:
- Use local state and don't update the app-db at paths
[:profile/login :password]
and[:profile/login :error]
on every key press. Use local state and then the wholeenter-password
component and its children would render once. The global state should be left for things that change less often. - The profile
key-uid
doesn't change when the user is typing, so it can be moved outside the renderer, and then we can make theon-press
of the button be created only once. This would allow Reagent to skip processing the button component entirely on every key press. The button component is not the cheapest too if we look at its implementation.
cc @flexsurfer A slightly different example than what we were discussing today in the perf channel. Still, a good example where multiple Reagent passes cascade down the component tree (and I haven't checked the other subcomponents, but on the surface they also have low-hanging fruits to optimize).
(defn on-biometric-fail | ||
[_ [on-auth-fail error]] | ||
(when on-auth-fail | ||
(on-auth-fail error)) |
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 odd in the event handler. There's no return value, so it's assumed to be a side-effect, but event handlers should only describe side-effects, not perform them. In re-frame we aspire to separate planning from execution.
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 file was added accidentally. I removed the entire file
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.
Okay, thanks @mmilad75
b8a59b0
to
f0a0adc
Compare
f0a0adc
to
3bec9d5
Compare
hey @mmilad75 what's the state of this PR? |
There was an issue with creating new account before, and now, the issue that this PR is fixing is no longer reproducible. I will close this PR |
fixes #18447
Screen.Recording.2024-02-19.at.16.28.53.mov