migrated timetable integration from WebUntis to the MarianumConnect API, implementing a Dio-based client with bearer token authentication, background session validation, and auto-refresh logic.

This commit is contained in:
2026-05-23 17:32:42 +02:00
parent 2858f910c9
commit 93b9929f8f
106 changed files with 2739 additions and 2624 deletions
+29 -1
View File
@@ -18,6 +18,8 @@ import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'api/marianumcloud/webdav/queries/list_files/list_files_cache.dart';
import 'api/marianumconnect/auth/session_validator.dart';
import 'api/marianumconnect/marianumconnect_endpoint.dart';
import 'api/mhsl/breaker/get_breakers/get_breakers_response.dart';
import 'app.dart';
import 'background/widget_background_task.dart';
@@ -183,18 +185,44 @@ class _MainState extends State<Main> {
AccountData().waitForPopulation().then((value) {
if (!mounted) return;
context.read<AccountBloc>().setStatus(
final accountBloc = context.read<AccountBloc>();
accountBloc.setStatus(
value ? AccountStatus.loggedIn : AccountStatus.loggedOut,
);
if (value) _scheduleSessionValidation(accountBloc);
});
}
/// Fires a background credential check against Marianum Connect — runs in
/// the background so it never blocks the cold-start path. A 401 means the
/// password has been rotated server-side; the validator wipes the local
/// session and we flip the account bloc back to `loggedOut`, which sends
/// the user to the login screen.
void _scheduleSessionValidation(AccountBloc accountBloc) {
unawaited(
SessionValidator.probeStored(
onInvalidated: () async {
if (!mounted) return;
accountBloc.setStatus(AccountStatus.loggedOut);
},
),
);
}
@override
Widget build(BuildContext context) => Directionality(
textDirection: TextDirection.ltr,
child: BlocBuilder<SettingsCubit, Settings>(
builder: (context, settings) {
final devToolsSettings = settings.devToolsSettings;
// Keep the MC dio singleton aligned with the currently selected
// endpoint (live / beta / custom). Idempotent when the URL is
// unchanged so it's safe to call on every rebuild. Mirrored into
// WidgetSync so the background isolate refreshes against the same
// endpoint.
final mcBaseUrl = devToolsSettings.resolveMarianumConnectBaseUrl();
MarianumConnectEndpoint.update(mcBaseUrl);
unawaited(WidgetSync.setMarianumConnectBaseUrl(mcBaseUrl));
return MaterialApp(
showPerformanceOverlay: devToolsSettings.showPerformanceOverlay,
checkerboardOffscreenLayers: