@@ -79,6 +79,14 @@ static nbgl_layoutTagValueList_t pairList;
7979
8080static nbgl_layoutTagValueList_t * extraPagesPtr = NULL ;
8181
82+ // Cache for page counts to avoid re-parsing
83+ #define MAX_CACHED_ITEMS 200
84+ static struct {
85+ bool valid ;
86+ uint8_t itemCount ;
87+ uint8_t pageCounts [MAX_CACHED_ITEMS ];
88+ } pageCountCache = {.valid = false, .itemCount = 0 };
89+
8290typedef enum {
8391 EXPERT_MODE_TOKEN = FIRST_USER_TOKEN ,
8492 ACCOUNT_MODE_TOKEN ,
@@ -209,14 +217,46 @@ void view_settings_show_impl() {
209217
210218void view_spinner_impl (const char * text ) { nbgl_useCaseSpinner (text ); }
211219
220+ /**
221+ * @brief Get the page count for a specific item, using cache when available
222+ */
223+ static uint8_t get_item_page_count (uint8_t itemIdx ) {
224+ // Check if cache is valid and contains this item
225+ if (pageCountCache .valid && itemIdx < pageCountCache .itemCount && itemIdx < MAX_CACHED_ITEMS ) {
226+ if (pageCountCache .pageCounts [itemIdx ] > 0 ) {
227+ return pageCountCache .pageCounts [itemIdx ];
228+ }
229+ }
230+
231+ // Cache miss or invalid - need to query
232+ uint8_t pageCount = 0 ;
233+ if (viewdata .viewfuncGetItem (itemIdx , viewdata .key , MAX_CHARS_PER_KEY_LINE , viewdata .value ,
234+ MAX_CHARS_PER_VALUE1_LINE , 0 , & pageCount ) == zxerr_ok ) {
235+ // Store in cache if valid
236+ if (pageCount > 0 && itemIdx < MAX_CACHED_ITEMS ) {
237+ if (!pageCountCache .valid ) {
238+ MEMZERO (& pageCountCache , sizeof (pageCountCache ));
239+ pageCountCache .valid = true;
240+ }
241+ pageCountCache .pageCounts [itemIdx ] = pageCount ;
242+ if (itemIdx >= pageCountCache .itemCount ) {
243+ pageCountCache .itemCount = itemIdx + 1 ;
244+ }
245+ }
246+ return pageCount ;
247+ }
248+ return 0 ;
249+ }
250+
212251static uint8_t get_pair_number () {
213252 uint8_t numItems = 0 ;
214253 uint8_t numPairs = 0 ;
215254 viewdata .viewfuncGetNumItems (& numItems );
255+
256+ // Use cached page counts to avoid re-parsing
216257 for (uint8_t i = 0 ; i < numItems ; i ++ ) {
217- viewdata .viewfuncGetItem (i , viewdata .key , MAX_CHARS_PER_KEY_LINE , viewdata .value , MAX_CHARS_PER_VALUE1_LINE , 0 ,
218- & viewdata .pageCount );
219- numPairs += viewdata .pageCount ;
258+ uint8_t pageCount = get_item_page_count (i );
259+ numPairs += pageCount ;
220260 }
221261 return numPairs ;
222262}
@@ -244,15 +284,16 @@ zxerr_t h_review_update_data() {
244284
245285 uint8_t accPages = 0 ;
246286 for (uint8_t i = 0 ; i < viewdata .itemCount ; i ++ ) {
247- CHECK_ZXERR ( viewdata . viewfuncGetItem ( i , viewdata . key , MAX_CHARS_PER_KEY_LINE , viewdata . value ,
248- MAX_CHARS_PER_VALUE1_LINE , 0 , & viewdata .pageCount ))
287+ // Use cached page count to avoid unnecessary re-parsing
288+ viewdata .pageCount = get_item_page_count ( i );
249289 if (viewdata .pageCount == 0 ) {
250290 ZEMU_LOGF (50 , "pageCount is 0!" )
251291 return zxerr_no_data ;
252292 }
253293
254294 if (accPages + viewdata .pageCount > viewdata .itemIdx ) {
255295 const uint8_t innerIdx = viewdata .itemIdx - accPages ;
296+ // Only call viewfuncGetItem when we actually need to display this page
256297 CHECK_ZXERR (viewdata .viewfuncGetItem (i , viewdata .key , MAX_CHARS_PER_KEY_LINE , viewdata .value ,
257298 MAX_CHARS_PER_VALUE1_LINE , innerIdx , & viewdata .pageCount ))
258299 if (viewdata .pageCount > 1 ) {
@@ -557,6 +598,10 @@ void view_review_show_impl(unsigned int requireReply, const char *title, const c
557598 }
558599 h_paging_init ();
559600
601+ // Invalidate page count cache for new review
602+ pageCountCache .valid = false;
603+ pageCountCache .itemCount = 0 ;
604+
560605 switch (review_type ) {
561606 case REVIEW_UI :
562607 nbgl_useCaseReviewStart (& C_ICON , "Review configuration" , NULL , CANCEL_LABEL , review_configuration ,
@@ -645,6 +690,10 @@ void view_review_show_with_intent_impl(unsigned int requireReply, const char *in
645690
646691 h_paging_init ();
647692
693+ // Invalidate page count cache for new review
694+ pageCountCache .valid = false;
695+ pageCountCache .itemCount = 0 ;
696+
648697 switch (review_type ) {
649698 case REVIEW_MSG : {
650699 config_useCaseMessageReview ();
0 commit comments