async def show_remaining_shares( ctx: wire.GenericContext, groups: Iterable[tuple[int, tuple[str, ...]]], # remaining + list 3 words shares_remaining: list[int], group_threshold: int, ) -> None: pages: list[ui.Component] = [] for remaining, group in groups: if 0 < remaining < MAX_SHARE_COUNT: text = Text("Remaining Shares") text.bold( strings.format_plural("{count} more {plural} starting", remaining, "share")) for word in group: text.normal(word) pages.append(text) elif (remaining == MAX_SHARE_COUNT and shares_remaining.count(0) < group_threshold): text = Text("Remaining Shares") groups_remaining = group_threshold - shares_remaining.count(0) text.bold( strings.format_plural("{count} more {plural} starting", groups_remaining, "group")) for word in group: text.normal(word) pages.append(text) await confirm(ctx, Paginated(pages), cancel=None)
def test_format_plural(self): VECTORS = [ ("We need {count} more {plural}", 1, "share", "We need 1 more share"), ("We need {count} more {plural}", 3, "share", "We need 3 more shares"), ("We need {count} more {plural}", 1, "candy", "We need 1 more candy"), ("We need {count} more {plural}", 7, "candy", "We need 7 more candies"), ("We need {count} more {plural}", 1, "key", "We need 1 more key"), ("We need {count} more {plural}", 5, "key", "We need 5 more keys"), ("We need {count} more {plural}", 1, "hash", "We need 1 more hash"), ("We need {count} more {plural}", 2, "hash", "We need 2 more hashes"), ("We need {count} more {plural}", 1, "fuzz", "We need 1 more fuzz"), ("We need {count} more {plural}", 2, "fuzz", "We need 2 more fuzzes"), ] for v in VECTORS: self.assertEqual(strings.format_plural(v[0], v[1], v[2]), v[3]) with self.assertRaises(ValueError): strings.format_plural("Hello", 1, "share")
async def require_sign_tx(ctx: wire.Context, num_actions: int) -> None: await confirm_action( ctx, "confirm_tx", title="Sign transaction", description="You are about to sign {}.", description_param=format_plural("{count} {plural}", num_actions, "action"), icon=ui.ICON_SEND, icon_color=ui.GREEN, br_code=ButtonRequestType.SignTx, )
async def should_show_array( ctx: Context, parent_objects: Iterable[str], data_type: str, size: int, ) -> bool: para = ((ui.NORMAL, format_plural("Array of {count} {plural}", size, data_type)),) return await should_show_more( ctx, title=limit_str(".".join(parent_objects)), para=para, button_text="Show full array", br_type="should_show_array", )
async def require_confirm_final(ctx: Context, fee: int, num_operations: int) -> None: op_str = strings.format_plural("{count} {plural}", num_operations, "operation") await confirm_metadata( ctx, "confirm_final", title="Final confirm", content="Sign this transaction made up of " + op_str + " and pay {}\nfor fee?", param=format_amount(fee), hide_continue=True, hold=True, )
async def _request_share_next_screen(ctx: wire.GenericContext) -> None: remaining = storage.recovery.fetch_slip39_remaining_shares() group_count = storage.recovery.get_slip39_group_count() if not remaining: # 'remaining' should be stored at this point raise RuntimeError if group_count > 1: content = layout.RecoveryHomescreen("More shares needed") await layout.homescreen_dialog(ctx, content, "Enter", _show_remaining_groups_and_shares) else: text = strings.format_plural("{count} more {plural}", remaining[0], "share") content = layout.RecoveryHomescreen(text, "needed to enter") await layout.homescreen_dialog(ctx, content, "Enter share")
async def should_show_struct( ctx: Context, description: str, data_members: list[EthereumStructMember], title: str = "Confirm struct", button_text: str = "Show full struct", ) -> bool: para = ( (ui.BOLD, description), ( ui.NORMAL, format_plural("Contains {count} {plural}", len(data_members), "key"), ), (ui.NORMAL, ", ".join(field.name for field in data_members)), ) return await should_show_more( ctx, title=title, para=para, button_text=button_text, br_type="should_show_struct", )