Skip to content

Commit f761edb

Browse files
committed
feat: handle app config loading states
- Added loading and failure widgets - Showed loading screen while fetching - Displayed error on config failure
1 parent 7a10ca4 commit f761edb

File tree

1 file changed

+87
-16
lines changed

1 file changed

+87
-16
lines changed

lib/app/view/app.dart

Lines changed: 87 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//
22
// ignore_for_file: deprecated_member_use
33

4+
import 'package:flex_color_scheme/flex_color_scheme.dart'; // Added
45
import 'package:flutter/material.dart';
56
import 'package:flutter_bloc/flutter_bloc.dart';
67
import 'package:go_router/go_router.dart';
@@ -12,6 +13,8 @@ import 'package:ht_main/authentication/bloc/authentication_bloc.dart';
1213
import 'package:ht_main/l10n/l10n.dart';
1314
import 'package:ht_main/router/router.dart';
1415
import 'package:ht_main/shared/theme/app_theme.dart';
16+
import 'package:ht_main/shared/widgets/failure_state_widget.dart'; // Added
17+
import 'package:ht_main/shared/widgets/loading_state_widget.dart'; // Added
1518
import 'package:ht_shared/ht_shared.dart'; // Shared models, FromJson, ToJson, etc.
1619

1720
class App extends StatelessWidget {
@@ -168,24 +171,93 @@ class _AppViewState extends State<_AppView> {
168171
// (specifically for updating the ValueNotifier) with a BlocListener.
169172
// The BlocBuilder remains for theme changes.
170173
return BlocListener<AppBloc, AppState>(
171-
// Only listen when the status actually changes
174+
// Listen for status changes to update the GoRouter's ValueNotifier
172175
listenWhen: (previous, current) => previous.status != current.status,
173176
listener: (context, state) {
174-
// Directly update the ValueNotifier when the AppBloc status changes.
175-
// This triggers the GoRouter's refreshListenable.
176177
_statusNotifier.value = state.status;
177178
},
178179
child: BlocBuilder<AppBloc, AppState>(
179-
// Build when theme-related properties change (including text scale factor)
180-
buildWhen:
181-
(previous, current) =>
182-
previous.themeMode != current.themeMode ||
183-
previous.flexScheme != current.flexScheme ||
184-
previous.fontFamily != current.fontFamily ||
185-
previous.appTextScaleFactor != current.appTextScaleFactor ||
186-
previous.locale != current.locale ||
187-
previous.settings != current.settings, // Added settings check
180+
// Rebuild the UI based on AppBloc's state (theme, locale, and critical app statuses)
188181
builder: (context, state) {
182+
// Defer l10n access until inside a MaterialApp context
183+
184+
// Handle critical AppConfig loading states globally
185+
if (state.status == AppStatus.configFetching) {
186+
return MaterialApp(
187+
debugShowCheckedModeBanner: false,
188+
theme: lightTheme(
189+
scheme: FlexScheme.material, // Default scheme
190+
appTextScaleFactor: AppTextScaleFactor.medium, // Default
191+
appFontWeight: AppFontWeight.regular, // Default
192+
fontFamily: null, // System default font
193+
),
194+
darkTheme: darkTheme(
195+
scheme: FlexScheme.material, // Default scheme
196+
appTextScaleFactor: AppTextScaleFactor.medium, // Default
197+
appFontWeight: AppFontWeight.regular, // Default
198+
fontFamily: null, // System default font
199+
),
200+
themeMode: state.themeMode, // Still respect light/dark if available from system
201+
localizationsDelegates: AppLocalizations.localizationsDelegates,
202+
supportedLocales: AppLocalizations.supportedLocales,
203+
home: Scaffold(
204+
body: Builder( // Use Builder to get context under MaterialApp
205+
builder: (innerContext) {
206+
final l10n = innerContext.l10n;
207+
return LoadingStateWidget(
208+
icon: Icons.settings_applications_outlined,
209+
headline: l10n.headlinesFeedLoadingHeadline, // "Loading..."
210+
subheadline: l10n.pleaseWait, // "Please wait..."
211+
);
212+
},
213+
),
214+
),
215+
);
216+
}
217+
218+
if (state.status == AppStatus.configFetchFailed) {
219+
return MaterialApp(
220+
debugShowCheckedModeBanner: false,
221+
theme: lightTheme(
222+
scheme: FlexScheme.material, // Default scheme
223+
appTextScaleFactor: AppTextScaleFactor.medium, // Default
224+
appFontWeight: AppFontWeight.regular, // Default
225+
fontFamily: null, // System default font
226+
),
227+
darkTheme: darkTheme(
228+
scheme: FlexScheme.material, // Default scheme
229+
appTextScaleFactor: AppTextScaleFactor.medium, // Default
230+
appFontWeight: AppFontWeight.regular, // Default
231+
fontFamily: null, // System default font
232+
),
233+
themeMode: state.themeMode,
234+
localizationsDelegates: AppLocalizations.localizationsDelegates,
235+
supportedLocales: AppLocalizations.supportedLocales,
236+
home: Scaffold(
237+
body: Builder( // Use Builder to get context under MaterialApp
238+
builder: (innerContext) {
239+
final l10n = innerContext.l10n;
240+
return FailureStateWidget(
241+
message: l10n.unknownError, // "An unknown error occurred."
242+
retryButtonText: "Retry", // Hardcoded for now
243+
onRetry: () {
244+
// Use outer context for BLoC access
245+
context
246+
.read<AppBloc>()
247+
.add(const AppConfigFetchRequested());
248+
},
249+
);
250+
},
251+
),
252+
),
253+
);
254+
}
255+
256+
// If config is loaded (or not in a failed/fetching state for config), proceed with main app UI
257+
// It's safe to access l10n here if needed for print statements,
258+
// as this path implies we are about to build the main MaterialApp.router
259+
// which provides localizations.
260+
// final l10n = context.l10n;
189261
print('[_AppViewState] Building MaterialApp.router');
190262
print('[_AppViewState] state.fontFamily: ${state.fontFamily}');
191263
print(
@@ -197,23 +269,22 @@ class _AppViewState extends State<_AppView> {
197269
return MaterialApp.router(
198270
debugShowCheckedModeBanner: false,
199271
themeMode: state.themeMode,
200-
// Pass scheme and font family from state to theme functions
201272
theme: lightTheme(
202273
scheme: state.flexScheme,
203274
appTextScaleFactor:
204275
state.settings.displaySettings.textScaleFactor,
205-
appFontWeight: state.settings.displaySettings.fontWeight, // Added
276+
appFontWeight: state.settings.displaySettings.fontWeight,
206277
fontFamily: state.settings.displaySettings.fontFamily,
207278
),
208279
darkTheme: darkTheme(
209280
scheme: state.flexScheme,
210281
appTextScaleFactor:
211282
state.settings.displaySettings.textScaleFactor,
212-
appFontWeight: state.settings.displaySettings.fontWeight, // Added
283+
appFontWeight: state.settings.displaySettings.fontWeight,
213284
fontFamily: state.settings.displaySettings.fontFamily,
214285
),
215286
routerConfig: _router,
216-
locale: state.locale, // Use locale from AppBloc state
287+
locale: state.locale,
217288
localizationsDelegates: AppLocalizations.localizationsDelegates,
218289
supportedLocales: AppLocalizations.supportedLocales,
219290
);

0 commit comments

Comments
 (0)