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
+12 -7
View File
@@ -13,7 +13,6 @@ import 'custom_events/custom_event_edit_dialog.dart';
import 'data/arbitrary_appointment.dart';
import 'data/lesson_period_schedule.dart';
import 'data/timetable_appointment_factory.dart';
import 'data/webuntis_time.dart';
import 'details/appointment_details_dispatcher.dart';
import 'widgets/custom_workweek_calendar.dart';
import 'widgets/special_regions_builder.dart';
@@ -70,8 +69,7 @@ class _TimetableState extends State<Timetable> {
return _cachedAppointments = TimetableAppointmentFactory(
lessons: state.getAllKnownLessons().toList(),
customEvents: state.customEvents?.events ?? const [],
rooms: state.rooms!,
subjects: state.subjects!,
subjects: state.subjects?.result ?? const [],
settings: timetableSettings,
now: DateTime.now(),
).build();
@@ -79,7 +77,7 @@ class _TimetableState extends State<Timetable> {
bool _isCrossedOut(Appointment appointment) {
final id = appointment.id;
if (id is WebuntisAppointment) return id.lesson.code == 'cancelled';
if (id is LessonAppointment) return id.entry.status == 'CANCELLED';
return false;
}
@@ -123,6 +121,13 @@ class _TimetableState extends State<Timetable> {
],
),
body: LoadableStateConsumer<TimetableBloc, TimetableState>(
// Without this predicate the consumer treats the freshly-initialised
// empty TimetableState as "has content" and only shows the error bar
// on top — but `_calendar` collapses to `SizedBox.shrink()` while the
// reference data is missing, leaving the user with a blank screen.
// Telling the consumer that "ready" means having reference data
// flips it into the proper error-screen path instead.
isReady: (state) => state.hasReferenceData,
child: (state, _) => _calendar(state, bloc),
),
);
@@ -192,12 +197,12 @@ class _TimetableState extends State<Timetable> {
/// `_mondayOf()` correctly walks back to the Monday of its own week,
/// which is the last fully-allowed week.
(DateTime, DateTime) _scrollBounds(TimetableState state) {
final year = state.schoolyear?.result;
final year = state.schoolyear;
final DateTime baseMin;
final DateTime baseMax;
if (year != null) {
baseMin = WebuntisTime.parse(year.startDate, 0);
baseMax = WebuntisTime.parse(year.endDate, 0);
baseMin = year.startDate;
baseMax = year.endDate;
} else {
final now = DateTime.now();
baseMin = now.subtractDays(14);