Skip to content

Commit e745256

Browse files
committed
feature: implemented the splash screen and updated the routing logic
1 parent c58025e commit e745256

File tree

4 files changed

+116
-13
lines changed

4 files changed

+116
-13
lines changed

lib/app/bloc/app_state.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ part of 'app_bloc.dart';
22

33
/// Represents the application's authentication status.
44
enum AppStatus {
5+
/// The application is initializing and the status is unknown.
6+
initial,
7+
58
/// The user is authenticated.
69
authenticated,
710

@@ -16,7 +19,7 @@ class AppState extends Equatable {
1619
AppState({
1720
this.selectedBottomNavigationIndex = 0,
1821
this.themeMode = ThemeMode.system,
19-
this.status = AppStatus.unauthenticated,
22+
this.status = AppStatus.initial, // Default to initial
2023
User? user,
2124
}) : user = user ?? User();
2225

lib/router/router.dart

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import 'package:ht_main/headlines-feed/view/headlines_feed_page.dart';
1515
import 'package:ht_main/headlines-search/view/headlines_search_page.dart';
1616
import 'package:ht_main/l10n/l10n.dart';
1717
import 'package:ht_main/router/routes.dart';
18+
import 'package:ht_main/splash/view/splash_page.dart'; // Import SplashPage
1819

1920
/// Creates and configures the GoRouter instance for the application.
2021
///
@@ -23,7 +24,7 @@ import 'package:ht_main/router/routes.dart';
2324
GoRouter createRouter({required ValueNotifier<AppStatus> authStatusNotifier}) {
2425
return GoRouter(
2526
refreshListenable: authStatusNotifier,
26-
initialLocation: Routes.feed,
27+
initialLocation: Routes.splash, // Set initial location to splash
2728
debugLogDiagnostics: true, // Enable verbose logging for debugging redirects
2829
// --- Redirect Logic ---
2930
redirect: (BuildContext context, GoRouterState state) {
@@ -67,12 +68,48 @@ GoRouter createRouter({required ValueNotifier<AppStatus> authStatusNotifier}) {
6768
// Check if the 'context=linking' query parameter is present in the URI.
6869
final isLinkingContext =
6970
currentUri.queryParameters['context'] == 'linking';
71+
// Check if the current location is the splash screen path.
72+
final isGoingToSplash = currentLocation == Routes.splash;
7073

7174
// --- Redirect Logic based on AppStatus ---
7275

73-
// --- Case 1: Unauthenticated User ---
76+
// --- Case 0: Initial Loading State ---
77+
// While the app is initializing, force the user to the splash screen.
78+
if (appStatus == AppStatus.initial) {
79+
print(' Redirect Decision: AppStatus is INITIAL.');
80+
// If already on splash, stay there.
81+
if (isGoingToSplash) {
82+
print(' Action: Already on splash screen. Allowing navigation.');
83+
return null;
84+
}
85+
// If trying to go anywhere else during initial load, force to splash.
86+
print(' Action: Forcing navigation to splash screen.');
87+
return Routes.splash;
88+
}
89+
90+
// --- Transitioning Away from Splash Screen ---
91+
// Once the status is determined (not initial), if the user is currently
92+
// on the splash screen, redirect them to the appropriate main screen.
93+
if (currentLocation == Routes.splash) {
94+
print(' Redirect Decision: Transitioning AWAY from Splash Screen.');
95+
if (appStatus == AppStatus.unauthenticated) {
96+
print(' Action: Redirecting to $authenticationPath');
97+
return authenticationPath;
98+
} else if (appStatus == AppStatus.authenticated ||
99+
appStatus == AppStatus.anonymous) {
100+
print(' Action: Redirecting to $feedPath');
101+
return feedPath;
102+
}
103+
// Fallback: Should not happen if status is known, but stay on splash if needed.
104+
print(' Action: Unknown status after initial, staying on splash (fallback).');
105+
return null;
106+
}
107+
108+
109+
// --- Case 1: Unauthenticated User (After Initial Load) ---
110+
// If the user is unauthenticated and NOT on the splash screen...
74111
if (appStatus == AppStatus.unauthenticated) {
75-
print(' Redirect Decision: User is UNauthenticated.');
112+
print(' Redirect Decision: User is UNauthenticated (post-initial).');
76113
// If the user is NOT already going to an authentication path...
77114
if (!isGoingToAuth) {
78115
// ...redirect them to the main authentication page to sign in or sign up.
@@ -159,25 +196,31 @@ GoRouter createRouter({required ValueNotifier<AppStatus> authStatusNotifier}) {
159196
);
160197
return null; // Allow access
161198
}
162-
// --- Case 4: Initial/Unknown Status ---
163-
// This might occur briefly during app startup before the status is determined.
164-
// Generally, allow navigation during this phase. If specific routes need
165-
// protection even during startup, add checks here.
199+
// --- Case 4: Fallback (Should not be reached with initial handling) ---
200+
// This case is less likely now with explicit initial handling.
201+
// If somehow the status is unknown after the initial phase, allow navigation.
166202
else {
167-
print(
168-
' Redirect Decision: AppStatus is initial/unknown. Allowing navigation.',
169-
);
170-
return null; // Allow access
203+
print(
204+
' Redirect Decision: AppStatus is UNEXPECTED ($appStatus). Allowing navigation (fallback).',
205+
);
206+
return null; // Allow access as a safe default
171207
}
172208

173-
// --- Default: No Redirect ---
209+
// --- Default: No Redirect (Should not be reached if logic is exhaustive) ---
174210
// If none of the above conditions triggered an explicit redirect, allow navigation.
175211
// This line should theoretically not be reached if the logic above is exhaustive.
176212
// print(' Redirect Decision: No specific redirect condition met. Allowing navigation.');
177213
// return null; // Allow access (already covered by the final return null below)
178214
},
179215
// --- Routes ---
180216
routes: [
217+
// --- Splash Screen Route ---
218+
GoRoute(
219+
path: Routes.splash,
220+
name: Routes.splashName,
221+
builder: (context, state) => const SplashPage(),
222+
),
223+
// --- Authentication Routes ---
181224
GoRoute(
182225
path: Routes.authentication,
183226
name: Routes.authenticationName,

lib/router/routes.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
abstract final class Routes {
2+
// --- Splash Screen ---
3+
static const splash = '/splash';
4+
static const splashName = 'splash';
5+
26
// --- Core App Routes ---
37
static const feed = '/feed';
48
static const feedName = 'feed';

lib/splash/view/splash_page.dart

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:ht_main/shared/constants/app_spacing.dart'; // Assuming spacing constants exist
3+
4+
/// A simple splash screen displayed during app initialization.
5+
class SplashPage extends StatelessWidget {
6+
/// Creates a [SplashPage].
7+
const SplashPage({super.key});
8+
9+
@override
10+
Widget build(BuildContext context) {
11+
final theme = Theme.of(context);
12+
final colorScheme = theme.colorScheme;
13+
final textTheme = theme.textTheme;
14+
15+
return Scaffold(
16+
body: Center(
17+
child: Padding(
18+
// Add horizontal padding for content safety
19+
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.lg), // Corrected constant
20+
child: Column(
21+
mainAxisAlignment: MainAxisAlignment.center,
22+
children: [
23+
// Icon representing news/articles
24+
Icon(
25+
Icons.article_outlined,
26+
size: 64.0,
27+
color: colorScheme.primary, // Use primary theme color
28+
),
29+
const SizedBox(height: AppSpacing.xl), // Use defined spacing
30+
31+
// App Title
32+
Text(
33+
'Headlines Toolkit', // App Name
34+
style: textTheme.headlineMedium, // Use theme text style
35+
textAlign: TextAlign.center,
36+
),
37+
const SizedBox(height: AppSpacing.md), // Use defined spacing
38+
39+
// Subheadline/Tagline
40+
Text(
41+
'Develop News Headlines Apps Rapidly & Reliably.', // Tagline
42+
style: textTheme.bodyLarge?.copyWith(
43+
color: colorScheme.secondary, // Use secondary theme color
44+
),
45+
textAlign: TextAlign.center,
46+
),
47+
],
48+
),
49+
),
50+
),
51+
);
52+
}
53+
}

0 commit comments

Comments
 (0)