Skip to content

Commit

Permalink
Add possible skipping when using nbgl_useCaseReviewStreamingXXX() fun…
Browse files Browse the repository at this point in the history
…ctions
  • Loading branch information
nroggeman-ledger committed May 23, 2024
1 parent 07eccbc commit 3bef0ec
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 30 deletions.
40 changes: 32 additions & 8 deletions lib_nbgl/include/nbgl_use_case.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,20 +145,43 @@ typedef struct {
} nbgl_genericContents_t;

typedef struct {
const char *text;
const nbgl_icon_details_t *icon;
nbgl_callback_t callback;
const char *text; ///< text to use in action button in Home page
const nbgl_icon_details_t *icon; ///< icon to use in action button in Home page
nbgl_callback_t callback; ///< function to call when action button is touched in Home page
} nbgl_homeAction_t;

/**
* @brief The different types of operation to review
*
*/
typedef enum {
TYPE_TRANSACTION = 0, // For operations transferring a coin or taken from an account to another
TYPE_MESSAGE, // For operations signing a message that will not be broadcast on the blockchain
TYPE_OPERATION, // For other types of operation (generic type)
} nbgl_operationType_t;
TYPE_TRANSACTION
= 0, ///< For operations transferring a coin or taken from an account to another
TYPE_MESSAGE, ///< For operations signing a message that will not be broadcast on the
///< blockchain
TYPE_OPERATION ///< For other types of operation (generic type)
} nbgl_opType_t;

/**
* @brief This is to use in @ref nbgl_operationType_t when the operation is skippable.
* This is used
*
*/
#define SKIPPABLE_OPERATION (1 << 4)

/**
* @brief This is to use in @ref nbgl_operationType_t when the operation is "blind"
* This is used to indicate a warning with a top-right button in review first & last page
*
*/
#define BLIND_OPERATION (1 << 5)

/**
* @brief This mask is used to describe the type of operation to review with additional options
* It is a mask of @ref nbgl_opType_t [| @ref SKIPPABLE_OPERATION] [| @ref BLIND_OPERATION]
*
*/
typedef uint32_t nbgl_operationType_t;

/**
* @brief The different types of review status
Expand Down Expand Up @@ -221,7 +244,8 @@ void nbgl_useCaseReviewStreamingStart(nbgl_operationType_t operationType,
nbgl_choiceCallback_t choiceCallback);

void nbgl_useCaseReviewStreamingContinue(const nbgl_contentTagValueList_t *tagValueList,
nbgl_choiceCallback_t choiceCallback);
nbgl_choiceCallback_t choiceCallback,
nbgl_callback_t skipCallback);

void nbgl_useCaseReviewStreamingFinish(const char *finishTitle,
nbgl_choiceCallback_t choiceCallback);
Expand Down
14 changes: 1 addition & 13 deletions lib_nbgl/src/nbgl_layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -2378,18 +2378,6 @@ int nbgl_layoutAddHeader(nbgl_layout_t *layout, const nbgl_layoutHeader_t *heade
= (nbgl_obj_t *) textArea;
layoutInt->headerContainer->nbChildren++;
layoutInt->headerContainer->obj.area.height = textArea->obj.area.height;

// create vertical line separating texts
separationLine = (nbgl_line_t *) nbgl_objPoolGet(LINE, layoutInt->layer);
separationLine->lineColor = LIGHT_GRAY;
separationLine->obj.area.width = 1;
separationLine->obj.area.height = layoutInt->headerContainer->obj.area.height;
separationLine->direction = VERTICAL;
separationLine->thickness = 1;
separationLine->obj.alignment = MID_LEFT;
separationLine->obj.alignTo = (nbgl_obj_t *) textArea;
separationLine->obj.alignmentMarginX = -1;
layoutInt->headerContainer->obj.area.height = textArea->obj.area.height;
break;
}
default:
Expand Down Expand Up @@ -2550,7 +2538,7 @@ int nbgl_layoutAddExtendedFooter(nbgl_layout_t *layout, const nbgl_layoutFooter_
separationLine->thickness = 1;
separationLine->obj.alignment = MID_LEFT;
separationLine->obj.alignTo = (nbgl_obj_t *) textArea;
separationLine->obj.alignmentMarginY = -1;
separationLine->obj.alignmentMarginX = -1;
break;
}
case FOOTER_TEXT_AND_NAV: {
Expand Down
2 changes: 1 addition & 1 deletion lib_nbgl/src/nbgl_page.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ nbgl_page_t *nbgl_pageDrawGenericContentExt(nbgl_layoutTouchCallback_t onA

if (nav->skipText != NULL) {
nbgl_layoutHeader_t headerDesc = {.type = HEADER_RIGHT_TEXT,
.separationLine = true,
.separationLine = false,
.rightText.text = nav->skipText,
.rightText.token = nav->skipToken,
.rightText.tuneId = nav->tuneId};
Expand Down
40 changes: 34 additions & 6 deletions lib_nbgl/src/nbgl_use_case.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ typedef struct {
typedef struct {
nbgl_operationType_t operationType;
nbgl_choiceCallback_t choiceCallback;
nbgl_callback_t skipCallback;
const nbgl_icon_details_t *icon;
uint8_t stepPageNb;
} nbgl_reviewStreamingContext_t;
Expand Down Expand Up @@ -393,6 +394,8 @@ static void prepareReviewLightLastPage(nbgl_contentInfoButton_t *infoButton,
static const char *getRejectReviewText(nbgl_operationType_t operationType)
{
#ifdef TARGET_STAX
// clear skip and blind bits)
operationType &= ~(SKIPPABLE_OPERATION | BLIND_OPERATION);
if (operationType == TYPE_TRANSACTION) {
return "Reject transaction";
}
Expand Down Expand Up @@ -427,7 +430,7 @@ static void pageModalCallback(int token, uint8_t index)
else if (token == SKIP_TOKEN) {
if (index == 0) {
// display the last forward only review page, whatever it is
displayReviewPage(LAST_PAGE_FOR_REVIEW, true);
displayGenericContextPage(LAST_PAGE_FOR_REVIEW, true);
}
else {
// display background, which should be the page where skip has been touched
Expand Down Expand Up @@ -907,9 +910,17 @@ static void displayGenericContextPage(uint8_t pageIdx, bool forceFullRefresh)
bool flag;
const nbgl_content_t *p_content = NULL;

if ((navType == STREAMING_NAV) && (pageIdx >= bundleNavContext.reviewStreaming.stepPageNb)) {
bundleNavReviewStreamingChoice(true);
return;
if (navType == STREAMING_NAV) {
if (pageIdx == LAST_PAGE_FOR_REVIEW) {
if (bundleNavContext.reviewStreaming.skipCallback != NULL) {
bundleNavContext.reviewStreaming.skipCallback();
}
return;
}
else if (pageIdx >= bundleNavContext.reviewStreaming.stepPageNb) {
bundleNavReviewStreamingChoice(true);
return;
}
}

if (navInfo.activePage == pageIdx) {
Expand Down Expand Up @@ -1441,7 +1452,8 @@ static void bundleNavReviewAskRejectionConfirmation(nbgl_operationType_t operati
{
const char *title;
const char *confirmText;

// clear skip and blind bits)
operationType &= ~(SKIPPABLE_OPERATION | BLIND_OPERATION);
if (operationType == TYPE_TRANSACTION) {
title = "Reject transaction?";
confirmText = "Go back to transaction";
Expand Down Expand Up @@ -2605,14 +2617,19 @@ void nbgl_useCaseReviewStreamingStart(nbgl_operationType_t operationType,
* @param tagValueList list of tag/value pairs
* @param choiceCallback callback called when more operation data are needed (param is true) or
* operation is rejected (param is false)
* @param skipCallback callback called when skip button is pressed (if operationType has the @ref
* SKIPPABLE_OPERATION in @ref nbgl_useCaseReviewStreamingStart)
* @ref nbgl_useCaseReviewStreamingFinish shall then be called.
*/
void nbgl_useCaseReviewStreamingContinue(const nbgl_contentTagValueList_t *tagValueList,
nbgl_choiceCallback_t choiceCallback)
nbgl_choiceCallback_t choiceCallback,
nbgl_callback_t skipCallback)
{
// Should follow a call to nbgl_useCaseReviewStreamingStart
memset(&genericContext, 0, sizeof(genericContext));

bundleNavContext.reviewStreaming.choiceCallback = choiceCallback;
bundleNavContext.reviewStreaming.skipCallback = skipCallback;

// memorize context
onChoice = bundleNavReviewStreamingChoice;
Expand All @@ -2635,6 +2652,17 @@ void nbgl_useCaseReviewStreamingContinue(const nbgl_contentTagValueList_t *tagVa
prepareNavInfo(true,
NBGL_NO_PROGRESS_INDICATOR,
getRejectReviewText(bundleNavContext.reviewStreaming.operationType));
// if the operation is skippable
if (bundleNavContext.reviewStreaming.operationType & SKIPPABLE_OPERATION) {
#ifdef TARGET_STAX
navInfo.skipText = "Skip >>";
navInfo.navWithTap.quitText = "Reject";
#else
navInfo.progressIndicator = false;
navInfo.skipText = "Skip";
#endif
navInfo.skipToken = SKIP_TOKEN;
}

displayGenericContextPage(0, true);
}
Expand Down
16 changes: 15 additions & 1 deletion lib_nbgl/src/nbgl_use_case_nanos.c
Original file line number Diff line number Diff line change
Expand Up @@ -972,9 +972,23 @@ void nbgl_useCaseReviewStreamingStart(nbgl_operationType_t operationType,
displayStreamingReviewPage(FORWARD_DIRECTION);
}

/**
* @brief Continue drawing the flow of pages of a review.
* @note This should be called after a call to nbgl_useCaseReviewStreamingStart and can be followed
* by others calls to nbgl_useCaseReviewStreamingContinue and finally to
* nbgl_useCaseReviewStreamingFinish.
*
* @param tagValueList list of tag/value pairs
* @param choiceCallback callback called when more operation data are needed (param is true) or
* operation is rejected (param is false)
* @param skipCallback callback unused on Nano.
*/
void nbgl_useCaseReviewStreamingContinue(const nbgl_contentTagValueList_t *tagValueList,
nbgl_choiceCallback_t choiceCallback)
nbgl_choiceCallback_t choiceCallback,
nbgl_callback_t skipCallback)
{
UNUSED(skipCallback);

memset(&context, 0, sizeof(UseCaseContext_t));
context.type = STREAMING_CONTINUE_REVIEW_USE_CASE;
context.review.tagValueList = tagValueList;
Expand Down
3 changes: 2 additions & 1 deletion lib_ux_sync/src/ux_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,8 @@ ux_sync_ret_t ux_sync_reviewStreamingContinue(const nbgl_contentTagValueList_t *

{
ux_sync_init();
nbgl_useCaseReviewStreamingContinue(tagValueList, choice_callback);
// no skipping
nbgl_useCaseReviewStreamingContinue(tagValueList, choice_callback, NULL);
return ux_sync_wait(false);
}

Expand Down

0 comments on commit 3bef0ec

Please sign in to comment.