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

UI tweaks for ETH contract flow #4346

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open

UI tweaks for ETH contract flow #4346

wants to merge 12 commits into from

Conversation

ibz
Copy link
Contributor

@ibz ibz commented Nov 13, 2024

This is a continuation of #4343, addressing the UI side of #4302.

@ibz ibz self-assigned this Nov 13, 2024
Copy link

github-actions bot commented Nov 13, 2024

legacy UI changes device test(screens) main(screens)

Copy link

github-actions bot commented Nov 13, 2024

core UI changes device test click test persistence test
T2T1 Model T test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
T3B1 Safe 3 test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
T3T1 Safe 5 test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
All main(screens)

@ibz ibz force-pushed the ibz/20241113-tweaks branch 2 times, most recently from 28d80a5 to 3374fa4 Compare November 14, 2024 11:36
@ibz ibz changed the base branch from main to ibz/20241112-cleanup November 14, 2024 16:36
@ibz ibz linked an issue Nov 15, 2024 that may be closed by this pull request
@ibz ibz marked this pull request as ready for review November 15, 2024 12:17
@ibz ibz requested review from obrusvit and removed request for prusnak November 15, 2024 12:17
@ibz ibz force-pushed the ibz/20241113-tweaks branch 2 times, most recently from f4bbfd8 to ee1642a Compare November 15, 2024 12:48
Copy link
Contributor

@matejcik matejcik left a comment

Choose a reason for hiding this comment

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

while we're at this, can you remove text_mono and info (and possibly even hold) from confirm_blob ?

core/embed/rust/src/ui/component/text/formatted.rs Outdated Show resolved Hide resolved
// we would need to account for that and we could not use a constant.
let mut menu_choices = VerticalMenu::empty().danger(
theme::ICON_CANCEL,
verb_cancel.unwrap_or(TR::buttons__cancel.into()),
Copy link
Contributor

Choose a reason for hiding this comment

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

why not make verb_cancel non-Optional and prefill this string at construction time?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure what is the benefit. It would just move the check / unwrap at a higher level, most probably in ConfirmBlobParams - because that one can have it missing. Let's say I also set it to TR::buttons__cancel in ConfirmBlobParams, I would still need to make the check in new_confirm_action. Unless I make it non-optional there too and set a default in uPy... Either way, the default would have to be somewhere, no?

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, yes, we kinda want to work with non-Options from as early as possible. If None here doesn't have a special meaning, it should be unwrapped at the earliest convenient place, which, yes, would be new_confirm_action.
No reason for a code tree this deep to be aware that the caller somewhere six stack frames out was too lazy to specify the value explicitly.

It may make sense to accept a None value from Python, because that's (a) an API boundary and (b) Python doesn't make it convenient to specify translated values as default arguments -- you can't say def confirm(verb: str = TR.some__verb) because then it does not get updated when you change a translation.

But that's a property of the API, that it allows you to not specify a verb. Not a property of the implementation, where we always require a string to work with (unless we don't?), just that we have a default value for it.

Copy link
Contributor Author

@ibz ibz Nov 20, 2024

Choose a reason for hiding this comment

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

OK: fc0bb63

I think I understand your point, and it can be seen like this too, indeed.

I was seeing it from the other angle - as much as possible instantiate these "string bearing structs" like ConfirmBlobParams and ConfirmActionMenuStrings (maybe I should rename it to ConfirmActionMenuParams while at it...) with no parameters, have everything default to None, and do with_XXX only when "XXX" needs to be changed to something other than the default. Otherwise the struct would carry the None all the way to the very end, where the default would be used. I think @obrusvit 's recent changes also went in this direction - dropping as many parameters from ConfirmBlobParams::new and moving them to .with_XXX.

Of course, the two ways are not mutually exclusive, which is what I tried to do at fc0bb6 - not sure whether you guys like it - but basically ConfirmBlobParams::new still means you want to go with defaults, but the default verb_cancel is set to TR::buttons__cancel.into() in the ctor rather than to None - so this "params bearing struct" carries the concrete default around. Maybe if this is what you meant, then I should just replace the rest of the strings in ConfirmBlobParams in the same way... I think I like it...

The disadvantage is of course that multiple instantiations of ConfirmBlobParams around multiple API functions have to unwrap_or if they want to do a .with_verb_cancel (in order to let the uPy code customize the verb. OOOOR, I could make with_verb_cancel accept an Option and have it set the default in case it received None - but I don't know why, that looks less appealing to me (even though the opposite leads to duplication of the default value).

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe if this is what you meant, then I should just replace the rest of the strings in ConfirmBlobParams in the same way... I think I like it...

yes, this is what I have in mind

multiple instantiations of ConfirmBlobParams around multiple API functions have to unwrap_or if they want to do a .with_verb_cancel (in order to let the uPy code customize the verb. OOOOR, I could make with_verb_cancel accept an Option and have it set the default in case it received None - but I don't know why, that looks less appealing to me (even though the opposite leads to duplication of the default value).

wondering about this .. would it make sense to construct ConfirmBlobParams and friends by passing the micropython options -- gated by #[feature(micropython)] of course?
wdyt @obrusvit

Copy link
Contributor

Choose a reason for hiding this comment

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

I think @obrusvit 's recent changes also went in this direction - dropping as many parameters from ConfirmBlobParams::new and moving them to .with_XXX.

My motivation was not to drop as may params as possible from ConfirmBlobParams::new but to keep only those which are used by all callers. There were 7 params and 4 calls were setting the last 4 to None/False Hence I reduced the new params count to 3 and put the rest to with_xyz builder methods.


wondering about this .. would it make sense to construct ConfirmBlobParams and friends by passing the micropython options -- gated by #[feature(micropython)] of course?
wdyt @obrusvit

Do you mean constructing ConfirmBlobParams with (n_args, args, kwargs). Hmmm, I don't like it very much. IMO, ConfirmBlobParams should be deeper in the UI code with rusty-types.
It's true that initially the trait UiFeaturesFirmware (or whatever the name will be) will be riddled with micropython stuff, but mostly just Obj, which should be replaced later on.

let content_menu = Frame::left_aligned("".into(), menu_choices)
.with_cancel_button()
.with_swipe(Direction::Right, SwipeSettings::immediate());
if has_info {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if has_info {
if let Some(verb_info) = verb_info {

assuming (again, dtto) that verb_info default value is prefilled at Menu construction time

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, something like this I guess: 1eff1d8

Now new_confirm_blob looks strange, but once I remove the info parameter completely, it will look great - basically the decision on whether to show info or not is done by passing Some or None in verb_info.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Turned out slightly different actually, but anyway, we'll discuss this in the next PR, which does not cleanup on confirm_blob.

Base automatically changed from ibz/20241112-cleanup to main November 19, 2024 11:36
This commit adds a margin and footer description to the first page of
the paginated blobs to be confirmed on Mercury. It also extracts the
part of confirm_blob that deals with the first page to a separate
function in order to keep confirm_blob simple.

[no changelog]
@ibz
Copy link
Contributor Author

ibz commented Nov 20, 2024

while we're at this, can you remove text_mono and info (and possibly even hold) from confirm_blob ?

I'll do that in the next PR if you don't mind, together with cleanup of warning_hi_prio. There's already too many unrelated changes in this PR, and rebasing becomes a pain.

Copy link
Contributor

@obrusvit obrusvit left a comment

Choose a reason for hiding this comment

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

I have some points to discuss.

@@ -150,7 +150,7 @@ impl<'a> Component for ShareWords<'a> {
}

impl<'a> Paginate for ShareWords<'a> {
fn page_count(&mut self) -> usize {
fn page_count(&self) -> usize {
// Not defining the logic here, as we do not want it to be `&mut`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove obsolete commentary since the param is not mut anymore.

@@ -318,11 +337,13 @@ pub fn new_confirm_action_simple<T: Component + Paginate + MaybeTrace + 'static>
strings: ConfirmActionStrings,
hold: bool,
page_limit: Option<usize>,
show_page_counter: bool,
Copy link
Contributor

Choose a reason for hiding this comment

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

could probably be also named page_counter just like in `ConfirmBlobParams.

@@ -191,6 +194,22 @@ fn new_confirm_action_uni<T: Component + MaybeTrace + 'static>(
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None);

if show_page_counter {
fn footer_update_fn<T: Component + Paginate>(
Copy link
Contributor

Choose a reason for hiding this comment

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

I think defining the fn inside this if has no benefit - it's not a Fn object which would not be created if show_page_counter was false. I would put it outside as a free-standing function and would just do

if show_page_counter {
     content_intro = content_intro
            .with_footer_counter(TR::instructions__swipe_up.into())
            .register_footer_update_fn(footer_update_fn::<T>);
}

Intro,
Menu,
Confirm,
enum ConfirmAction {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm surprised this is even needed - no menu means no way to "Cancel"

// we would need to account for that and we could not use a constant.
let mut menu_choices = VerticalMenu::empty().danger(
theme::ICON_CANCEL,
verb_cancel.unwrap_or(TR::buttons__cancel.into()),
Copy link
Contributor

Choose a reason for hiding this comment

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

I think @obrusvit 's recent changes also went in this direction - dropping as many parameters from ConfirmBlobParams::new and moving them to .with_XXX.

My motivation was not to drop as may params as possible from ConfirmBlobParams::new but to keep only those which are used by all callers. There were 7 params and 4 calls were setting the last 4 to None/False Hence I reduced the new params count to 3 and put the rest to with_xyz builder methods.


wondering about this .. would it make sense to construct ConfirmBlobParams and friends by passing the micropython options -- gated by #[feature(micropython)] of course?
wdyt @obrusvit

Do you mean constructing ConfirmBlobParams with (n_args, args, kwargs). Hmmm, I don't like it very much. IMO, ConfirmBlobParams should be deeper in the UI code with rusty-types.
It's true that initially the trait UiFeaturesFirmware (or whatever the name will be) will be riddled with micropython stuff, but mostly just Obj, which should be replaced later on.

@@ -262,9 +269,19 @@ impl ConfirmBlobParams {
}
.into_paragraphs();

let confirm_extra = if self.cancel {
Copy link
Contributor

Choose a reason for hiding this comment

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

so cancel param means it's just "Cancel" in the menu but if cancel == false then the menu contains and "Cancel"?

content_area = content_area.inset(Insets::top(theme::SPACING));
content_area = content_area
.inset(Insets::top(theme::SPACING))
.inset(Insets::top(margin as i16));
Copy link
Contributor

Choose a reason for hiding this comment

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

This makes the real margin now SPACING + margin. It's quite confusing but probably fine.

@@ -329,6 +317,44 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}

extern "C" fn new_confirm_blob_intro(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
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 love it as it creates mercury specific layout. But probably fine for now.

has_info: bool,
verb_info: Option<TString<'static>>,
}

impl ConfirmActionMenuStrings {
pub fn new() -> Self {
Self {
verb_cancel: None,
verb_cancel: TR::buttons__cancel.into(),
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we can introduce:

const VERB_CANCE_DEFAULT: TranslatedString = TR::buttions__cancel`;

and use it on the unwrap_or calls?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 🔎 Needs review
Development

Successfully merging this pull request may close these issues.

Improve EVM contract flow
3 participants