removed timetable limits, fully dependent on marianumConnect now

This commit is contained in:
2026-08-05 20:03:02 +02:00
parent 246cb0f527
commit 646e2c0451
8 changed files with 109 additions and 55 deletions
@@ -4,6 +4,7 @@ import 'package:syncfusion_flutter_calendar/calendar.dart';
import '../../../../api/mhsl/custom_timetable_event/custom_timetable_event.dart';
import '../../../../extensions/date_time.dart';
import '../../../../state/app/modules/capabilities/bloc/capabilities_cubit.dart';
import '../../../../state/app/modules/settings/bloc/settings_cubit.dart';
import '../../../../state/app/modules/timetable/bloc/timetable_state.dart';
import '../../../../storage/timetable_settings.dart';
@@ -105,7 +106,12 @@ class TimetableCalendarViewState extends State<TimetableCalendarView> {
disabledColor: Theme.of(context).disabledColor,
).build();
final (minDate, maxDate) = _scrollBounds(state);
final capabilities = context.watch<CapabilitiesCubit>();
final (minDate, maxDate) = _scrollBounds(
state,
pastDays: capabilities.timetablePastDays,
futureDays: capabilities.timetableFutureDays,
);
return CustomWorkWeekCalendar(
key: _calendarKey,
@@ -122,17 +128,21 @@ class TimetableCalendarViewState extends State<TimetableCalendarView> {
);
}
/// Hard caps applied on top of whatever Webuntis would allow. Even if the
/// school year (or a stale persisted bound) would let the user scroll
/// further, we never expose more than this much around the current week.
static const int _maxWeeksBack = 4;
static const int _maxWeeksForward = 2;
/// Returns the (minDate, maxDate) the user is allowed to scroll between.
/// Starts from the Webuntis school year (or a tight window when that hasn't
/// loaded yet), tightens by anything the bloc has learned from past denials,
/// and finally clamps to a fixed window around today.
(DateTime, DateTime) _scrollBounds(TimetableState state) {
/// Starts from the (server-narrowed) Webuntis school year or a tight window
/// when that hasn't loaded yet, tightens by anything the bloc has learned
/// from past denials, and finally clamps to the window Connect grants via
/// [CapabilitiesCubit.timetablePastDays]/[CapabilitiesCubit.timetableFutureDays].
///
/// The capability clamp mirrors the server: `null` means unlimited (no client
/// clamp at all), and a given day count is widened to at least cover the
/// current MonSun week — so the two windows always coincide and the clamp
/// can never invert.
(DateTime, DateTime) _scrollBounds(
TimetableState state, {
required int? pastDays,
required int? futureDays,
}) {
final year = state.schoolyear;
final DateTime baseMin;
final DateTime baseMax;
@@ -154,39 +164,43 @@ class TimetableCalendarViewState extends State<TimetableCalendarView> {
? state.accessibleEndDate!
: baseMax)
: baseMax;
final todayMonday = _mondayOf(DateTime.now());
final cappedMin = effectiveMin.isBefore(
todayMonday.subtractDays(_maxWeeksBack * 7),
)
? todayMonday.subtractDays(_maxWeeksBack * 7)
final today = _startOfDay(DateTime.now());
final todayMonday = _mondayOf(today);
final currentWeekEnd = todayMonday.addDays(DateTime.daysPerWeek - 1);
final capMin = pastDays == null
? null
: _earlier(today.subtractDays(pastDays), todayMonday);
final capMax = futureDays == null
? null
: _later(today.addDays(futureDays), currentWeekEnd);
final cappedMin = capMin != null && effectiveMin.isBefore(capMin)
? capMin
: effectiveMin;
final cappedMax = effectiveMax.isAfter(
todayMonday.addDays(_maxWeeksForward * 7 + 6),
)
? todayMonday.addDays(_maxWeeksForward * 7 + 6)
final cappedMax = capMax != null && effectiveMax.isAfter(capMax)
? capMax
: effectiveMax;
// When the resulting range does not cover the current week — the summer gap
// between two school years, or a stale persisted bound — fall back to the
// full fixed window around today. Otherwise the PageView clamps the initial
// page to the last week before the holidays (hiding the "Schulfrei" region)
// and forward scrolling collapses to the current week only.
final currentWeekEnd = todayMonday.addDays(DateTime.daysPerWeek - 1);
// current week, widened to whatever the capabilities still allow. Otherwise
// the PageView clamps the initial page to the last week before the holidays
// (hiding the "Schulfrei" region) and forward scrolling collapses to the
// current week only.
final outsideRange =
cappedMax.isBefore(todayMonday) || cappedMin.isAfter(currentWeekEnd);
final finalMin = outsideRange
? todayMonday.subtractDays(_maxWeeksBack * 7)
: cappedMin;
final finalMax = outsideRange
? todayMonday.addDays(_maxWeeksForward * 7 + 6)
: cappedMax;
final finalMin = outsideRange ? (capMin ?? todayMonday) : cappedMin;
final finalMax = outsideRange ? (capMax ?? currentWeekEnd) : cappedMax;
final daysToMonday =
(DateTime.monday - finalMin.weekday) % DateTime.daysPerWeek;
final mondayMin = finalMin.addDays(daysToMonday);
return (mondayMin, finalMax);
}
static DateTime _mondayOf(DateTime d) {
final monday = d.subtractDays(d.weekday - 1);
return DateTime(monday.year, monday.month, monday.day);
}
static DateTime _mondayOf(DateTime d) =>
_startOfDay(d.subtractDays(d.weekday - 1));
static DateTime _startOfDay(DateTime d) => DateTime(d.year, d.month, d.day);
static DateTime _earlier(DateTime a, DateTime b) => a.isBefore(b) ? a : b;
static DateTime _later(DateTime a, DateTime b) => a.isAfter(b) ? a : b;
}