worldhopper/lib/providers/connectivity_provider.dart
Felipe M. 30df288552
All checks were successful
ci/woodpecker/tag/release Pipeline was successful
feat: add offline series download with local reading support
Enable downloading entire series for offline reading. Includes database
tables and migration for downloaded series/chapters, download orchestration
with progress tracking, per-chapter EPUB and image stream downloading,
a Downloaded section in the library, and offline-first reader support.

Key changes:
- DB migration v11 with downloaded_series and downloaded_chapters tables
- Series download service with pagination, cancellation, and progress stream
- Feed screen download button with status indicators and completion feedback
- Library screen Downloaded section with series cards and detail screen
- Reader pre-caching using local files (including two-page spread mode)
- Next-in-series navigation resolves from downloaded chapters when offline
- Skip image downloads and progress sync when device is offline
- Settings screen shows download storage usage with clear option

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 23:40:15 +01:00

60 lines
1.9 KiB
Dart

import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:worldhopper/providers/download_provider.dart';
import 'package:worldhopper/services/connectivity_service.dart';
import 'package:worldhopper/services/epub_download_service.dart';
import 'package:worldhopper/services/offline_content_checker.dart';
part 'connectivity_provider.g.dart';
/// Provider for ConnectivityService singleton
@riverpod
ConnectivityService connectivityService(ConnectivityServiceRef ref) {
return ConnectivityService();
}
/// Stream provider for connectivity status
///
/// Emits true when online, false when offline.
/// Automatically updates all watching widgets when connectivity changes.
@riverpod
Stream<bool> connectivityStatus(ConnectivityStatusRef ref) {
final service = ref.watch(connectivityServiceProvider);
return service.connectivityStream;
}
/// Provider for current connectivity state
///
/// This provider caches the current connectivity status and updates
/// automatically when the status changes.
@riverpod
class ConnectivityState extends _$ConnectivityState {
@override
Future<bool> build() async {
final service = ref.watch(connectivityServiceProvider);
// Subscribe to connectivity changes
ref.listen(connectivityStatusProvider, (_, next) {
next.whenData((isOnline) => state = AsyncValue.data(isOnline));
});
// Return initial connectivity status
return await service.isConnected();
}
}
/// Provider for EpubDownloadService singleton
@riverpod
EpubDownloadService epubDownloadService(EpubDownloadServiceRef ref) {
return EpubDownloadService();
}
/// Provider for OfflineContentChecker singleton
@riverpod
OfflineContentChecker offlineContentChecker(OfflineContentCheckerRef ref) {
final epubService = ref.watch(epubDownloadServiceProvider);
final chaptersRepo = ref.watch(downloadedChaptersRepositoryProvider);
return OfflineContentChecker(
epubService: epubService,
chaptersRepo: chaptersRepo,
);
}