114 lines
3.3 KiB
Dart
114 lines
3.3 KiB
Dart
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: () => CircularProgressIndicator(),
|
|
/// error: (error, _) => Text('Error: $error'),
|
|
/// );
|
|
/// ```
|
|
@riverpod
|
|
Stream<ConnectivityStatus> connectivityStream(Ref ref) {
|
|
final connectivity = ref.watch(connectivityProvider);
|
|
|
|
return connectivity.onConnectivityChanged.map((result) {
|
|
// Handle the List<ConnectivityResult> 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<ConnectivityStatus> currentConnectivity(Ref ref) async {
|
|
final connectivity = ref.watch(connectivityProvider);
|
|
final result = await connectivity.checkConnectivity();
|
|
|
|
// Handle the List<ConnectivityResult>
|
|
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: () => CircularProgressIndicator(),
|
|
/// error: (error, _) => Text('Error: $error'),
|
|
/// );
|
|
/// ```
|
|
@riverpod
|
|
Stream<bool> 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
|
|
/// ),
|
|
/// );
|
|
/// ```
|