@@ -395,6 +395,15 @@ static address_network_t detect_address_network(const char *data) {
395395 return result ;
396396}
397397
398+ static lv_obj_t * progress_dialog = NULL ;
399+
400+ static void dismiss_progress (void ) {
401+ if (progress_dialog ) {
402+ lv_obj_del (progress_dialog );
403+ progress_dialog = NULL ;
404+ }
405+ }
406+
398407// Classify an already-assembled blob and route it to the matching review
399408// screen. Shared by the QR scanner and the SD-card loader, so it must not touch
400409// any qr_scanner_page_* state — the caller tears the scanner down first. Takes
@@ -504,15 +513,9 @@ static void finish_dispatch(char *qr_content, size_t qr_content_len,
504513
505514// --- Main scanner callback with two-layer detection ---
506515
507- static void return_from_qr_scanner_cb (void ) {
508- if (!qr_scanner_has_completed_result ()) {
509- qr_scanner_page_hide ();
510- qr_scanner_page_destroy ();
511- if (return_callback )
512- return_callback ();
513- return ;
514- }
515-
516+ // Camera teardown plus payload parsing — for large PSBTs this can take over a
517+ // second, so it runs behind the progress dialog from a one-shot timer.
518+ static void process_scan_result (void ) {
516519 int detected_format = qr_scanner_get_format ();
517520
518521 char * qr_content = NULL ;
@@ -597,6 +600,29 @@ static void return_from_qr_scanner_cb(void) {
597600 finish_dispatch (qr_content , qr_content_len , parse_success , detected_format );
598601}
599602
603+ static void deferred_scan_process_cb (lv_timer_t * timer ) {
604+ (void )timer ;
605+ process_scan_result ();
606+ dismiss_progress ();
607+ }
608+
609+ static void return_from_qr_scanner_cb (void ) {
610+ if (!qr_scanner_has_completed_result ()) {
611+ qr_scanner_page_hide ();
612+ qr_scanner_page_destroy ();
613+ if (return_callback )
614+ return_callback ();
615+ return ;
616+ }
617+
618+ // Parsing large PSBTs can take over a second — show a progress dialog and
619+ // defer the work to a one-shot timer so LVGL gets to render it first.
620+ progress_dialog =
621+ dialog_show_progress ("Scan" , "Processing..." , DIALOG_STYLE_OVERLAY );
622+ lv_timer_t * t = lv_timer_create (deferred_scan_process_cb , 50 , NULL );
623+ lv_timer_set_repeat_count (t , 1 );
624+ }
625+
600626// Resets the signed-PSBT export context. A scanned PSBT has no source folder
601627// or file name — a saved signature lands at the card root in binary, unless
602628// layer 2 detects base64 text; a file load passes the folder it came from and
@@ -1465,15 +1491,6 @@ static bool create_psbt_info_display(void) {
14651491 return true;
14661492}
14671493
1468- static lv_obj_t * progress_dialog = NULL ;
1469-
1470- static void dismiss_progress (void ) {
1471- if (progress_dialog ) {
1472- lv_obj_del (progress_dialog );
1473- progress_dialog = NULL ;
1474- }
1475- }
1476-
14771494static void destroy_export_menu (void ) {
14781495 if (export_menu ) {
14791496 ui_menu_destroy (export_menu );
0 commit comments