implemented current schoolyear API and dynamic timetable scroll boundaries, added handling for out-of-range errors to narrow accessible dates, optimized holiday region rendering by collapsing overlaps, and refined holiday tile UI

This commit is contained in:
2026-05-14 15:07:48 +02:00
parent 2cb8321d07
commit 582eff8750
13 changed files with 368 additions and 51 deletions
@@ -0,0 +1,18 @@
import 'dart:convert';
import '../../webuntis_api.dart';
import 'get_current_schoolyear_response.dart';
class GetCurrentSchoolyear extends WebuntisApi {
GetCurrentSchoolyear() : super('getCurrentSchoolyear', null);
@override
Future<GetCurrentSchoolyearResponse> run() async {
final rawAnswer = await query(this);
return finalize(
GetCurrentSchoolyearResponse.fromJson(
jsonDecode(rawAnswer) as Map<String, dynamic>,
),
);
}
}
@@ -0,0 +1,15 @@
import '../../../request_cache.dart';
import 'get_current_schoolyear.dart';
import 'get_current_schoolyear_response.dart';
class GetCurrentSchoolyearCache
extends SimpleCache<GetCurrentSchoolyearResponse> {
GetCurrentSchoolyearCache({super.onUpdate, super.onError, super.renew})
: super(
cacheTime: RequestCache.cacheDay,
loader: () => GetCurrentSchoolyear().run(),
fromJson: GetCurrentSchoolyearResponse.fromJson,
) {
start('wu-current-schoolyear');
}
}
@@ -0,0 +1,39 @@
import 'package:json_annotation/json_annotation.dart';
import '../../../api_response.dart';
part 'get_current_schoolyear_response.g.dart';
/// Wraps Webuntis' `getCurrentSchoolyear` payload. The server returns a
/// single object with the current school year's bounds (yyyyMMdd integers).
@JsonSerializable(explicitToJson: true)
class GetCurrentSchoolyearResponse extends ApiResponse {
GetCurrentSchoolyearResponseObject result;
GetCurrentSchoolyearResponse(this.result);
factory GetCurrentSchoolyearResponse.fromJson(Map<String, dynamic> json) =>
_$GetCurrentSchoolyearResponseFromJson(json);
Map<String, dynamic> toJson() => _$GetCurrentSchoolyearResponseToJson(this);
}
@JsonSerializable()
class GetCurrentSchoolyearResponseObject {
int id;
String name;
int startDate;
int endDate;
GetCurrentSchoolyearResponseObject(
this.id,
this.name,
this.startDate,
this.endDate,
);
factory GetCurrentSchoolyearResponseObject.fromJson(
Map<String, dynamic> json,
) => _$GetCurrentSchoolyearResponseObjectFromJson(json);
Map<String, dynamic> toJson() =>
_$GetCurrentSchoolyearResponseObjectToJson(this);
}
@@ -0,0 +1,44 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'get_current_schoolyear_response.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
GetCurrentSchoolyearResponse _$GetCurrentSchoolyearResponseFromJson(
Map<String, dynamic> json,
) =>
GetCurrentSchoolyearResponse(
GetCurrentSchoolyearResponseObject.fromJson(
json['result'] as Map<String, dynamic>,
),
)
..headers = (json['headers'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, e as String),
);
Map<String, dynamic> _$GetCurrentSchoolyearResponseToJson(
GetCurrentSchoolyearResponse instance,
) => <String, dynamic>{
'headers': ?instance.headers,
'result': instance.result.toJson(),
};
GetCurrentSchoolyearResponseObject _$GetCurrentSchoolyearResponseObjectFromJson(
Map<String, dynamic> json,
) => GetCurrentSchoolyearResponseObject(
(json['id'] as num).toInt(),
json['name'] as String,
(json['startDate'] as num).toInt(),
(json['endDate'] as num).toInt(),
);
Map<String, dynamic> _$GetCurrentSchoolyearResponseObjectToJson(
GetCurrentSchoolyearResponseObject instance,
) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'startDate': instance.startDate,
'endDate': instance.endDate,
};