119 lines
3.8 KiB
Dart
119 lines
3.8 KiB
Dart
import '../../../../../api/marianumconnect/queries/timetable_custom_events/custom_events_migration.dart';
|
|
import '../../../../../api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.dart';
|
|
import '../../../../../api/mhsl/custom_timetable_event/custom_timetable_event.dart';
|
|
import '../../../infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_hydrated_bloc.dart';
|
|
import '../../../infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_hydrated_bloc_event.dart';
|
|
import '../data_provider/timetable_data_provider.dart';
|
|
import '../repository/timetable_repository.dart';
|
|
import 'timetable_event.dart';
|
|
import 'timetable_state.dart';
|
|
import 'timetable_week_loader.dart';
|
|
|
|
class TimetableBloc
|
|
extends
|
|
LoadableHydratedBloc<
|
|
TimetableEvent,
|
|
TimetableState,
|
|
TimetableRepository
|
|
>
|
|
with TimetableWeekLoader<TimetableRepository> {
|
|
/// Set by [retry] to force the next [gatherData] to bypass the custom-event
|
|
/// cache and actually hit the network. Cleared at the top of [gatherData].
|
|
bool _forceRenew = false;
|
|
|
|
@override
|
|
void retry() {
|
|
_forceRenew = true;
|
|
super.retry();
|
|
}
|
|
|
|
@override
|
|
TimetableRepository repository() => TimetableRepository();
|
|
|
|
@override
|
|
TimetableDataProvider get referenceData => repo.data;
|
|
|
|
@override
|
|
Future<TimetableGetWeekResponse> fetchWeek(DateTime start, DateTime end) =>
|
|
repo.data.getWeek(start, end);
|
|
|
|
/// Persisted state may carry a stale `startDate`/`endDate` from the user's
|
|
/// last view. Reset on every cold start so the calendar always mounts on
|
|
/// the current week, not on whatever week the user closed the app on.
|
|
@override
|
|
TimetableState fromStorage(Map<String, dynamic> json) {
|
|
final (start, end) = currentTimetableWeek();
|
|
return TimetableState.fromJson(json).copyWith(
|
|
startDate: start,
|
|
endDate: end,
|
|
accessibleStartDate: null,
|
|
accessibleEndDate: null,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Map<String, dynamic>? toStorage(TimetableState state) => state.toJson();
|
|
|
|
@override
|
|
Future<void> gatherData() {
|
|
final renew = _forceRenew;
|
|
_forceRenew = false;
|
|
return gatherWeek(
|
|
also: (onError) => _loadCustomEvents(onError: onError, renew: renew),
|
|
);
|
|
}
|
|
|
|
Future<void> addCustomEvent(CustomTimetableEvent event) async {
|
|
await repo.data.addCustomEvent(event);
|
|
await _refreshCustomEvents();
|
|
}
|
|
|
|
Future<void> updateCustomEvent(String id, CustomTimetableEvent event) async {
|
|
await repo.data.updateCustomEvent(id, event);
|
|
await _refreshCustomEvents();
|
|
}
|
|
|
|
Future<void> removeCustomEvent(String id) async {
|
|
await repo.data.removeCustomEvent(id);
|
|
await _refreshCustomEvents();
|
|
}
|
|
|
|
/// Setzt die persönliche Farbe eines Fachs (Schlüssel: Fach-Kürzel) und lädt
|
|
/// die Fächer neu, damit die eingebettete Farbe im Kalender wirkt.
|
|
Future<void> setSubjectColor(String subjectShort, String color) async {
|
|
await repo.data.setSubjectColor(subjectShort, color);
|
|
await _refreshSubjects();
|
|
}
|
|
|
|
Future<void> clearSubjectColor(String subjectShort) async {
|
|
await repo.data.removeSubjectColor(subjectShort);
|
|
await _refreshSubjects();
|
|
}
|
|
|
|
Future<void> _refreshSubjects() async {
|
|
final subjects = await repo.data.getSubjects();
|
|
add(DataGathered((s) => s.withReferenceData(subjects: subjects)));
|
|
}
|
|
|
|
Future<void> _loadCustomEvents({
|
|
void Function(Object)? onError,
|
|
bool renew = false,
|
|
}) async {
|
|
try {
|
|
await CustomEventsMigration.runOnce();
|
|
final events = await repo.data.getCustomEvents(
|
|
renew: renew,
|
|
onError: onError,
|
|
);
|
|
add(Emit((s) => s.withReferenceData(customEvents: events)));
|
|
} catch (e) {
|
|
onError?.call(e);
|
|
}
|
|
}
|
|
|
|
Future<void> _refreshCustomEvents() async {
|
|
final events = await repo.data.getCustomEvents(renew: true);
|
|
add(DataGathered((s) => s.withReferenceData(customEvents: events)));
|
|
}
|
|
}
|