fixed connection problem
This commit is contained in:
parent
127a09b597
commit
47945dbec7
11 changed files with 218 additions and 196 deletions
|
@ -1,142 +0,0 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:internet_connection_checker/internet_connection_checker.dart';
|
||||
import 'package:mc_gallery/features/core/services/logging_service.dart';
|
||||
|
||||
import '/locator.dart';
|
||||
|
||||
/// Used to observe the current connection type.
|
||||
class ConnectionService with LoggingService {
|
||||
ConnectionService({
|
||||
required Connectivity connectivity,
|
||||
required InternetConnectionChecker internetConnectionChecker,
|
||||
bool shouldInitialize = true,
|
||||
}) : _connectivity = connectivity,
|
||||
_internetConnectionChecker = internetConnectionChecker {
|
||||
if (shouldInitialize) initialize();
|
||||
}
|
||||
|
||||
ConnectivityResult? _connectivityResult;
|
||||
ConnectivityResult? get connectivityResult => _connectivityResult;
|
||||
|
||||
final Connectivity _connectivity;
|
||||
final Map<String, StreamSubscription> _connectivitySubscriptions = {};
|
||||
|
||||
final InternetConnectionChecker _internetConnectionChecker;
|
||||
|
||||
final Completer _isInitialized = Completer();
|
||||
|
||||
Completer<bool>? _hasInternetConnection;
|
||||
|
||||
final ValueNotifier<bool> _hasInternetConnectionListenable = ValueNotifier(false);
|
||||
ValueListenable<bool> get hasInternetConnectionListenable => _hasInternetConnectionListenable;
|
||||
|
||||
Future<bool> get hasInternetConnection async {
|
||||
try {
|
||||
if (_hasInternetConnection == null) {
|
||||
_hasInternetConnection = Completer<bool>();
|
||||
try {
|
||||
final hasInternetConnection = await _internetConnectionChecker.hasConnection;
|
||||
_hasInternetConnection!.complete(hasInternetConnection);
|
||||
return hasInternetConnection;
|
||||
} catch (error) {
|
||||
_hasInternetConnection!.complete(false);
|
||||
return false;
|
||||
} finally {
|
||||
_hasInternetConnection = null;
|
||||
}
|
||||
} else {
|
||||
final awaitedHasInternet = await _hasInternetConnection!.future;
|
||||
|
||||
return awaitedHasInternet;
|
||||
}
|
||||
} on SocketException catch (_, __) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> initialize() async {
|
||||
try {
|
||||
final tag = runtimeType.toString();
|
||||
if (_connectivitySubscriptions[tag] != null) {
|
||||
await dispose();
|
||||
}
|
||||
_connectivitySubscriptions[tag] = _connectivity.onConnectivityChanged.listen(
|
||||
_onConnectivityChanged,
|
||||
cancelOnError: false,
|
||||
onError: (error, stack) {},
|
||||
);
|
||||
await _onConnectivityChanged(await _connectivity.checkConnectivity());
|
||||
_internetConnectionChecker.onStatusChange.listen((final event) {
|
||||
switch (event) {
|
||||
case InternetConnectionStatus.connected:
|
||||
_hasInternetConnectionListenable.value = true;
|
||||
break;
|
||||
case InternetConnectionStatus.disconnected:
|
||||
_hasInternetConnectionListenable.value = false;
|
||||
break;
|
||||
}
|
||||
});
|
||||
_isInitialized.complete();
|
||||
} catch (error, stackTrace) {
|
||||
handle(error, stackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
for (final subscription in _connectivitySubscriptions.values) {
|
||||
await subscription.cancel();
|
||||
}
|
||||
_connectivitySubscriptions.clear();
|
||||
_connectivityResult = null;
|
||||
}
|
||||
|
||||
Future<void> addListener({
|
||||
required String tag,
|
||||
required Future<void> Function({
|
||||
required ConnectivityResult connectivityResult,
|
||||
required bool hasInternet,
|
||||
})
|
||||
listener,
|
||||
bool tryCallListenerOnAdd = true,
|
||||
}) async {
|
||||
try {
|
||||
if (_connectivityResult != null && tryCallListenerOnAdd)
|
||||
await listener(
|
||||
connectivityResult: _connectivityResult!, hasInternet: await hasInternetConnection);
|
||||
_connectivitySubscriptions[tag] =
|
||||
_connectivity.onConnectivityChanged.listen((connectivityResult) async {
|
||||
await listener(
|
||||
connectivityResult: connectivityResult, hasInternet: await hasInternetConnection);
|
||||
});
|
||||
} catch (error, stackTrace) {
|
||||
handle(error, stackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> removeListener({required String tag}) async {
|
||||
try {
|
||||
final subscription = _connectivitySubscriptions[tag];
|
||||
if (subscription != null) {
|
||||
await subscription.cancel();
|
||||
} else {}
|
||||
} catch (error, stackTrace) {
|
||||
handle(error, stackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onConnectivityChanged(ConnectivityResult connectivityResult) async {
|
||||
try {
|
||||
_connectivityResult = connectivityResult;
|
||||
} catch (error, stackTrace) {
|
||||
handle(error, stackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
static ConnectionService get locate => Locator.locate();
|
||||
}
|
||||
|
||||
class NoInternetException implements Exception {}
|
95
lib/features/core/services/connections_service.dart
Normal file
95
lib/features/core/services/connections_service.dart
Normal file
|
@ -0,0 +1,95 @@
|
|||
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 '/features/core/services/logging_service.dart';
|
||||
import '/locator.dart';
|
||||
|
||||
/// Used to observe the current connection type.
|
||||
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<InternetConnectionStatus> _internetConnectionStatusNotifier;
|
||||
ValueListenable<InternetConnectionStatus> get internetConnectionStatusListenable =>
|
||||
_internetConnectionStatusNotifier;
|
||||
late final ValueNotifier<ConnectivityResult> _connectivityResultNotifier;
|
||||
ValueListenable<ConnectivityResult> get connectivityResultListenable =>
|
||||
_connectivityResultNotifier;
|
||||
|
||||
Future<void> _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<void> 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 (🔒)';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,7 +13,9 @@ class LoggingService {
|
|||
settings: TalkerSettings(
|
||||
useHistory: false,
|
||||
),
|
||||
logger: TalkerLogger(formater: const ColoredLoggerFormatter()),
|
||||
logger: TalkerLogger(
|
||||
formater:
|
||||
!Platform.isIOS ? const ColoredLoggerFormatter() : const ExtendedLoggerFormatter()),
|
||||
loggerSettings: TalkerLoggerSettings(
|
||||
enableColors: !Platform.isIOS,
|
||||
),
|
||||
|
@ -44,7 +46,10 @@ class LoggingService {
|
|||
dio.interceptors.add(
|
||||
TalkerDioLogger(
|
||||
talker: Talker(
|
||||
logger: TalkerLogger(formater: const ColoredLoggerFormatter()),
|
||||
logger: TalkerLogger(
|
||||
formater: !Platform.isIOS
|
||||
? const ColoredLoggerFormatter()
|
||||
: const ExtendedLoggerFormatter()),
|
||||
settings: TalkerSettings(
|
||||
useConsoleLogs: true,
|
||||
useHistory: false,
|
||||
|
|
|
@ -16,18 +16,30 @@ class OverlayService {
|
|||
required String tag,
|
||||
required OverlayEntry overlayEntry,
|
||||
}) {
|
||||
_overlayEntryMap.addEntries([MapEntry(tag.hashCode, overlayEntry)]);
|
||||
|
||||
Overlay.of(context, rootOverlay: true)?.insert(overlayEntry);
|
||||
_loggingService.info('Overlay inserted with tag: $tag');
|
||||
if (!_overlayEntryMap.containsKey(tag.hashCode) && !overlayEntry.mounted) {
|
||||
_overlayEntryMap.addEntries([MapEntry(tag.hashCode, overlayEntry)]);
|
||||
try {
|
||||
Overlay.of(context, rootOverlay: true)?.insert(overlayEntry);
|
||||
//todo(mehul): Fix and not ignore Overlay building while Widget building error.
|
||||
} on FlutterError catch (_) {}
|
||||
_loggingService.info('Overlay inserted with tag: $tag');
|
||||
} else
|
||||
_loggingService.info('Overlay with tag: $tag, NOT inserted');
|
||||
}
|
||||
|
||||
void removeOverlayEntry({
|
||||
required String tag,
|
||||
}) {
|
||||
_overlayEntryMap[tag.hashCode]?.remove();
|
||||
_overlayEntryMap.remove(tag.hashCode);
|
||||
_loggingService.info('Overlay removed with tag: $tag');
|
||||
if (_overlayEntryMap.containsKey(tag.hashCode)) {
|
||||
final _overlayEntry = _overlayEntryMap[tag.hashCode];
|
||||
if (_overlayEntry?.mounted ?? false) {
|
||||
_overlayEntryMap[tag.hashCode]?.remove();
|
||||
_overlayEntryMap.remove(tag.hashCode);
|
||||
_loggingService.info('Overlay removed with tag: $tag');
|
||||
} else
|
||||
_loggingService.info('Overlay with tag: $tag already mounted OR not found. Skipped');
|
||||
} else
|
||||
_loggingService.info('Overlay with tag: $tag already exists. Skipped');
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue