@@ -67,45 +67,53 @@ static void flytrap_dash_refresh(FlytrapApp* app) {
6767 furi_string_free (tmp );
6868}
6969
70- // Shown while the portal is coming up — the ESP handshake plus the ~3s it takes
71- // to stream the portal HTML over UART (which blocks the UI), so the user sees
72- // progress instead of a frozen dashboard.
73- static void flytrap_loading_render (FlytrapApp * app ) {
70+ // A centered status card (title + divider + two lines). Used for the detecting /
71+ // no-board / starting screens so a blocking step never shows a blank frame.
72+ static void flytrap_status_screen (FlytrapApp * app , const char * l1 , const char * l2 ) {
7473 widget_reset (app -> widget );
7574 widget_add_string_element (app -> widget , 64 , 6 , AlignCenter , AlignTop , FontPrimary , "Flytrap" );
7675 widget_add_line_element (app -> widget , 0 , 20 , 127 , 20 );
77- widget_add_string_element (
78- app -> widget , 64 , 25 , AlignCenter , AlignTop , FontSecondary , "Starting portal..." );
79- FuriString * tmp = furi_string_alloc ();
80- furi_string_printf (tmp , "SSID: %s" , furi_string_get_cstr (app -> ssid ));
81- widget_add_string_element (
82- app -> widget , 64 , 38 , AlignCenter , AlignTop , FontSecondary , furi_string_get_cstr (tmp ));
83- widget_add_string_element (
84- app -> widget , 64 , 51 , AlignCenter , AlignTop , FontSecondary , "Bringing up Wi-Fi" );
85- furi_string_free (tmp );
76+ widget_add_string_element (app -> widget , 64 , 27 , AlignCenter , AlignTop , FontSecondary , l1 );
77+ if (l2 && l2 [0 ])
78+ widget_add_string_element (app -> widget , 64 , 42 , AlignCenter , AlignTop , FontSecondary , l2 );
8679}
8780
88- // Loading screen until the portal is broadcasting (or errors), then the dashboard.
81+ // Render the screen for the current start state: detecting / no-board / starting,
82+ // then the dashboard once broadcasting (or on error / a lost board link).
8983static void flytrap_live_render (FlytrapApp * app ) {
84+ const char * s = furi_string_get_cstr (app -> status );
85+ if (strcmp (s , "detecting" ) == 0 ) {
86+ flytrap_status_screen (app , "Detecting board..." , "" );
87+ return ;
88+ }
89+ if (strcmp (s , "noboard" ) == 0 ) {
90+ flytrap_status_screen (app , "No board detected" , "Attach the ESP32 board" );
91+ return ;
92+ }
9093 bool live = false;
91- flytrap_state_label (furi_string_get_cstr ( app -> status ) , & live );
92- bool err = strstr (furi_string_get_cstr ( app -> status ) , "err" ) != NULL ;
94+ flytrap_state_label (s , & live );
95+ bool err = strstr (s , "err" ) != NULL ;
9396 if (live || err || app -> link_lost ) {
9497 flytrap_dash_refresh (app );
9598 } else {
96- flytrap_loading_render (app );
99+ FuriString * tmp = furi_string_alloc ();
100+ furi_string_printf (tmp , "SSID: %s" , furi_string_get_cstr (app -> ssid ));
101+ flytrap_status_screen (app , "Starting portal..." , furi_string_get_cstr (tmp ));
102+ furi_string_free (tmp );
97103 }
98104}
99105
100106void flytrap_scene_live_on_enter (void * context ) {
101107 FlytrapApp * app = context ;
102108 if (!app -> session_active ) {
103- // Fresh start: paint the loading screen first, then kick off the blocking
104- // send on the next event loop pass so it doesn't freeze on a blank frame.
105- furi_string_set (app -> status , "starting" );
106- flytrap_loading_render (app );
109+ // Fresh start: paint "Detecting board..." first, then run the (possibly
110+ // blocking) check on the next loop pass so it doesn't freeze on a blank frame.
111+ app -> awaiting_board = false;
112+ app -> link_lost = false; // clear any stale disconnect from a prior session
113+ furi_string_set (app -> status , "detecting" );
114+ flytrap_live_render (app );
107115 view_dispatcher_switch_to_view (app -> view_dispatcher , FlytrapViewWidget );
108- view_dispatcher_send_custom_event (app -> view_dispatcher , FlytrapEventBeginSend );
116+ view_dispatcher_send_custom_event (app -> view_dispatcher , FlytrapEventDetectBoard );
109117 } else {
110118 flytrap_live_render (app );
111119 view_dispatcher_switch_to_view (app -> view_dispatcher , FlytrapViewWidget );
@@ -116,8 +124,21 @@ bool flytrap_scene_live_on_event(void* context, SceneManagerEvent event) {
116124 FlytrapApp * app = context ;
117125 if (event .type != SceneManagerEventTypeCustom ) return false;
118126 switch (event .event ) {
127+ case FlytrapEventDetectBoard :
128+ if (flytrap_board_present (app , 2500 )) {
129+ furi_string_set (app -> status , "starting" );
130+ flytrap_live_render (app ); // paint "Starting..." before the blocking send
131+ view_dispatcher_send_custom_event (app -> view_dispatcher , FlytrapEventBeginSend );
132+ } else {
133+ // Keep watching: the tick resumes this flow when the board's beacon
134+ // shows up, so plugging it in auto-continues without a Back + Start.
135+ app -> awaiting_board = true;
136+ furi_string_set (app -> status , "noboard" );
137+ flytrap_live_render (app );
138+ }
139+ return true;
119140 case FlytrapEventBeginSend :
120- flytrap_session_start (app ); // blocks while the portal streams; loading stays up
141+ flytrap_session_start (app ); // blocks while the portal streams; "Starting..." stays
121142 flytrap_live_render (app );
122143 return true;
123144 case FlytrapEventRefreshView :
@@ -135,6 +156,7 @@ bool flytrap_scene_live_on_event(void* context, SceneManagerEvent event) {
135156}
136157
137158void flytrap_scene_live_on_exit (void * context ) {
138- UNUSED (context );
159+ FlytrapApp * app = context ;
160+ app -> awaiting_board = false; // stop watching once we leave the start screen
139161 // Session persists across the menu/sub-views; stopped via menu "Stop" or app exit.
140162}
0 commit comments