diff --git a/lib/providers/connectivity_provider.dart b/lib/providers/connectivity_provider.dart index 2c6f1b969..f53061cb9 100644 --- a/lib/providers/connectivity_provider.dart +++ b/lib/providers/connectivity_provider.dart @@ -31,13 +31,19 @@ enum ConnectionState { @Riverpod(keepAlive: true) class ConnectivityStatus extends _$ConnectivityStatus { String? localUrl; + DateTime? _lastCheck; + static const Duration _minCheckInterval = Duration(seconds: 5); @override ConnectionState build() { ref.listen(userProvider, (previous, next) { checkLocalUrl(previous, next); }); - Connectivity().onConnectivityChanged.listen(onStateChange); + final sub = Connectivity().onConnectivityChanged.listen( + onStateChange, + onError: (error) => log('Connectivity stream error: $error'), + ); + ref.onDispose(sub.cancel); checkConnectivity(); return ConnectionState.mobile; } @@ -50,35 +56,49 @@ class ConnectivityStatus extends _$ConnectivityStatus { } Future onStateChange(List connectivityResult) async { - if (connectivityResult.contains(ConnectivityResult.ethernet)) { - state = ConnectionState.ethernet; - } else if (connectivityResult.contains(ConnectivityResult.wifi)) { - state = ConnectionState.wifi; - } else if (connectivityResult.contains(ConnectivityResult.mobile)) { - state = ConnectionState.mobile; - } else if (connectivityResult.contains(ConnectivityResult.none)) { - state = ConnectionState.offline; + try { + if (connectivityResult.contains(ConnectivityResult.ethernet)) { + state = ConnectionState.ethernet; + } else if (connectivityResult.contains(ConnectivityResult.wifi)) { + state = ConnectionState.wifi; + } else if (connectivityResult.contains(ConnectivityResult.mobile)) { + state = ConnectionState.mobile; + } else if (connectivityResult.contains(ConnectivityResult.none)) { + state = ConnectionState.offline; + } + final newUrl = ref.read(userProvider.select((value) => value?.credentials.localUrl)); + if (localUrl == newUrl) return; + localUrl = newUrl; + final localConnection = localUrl != null && localUrl?.isNotEmpty == true + ? await fetchSystemInfoDynamic(normalizeUrl(localUrl!)) + : null; + final correctServerResponse = + localConnection?.id == ref.read(userProvider.select((value) => value?.credentials.serverId)); + ref.read(localConnectionAvailableProvider.notifier).update((state) => correctServerResponse); + } catch (e) { + log('Error handling connectivity state change: $e'); } - final newUrl = ref.read(userProvider.select((value) => value?.credentials.localUrl)); - if (localUrl == newUrl) return; - localUrl = newUrl; - final localConnection = - localUrl != null && localUrl?.isNotEmpty == true ? await fetchSystemInfoDynamic(normalizeUrl(localUrl!)) : null; - final correctServerResponse = - localConnection?.id == ref.read(userProvider.select((value) => value?.credentials.serverId)); - ref.read(localConnectionAvailableProvider.notifier).update((state) => correctServerResponse); } Future checkConnectivity() async { - final connectivityResult = await Connectivity().checkConnectivity(); - final serverUrl = ref.read(serverUrlProvider); - final checkServer = await probeJellyfinUrl( - serverUrl ?? "", - ); - if (checkServer != null) { - onStateChange(connectivityResult); - } else { - onStateChange([ConnectivityResult.none]); + final now = DateTime.now(); + if (_lastCheck != null && now.difference(_lastCheck!) < _minCheckInterval) { + return; + } + _lastCheck = now; + try { + final connectivityResult = await Connectivity().checkConnectivity(); + final serverUrl = ref.read(serverUrlProvider); + final checkServer = await probeJellyfinUrl( + serverUrl ?? "", + ); + if (checkServer != null) { + onStateChange(connectivityResult); + } else { + onStateChange([ConnectivityResult.none]); + } + } catch (e) { + log('Failed to check connectivity: $e'); } } diff --git a/lib/services/notification_service.dart b/lib/services/notification_service.dart index 7e256d7c0..be824cfca 100644 --- a/lib/services/notification_service.dart +++ b/lib/services/notification_service.dart @@ -64,8 +64,12 @@ class NotificationService { } static Future getInitialNotificationPayload() async { - final details = await _plugin.getNotificationAppLaunchDetails(); - return details?.notificationResponse?.payload; + try { + final details = await _plugin.getNotificationAppLaunchDetails(); + return details?.notificationResponse?.payload; + } catch (e) { + return null; + } } static Future requestPermission() async {