|
1 |
| -// Required for StreamSubscription |
2 |
| - |
3 | 1 | import 'package:flex_color_scheme/flex_color_scheme.dart';
|
4 |
| -// Required for Listenable |
5 | 2 | import 'package:flutter/material.dart';
|
6 | 3 | import 'package:flutter_bloc/flutter_bloc.dart';
|
7 |
| -import 'package:go_router/go_router.dart'; // Import GoRouter |
| 4 | +import 'package:go_router/go_router.dart'; |
8 | 5 | import 'package:google_fonts/google_fonts.dart';
|
9 | 6 | import 'package:ht_authentication_repository/ht_authentication_repository.dart';
|
10 | 7 | import 'package:ht_headlines_repository/ht_headlines_repository.dart';
|
11 | 8 | import 'package:ht_main/app/bloc/app_bloc.dart';
|
12 | 9 | import 'package:ht_main/l10n/l10n.dart';
|
13 |
| -// Import the createRouter function and the helper stream |
14 |
| -import 'package:ht_main/router/go_router_refresh_stream.dart'; |
15 | 10 | import 'package:ht_main/router/router.dart';
|
16 |
| -// Routes class is still needed if createRouter uses it, which it does |
17 | 11 |
|
18 | 12 | class App extends StatelessWidget {
|
19 | 13 | const App({
|
20 | 14 | required HtHeadlinesRepository htHeadlinesRepository,
|
21 | 15 | required HtAuthenticationRepository htAuthenticationRepository,
|
22 |
| - // AppBloc is no longer passed in constructor |
23 | 16 | super.key,
|
24 | 17 | }) : _htHeadlinesRepository = htHeadlinesRepository,
|
25 | 18 | _htAuthenticationRepository = htAuthenticationRepository;
|
26 | 19 |
|
27 | 20 | final HtHeadlinesRepository _htHeadlinesRepository;
|
28 | 21 | final HtAuthenticationRepository _htAuthenticationRepository;
|
29 |
| - // No longer storing AppBloc instance here |
30 | 22 |
|
31 | 23 | @override
|
32 | 24 | Widget build(BuildContext context) {
|
33 |
| - // Provide repositories globally |
34 | 25 | return MultiRepositoryProvider(
|
35 | 26 | providers: [
|
36 | 27 | RepositoryProvider.value(value: _htHeadlinesRepository),
|
37 | 28 | RepositoryProvider.value(value: _htAuthenticationRepository),
|
38 | 29 | ],
|
39 |
| - // Create AppBloc here using BlocProvider |
40 | 30 | child: BlocProvider(
|
41 | 31 | create: (context) => AppBloc(
|
42 | 32 | authenticationRepository: context.read<HtAuthenticationRepository>(),
|
43 | 33 | ),
|
44 |
| - // _AppView now reads AppBloc from context |
45 | 34 | child: const _AppView(),
|
46 | 35 | ),
|
47 | 36 | );
|
48 | 37 | }
|
49 | 38 | }
|
50 | 39 |
|
51 |
| -// Change _AppView to StatefulWidget to manage GoRouter lifecycle |
52 | 40 | class _AppView extends StatefulWidget {
|
53 |
| - const _AppView(); // No longer needs appBloc passed |
| 41 | + const _AppView(); |
54 | 42 |
|
55 | 43 | @override
|
56 | 44 | State<_AppView> createState() => _AppViewState();
|
57 | 45 | }
|
58 | 46 |
|
59 | 47 | class _AppViewState extends State<_AppView> {
|
60 |
| - // Store the router and the refresh stream listener |
| 48 | + // Store the router and the status notifier |
61 | 49 | late final GoRouter _router;
|
62 |
| - late final GoRouterRefreshStream _refreshListener; |
| 50 | + late final ValueNotifier<AppStatus> _statusNotifier; |
63 | 51 |
|
64 | 52 | @override
|
65 | 53 | void initState() {
|
66 | 54 | super.initState();
|
67 | 55 | // Get the AppBloc instance from the BlocProvider above
|
68 | 56 | final appBloc = context.read<AppBloc>();
|
69 |
| - // Create the refresh listener using the AppBloc stream |
70 |
| - _refreshListener = GoRouterRefreshStream(appBloc.stream); |
71 |
| - // Create the router instance by calling the function from router.dart |
72 |
| - _router = createRouter(refreshListenable: _refreshListener); |
| 57 | + |
| 58 | + // Create the ValueNotifier, initialized with the current status |
| 59 | + _statusNotifier = ValueNotifier<AppStatus>(appBloc.state.status); |
| 60 | + |
| 61 | + // Create the router instance, passing the ValueNotifier as the listenable |
| 62 | + _router = createRouter(authStatusNotifier: _statusNotifier); |
73 | 63 | }
|
74 | 64 |
|
75 | 65 | @override
|
76 | 66 | void dispose() {
|
77 |
| - // Dispose the refresh listener when the widget is disposed |
78 |
| - _refreshListener.dispose(); |
| 67 | + // Remove subscription cancellation |
| 68 | + // _blocSubscription.cancel(); |
| 69 | + // Dispose the ValueNotifier |
| 70 | + _statusNotifier.dispose(); |
79 | 71 | super.dispose();
|
80 | 72 | }
|
81 | 73 |
|
82 | 74 | @override
|
83 | 75 | Widget build(BuildContext context) {
|
84 |
| - // Use BlocBuilder to react to theme changes from AppBloc |
85 |
| - return BlocBuilder<AppBloc, AppState>( |
86 |
| - // Use buildWhen for optimization if only theme affects MaterialApp |
87 |
| - buildWhen: (previous, current) => previous.themeMode != current.themeMode, |
88 |
| - builder: (context, state) { |
89 |
| - return MaterialApp.router( |
90 |
| - debugShowCheckedModeBanner: false, |
91 |
| - // Apply theme based on AppBloc state |
92 |
| - themeMode: state.themeMode, |
93 |
| - theme: lightTheme(), |
94 |
| - darkTheme: darkTheme(), |
95 |
| - // Use the router created and stored in the state |
96 |
| - routerConfig: _router, |
97 |
| - localizationsDelegates: AppLocalizations.localizationsDelegates, |
98 |
| - supportedLocales: AppLocalizations.supportedLocales, |
99 |
| - ); |
| 76 | + // Wrap the part of the tree that needs to react to AppBloc state changes |
| 77 | + // (specifically for updating the ValueNotifier) with a BlocListener. |
| 78 | + // The BlocBuilder remains for theme changes. |
| 79 | + return BlocListener<AppBloc, AppState>( |
| 80 | + // Only listen when the status actually changes |
| 81 | + listenWhen: (previous, current) => previous.status != current.status, |
| 82 | + listener: (context, state) { |
| 83 | + // Update the ValueNotifier when the AppBloc status changes. |
| 84 | + // This triggers the GoRouter's refreshListenable. |
| 85 | + _statusNotifier.value = state.status; |
100 | 86 | },
|
| 87 | + child: BlocBuilder<AppBloc, AppState>( |
| 88 | + buildWhen: (previous, current) => |
| 89 | + previous.themeMode != current.themeMode, |
| 90 | + builder: (context, state) { |
| 91 | + return MaterialApp.router( |
| 92 | + debugShowCheckedModeBanner: false, |
| 93 | + themeMode: state.themeMode, |
| 94 | + theme: lightTheme(), |
| 95 | + darkTheme: darkTheme(), |
| 96 | + routerConfig: _router, |
| 97 | + localizationsDelegates: AppLocalizations.localizationsDelegates, |
| 98 | + supportedLocales: AppLocalizations.supportedLocales, |
| 99 | + ); |
| 100 | + }, |
| 101 | + ), |
101 | 102 | );
|
102 | 103 | }
|
103 | 104 | }
|
104 | 105 |
|
105 |
| -// --- Themes (unchanged) --- |
106 | 106 | ThemeData lightTheme() {
|
107 | 107 | return FlexThemeData.light(
|
108 |
| - scheme: FlexScheme.greyLaw, |
| 108 | + scheme: FlexScheme.material, |
109 | 109 | fontFamily: GoogleFonts.notoSans().fontFamily,
|
110 | 110 | );
|
111 | 111 | }
|
112 | 112 |
|
113 | 113 | ThemeData darkTheme() {
|
114 | 114 | return FlexThemeData.dark(
|
115 |
| - scheme: FlexScheme.greyLaw, |
| 115 | + scheme: FlexScheme.material, |
116 | 116 | fontFamily: GoogleFonts.notoSans().fontFamily,
|
117 | 117 | );
|
118 | 118 | }
|
0 commit comments