Skip to content

Commit 6ad0a46

Browse files
authored
Merge pull request #204 from Zondax/review_with_intent
Adds review with intent functionality
2 parents f3bdfda + 71e1e60 commit 6ad0a46

File tree

7 files changed

+136
-3
lines changed

7 files changed

+136
-3
lines changed

app/ui/view.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ void view_review_show(review_type_e reviewKind) {
7878
view_review_show_impl((unsigned int)reviewKind, NULL, NULL);
7979
}
8080

81+
void view_review_show_with_intent(review_type_e reviewKind, const char *intent) {
82+
// New function that explicitly handles intent
83+
view_review_show_with_intent_impl((unsigned int)reviewKind, intent);
84+
}
85+
8186
void view_review_show_generic(review_type_e reviewKind, const char *title, const char *validate) {
8287
view_review_show_impl((unsigned int)reviewKind, title, validate);
8388
}

app/ui/view.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ void view_inspect_init(viewfunc_getInnerItem_t view_funcGetInnerItem, viewfunc_g
128128

129129
void view_review_show(review_type_e reviewKind);
130130

131+
void view_review_show_with_intent(review_type_e reviewKind, const char *intent);
132+
131133
void view_spinner_show(const char *text);
132134

133135
void view_review_show_generic(review_type_e reviewKind, const char *title, const char *validate);
@@ -148,4 +150,4 @@ typedef enum {
148150
} settings_list_e;
149151

150152
void view_set_switch_subtext(settings_list_e switch_id, const char *subtext);
151-
#endif // TARGET_STAX || TARGET_FLEX
153+
#endif // TARGET_STAX || TARGET_FLEX

app/ui/view_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ void h_inspect_init();
230230

231231
void view_review_show_impl(unsigned int requireReply, const char *title, const char *validate);
232232

233+
void view_review_show_with_intent_impl(unsigned int requireReply, const char *intent);
234+
233235
void view_inspect_show_impl();
234236

235237
void view_initialize_show_impl(uint8_t item_idx, const char *statusString);

app/ui/view_nbgl.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ const char *intro_submessage = NULL;
5454
char intro_msg_buf[MAX_CHARS_PER_VALUE1_LINE];
5555
char intro_submsg_buf[MAX_CHARS_SUBMSG_LINE];
5656

57+
#define REVIEW_STANDALONE_SIZE 22
58+
#define REVIEW_MESSAGE_SIZE 18
59+
5760
static nbgl_layoutTagValue_t pairs[NB_MAX_DISPLAYED_PAIRS_IN_REVIEW];
5861

5962
static nbgl_layoutTagValue_t pair;
@@ -464,6 +467,7 @@ static void config_useCaseReview(nbgl_operationType_t type) {
464467
pairList.pairs = NULL; // to indicate that callback should be used
465468
pairList.callback = update_item_callback;
466469
pairList.startIndex = 0;
470+
467471
if (app_mode_blindsign_required()) {
468472
nbgl_useCaseReviewBlindSigning(type, &pairList, &C_icon_stax_64,
469473
(intro_message == NULL ? "Review transaction" : intro_message),
@@ -563,6 +567,50 @@ void view_review_show_impl(unsigned int requireReply, const char *title, const c
563567
}
564568
}
565569

570+
void view_review_show_with_intent_impl(unsigned int requireReply, const char *intent) {
571+
review_type = (review_type_e)requireReply;
572+
573+
intro_message = NULL;
574+
intro_submessage = NULL;
575+
intro_msg_buf[0] = '\0';
576+
intro_submsg_buf[0] = '\0';
577+
viewdata.key = viewdata.keys[0];
578+
viewdata.value = viewdata.values[0];
579+
580+
// Format the intro message based on the intent
581+
if (intent != NULL && strlen(intent) > 0) {
582+
// Show everything on a single line for NBGL
583+
const char *review_text = (review_type == REVIEW_MSG) ? "Review message" : "Review transaction";
584+
int ret = snprintf(intro_msg_buf, sizeof(intro_msg_buf), "%s to %s", review_text, intent);
585+
586+
// Check if truncation occurred and add ellipsis if needed
587+
if (ret >= (int)sizeof(intro_msg_buf)) {
588+
const size_t buf_len = sizeof(intro_msg_buf);
589+
if (buf_len >= 4) {
590+
intro_msg_buf[buf_len - 4] = '.';
591+
intro_msg_buf[buf_len - 3] = '.';
592+
intro_msg_buf[buf_len - 2] = '.';
593+
intro_msg_buf[buf_len - 1] = '\0';
594+
}
595+
}
596+
intro_message = intro_msg_buf;
597+
intro_submessage = NULL; // No second line for NBGL
598+
}
599+
600+
h_paging_init();
601+
602+
switch (review_type) {
603+
case REVIEW_MSG: {
604+
config_useCaseMessageReview();
605+
break;
606+
}
607+
case REVIEW_TXN:
608+
default:
609+
config_useCaseReview(TYPE_TRANSACTION);
610+
break;
611+
}
612+
}
613+
566614
void view_set_switch_subtext(settings_list_e switch_id, const char *subtext) {
567615
if (switch_id >= SETTINGS_SWITCHES_NB_LEN) {
568616
return;

app/ui/view_s.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,4 +608,11 @@ static unsigned int view_skip_button(unsigned int button_mask, __Z_UNUSED unsign
608608
return 0;
609609
}
610610

611+
void view_review_show_with_intent_impl(unsigned int requireReply, const char *intent) {
612+
// For Nano S, we don't have space to display the intent in the title
613+
// Just use the normal review flow
614+
UNUSED(intent);
615+
view_review_show_impl(requireReply, NULL, NULL);
616+
}
617+
611618
#endif

app/ui/view_x.c

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,6 @@ UX_FLOW_DEF_NOCB(ux_review_flow_4_review_title, pbb,
282282
REVIEW_MSG_TITLE,
283283
REVIEW_MSG_VALUE,
284284
});
285-
286285
UX_STEP_INIT(ux_review_flow_2_start_step, NULL, NULL, { h_review_loop_start(); });
287286
#ifdef HAVE_INSPECT
288287
UX_STEP_CB_INIT(ux_review_flow_2_step, bnnn_paging, h_review_loop_inside(), inspect_init(),
@@ -566,6 +565,76 @@ void view_review_show_impl(unsigned int requireReply, const char *title, const c
566565

567566
void run_root_txn_flow() { run_ux_review_flow(review_type, &ux_review_flow_2_start_step); }
568567

568+
void view_review_show_with_intent_impl(unsigned int requireReply, const char *intent) {
569+
review_type = requireReply;
570+
h_paging_init();
571+
h_paging_decrease();
572+
573+
// Format the intro message based on the intent
574+
if (intent != NULL && strlen(intent) > 0) {
575+
// Put "Review transaction" or "Review message" on first line
576+
const char *first_line = (review_type == REVIEW_MSG) ? "Review message" : "Review transaction";
577+
snprintf(intro_msg_buf, sizeof(intro_msg_buf), "%s", first_line);
578+
579+
// Put "to {intent}" on second line
580+
const size_t max_intent_len = sizeof(intro_submsg_buf) - 4; // Reserve 4 bytes: "to " (3) + null terminator (1)
581+
int ret = snprintf(intro_submsg_buf, sizeof(intro_submsg_buf), "to %.*s", (int)max_intent_len, intent);
582+
583+
// Check if truncation occurred and add ellipsis if needed
584+
if (ret >= (int)sizeof(intro_submsg_buf)) {
585+
const size_t buf_len = sizeof(intro_submsg_buf);
586+
if (buf_len >= 4) {
587+
intro_submsg_buf[buf_len - 4] = '.';
588+
intro_submsg_buf[buf_len - 3] = '.';
589+
intro_submsg_buf[buf_len - 2] = '.';
590+
intro_submsg_buf[buf_len - 1] = '\0';
591+
}
592+
}
593+
594+
// Use the dynamic review flow for transactions and messages with intent
595+
if (review_type == REVIEW_TXN) {
596+
flow_inside_loop = 0;
597+
if (G_ux.stack_count == 0) {
598+
ux_stack_push();
599+
}
600+
// Build flow with dynamic title for transaction
601+
uint8_t index = 0;
602+
ux_review_flow[index++] = &ux_review_flow_1_review_group_title;
603+
ux_review_flow[index++] = &ux_review_flow_2_start_step;
604+
ux_review_flow[index++] = &ux_review_flow_2_step;
605+
ux_review_flow[index++] = &ux_review_flow_2_end_step;
606+
ux_review_flow[index++] = &ux_review_flow_3_step;
607+
ux_review_flow[index++] = FLOW_END_STEP;
608+
ux_flow_init(0, ux_review_flow, NULL);
609+
return;
610+
} else if (review_type == REVIEW_MSG) {
611+
// Create custom flow for message with intent
612+
flow_inside_loop = 0;
613+
if (G_ux.stack_count == 0) {
614+
ux_stack_push();
615+
}
616+
// Build flow with dynamic title for message
617+
uint8_t index = 0;
618+
// Use the group title flow which displays intro_msg_buf
619+
ux_review_flow[index++] = &ux_review_flow_1_review_group_title;
620+
ux_review_flow[index++] = &ux_review_flow_2_start_step;
621+
ux_review_flow[index++] = &ux_review_flow_2_step;
622+
ux_review_flow[index++] = &ux_review_flow_2_end_step;
623+
ux_review_flow[index++] = &ux_review_flow_6_step;
624+
ux_review_flow[index++] = FLOW_END_STEP;
625+
ux_flow_init(0, ux_review_flow, NULL);
626+
return;
627+
}
628+
}
629+
630+
// Fallback to normal review flow if no intent or other review types
631+
flow_inside_loop = 0;
632+
if (G_ux.stack_count == 0) {
633+
ux_stack_push();
634+
}
635+
run_ux_review_flow((review_type_e)review_type, NULL);
636+
}
637+
569638
// Build review UX flow and run it
570639
void run_ux_review_flow(review_type_e reviewType, const ux_flow_step_t *const start_step) {
571640
uint8_t index = 0;

include/zxversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717

1818
#define ZXLIB_MAJOR 36
1919
#define ZXLIB_MINOR 0
20-
#define ZXLIB_PATCH 1
20+
#define ZXLIB_PATCH 2

0 commit comments

Comments
 (0)