initial commit
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../../../core/network/api_exception.dart';
|
||||
import '../../../core/polling/polling_async_notifier.dart';
|
||||
import '../../../data/repositories/node_repository.dart';
|
||||
import '../../../data/repositories/services_repository.dart';
|
||||
import 'dashboard_summary.dart';
|
||||
|
||||
part 'dashboard_summary_provider.g.dart';
|
||||
|
||||
/// Polled every 20s while the Dashboard is mounted — deliberately its own
|
||||
/// notifier rather than watching `servicesListProvider`/`currentNodeProvider`
|
||||
/// directly, so Dashboard auto-refreshes independent of whether the
|
||||
/// Services screen (manual-refresh only) happens to be open too.
|
||||
@riverpod
|
||||
class DashboardSummaryNotifier extends _$DashboardSummaryNotifier
|
||||
with PollingMixin<DashboardSummary> {
|
||||
@override
|
||||
Duration get interval => const Duration(seconds: 20);
|
||||
|
||||
@override
|
||||
Future<DashboardSummary> fetch() async {
|
||||
final servicesRepo = ref.watch(servicesRepositoryProvider);
|
||||
final nodeRepo = ref.watch(nodeRepositoryProvider);
|
||||
if (servicesRepo == null || nodeRepo == null) {
|
||||
// The router redirects to Settings whenever there's no active
|
||||
// connection, so reaching this in the UI would mean that redirect
|
||||
// hasn't fired yet — an ApiException here (vs. a raw StateError)
|
||||
// keeps error handling on the same path as every other screen.
|
||||
throw const ApiException.unknown('No active connection.');
|
||||
}
|
||||
final services = await servicesRepo.getAll();
|
||||
final node = await nodeRepo.getNode();
|
||||
return DashboardSummary(services: services, node: node);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DashboardSummary> build() => startPolling();
|
||||
}
|
||||
Reference in New Issue
Block a user