Files
Melo/lib/services/cache_manager.dart
Hermes (Server) 51cab003f9 feat(phase2): Caching + Offline-Mode Infrastruktur (P0)
CACHING:
- CacheManager: Speichert Stream-Lieder lokal mit MD5-Hash-Namensgebung
- getCacheSize(): Berechne Cache-Größe
- clearCache(): Lösche alle gecachten Lieder
- streamAndCache(): Stream gleichzeitig abspielen + cachen

OFFLINE-MODE:
- OfflineMode-Service: Toggle Offline-Modus
- Persistiert in SharedPreferences
- ChangeNotifier für UI-Updates
- Flag: Nur gecachte Lieder spielen

Infrastructure für Phase 2 P0 ready
Tests: 70/70 
2026-08-19 18:54:31 +02:00

72 lines
1.9 KiB
Dart

import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:flutter/foundation.dart';
import 'package:path_provider/path_provider.dart';
class CacheManager {
static const _cacheDir = 'melo_cache';
late Directory _cacheFolder;
Future<void> init() async {
final appDir = await getApplicationCacheDirectory();
_cacheFolder = Directory('${appDir.path}/$_cacheDir');
if (!await _cacheFolder.exists()) {
await _cacheFolder.create(recursive: true);
}
}
Future<int> getCacheSize() async {
int size = 0;
final files = _cacheFolder.listSync(recursive: true);
for (final file in files) {
if (file is File) {
size += await file.length();
}
}
return size;
}
Future<void> clearCache() async {
try {
if (await _cacheFolder.exists()) {
await _cacheFolder.delete(recursive: true);
}
await _cacheFolder.create(recursive: true);
debugPrint('Cache gelöscht');
} catch (e) {
debugPrint('Fehler beim Löschen des Cache: $e');
}
}
Future<File?> getCachedFile(String streamUrl) async {
try {
final hash = md5.convert(streamUrl.codeUnits).toString();
final file = File('${_cacheFolder.path}/$hash.mp3');
if (await file.exists()) {
return file;
}
return null;
} catch (e) {
debugPrint('Fehler beim Abrufen der Cache-Datei: $e');
return null;
}
}
Future<File> getCacheFile(String streamUrl) async {
final hash = md5.convert(streamUrl.codeUnits).toString();
return File('${_cacheFolder.path}/$hash.mp3');
}
Stream<File> streamAndCache(Stream<List<int>> sourceStream, String streamUrl) async* {
final cacheFile = await getCacheFile(streamUrl);
final sink = cacheFile.openWrite();
await for (final chunk in sourceStream) {
sink.add(chunk);
yield cacheFile;
}
await sink.close();
}
}