import 'dart:async'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/foundation.dart'; import 'package:internet_connection_checker/internet_connection_checker.dart'; import '/locator.dart'; import 'logging_service.dart'; /// Used to observe the current connection type and status. class ConnectionsService { ConnectionsService({ required Connectivity connectivity, required InternetConnectionChecker internetConnectionChecker, required LoggingService loggingService, }) : _internetConnectionChecker = internetConnectionChecker, _connectivity = connectivity, _loggingService = loggingService { _init(); } final InternetConnectionChecker _internetConnectionChecker; final Connectivity _connectivity; final LoggingService _loggingService; late final ValueNotifier _internetConnectionStatusNotifier; ValueListenable get internetConnectionStatusListenable => _internetConnectionStatusNotifier; late final ValueNotifier _connectivityResultNotifier; ValueListenable get connectivityResultListenable => _connectivityResultNotifier; Future _init() async { // Initialize notifiers _internetConnectionStatusNotifier = ValueNotifier(await _internetConnectionChecker.connectionStatus); _connectivityResultNotifier = ValueNotifier(await _connectivity.checkConnectivity()); _loggingService .info('Initial internet status: ${internetConnectionStatusListenable.value.nameWithIcon}'); _loggingService .info('Initial connectivity result: ${connectivityResultListenable.value.nameWithIcon}'); // Attach converters by listening to stream _internetConnectionChecker.onStatusChange .listen((final InternetConnectionStatus internetConnectionStatus) { _loggingService.info( 'Internet status changed to: ${internetConnectionStatus.nameWithIcon}. Notifying...'); _internetConnectionStatusNotifier.value = internetConnectionStatus; }); _connectivity.onConnectivityChanged.listen((final connectivityResult) { _loggingService .info('Connectivity result changed to: ${connectivityResult.nameWithIcon}. Notifying...'); _connectivityResultNotifier.value = connectivityResult; }); Locator.instance().signalReady(this); } Future dispose() async { _internetConnectionStatusNotifier.dispose(); _connectivityResultNotifier.dispose(); } static ConnectionsService get locate => Locator.locate(); } extension _ConnectionStatusEmojiExtension on InternetConnectionStatus { String get nameWithIcon { switch (this) { case InternetConnectionStatus.connected: return '$name (🌐✅)'; case InternetConnectionStatus.disconnected: return '$name (🔌)'; } } } extension _ConnectivityEmojiExtension on ConnectivityResult { String get nameWithIcon { switch (this) { case ConnectivityResult.bluetooth: return '$name (ᛒ🟦)'; case ConnectivityResult.wifi: return '$name (◲)'; case ConnectivityResult.ethernet: return '$name (🌐)'; case ConnectivityResult.mobile: return '$name (📶)'; case ConnectivityResult.none: return '$name (🔌)'; case ConnectivityResult.vpn: return '$name (🔒)'; } } }