Skip to content

Commit a79e439

Browse files
committed
refactor(app): improve comments and structure in _AppViewState
- Enhance comments to explain the purpose and functionality of key widgets - Reorganize comment sections for better clarity and flow - Add explanations for the use of separate MaterialApp widgets - Clarify the theme configuration process for different app states - Emphasize the importance of the stable main application UI root
1 parent 513063b commit a79e439

File tree

1 file changed

+39
-10
lines changed

1 file changed

+39
-10
lines changed

lib/app/view/app.dart

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -184,17 +184,22 @@ class _AppViewState extends State<_AppView> {
184184
@override
185185
Widget build(BuildContext context) {
186186
// Wrap the part of the tree that needs to react to AppBloc state changes
187-
// (specifically for updating the ValueNotifier) with a BlocListener.
188-
// The BlocBuilder remains for theme changes.
187+
// with a BlocListener and a BlocBuilder.
189188
return BlocListener<AppBloc, AppState>(
190-
// Listen for status changes to update the GoRouter's ValueNotifier
189+
// The BlocListener's primary role here is to keep GoRouter's refresh
190+
// mechanism informed about authentication status changes.
191+
// GoRouter's `redirect` logic depends on this notifier to re-evaluate
192+
// routes when the user logs in or out *while the app is running*.
191193
listenWhen: (previous, current) => previous.status != current.status,
192194
listener: (context, state) {
193195
_statusNotifier.value = state.status;
194196
},
195197
// The BlocBuilder is the core of the new stable startup architecture.
196-
// It acts as a high-level switch that determines which UI to show based
197-
// on the application's status.
198+
// It functions as a "master switch" for the entire application's UI.
199+
// Based on the AppStatus, it decides whether to show a full-screen
200+
// status page (like Maintenance or Loading) or to build the main
201+
// application UI with its nested router. This approach is fundamental
202+
// to fixing the original race conditions and BuildContext instability.
198203
child: BlocBuilder<AppBloc, AppState>(
199204
builder: (context, state) {
200205
// --- Full-Screen Status Pages ---
@@ -205,7 +210,19 @@ class _AppViewState extends State<_AppView> {
205210

206211
if (state.status == AppStatus.underMaintenance) {
207212
// The app is in maintenance mode. Show the MaintenancePage.
208-
// It's wrapped in a basic MaterialApp to provide theme and l10n.
213+
//
214+
// WHY A SEPARATE MATERIALAPP?
215+
// Each status page is wrapped in its own simple MaterialApp to create
216+
// a self-contained environment. This provides the necessary
217+
// Directionality, theme, and localization context for the page
218+
// to render correctly, without needing the main app's router.
219+
//
220+
// WHY A DEFAULT THEME?
221+
// The theme uses hardcoded, sensible defaults (like FlexScheme.material)
222+
// because at this early stage, we only need a basic visual structure.
223+
// However, we critically use `state.themeMode` and `state.locale`,
224+
// which are loaded from user settings *before* the maintenance check,
225+
// ensuring the page respects the user's chosen light/dark mode and language.
209226
return MaterialApp(
210227
debugShowCheckedModeBanner: false,
211228
theme: lightTheme(
@@ -223,6 +240,7 @@ class _AppViewState extends State<_AppView> {
223240
themeMode: state.themeMode,
224241
localizationsDelegates: AppLocalizations.localizationsDelegates,
225242
supportedLocales: AppLocalizations.supportedLocales,
243+
locale: state.locale,
226244
home: const MaintenancePage(),
227245
);
228246
}
@@ -246,6 +264,7 @@ class _AppViewState extends State<_AppView> {
246264
themeMode: state.themeMode,
247265
localizationsDelegates: AppLocalizations.localizationsDelegates,
248266
supportedLocales: AppLocalizations.supportedLocales,
267+
locale: state.locale,
249268
home: const UpdateRequiredPage(),
250269
);
251270
}
@@ -272,18 +291,28 @@ class _AppViewState extends State<_AppView> {
272291
themeMode: state.themeMode,
273292
localizationsDelegates: AppLocalizations.localizationsDelegates,
274293
supportedLocales: AppLocalizations.supportedLocales,
294+
locale: state.locale,
275295
home: const StatusPage(),
276296
);
277297
}
278298

279299
// --- Main Application UI ---
280300
// If none of the critical states above are met, the app is ready
281301
// to display its main UI. We build the MaterialApp.router here.
302+
// This is the single, STABLE root widget for the entire main app.
282303
//
283-
// This is the STABLE root of the main application. Because it is
284-
// only built when the app is in a "running" state, it will not be
285-
// destroyed and rebuilt during startup, which fixes the
286-
// `BuildContext` instability and related crashes.
304+
// WHY IS THIS SO IMPORTANT?
305+
// Because this widget is now built conditionally inside a single
306+
// BlocBuilder, it is created only ONCE when the app enters a
307+
// "running" state (e.g., authenticated, anonymous). It is no longer
308+
// destroyed and rebuilt during startup, which was the root cause of
309+
// the `BuildContext` instability and the `l10n` crashes.
310+
//
311+
// THEME CONFIGURATION:
312+
// Unlike the status pages, this MaterialApp is themed using the full,
313+
// detailed settings loaded into the AppState (e.g., `state.flexScheme`,
314+
// `state.settings.displaySettings...`), providing the complete,
315+
// personalized user experience.
287316
return MaterialApp.router(
288317
debugShowCheckedModeBanner: false,
289318
themeMode: state.themeMode,

0 commit comments

Comments
 (0)