import 'package:dio/dio.dart'; /// A value from the API, or the last one [CacheInterceptor] had on file for the /// same endpoint+params when the live request failed. `fetchedAt` is null for /// a live answer — that is the one bit a screen needs to decide whether to /// show a `StaleBanner`. See `docs/ai/offline-cache.md`. class Cached { const Cached(this.data, {this.fetchedAt}); final T data; final DateTime? fetchedAt; } extension CachedResponseX on Response { /// Wraps this response's data with the staleness [CacheInterceptor] recorded /// in `extra['fetchedAt']`. A provider that wants offline support returns /// `r.cached` instead of `r.data!`. Cached get cached => Cached(data as T, fetchedAt: extra['fetchedAt'] as DateTime?); } /// The oldest of several fetch times, or null if none of them is stale. /// Screens with several cached providers show one banner for the lot rather /// than one per tile. DateTime? oldestFetch(Iterable fetchedAt) { DateTime? oldest; for (final at in fetchedAt) { if (at == null) continue; if (oldest == null || at.isBefore(oldest)) oldest = at; } return oldest; }