Files
Ensemble/lib/services/image_prefetch_service.dart
ChrisandClaude Opus 4.6 e91bdf2353 Add detail track cache, image prefetch, and offline caching improvements
Cache album/playlist tracks in a new DetailTrackCache DB table (schema v7)
so detail screens load instantly on revisit. Prefetch album artwork after
sync via ImagePrefetchService with batched downloads and LRU eviction.
Expand sync_service and cache_service to support the new caching layers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:42:43 +00:00

65 lines
1.8 KiB
Dart

import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'debug_logger.dart';
/// Custom cache manager for album images with extended retention
class AlbumImageCacheManager extends CacheManager with ImageCacheManager {
static const key = 'albumImageCache';
static final AlbumImageCacheManager _instance = AlbumImageCacheManager._();
factory AlbumImageCacheManager() => _instance;
AlbumImageCacheManager._()
: super(Config(
key,
stalePeriod: const Duration(days: 30),
maxNrOfCacheObjects: 2000,
));
}
/// Service to prefetch album images in the background after sync
class ImagePrefetchService {
static final _logger = DebugLogger();
bool _cancelled = false;
/// Cancel any in-progress prefetch
void cancel() {
_cancelled = true;
}
/// Prefetch images in batches, skipping already-cached URLs
Future<void> prefetchImages(List<String> urls) async {
_cancelled = false;
if (urls.isEmpty) return;
final cacheManager = AlbumImageCacheManager();
int cached = 0;
int skipped = 0;
int failed = 0;
const batchSize = 10;
for (var i = 0; i < urls.length; i += batchSize) {
if (_cancelled) {
_logger.log('🖼️ Image prefetch cancelled after $cached cached, $skipped skipped');
return;
}
final batch = urls.skip(i).take(batchSize);
await Future.wait(batch.map((url) async {
try {
final fileInfo = await cacheManager.getFileFromCache(url);
if (fileInfo != null) {
skipped++;
return;
}
await cacheManager.downloadFile(url);
cached++;
} catch (_) {
failed++;
}
}));
}
_logger.log('🖼️ Image prefetch complete: $cached cached, $skipped already cached, $failed failed (${urls.length} total)');
}
}