refactored lesson details, centralized logout logic, and added resume re-fetch
This commit is contained in:
+61
-1
@@ -15,6 +15,7 @@ import 'package:jiffy/jiffy.dart';
|
||||
import 'package:loader_overlay/loader_overlay.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'api/mhsl/breaker/get_breakers/get_breakers_response.dart';
|
||||
import 'app.dart';
|
||||
@@ -33,6 +34,7 @@ import 'theming/light_app_theme.dart';
|
||||
import 'view/login/login.dart';
|
||||
import 'widget/app_progress_indicator.dart';
|
||||
import 'widget/breaker/breaker.dart';
|
||||
import 'widget/debug/cache_view.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
log('MarianumMobile started');
|
||||
@@ -160,7 +162,40 @@ class _MainState extends State<Main> {
|
||||
home: LoaderOverlay(
|
||||
child: Breaker(
|
||||
breaker: BreakerArea.global,
|
||||
child: BlocBuilder<AccountBloc, AccountState>(
|
||||
child: BlocConsumer<AccountBloc, AccountState>(
|
||||
listenWhen: (previous, current) => previous.status != current.status,
|
||||
listener: (context, accountState) {
|
||||
if (accountState.status != AccountStatus.loggedOut) return;
|
||||
// Routes pushed via AppRoutes (e.g. Settings) live on the
|
||||
// root navigator and survive the home swap below, so they
|
||||
// would still cover the Login screen after logout. Pop
|
||||
// them here so the user immediately sees Login.
|
||||
final navigator = Navigator.of(context);
|
||||
if (navigator.canPop()) {
|
||||
navigator.popUntil((route) => route.isFirst);
|
||||
}
|
||||
// Capture bloc references before the post-frame callback
|
||||
// — by the time it runs the dialog/Settings context is
|
||||
// gone but this listener context is still valid.
|
||||
final settingsCubit = context.read<SettingsCubit>();
|
||||
final timetableBloc = context.read<TimetableBloc>();
|
||||
final chatListBloc = context.read<ChatListBloc>();
|
||||
final chatBloc = context.read<ChatBloc>();
|
||||
final breakerBloc = context.read<BreakerBloc>();
|
||||
// Defer the actual wipe until after this frame so the
|
||||
// App tree (TimetableBloc/ChatListBloc watchers etc.)
|
||||
// is already torn down. Resetting blocs while App is
|
||||
// still in front caused a black-frame race.
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
unawaited(_wipeUserState(
|
||||
settingsCubit: settingsCubit,
|
||||
timetableBloc: timetableBloc,
|
||||
chatListBloc: chatListBloc,
|
||||
chatBloc: chatBloc,
|
||||
breakerBloc: breakerBloc,
|
||||
));
|
||||
});
|
||||
},
|
||||
builder: (context, accountState) {
|
||||
switch (accountState.status) {
|
||||
case AccountStatus.loggedIn:
|
||||
@@ -190,3 +225,28 @@ class _MainState extends State<Main> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _wipeUserState({
|
||||
required SettingsCubit settingsCubit,
|
||||
required TimetableBloc timetableBloc,
|
||||
required ChatListBloc chatListBloc,
|
||||
required ChatBloc chatBloc,
|
||||
required BreakerBloc breakerBloc,
|
||||
}) async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.clear();
|
||||
PaintingBinding.instance.imageCache.clear();
|
||||
await settingsCubit.reset();
|
||||
await Future.wait([
|
||||
timetableBloc.reset(),
|
||||
chatListBloc.reset(),
|
||||
chatBloc.reset(),
|
||||
breakerBloc.reset(),
|
||||
]);
|
||||
await HydratedBloc.storage.clear();
|
||||
await const CacheView().clear();
|
||||
} catch (e, s) {
|
||||
log('User state wipe failed: $e', stackTrace: s);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user