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 { @override Duration get interval => const Duration(seconds: 20); @override Future 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 build() => startPolling(); }