107 lines
4.3 KiB
Dart
107 lines
4.3 KiB
Dart
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
|
|
import '../../../../../api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.dart';
|
|
import '../../../../../api/marianumconnect/queries/timetable_get_rooms/timetable_get_rooms_response.dart';
|
|
import '../../../../../api/marianumconnect/queries/timetable_get_schoolyear/timetable_get_schoolyear_response.dart';
|
|
import '../../../../../api/marianumconnect/queries/timetable_get_subjects/timetable_get_subjects_response.dart';
|
|
import '../../../../../api/marianumconnect/queries/timetable_get_timegrid/timetable_get_timegrid_response.dart';
|
|
import '../../../../../api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.dart';
|
|
import '../../../../../api/mhsl/custom_timetable_event/get/get_custom_timetable_event_response.dart';
|
|
import '../../../../../utils/json_equality.dart';
|
|
import 'week_cache.dart';
|
|
|
|
part 'timetable_state.freezed.dart';
|
|
part 'timetable_state.g.dart';
|
|
|
|
@freezed
|
|
abstract class TimetableState with _$TimetableState {
|
|
const TimetableState._();
|
|
|
|
const factory TimetableState({
|
|
@Default(<String, TimetableGetWeekResponse>{})
|
|
Map<String, TimetableGetWeekResponse> weekCache,
|
|
TimetableGetRoomsResponse? rooms,
|
|
TimetableGetSubjectsResponse? subjects,
|
|
TimetableGetHolidaysResponse? schoolHolidays,
|
|
TimetableGetSchoolyearResponse? schoolyear,
|
|
TimetableGetTimegridResponse? timegrid,
|
|
GetCustomTimetableEventResponse? customEvents,
|
|
required DateTime startDate,
|
|
required DateTime endDate,
|
|
@Default(0) int dataVersion,
|
|
// Boundaries learned from past server denials. A week is permitted when its
|
|
// start is on/before `accessibleEndDate` and its end on/after
|
|
// `accessibleStartDate`. Null = that bound not discovered yet.
|
|
DateTime? accessibleStartDate,
|
|
DateTime? accessibleEndDate,
|
|
}) = _TimetableState;
|
|
|
|
factory TimetableState.fromJson(Map<String, Object?> json) =>
|
|
_$TimetableStateFromJson(json);
|
|
|
|
Iterable<McTimetableEntry> getAllKnownLessons() =>
|
|
weekCache.values.expand((response) => response.entries);
|
|
|
|
/// This state with [week] cached, or `this` when its content is unchanged
|
|
/// (so the emit is dropped as equal).
|
|
TimetableState withFetchedWeek(
|
|
DateTime weekStart,
|
|
TimetableGetWeekResponse week,
|
|
) {
|
|
final updated = mergeWeekIntoCache(
|
|
weekCache,
|
|
weekStart,
|
|
week,
|
|
viewedWeekStart: startDate,
|
|
now: DateTime.now(),
|
|
);
|
|
if (updated == null) return this;
|
|
return copyWith(weekCache: updated, dataVersion: dataVersion + 1);
|
|
}
|
|
|
|
/// Applies freshly loaded reference data. Values whose content equals the
|
|
/// current one keep the old instance, and when nothing changed at all this
|
|
/// returns `this` — every `dataVersion` bump and new identity makes the
|
|
/// calendar rebuild all appointments and break regions.
|
|
TimetableState withReferenceData({
|
|
TimetableGetRoomsResponse? rooms,
|
|
TimetableGetSubjectsResponse? subjects,
|
|
TimetableGetHolidaysResponse? schoolHolidays,
|
|
TimetableGetSchoolyearResponse? schoolyear,
|
|
TimetableGetTimegridResponse? timegrid,
|
|
GetCustomTimetableEventResponse? customEvents,
|
|
}) {
|
|
T? changed<T>(T? next, T? current) =>
|
|
next == null || sameJson(next, current) ? null : next;
|
|
final newRooms = changed(rooms, this.rooms);
|
|
final newSubjects = changed(subjects, this.subjects);
|
|
final newHolidays = changed(schoolHolidays, this.schoolHolidays);
|
|
final newSchoolyear = changed(schoolyear, this.schoolyear);
|
|
final newTimegrid = changed(timegrid, this.timegrid);
|
|
final newCustomEvents = changed(customEvents, this.customEvents);
|
|
if (newRooms == null &&
|
|
newSubjects == null &&
|
|
newHolidays == null &&
|
|
newSchoolyear == null &&
|
|
newTimegrid == null &&
|
|
newCustomEvents == null) {
|
|
return this;
|
|
}
|
|
return copyWith(
|
|
rooms: newRooms ?? this.rooms,
|
|
subjects: newSubjects ?? this.subjects,
|
|
schoolHolidays: newHolidays ?? this.schoolHolidays,
|
|
schoolyear: newSchoolyear ?? this.schoolyear,
|
|
timegrid: newTimegrid ?? this.timegrid,
|
|
customEvents: newCustomEvents ?? this.customEvents,
|
|
dataVersion: dataVersion + 1,
|
|
);
|
|
}
|
|
|
|
bool get hasReferenceData =>
|
|
rooms != null &&
|
|
subjects != null &&
|
|
schoolHolidays != null &&
|
|
customEvents != null;
|
|
}
|