timetable performance optimization
This commit is contained in:
@@ -55,6 +55,13 @@ class TimetableCalendarViewState extends State<TimetableCalendarView> {
|
||||
// the same identity checks the cache always used.
|
||||
(int, TimetableSettings, List<CustomTimetableEvent>, bool)? _cacheKey;
|
||||
|
||||
// Stable identities let the calendar reuse its per-week pages across
|
||||
// rebuilds; rebuilding these every frame would invalidate that cache.
|
||||
LessonPeriodSchedule? _schedule;
|
||||
Object? _scheduleKey;
|
||||
List<TimeRegion>? _regions;
|
||||
Object? _regionsKey;
|
||||
|
||||
DateTime _initialDisplayDate() => DateTime.now().addDays(2);
|
||||
|
||||
/// Snaps the calendar back to the current week. Exposed so host pages can
|
||||
@@ -90,7 +97,37 @@ class TimetableCalendarViewState extends State<TimetableCalendarView> {
|
||||
).build();
|
||||
}
|
||||
|
||||
bool _isCrossedOut(Appointment appointment) {
|
||||
LessonPeriodSchedule _scheduleFor(TimetableState state) {
|
||||
if (_schedule != null && identical(_scheduleKey, state.timegrid)) {
|
||||
return _schedule!;
|
||||
}
|
||||
_scheduleKey = state.timegrid;
|
||||
return _schedule = LessonPeriodSchedule.fromState(state);
|
||||
}
|
||||
|
||||
List<TimeRegion> _regionsFor(
|
||||
TimetableState state,
|
||||
LessonPeriodSchedule schedule,
|
||||
) {
|
||||
final theme = Theme.of(context);
|
||||
final key = (
|
||||
state.schoolHolidays,
|
||||
schedule,
|
||||
theme.colorScheme,
|
||||
theme.disabledColor,
|
||||
DateTime.now().dateOnly,
|
||||
);
|
||||
if (_regions != null && key == _regionsKey) return _regions!;
|
||||
_regionsKey = key;
|
||||
return _regions = SpecialRegionsBuilder(
|
||||
holidays: state.schoolHolidays!,
|
||||
schedule: schedule,
|
||||
colorScheme: theme.colorScheme,
|
||||
disabledColor: theme.disabledColor,
|
||||
).build();
|
||||
}
|
||||
|
||||
static bool _isCrossedOut(Appointment appointment) {
|
||||
final id = appointment.id;
|
||||
if (id is LessonAppointment) return id.entry.status == 'CANCELLED';
|
||||
return false;
|
||||
@@ -104,14 +141,9 @@ class TimetableCalendarViewState extends State<TimetableCalendarView> {
|
||||
// transient null can never crash the build.
|
||||
if (state.schoolHolidays == null) return const SizedBox.shrink();
|
||||
|
||||
final schedule = LessonPeriodSchedule.fromState(state);
|
||||
final schedule = _scheduleFor(state);
|
||||
final appointments = _appointments(state);
|
||||
final regions = SpecialRegionsBuilder(
|
||||
holidays: state.schoolHolidays!,
|
||||
schedule: schedule,
|
||||
colorScheme: Theme.of(context).colorScheme,
|
||||
disabledColor: Theme.of(context).disabledColor,
|
||||
).build();
|
||||
final regions = _regionsFor(state, schedule);
|
||||
|
||||
final capabilities = context.watch<CapabilitiesCubit>();
|
||||
final (minDate, maxDate) = _scrollBounds(
|
||||
@@ -171,8 +203,8 @@ class TimetableCalendarViewState extends State<TimetableCalendarView> {
|
||||
? state.accessibleEndDate!
|
||||
: baseMax)
|
||||
: baseMax;
|
||||
final today = _startOfDay(DateTime.now());
|
||||
final todayMonday = _mondayOf(today);
|
||||
final today = DateTime.now().dateOnly;
|
||||
final todayMonday = today.mondayOfWeek;
|
||||
final currentWeekEnd = todayMonday.addDays(DateTime.daysPerWeek - 1);
|
||||
final capMin = pastDays == null
|
||||
? null
|
||||
@@ -202,11 +234,6 @@ class TimetableCalendarViewState extends State<TimetableCalendarView> {
|
||||
return (mondayMin, finalMax);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user