implemented background prefetching for files root, added 24-hour caching for root directory listing, and enabled cache renewal for manual refreshes

This commit is contained in:
2026-05-09 23:39:06 +02:00
parent 14090b96f4
commit bf28a678c9
4 changed files with 67 additions and 3 deletions
@@ -16,8 +16,9 @@ class ListFilesCache extends SimpleCache<ListFilesResponse> {
super.onNetworkData,
super.onError,
required String path,
super.renew = false,
}) : super(
cacheTime: RequestCache.cacheNothing,
cacheTime: _cacheTimeFor(path),
loader: () => ListFiles(ListFilesParams(path)).run(),
fromJson: ListFilesResponse.fromJson,
onUpdate: onUpdate,
@@ -25,6 +26,44 @@ class ListFilesCache extends SimpleCache<ListFilesResponse> {
start(_documentId(path));
}
/// The Nextcloud root listing is significantly slower than subfolders on
/// our instance and frequently returns HTTP 500. Since its content rarely
/// changes, the root payload is cached for a full day so app-resume and
/// connectivity-change auto-refetch triggers do not re-hit the slow root
/// endpoint within the same day. To avoid a long wait on the very first
/// open of the Files page, `prefetchRootListing` (called from `main`)
/// kicks off an async warm-up fetch in the background while the user is
/// still on the launch screen / other modules. Subfolders keep the
/// previous "always refetch on visit" TTL because their content changes
/// more often. Explicit user refreshes (rename, delete, copy/move,
/// upload) bypass the TTL via the inherited [renew] flag or via
/// [invalidate].
static int _cacheTimeFor(String path) {
final stripped = path.replaceAll('/', '').trim();
return stripped.isEmpty
? RequestCache.cacheDay
: RequestCache.cacheNothing;
}
/// Triggers a root-listing fetch in the background if no cached payload
/// exists yet. Intended to be called once after login from `main` so the
/// (slow) root listing is already populated by the time the user
/// navigates to the Files module.
///
/// No-ops when a cached root payload is already present in localstore —
/// the regular TTL handling in [RequestCache] takes over from there.
static Future<void> prefetchRootListing() async {
const rootPath = '';
final cached = await Localstore.instance
.collection(RequestCache.collection)
.doc(_documentId(rootPath))
.get();
if (cached != null) return;
// Drive the same code path as a regular fetch so the result lands in
// the cache; we don't care about the in-memory callback here.
ListFilesCache(path: rootPath, onUpdate: (_) {});
}
static String _documentId(String path) {
final cacheName = md5
.convert(utf8.encode('MarianumMobile-$path'))