timetable performance optimization
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
import '../../../../../api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.dart';
|
||||
import '../../../../../extensions/date_time.dart';
|
||||
|
||||
/// Weeks kept around the viewed week and around today's week. Everything
|
||||
/// further away is dropped: every state emit re-serializes the whole cache for
|
||||
/// HydratedBloc and the calendar rebuilds its appointments from all of it, so
|
||||
/// an unbounded cache makes week swipes slower the longer the app is used.
|
||||
const int kWeekCacheRadius = 4;
|
||||
|
||||
/// Returns the cache with [week] stored under [weekStart], pruned to the
|
||||
/// weeks near [viewedWeekStart] or [now]. Returns null when the stored week
|
||||
/// already has identical content, so callers can skip the emit entirely.
|
||||
Map<String, TimetableGetWeekResponse>? mergeWeekIntoCache(
|
||||
Map<String, TimetableGetWeekResponse> cache,
|
||||
DateTime weekStart,
|
||||
TimetableGetWeekResponse week, {
|
||||
required DateTime viewedWeekStart,
|
||||
required DateTime now,
|
||||
}) {
|
||||
final key = weekStart.weekKey();
|
||||
final existing = cache[key];
|
||||
if (existing != null &&
|
||||
const DeepCollectionEquality().equals(existing.toJson(), week.toJson())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final viewedMonday = viewedWeekStart.mondayOfWeek;
|
||||
final todayMonday = now.mondayOfWeek;
|
||||
bool isNear(DateTime monday, DateTime anchor) =>
|
||||
monday.difference(anchor).inDays.abs() <= kWeekCacheRadius * 7 + 1;
|
||||
|
||||
final updated = <String, TimetableGetWeekResponse>{};
|
||||
for (final entry in cache.entries) {
|
||||
final monday = DateTime.tryParse(entry.key);
|
||||
if (monday == null ||
|
||||
isNear(monday, viewedMonday) ||
|
||||
isNear(monday, todayMonday)) {
|
||||
updated[entry.key] = entry.value;
|
||||
}
|
||||
}
|
||||
updated[key] = week;
|
||||
return updated;
|
||||
}
|
||||
Reference in New Issue
Block a user