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
@@ -38,7 +38,10 @@ class _OutsideHoursStrip extends StatelessWidget {
(maxChipsPerDay > 1 ? (maxChipsPerDay - 1) * kOutsideChipSpacing : 0);
return Container(
color: theme.colorScheme.surfaceContainerLowest,
// Scaffold-Background, damit die Ganztagestermine-Leiste optisch nahtlos
// an Header und Stundenplan-Hintergrund anschließt; surfaceContainerLowest
// ist in M3-Light reinweiß und sticht gegen die getönte Seed-Surface ab.
color: theme.scaffoldBackgroundColor,
padding: const EdgeInsets.symmetric(
vertical: kOutsideStripVerticalPadding,
),
@@ -1,15 +1,14 @@
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_calendar/calendar.dart';
import '../../../../api/webuntis/queries/get_holidays/get_holidays_response.dart';
import '../../../../api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.dart';
import '../../../../extensions/date_time.dart';
import '../data/calendar_layout.dart';
import '../data/lesson_period_schedule.dart';
import '../data/webuntis_time.dart';
import 'time_region_tile.dart';
class SpecialRegionsBuilder {
final GetHolidaysResponse holidays;
final TimetableGetHolidaysResponse holidays;
final LessonPeriodSchedule schedule;
final ColorScheme colorScheme;
final Color disabledColor;
@@ -59,14 +58,22 @@ class SpecialRegionsBuilder {
static String _dayKey(DateTime d) => '${d.year}-${d.month}-${d.day}';
Iterable<TimeRegion> _buildHolidayRegions() {
// Multiple Webuntis holiday entries can cover the same day (e.g. a
// public holiday falling inside a vacation period). Collapse them
// per-day so we emit exactly one TimeRegion per day and the
// overlapping labels don't render on top of each other.
// Multiple holiday entries can cover the same day (e.g. a public holiday
// falling inside a vacation period). Collapse them per-day so we emit
// exactly one TimeRegion per day and the overlapping labels don't render
// on top of each other.
final byDay = <String, _HolidayDay>{};
for (final holiday in holidays.result) {
final startDay = WebuntisTime.parse(holiday.startDate, 0);
final endDay = WebuntisTime.parse(holiday.endDate, 0);
final startDay = DateTime(
holiday.startDate.year,
holiday.startDate.month,
holiday.startDate.day,
);
final endDay = DateTime(
holiday.endDate.year,
holiday.endDate.month,
holiday.endDate.day,
);
// Webuntis treats endDate inclusively (last day of the break) — the
// `+ 1` covers single-day public holidays (where startDate == endDate)
// and the final day of a multi-day vacation, both of which would
@@ -76,7 +83,7 @@ class SpecialRegionsBuilder {
final day = startDay.addDays(i);
final key = _dayKey(day);
byDay.putIfAbsent(key, () => _HolidayDay(day, [])).names.add(
holiday.name,
holiday.shortName,
);
}
}