import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'connectivity_provider.g.dart'; /// Enum representing connectivity status enum ConnectivityStatus { /// Connected to WiFi wifi, /// Connected to mobile data mobile, /// No internet connection offline, } /// Provider for the Connectivity instance /// This is a simple provider that returns a singleton instance @riverpod Connectivity connectivity(Ref ref) { return Connectivity(); } /// Stream provider that monitors real-time connectivity changes /// This automatically updates whenever the device connectivity changes /// /// Usage: /// ```dart /// final connectivityState = ref.watch(connectivityStreamProvider); /// connectivityState.when( /// data: (status) => Text('Status: $status'), /// loading: () => const CustomLoadingIndicator(), /// error: (error, _) => Text('Error: $error'), /// ); /// ``` @riverpod Stream connectivityStream(Ref ref) { final connectivity = ref.watch(connectivityProvider); return connectivity.onConnectivityChanged.map((result) { // Handle the List from connectivity_plus if (result.contains(ConnectivityResult.wifi)) { return ConnectivityStatus.wifi; } else if (result.contains(ConnectivityResult.mobile)) { return ConnectivityStatus.mobile; } else { return ConnectivityStatus.offline; } }); } /// Provider that checks current connectivity status once /// This is useful for one-time checks without listening to changes /// /// Usage: /// ```dart /// final status = await ref.read(currentConnectivityProvider.future); /// if (status == ConnectivityStatus.offline) { /// showOfflineDialog(); /// } /// ``` @riverpod Future currentConnectivity(Ref ref) async { final connectivity = ref.watch(connectivityProvider); final result = await connectivity.checkConnectivity(); // Handle the List if (result.contains(ConnectivityResult.wifi)) { return ConnectivityStatus.wifi; } else if (result.contains(ConnectivityResult.mobile)) { return ConnectivityStatus.mobile; } else { return ConnectivityStatus.offline; } } /// Provider that returns whether the device is currently online /// Convenient boolean check for connectivity /// /// Usage: /// ```dart /// final isOnlineAsync = ref.watch(isOnlineProvider); /// isOnlineAsync.when( /// data: (isOnline) => isOnline ? Text('Online') : Text('Offline'), /// loading: () => const CustomLoadingIndicator(), /// error: (error, _) => Text('Error: $error'), /// ); /// ``` @riverpod Stream isOnline(Ref ref) { // Get the connectivity stream and map it to a boolean final connectivity = ref.watch(connectivityProvider); return connectivity.onConnectivityChanged.map((result) { // Online if connected to WiFi or mobile return result.contains(ConnectivityResult.wifi) || result.contains(ConnectivityResult.mobile); }); } /// Example of using .select() for optimization /// Only rebuilds when the online status changes, not on WiFi<->Mobile switches /// /// Usage: /// ```dart /// // This only rebuilds when going online/offline /// final isOnline = ref.watch( /// connectivityStreamProvider.select((async) => /// async.value != ConnectivityStatus.offline /// ), /// ); /// ```