migrated custom timetable events to Marianum-Connect and refactored push notification handling

This commit is contained in:
2026-07-12 14:31:48 +02:00
parent c444ed54a5
commit 91a6216f66
28 changed files with 474 additions and 212 deletions
@@ -1,22 +0,0 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:http/http.dart' as http;
import '../../mhsl_api.dart';
import 'add_custom_timetable_event_params.dart';
class AddCustomTimetableEvent extends MhslApi<void> {
AddCustomTimetableEventParams params;
AddCustomTimetableEvent(this.params) : super('server/timetable/customEvents');
@override
void assemble(String raw) {}
@override
Future<Response>? request(Uri uri) {
var body = jsonEncode(params.toJson());
return http.post(uri, body: body);
}
}
@@ -1,17 +0,0 @@
import 'package:json_annotation/json_annotation.dart';
import '../custom_timetable_event.dart';
part 'add_custom_timetable_event_params.g.dart';
@JsonSerializable(explicitToJson: true)
class AddCustomTimetableEventParams {
String user;
CustomTimetableEvent event;
AddCustomTimetableEventParams(this.user, this.event);
factory AddCustomTimetableEventParams.fromJson(Map<String, dynamic> json) =>
_$AddCustomTimetableEventParamsFromJson(json);
Map<String, dynamic> toJson() => _$AddCustomTimetableEventParamsToJson(this);
}
@@ -1,18 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'add_custom_timetable_event_params.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
AddCustomTimetableEventParams _$AddCustomTimetableEventParamsFromJson(
Map<String, dynamic> json,
) => AddCustomTimetableEventParams(
json['user'] as String,
CustomTimetableEvent.fromJson(json['event'] as Map<String, dynamic>),
);
Map<String, dynamic> _$AddCustomTimetableEventParamsToJson(
AddCustomTimetableEventParams instance,
) => <String, dynamic>{'user': instance.user, 'event': instance.event.toJson()};
@@ -1,7 +1,5 @@
import 'package:json_annotation/json_annotation.dart';
import '../mhsl_api.dart';
part 'custom_timetable_event.g.dart';
@JsonSerializable()
@@ -9,15 +7,23 @@ class CustomTimetableEvent {
String id;
String title;
String description;
@JsonKey(toJson: MhslApi.dateTimeToJson, fromJson: MhslApi.dateTimeFromJson)
@JsonKey(toJson: _dateToJson, fromJson: _dateFromJson)
DateTime startDate;
@JsonKey(toJson: MhslApi.dateTimeToJson, fromJson: MhslApi.dateTimeFromJson)
@JsonKey(toJson: _dateToJson, fromJson: _dateFromJson)
DateTime endDate;
String? color;
String rrule;
@JsonKey(toJson: MhslApi.dateTimeToJson, fromJson: MhslApi.dateTimeFromJson)
/// When true, occurrences of a recurring event that fall inside a school
/// holiday are hidden in the calendar. Purely client-side: the backend only
/// stores the flag, the exclusion is applied at render time against the
/// holiday list. Ignored for non-recurring events (empty [rrule]).
@JsonKey(defaultValue: false)
bool skipHolidays;
@JsonKey(toJson: _dateToJson, fromJson: _dateFromJson)
DateTime createdAt;
@JsonKey(toJson: MhslApi.dateTimeToJson, fromJson: MhslApi.dateTimeFromJson)
@JsonKey(toJson: _dateToJson, fromJson: _dateFromJson)
DateTime updatedAt;
CustomTimetableEvent({
@@ -28,6 +34,7 @@ class CustomTimetableEvent {
required this.endDate,
required this.color,
required this.rrule,
this.skipHolidays = false,
required this.createdAt,
required this.updatedAt,
});
@@ -35,4 +42,13 @@ class CustomTimetableEvent {
factory CustomTimetableEvent.fromJson(Map<String, dynamic> json) =>
_$CustomTimetableEventFromJson(json);
Map<String, dynamic> toJson() => _$CustomTimetableEventToJson(this);
// Marianum-Connect serializes LocalDateTime as ISO-8601 (`yyyy-MM-ddTHH:mm:ss`)
// and its GSON parser rejects anything else. DateTime.parse still reads the
// old MHSL `yyyy-MM-dd HH:mm:ss` shape too, so events fetched during the
// one-time migration deserialize unchanged.
static DateTime _dateFromJson(String raw) => DateTime.parse(raw);
static String _dateToJson(DateTime d) =>
'${d.year.toString().padLeft(4, '0')}-${d.month.toString().padLeft(2, '0')}-${d.day.toString().padLeft(2, '0')}'
'T${d.hour.toString().padLeft(2, '0')}:${d.minute.toString().padLeft(2, '0')}:${d.second.toString().padLeft(2, '0')}';
}
@@ -12,12 +12,13 @@ CustomTimetableEvent _$CustomTimetableEventFromJson(
id: json['id'] as String,
title: json['title'] as String,
description: json['description'] as String,
startDate: MhslApi.dateTimeFromJson(json['startDate'] as String),
endDate: MhslApi.dateTimeFromJson(json['endDate'] as String),
startDate: CustomTimetableEvent._dateFromJson(json['startDate'] as String),
endDate: CustomTimetableEvent._dateFromJson(json['endDate'] as String),
color: json['color'] as String?,
rrule: json['rrule'] as String,
createdAt: MhslApi.dateTimeFromJson(json['createdAt'] as String),
updatedAt: MhslApi.dateTimeFromJson(json['updatedAt'] as String),
skipHolidays: json['skipHolidays'] as bool? ?? false,
createdAt: CustomTimetableEvent._dateFromJson(json['createdAt'] as String),
updatedAt: CustomTimetableEvent._dateFromJson(json['updatedAt'] as String),
);
Map<String, dynamic> _$CustomTimetableEventToJson(
@@ -26,10 +27,11 @@ Map<String, dynamic> _$CustomTimetableEventToJson(
'id': instance.id,
'title': instance.title,
'description': instance.description,
'startDate': MhslApi.dateTimeToJson(instance.startDate),
'endDate': MhslApi.dateTimeToJson(instance.endDate),
'startDate': CustomTimetableEvent._dateToJson(instance.startDate),
'endDate': CustomTimetableEvent._dateToJson(instance.endDate),
'color': instance.color,
'rrule': instance.rrule,
'createdAt': MhslApi.dateTimeToJson(instance.createdAt),
'updatedAt': MhslApi.dateTimeToJson(instance.updatedAt),
'skipHolidays': instance.skipHolidays,
'createdAt': CustomTimetableEvent._dateToJson(instance.createdAt),
'updatedAt': CustomTimetableEvent._dateToJson(instance.updatedAt),
};
@@ -1,20 +0,0 @@
import '../../../request_cache.dart';
import 'get_custom_timetable_event.dart';
import 'get_custom_timetable_event_params.dart';
import 'get_custom_timetable_event_response.dart';
class GetCustomTimetableEventCache
extends SimpleCache<GetCustomTimetableEventResponse> {
GetCustomTimetableEventCache(
GetCustomTimetableEventParams params, {
super.onUpdate,
super.onError,
super.renew,
}) : super(
cacheTime: RequestCache.cacheMinute,
loader: () => GetCustomTimetableEvent(params).run(),
fromJson: GetCustomTimetableEventResponse.fromJson,
) {
start('customTimetableEvents');
}
}
@@ -1,21 +0,0 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:http/http.dart' as http;
import '../../mhsl_api.dart';
import 'update_custom_timetable_event_params.dart';
class UpdateCustomTimetableEvent extends MhslApi<void> {
UpdateCustomTimetableEventParams params;
UpdateCustomTimetableEvent(this.params)
: super('server/timetable/customEvents');
@override
void assemble(String raw) {}
@override
Future<Response>? request(Uri uri) =>
http.patch(uri, body: jsonEncode(params.toJson()));
}
@@ -1,19 +0,0 @@
import 'package:json_annotation/json_annotation.dart';
import '../custom_timetable_event.dart';
part 'update_custom_timetable_event_params.g.dart';
@JsonSerializable(explicitToJson: true)
class UpdateCustomTimetableEventParams {
String id;
CustomTimetableEvent event;
UpdateCustomTimetableEventParams(this.id, this.event);
factory UpdateCustomTimetableEventParams.fromJson(
Map<String, dynamic> json,
) => _$UpdateCustomTimetableEventParamsFromJson(json);
Map<String, dynamic> toJson() =>
_$UpdateCustomTimetableEventParamsToJson(this);
}
@@ -1,18 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'update_custom_timetable_event_params.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
UpdateCustomTimetableEventParams _$UpdateCustomTimetableEventParamsFromJson(
Map<String, dynamic> json,
) => UpdateCustomTimetableEventParams(
json['id'] as String,
CustomTimetableEvent.fromJson(json['event'] as Map<String, dynamic>),
);
Map<String, dynamic> _$UpdateCustomTimetableEventParamsToJson(
UpdateCustomTimetableEventParams instance,
) => <String, dynamic>{'id': instance.id, 'event': instance.event.toJson()};