Files
social-app/apps/lib/features/todo/data/todo_repository.dart
T

76 lines
1.9 KiB
Dart
Raw Normal View History

import 'dart:async';
import '../../../core/cache/cache_entry.dart';
import '../../../core/cache/cache_invalidator.dart';
import '../../../core/cache/hybrid_cache_store.dart';
import 'todo_api.dart';
class TodoRepository {
static const String pendingListKey = 'todo:list:pending';
final TodoApi api;
final HybridCacheStore store;
final CacheInvalidator invalidator;
final DateTime Function() now;
TodoRepository({
required this.api,
required this.store,
required this.invalidator,
DateTime Function()? now,
}) : now = now ?? DateTime.now;
Future<List<TodoResponse>> getPendingTodos({
bool forceRefresh = false,
}) async {
if (!forceRefresh) {
final cached = await store.read<CacheEntry<List<TodoResponse>>>(
pendingListKey,
);
if (cached != null) {
return cached.value;
}
}
final remote = await api.getPendingTodos();
await store.write<CacheEntry<List<TodoResponse>>>(
pendingListKey,
CacheEntry(value: remote, fetchedAt: now()),
);
return remote;
}
Future<void> completeTodo(String id) async {
final cached = await store.read<CacheEntry<List<TodoResponse>>>(
pendingListKey,
);
if (cached != null) {
final next = cached.value
.where((todo) => todo.id != id)
.toList(growable: false);
await store.write<CacheEntry<List<TodoResponse>>>(
pendingListKey,
CacheEntry(value: next, fetchedAt: now()),
);
}
try {
await api.completeTodo(id);
invalidator.invalidate(pendingListKey);
} catch (error) {
if (cached != null) {
await store.write<CacheEntry<List<TodoResponse>>>(
pendingListKey,
cached,
);
}
rethrow;
}
}
Future<void> invalidatePending() {
invalidator.invalidate(pendingListKey);
return Future<void>.value();
}
}