@@ -70,28 +70,68 @@ class _AppView extends StatefulWidget {
70
70
71
71
class _AppViewState extends State <_AppView > {
72
72
late final GoRouter _router;
73
- late final ValueNotifier <AppStatus > _statusNotifier;
73
+ // Notifier that GoRouter listens to. We control its value.
74
+ late final ValueNotifier <AppStatus > _routerNotifier;
74
75
StreamSubscription <PendingDynamicLinkData >? _linkSubscription;
75
76
77
+ // Flags to manage splash screen duration
78
+ bool _isAuthStatusKnown = false ;
79
+ bool _isMinTimeElapsed = false ;
80
+ // Store the actual latest status from AppBloc
81
+ AppStatus _currentAppStatus = AppStatus .initial;
82
+
83
+ // Minimum splash duration
84
+ static const _minSplashDuration = Duration (seconds: 2 );
85
+
76
86
@override
77
87
void initState () {
78
88
super .initState ();
79
89
final appBloc = context.read <AppBloc >();
80
- _statusNotifier = ValueNotifier <AppStatus >(appBloc.state.status);
81
- _router = createRouter (authStatusNotifier: _statusNotifier);
90
+ _currentAppStatus = appBloc.state.status; // Store initial status
91
+ // Initialize the router notifier with the initial status
92
+ _routerNotifier = ValueNotifier <AppStatus >(_currentAppStatus);
93
+ _router = createRouter (authStatusNotifier: _routerNotifier);
94
+
95
+ // Start the minimum time timer
96
+ Future .delayed (_minSplashDuration, () {
97
+ if (mounted) {
98
+ setState (() {
99
+ _isMinTimeElapsed = true ;
100
+ });
101
+ _updateRouterNotifier (); // Check if we can navigate away
102
+ }
103
+ });
82
104
83
105
// --- Initialize Deep Link Handling ---
84
106
_initDynamicLinks ();
85
107
// ------------------------------------
108
+
109
+ // Initial check in case status is already known *at the end of initState*
110
+ if (_currentAppStatus != AppStatus .initial) {
111
+ _isAuthStatusKnown = true ;
112
+ _updateRouterNotifier ();
113
+ }
86
114
}
87
115
88
116
@override
89
117
void dispose () {
90
118
_linkSubscription? .cancel ();
91
- _statusNotifier .dispose ();
119
+ _routerNotifier .dispose (); // Dispose the correct notifier
92
120
super .dispose ();
93
121
}
94
122
123
+ /// Checks conditions and updates the router notifier if ready.
124
+ void _updateRouterNotifier () {
125
+ // Only update the router notifier (triggering redirect) if both
126
+ // minimum time has passed AND the auth status is known.
127
+ if (_isMinTimeElapsed && _isAuthStatusKnown) {
128
+ // Update with the *actual* current status
129
+ _routerNotifier.value = _currentAppStatus;
130
+ }
131
+ // Otherwise, the router notifier remains AppStatus.initial, keeping
132
+ // the user on the splash screen.
133
+ }
134
+
95
135
/// Initializes Firebase Dynamic Links listeners.
96
136
Future <void > _initDynamicLinks () async {
97
137
// Handle links received while the app is running
@@ -168,13 +208,31 @@ class _AppViewState extends State<_AppView> {
168
208
// The BlocBuilder remains for theme changes.
169
209
return BlocListener <AppBloc , AppState >(
170
210
// Only listen when the status actually changes
171
- listenWhen : (previous, current) => previous. status != current.status,
211
+ // Listen to all status changes from AppBloc
172
212
listener: (context, state) {
173
- // Update the ValueNotifier when the AppBloc status changes.
174
- // This triggers the GoRouter's refreshListenable.
175
- _statusNotifier.value = state.status;
213
+ // Store the latest actual status
214
+ _currentAppStatus = state.status;
215
+
216
+ // If the status is no longer initial, mark it as known
217
+ if (state.status != AppStatus .initial) {
218
+ if (! _isAuthStatusKnown) { // Only update state if it changes
219
+ setState (() {
220
+ _isAuthStatusKnown = true ;
221
+ });
222
+ }
223
+ _updateRouterNotifier (); // Check if we can navigate away
224
+ }
225
+ // If the status somehow reverts to initial (unlikely), reset flag
226
+ else if (_isAuthStatusKnown) {
227
+ setState (() {
228
+ _isAuthStatusKnown = false ;
229
+ });
230
+ // Ensure router notifier reflects initial state again
231
+ _routerNotifier.value = AppStatus .initial;
232
+ }
176
233
},
177
234
child: BlocBuilder <AppBloc , AppState >(
235
+ // Build only for theme changes, listener handles status
178
236
buildWhen:
179
237
(previous, current) => previous.themeMode != current.themeMode,
180
238
builder: (context, state) {
0 commit comments