simplified code across the app and consolidated duplicated helpers
This commit is contained in:
+30
-35
@@ -80,6 +80,25 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
||||
}
|
||||
}
|
||||
|
||||
/// Shares one debounce key, so a later emit supersedes a pending publish.
|
||||
void _scheduleWidgetPublish(TimetableState data, Duration delay) {
|
||||
final settingsCubit = context.read<SettingsCubit>();
|
||||
final capabilitiesCubit = context.read<CapabilitiesCubit>();
|
||||
final epoch = SessionManager().sessionEpoch;
|
||||
Debouncer.debounce(
|
||||
'widgetPublish',
|
||||
delay,
|
||||
() => unawaited(
|
||||
WidgetPublisher.publishFromBlocState(
|
||||
data,
|
||||
settings: settingsCubit.val(),
|
||||
isTeacher: capabilitiesCubit.isTeacher,
|
||||
epoch: epoch,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _reportTelemetry() {
|
||||
if (!mounted) return;
|
||||
TelemetryHeartbeat.report(
|
||||
@@ -125,13 +144,18 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
||||
final pending = await WidgetNavigation.consumePendingTimetableTap();
|
||||
if (!pending || !mounted) return;
|
||||
// `withNavBar: false` routes sit on the root navigator above the
|
||||
// bottom-nav; pop them so jumpToTab is actually visible. Stop at
|
||||
// popups so open dialogs/sheets stay alive.
|
||||
// bottom-nav; pop them so jumpToTab is actually visible.
|
||||
_popToShell();
|
||||
AppRoutes.goToTab(context, Modules.timetable);
|
||||
}
|
||||
|
||||
/// Pops full-page routes back to the tab shell, stopping at popups so open
|
||||
/// dialogs/sheets stay alive.
|
||||
void _popToShell() {
|
||||
final navigator = Navigator.of(context);
|
||||
if (navigator.canPop()) {
|
||||
navigator.popUntil((route) => route.isFirst || route is PopupRoute);
|
||||
}
|
||||
AppRoutes.goToTab(context, Modules.timetable);
|
||||
}
|
||||
|
||||
void _handlePendingShare() {
|
||||
@@ -140,10 +164,7 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
||||
if (share == null || ShareIntentListener.instance.isShown(share)) return;
|
||||
// A second share would otherwise leave the previous share-flow page
|
||||
// on top with stale (already-cleared) file paths.
|
||||
final navigator = Navigator.of(context);
|
||||
if (navigator.canPop()) {
|
||||
navigator.popUntil((route) => route.isFirst || route is PopupRoute);
|
||||
}
|
||||
_popToShell();
|
||||
ShareIntentListener.instance.markShown(share);
|
||||
AppRoutes.openShareTarget(context, share);
|
||||
}
|
||||
@@ -166,27 +187,13 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
||||
timetable.refresh();
|
||||
// Mirror BLoC updates into the home-screen widget without waiting
|
||||
// for the periodic background refresh.
|
||||
final settingsCubit = context.read<SettingsCubit>();
|
||||
final capabilitiesCubit = context.read<CapabilitiesCubit>();
|
||||
_timetableWidgetSync?.cancel();
|
||||
// Debounced: a refresh or week swipe emits several times in a row, and
|
||||
// only the settled state is worth mirroring.
|
||||
_timetableWidgetSync = timetable.stream.listen((state) {
|
||||
final data = state.data;
|
||||
if (data is TimetableState && !state.isLoading) {
|
||||
final epoch = SessionManager().sessionEpoch;
|
||||
Debouncer.debounce(
|
||||
'widgetPublish',
|
||||
const Duration(seconds: 1),
|
||||
() => unawaited(
|
||||
WidgetPublisher.publishFromBlocState(
|
||||
data,
|
||||
settings: settingsCubit.val(),
|
||||
isTeacher: capabilitiesCubit.isTeacher,
|
||||
epoch: epoch,
|
||||
),
|
||||
),
|
||||
);
|
||||
_scheduleWidgetPublish(data, const Duration(seconds: 1));
|
||||
}
|
||||
});
|
||||
// Initial publish in case hydrated storage already has data. The widget
|
||||
@@ -194,19 +201,7 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
||||
// frames are done (a fresh bloc emit in the meantime supersedes it).
|
||||
final initialData = timetable.state.data;
|
||||
if (initialData is TimetableState) {
|
||||
final epoch = SessionManager().sessionEpoch;
|
||||
Debouncer.debounce(
|
||||
'widgetPublish',
|
||||
const Duration(seconds: 3),
|
||||
() => unawaited(
|
||||
WidgetPublisher.publishFromBlocState(
|
||||
initialData,
|
||||
settings: settingsCubit.val(),
|
||||
isTeacher: capabilitiesCubit.isTeacher,
|
||||
epoch: epoch,
|
||||
),
|
||||
),
|
||||
);
|
||||
_scheduleWidgetPublish(initialData, const Duration(seconds: 3));
|
||||
}
|
||||
unawaited(_handlePendingWidgetNavigation());
|
||||
ShareIntentListener.pending.addListener(_handlePendingShare);
|
||||
|
||||
Reference in New Issue
Block a user