import '../../../../../api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.dart'; import '../../../../../extensions/date_time.dart'; import '../../../../../utils/json_equality.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 = 8; /// 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? mergeWeekIntoCache( Map cache, DateTime weekStart, TimetableGetWeekResponse week, { required DateTime viewedWeekStart, required DateTime now, }) { final key = weekStart.weekKey(); final existing = cache[key]; if (sameJson(existing, week)) 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 = {}; 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; }