Skip to content

Commit

Permalink
chore(core): middle button to confirm on TS3
Browse files Browse the repository at this point in the history
  • Loading branch information
ibz committed Mar 6, 2025
1 parent b270159 commit a4e1326
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 43 deletions.
39 changes: 22 additions & 17 deletions core/embed/rust/src/ui/layout_caesar/component/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ where
pad: Pad,
cancel_btn_details: Option<ButtonDetails>,
confirm_btn_details: Option<ButtonDetails>,
middle_confirm: bool,
back_btn_details: Option<ButtonDetails>,
next_btn_details: Option<ButtonDetails>,
buttons: Child<ButtonController>,
Expand All @@ -40,6 +41,7 @@ where
pad: Pad::with_background(background).with_clear(),
cancel_btn_details: Some(ButtonDetails::cancel_icon()),
confirm_btn_details: Some(ButtonDetails::text(TR::buttons__confirm.into())),
middle_confirm: false,
back_btn_details: Some(ButtonDetails::up_arrow_icon()),
next_btn_details: Some(ButtonDetails::down_arrow_icon_wide()),
// Setting empty layout for now, we do not yet know the page count.
Expand All @@ -59,6 +61,14 @@ where
self
}

pub fn with_middle_confirm(mut self, middle_confirm: bool) -> Self {
self.middle_confirm = middle_confirm;
self.confirm_btn_details =
self.confirm_btn_details
.map(|btn| if middle_confirm { btn.with_arms() } else { btn });
self
}

pub fn with_back_btn(mut self, btn_details: Option<ButtonDetails>) -> Self {
self.back_btn_details = btn_details;
self
Expand Down Expand Up @@ -114,25 +124,17 @@ where
}

fn get_button_layout(&self, has_prev: bool, has_next: bool) -> ButtonLayout {
let btn_left = self.get_left_button_details(!has_prev);
let btn_right = self.get_right_button_details(has_next);
ButtonLayout::new(btn_left, None, btn_right)
}

fn get_left_button_details(&self, is_first: bool) -> Option<ButtonDetails> {
if is_first {
let btn_left = if !has_prev {
self.cancel_btn_details.clone()
} else {
self.back_btn_details.clone()
}
}

fn get_right_button_details(&self, has_next_page: bool) -> Option<ButtonDetails> {
if has_next_page {
self.next_btn_details.clone()
} else {
self.confirm_btn_details.clone()
}
};
let (btn_middle, btn_right) = match (has_next, self.middle_confirm) {
(true, _) => (None, self.next_btn_details.clone()),
(false, true) => (self.confirm_btn_details.clone(), None),
(false, false) => (None, self.confirm_btn_details.clone()),
};
ButtonLayout::new(btn_left, btn_middle, btn_right)
}
}

Expand Down Expand Up @@ -186,6 +188,10 @@ where
return None;
}
}
ButtonPos::Middle => {
// Clicked CONFIRM. Send result.
return Some(PageMsg::Confirmed);
}
ButtonPos::Right => {
if self.has_next_page() {
// Clicked NEXT. Scroll down.
Expand All @@ -196,7 +202,6 @@ where
return Some(PageMsg::Confirmed);
}
}
_ => {}
}
}

Expand Down
23 changes: 7 additions & 16 deletions core/embed/rust/src/ui/layout_caesar/ui_firmware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl FirmwareUI for UICaesar {
content_in_button_page(
title,
paragraphs,
verb.unwrap_or(TString::empty()),
verb.unwrap_or(TR::buttons__confirm.into()),
verb_cancel,
hold,
)
Expand Down Expand Up @@ -211,7 +211,7 @@ impl FirmwareUI for UICaesar {
content_in_button_page(
TR::coinjoin__title.into(),
paragraphs,
TR::buttons__hold_to_confirm.into(),
TR::buttons__confirm.into(),
None,
true,
)
Expand Down Expand Up @@ -407,7 +407,7 @@ impl FirmwareUI for UICaesar {
paragraphs.into_paragraphs(),
button,
Some("<".into()),
false,
true,
)
}

Expand Down Expand Up @@ -446,16 +446,11 @@ impl FirmwareUI for UICaesar {
paragraphs.add(Paragraph::new(style, value));
}
}
let button_text = if hold {
TR::buttons__hold_to_confirm.into()
} else {
TR::buttons__confirm.into()
};

content_in_button_page(
title,
paragraphs.into_paragraphs(),
button_text,
TR::buttons__confirm.into(),
Some("".into()),
hold,
)
Expand Down Expand Up @@ -1306,20 +1301,16 @@ fn content_in_button_page<T: Component + Paginate + MaybeTrace + 'static>(
// Left button - icon, text or nothing.
let cancel_btn = verb_cancel.map(ButtonDetails::from_text_possible_icon);

// Right button - text or nothing.
// Optional HoldToConfirm
let mut confirm_btn = if !verb.is_empty() {
let confirm_btn = if !verb.is_empty() {
Some(ButtonDetails::text(verb))
} else {
None
};
if hold {
confirm_btn = confirm_btn.map(|btn| btn.with_default_duration());
}

let content = ButtonPage::new(content, theme::BG)
.with_cancel_btn(cancel_btn)
.with_confirm_btn(confirm_btn);
.with_confirm_btn(confirm_btn)
.with_middle_confirm(hold);

let mut frame = ScrollableFrame::new(content);
if !title.is_empty() {
Expand Down
1 change: 0 additions & 1 deletion core/src/apps/ethereum/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@ async def confirm_typed_data_final() -> None:
"confirm_typed_data_final",
TR.ethereum__title_confirm_typed_data,
TR.ethereum__sign_eip712,
verb=TR.buttons__hold_to_confirm,
hold=True,
)

Expand Down
1 change: 0 additions & 1 deletion core/src/apps/management/apply_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ async def _require_confirm_safety_checks(level: SafetyCheckLevel) -> None:
TR.words__are_you_sure,
description,
hold=True,
verb=TR.buttons__hold_to_confirm,
reverse=True,
br_code=BRT_PROTECT_CALL,
prompt_screen=True,
Expand Down
1 change: 0 additions & 1 deletion core/src/apps/management/wipe_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ async def wipe_device(msg: WipeDevice) -> Success:
TR.wipe__info,
TR.wipe__want_to_wipe,
reverse=True,
verb=TR.buttons__hold_to_confirm,
hold=True,
hold_danger=True,
br_code=ButtonRequestType.WipeDevice,
Expand Down
11 changes: 7 additions & 4 deletions tests/click_tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,26 @@ def get_char_category(char: str) -> PassphraseCategory:
return PassphraseCategory.SPECIAL


def go_next(debug: "DebugLink") -> LayoutContent:
def go_next(debug: "DebugLink", caesar_middle: bool = False) -> LayoutContent:
if debug.layout_type is LayoutType.Bolt:
debug.click(buttons.OK)
elif debug.layout_type is LayoutType.Caesar:
debug.press_right()
if caesar_middle:
debug.press_middle()
else:
debug.press_right()
elif debug.layout_type is LayoutType.Delizia:
debug.swipe_up()
else:
raise RuntimeError("Unknown model")
return debug.read_layout()


def go_back(debug: "DebugLink", r_middle: bool = False) -> LayoutContent:
def go_back(debug: "DebugLink", caesar_middle: bool = False) -> LayoutContent:
if debug.layout_type in (LayoutType.Bolt, LayoutType.Delizia):
debug.click(buttons.CANCEL)
elif debug.layout_type is LayoutType.Caesar:
if r_middle:
if caesar_middle:
debug.press_middle()
else:
debug.press_left()
Expand Down
2 changes: 1 addition & 1 deletion tests/click_tests/test_pin.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ def test_pin_same_as_wipe_code(device_handler: "BackgroundDeviceHandler"):
_enter_two_times(debug, "1", "1")
with PIN_INVALID, prepare(device_handler, Situation.PIN_SETUP) as debug:
_enter_two_times(debug, "1", "1")
go_back(debug, r_middle=True)
go_back(debug, caesar_middle=True)


@pytest.mark.setup_client(pin=PIN4)
Expand Down
4 changes: 2 additions & 2 deletions tests/input_flows_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,9 @@ def paginate_data(self) -> BRGeneratorType:
assert br.name == "confirm_data"
assert br.pages is not None
assert self.debug.read_layout().title() == TR.ethereum__title_input_data
for _ in range(br.pages):
for i in range(br.pages):
self.debug.read_layout()
go_next(self.debug)
go_next(self.debug, i == br.pages - 1)
self.debug.read_layout()

def paginate_data_go_back(self) -> BRGeneratorType:
Expand Down

0 comments on commit a4e1326

Please sign in to comment.