77using Bible . Alarm . Views . General ;
88using Bible . Alarm . ViewModels ;
99using Bible . Alarm . ViewModels . Shared ;
10- using Bible . Alarm . Views . Shared ;
11-
1210#nullable enable
1311
1412namespace Bible . Alarm ;
@@ -19,13 +17,14 @@ public partial class App : Application,
1917 IRecipient < ShowMediaProgressModalMessage > ,
2018 IRecipient < HideMediaProgressModalMessage > ,
2119 IRecipient < ShowToastMessage > ,
22- IRecipient < ClearToastsMessage >
20+ IRecipient < ClearToastsMessage > ,
21+ IRecipient < InitializedMessage >
2322{
2423 private readonly Serilog . ILogger _logger ;
2524 private readonly IServiceProvider _serviceProvider ;
2625
2726 public static bool IsInForeground { get ; set ; } = false ;
28- private INavigation ? _navigation ;
27+ private INavigation ? Navigation => _serviceProvider . GetService < INavigation > ( ) ;
2928
3029 public App ( Serilog . ILogger logger , IServiceProvider serviceProvider )
3130 {
@@ -34,6 +33,10 @@ public App(Serilog.ILogger logger, IServiceProvider serviceProvider)
3433 _serviceProvider = serviceProvider ;
3534 InitializeComponent ( ) ;
3635
36+ // Register for InitializedMessage before bootstrap is called
37+ // This will handle showing HomePage after bootstrap completes
38+ WeakReferenceMessenger . Default . Register < InitializedMessage > ( this ) ;
39+
3740 // Register for modal messages
3841 WeakReferenceMessenger . Default . Register < ShowAlarmModalMessage > ( this ) ;
3942 WeakReferenceMessenger . Default . Register < HideAlarmModalMessage > ( this ) ;
@@ -46,75 +49,31 @@ public App(Serilog.ILogger logger, IServiceProvider serviceProvider)
4649 protected override Window CreateWindow ( IActivationState ? activationState )
4750 {
4851 System . Diagnostics . Debug . WriteLine ( "CreateWindow called!" ) ;
49-
50- var homePage = _serviceProvider . GetRequiredService < Home > ( ) ;
51- var navigationPage = new NavigationPage ( homePage )
52+
53+ var loadingPage = _serviceProvider . GetRequiredService < LoadingPage > ( ) ;
54+ var navigationPage = new NavigationPage ( loadingPage )
5255 {
5356 BarBackgroundColor = Colors . Transparent ,
5457 BarTextColor = Colors . White
5558 } ;
5659
57- // Hide the nav bar on HomePage only
58- NavigationPage . SetHasNavigationBar ( homePage , false ) ;
60+ NavigationPage . SetHasNavigationBar ( loadingPage , false ) ;
5961
60- // Run bootstrapper after navigation page setup for foreground launch
61- // This ensures UI is ready before bootstrap initializes
62- MauiProgram . InitializePlatformBootstrap ( _serviceProvider , isForeground : true ) ;
63-
64- #if IOS
65- // Note: Large titles in MAUI are typically configured via platform-specific code
66- // or using Shell if needed. For now, we'll skip this configuration.
67- #endif
68-
69- _navigation = navigationPage . Navigation ;
70-
71- var window = new Window ( navigationPage ) ;
72-
73- // Initialize services in background
74- _ = Task . Run ( async ( ) =>
75- {
76- try
77- {
78- System . Diagnostics . Debug . WriteLine ( "Starting service initialization..." ) ;
79-
80- var playbackService = _serviceProvider . GetRequiredService < IPlaybackService > ( ) ;
81- if ( playbackService . IsPrepared ) WeakReferenceMessenger . Default . Send ( new ShowAlarmModalMessage ( null ) ) ;
82-
83- await Task . Delay ( 100 ) ; // Small delay to ensure initialization
84-
85- System . Diagnostics . Debug . WriteLine ( "Service initialization completed!" ) ;
86- }
87- catch ( Exception ex )
88- {
89- System . Diagnostics . Debug . WriteLine ( $ "Error in initialization: { ex . Message } ") ;
90- System . Diagnostics . Debug . WriteLine ( $ "Stack trace: { ex . StackTrace } ") ;
91- }
92- } ) ;
93-
94- return window ;
62+ return new Window ( navigationPage ) ;
9563 }
9664
9765 protected override void OnStart ( )
9866 {
9967 IsInForeground = true ;
10068
10169 base . OnStart ( ) ;
70+
71+ MauiProgram . InitializePlatformBootstrap ( _serviceProvider , isForeground : true ) ;
72+
10273 Task . Run ( async ( ) =>
10374 {
10475 try
10576 {
106- // Navigate to home
107- if ( _navigation != null )
108- {
109- await MainThread . InvokeOnMainThreadAsync ( async ( ) =>
110- {
111- while ( _navigation . ModalStack . Count > 0 )
112- await _navigation . PopModalAsync ( ) ;
113-
114- while ( _navigation . NavigationStack . Count > 1 )
115- await _navigation . PopAsync ( ) ;
116- } ) ;
117- }
11877
11978 var playbackService = _serviceProvider . GetRequiredService < IPlaybackService > ( ) ;
12079
@@ -149,8 +108,9 @@ protected override void OnResume()
149108 try
150109 {
151110 var playbackService = _serviceProvider . GetRequiredService < IPlaybackService > ( ) ;
152- // Handle when your app resumes
153- if ( playbackService . IsPrepared ) WeakReferenceMessenger . Default . Send ( new ShowAlarmModalMessage ( null ) ) ;
111+
112+ if ( playbackService . IsPrepared )
113+ WeakReferenceMessenger . Default . Send ( new ShowAlarmModalMessage ( null ) ) ;
154114
155115 await Task . Delay ( 1000 ) ;
156116
@@ -169,29 +129,29 @@ public void Receive(ShowAlarmModalMessage message)
169129 {
170130 _ = MainThread . InvokeOnMainThreadAsync ( async ( ) =>
171131 {
172- if ( _navigation == null ) return ;
132+ if ( Navigation == null ) return ;
173133
174- // Prevent showing alarm modal when playback is not active
175134 var playbackService = _serviceProvider . GetRequiredService < IPlaybackService > ( ) ;
176- if ( ! playbackService . IsPlaying ) return ;
135+ if ( ! playbackService . IsPlaying )
136+ return ;
177137
178- if ( _navigation . ModalStack . LastOrDefault ( ) ? . GetType ( ) == typeof ( AlarmModal ) ) return ;
138+ if ( Navigation . ModalStack . LastOrDefault ( ) ? . GetType ( ) == typeof ( AlarmModal ) ) return ;
179139
180140 var vm = _serviceProvider . GetRequiredService < AlarmViewModal > ( ) ;
181141 var modal = _serviceProvider . GetRequiredService < AlarmModal > ( ) ;
182142 modal . BindingContext = vm ;
183- await _navigation . PushModalAsync ( modal ) ;
143+ await Navigation . PushModalAsync ( modal ) ;
184144 } ) ;
185145 }
186146
187147 public void Receive ( HideAlarmModalMessage message )
188148 {
189149 _ = MainThread . InvokeOnMainThreadAsync ( async ( ) =>
190150 {
191- if ( _navigation == null ) return ;
192- if ( _navigation . ModalStack . Count > 0 )
151+ if ( Navigation == null ) return ;
152+ if ( Navigation . ModalStack . Count > 0 )
193153 {
194- var modal = await _navigation . PopModalAsync ( ) ;
154+ var modal = await Navigation . PopModalAsync ( ) ;
195155 if ( modal . BindingContext is IDisposable disposable ) disposable . Dispose ( ) ;
196156 }
197157 } ) ;
@@ -201,25 +161,25 @@ public void Receive(ShowMediaProgressModalMessage message)
201161 {
202162 _ = MainThread . InvokeOnMainThreadAsync ( async ( ) =>
203163 {
204- if ( _navigation == null ) return ;
164+ if ( Navigation == null ) return ;
205165
206- if ( _navigation . ModalStack . LastOrDefault ( ) ? . GetType ( ) == typeof ( MediaProgressModal ) ) return ;
166+ if ( Navigation . ModalStack . LastOrDefault ( ) ? . GetType ( ) == typeof ( MediaProgressModal ) ) return ;
207167
208168 var vm = _serviceProvider . GetRequiredService < MediaProgressViewModal > ( ) ;
209169 var modal = _serviceProvider . GetRequiredService < MediaProgressModal > ( ) ;
210170 modal . BindingContext = vm ;
211- await _navigation . PushModalAsync ( modal ) ;
171+ await Navigation . PushModalAsync ( modal ) ;
212172 } ) ;
213173 }
214174
215175 public void Receive ( HideMediaProgressModalMessage message )
216176 {
217177 _ = MainThread . InvokeOnMainThreadAsync ( async ( ) =>
218178 {
219- if ( _navigation == null ) return ;
220- if ( _navigation . ModalStack . Count > 0 )
179+ if ( Navigation == null ) return ;
180+ if ( Navigation . ModalStack . Count > 0 )
221181 {
222- var modal = await _navigation . PopModalAsync ( ) ;
182+ var modal = await Navigation . PopModalAsync ( ) ;
223183 if ( modal . BindingContext is IDisposable disposable ) disposable . Dispose ( ) ;
224184 }
225185 } ) ;
@@ -242,4 +202,58 @@ public void Receive(ClearToastsMessage message)
242202 await toastService . Clear ( ) ;
243203 } ) ;
244204 }
205+
206+ public void Receive ( InitializedMessage message )
207+ {
208+ _ = MainThread . InvokeOnMainThreadAsync ( async ( ) =>
209+ {
210+ if ( Navigation == null ) return ;
211+
212+ try
213+ {
214+ var homePage = _serviceProvider . GetRequiredService < Home > ( ) ;
215+
216+ NavigationPage . SetHasNavigationBar ( homePage , false ) ;
217+
218+ await Navigation . PushAsync ( homePage ) ;
219+
220+ // PopAsync removes the TOP page (HomePage), so we need to manipulate the stack differently
221+ var pagesToRemove = Navigation . NavigationStack . Where ( p => p != homePage ) . ToList ( ) ;
222+ foreach ( var page in pagesToRemove )
223+ {
224+ Navigation . RemovePage ( page ) ;
225+ }
226+
227+ if ( homePage . BindingContext is HomeViewModel homeViewModel )
228+ {
229+ await homeViewModel . InitializeAsync ( ) ;
230+ }
231+
232+
233+ _ = Task . Run ( async ( ) =>
234+ {
235+ try
236+ {
237+ System . Diagnostics . Debug . WriteLine ( "Starting service initialization..." ) ;
238+
239+ var playbackService = _serviceProvider . GetRequiredService < IPlaybackService > ( ) ;
240+ if ( playbackService . IsPrepared ) WeakReferenceMessenger . Default . Send ( new ShowAlarmModalMessage ( null ) ) ;
241+
242+ await Task . Delay ( 100 ) ;
243+
244+ System . Diagnostics . Debug . WriteLine ( "Service initialization completed!" ) ;
245+ }
246+ catch ( Exception ex )
247+ {
248+ System . Diagnostics . Debug . WriteLine ( $ "Error in initialization: { ex . Message } ") ;
249+ System . Diagnostics . Debug . WriteLine ( $ "Stack trace: { ex . StackTrace } ") ;
250+ }
251+ } ) ;
252+ }
253+ catch ( Exception e )
254+ {
255+ _logger . Error ( e , "An error happened while showing HomePage after initialization." ) ;
256+ }
257+ } ) ;
258+ }
245259}
0 commit comments