worldhopper/lib/providers/reading_progress_provider.dart

101 lines
3.2 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:worldhopper/models/reading_progress.dart';
import 'package:worldhopper/repositories/reading_progress_repository.dart';
/// Provider for ReadingProgressRepository instance
final readingProgressRepositoryProvider =
Provider<ReadingProgressRepository>((ref) {
return ReadingProgressRepository();
});
/// Provider for reading progress of a specific publication
final readingProgressProvider =
FutureProvider.family<ReadingProgress?, ProgressKey>(
(ref, key) async {
final repository = ref.watch(readingProgressRepositoryProvider);
return await repository.getProgress(key.publicationId, key.serverId);
},
);
/// Provider for recently read publications
final recentlyReadProvider = FutureProvider<List<ReadingProgress>>((ref) async {
final repository = ref.watch(readingProgressRepositoryProvider);
return await repository.getRecentlyRead();
});
/// Provider for in-progress count
final inProgressCountProvider = FutureProvider<int>((ref) async {
final repository = ref.watch(readingProgressRepositoryProvider);
return await repository.getInProgressCount();
});
/// Provider for completed count
final completedCountProvider = FutureProvider<int>((ref) async {
final repository = ref.watch(readingProgressRepositoryProvider);
return await repository.getCompletedCount();
});
/// Notifier for managing reading progress operations
class ReadingProgressNotifier extends StateNotifier<AsyncValue<void>> {
final ReadingProgressRepository _repository;
ReadingProgressNotifier(this._repository)
: super(const AsyncValue.data(null));
/// Save or update reading progress
Future<void> saveProgress(ReadingProgress progress) async {
state = const AsyncValue.loading();
state = await AsyncValue.guard(() async {
await _repository.saveProgress(progress);
});
}
/// Update current page
Future<void> updateCurrentPage(
String publicationId,
String serverId,
int currentPage,
) async {
state = const AsyncValue.loading();
state = await AsyncValue.guard(() async {
await _repository.updateCurrentPage(publicationId, serverId, currentPage);
});
}
/// Delete progress
Future<void> deleteProgress(String publicationId, String serverId) async {
state = const AsyncValue.loading();
state = await AsyncValue.guard(() async {
await _repository.deleteProgress(publicationId, serverId);
});
}
}
/// Provider for ReadingProgressNotifier
final readingProgressNotifierProvider =
StateNotifierProvider<ReadingProgressNotifier, AsyncValue<void>>((ref) {
final repository = ref.watch(readingProgressRepositoryProvider);
return ReadingProgressNotifier(repository);
});
/// Key for reading progress lookup
class ProgressKey {
final String publicationId;
final String serverId;
const ProgressKey({
required this.publicationId,
required this.serverId,
});
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ProgressKey &&
runtimeType == other.runtimeType &&
publicationId == other.publicationId &&
serverId == other.serverId;
@override
int get hashCode => publicationId.hashCode ^ serverId.hashCode;
}