diff --git a/lib/models/device.dart b/lib/models/device.dart index 40348216..ec7294c7 100644 --- a/lib/models/device.dart +++ b/lib/models/device.dart @@ -21,6 +21,7 @@ import 'dart:convert'; import 'package:bluecherry_client/models/server.dart'; import 'package:bluecherry_client/providers/server_provider.dart'; +import 'package:bluecherry_client/utils/extensions.dart'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; @@ -73,7 +74,7 @@ class Device { return '${server.ip}:${server.port}/$id'; } - static Device fromUUID(String uuid) { + static Device? fromUUID(String uuid) { final serverIp = uuid.split(':')[0]; final serverPort = int.tryParse(uuid.split(':')[1].split('/')[0]) ?? -1; final deviceId = int.tryParse(uuid.split(':')[1].split('/')[1]) ?? -1; @@ -83,7 +84,7 @@ class Device { orElse: Server.dump, ); - return server.devices.firstWhere((d) => d.id == deviceId); + return server.devices.firstWhereOrNull((d) => d.id == deviceId); } factory Device.fromServerJson(Map map, Server server) { diff --git a/lib/providers/downloads_provider.dart b/lib/providers/downloads_provider.dart index a8804be4..f4570daf 100644 --- a/lib/providers/downloads_provider.dart +++ b/lib/providers/downloads_provider.dart @@ -174,6 +174,7 @@ class DownloadsManager extends ChangeNotifier { } String getDownloadedPathForEvent(int eventId) { + assert(isEventDownloaded(eventId)); return downloadedEvents .firstWhere((de) => de.event.id == eventId) .downloadPath; diff --git a/lib/providers/server_provider.dart b/lib/providers/server_provider.dart index 9d7a6ef7..29d19d6a 100644 --- a/lib/providers/server_provider.dart +++ b/lib/providers/server_provider.dart @@ -138,8 +138,10 @@ class ServersProvider extends ChangeNotifier { return add(server); } - final s = - servers.firstWhere((s) => s.ip == server.ip && s.port == server.port); + final s = servers.firstWhere( + (s) => s.ip == server.ip && s.port == server.port, + orElse: () => server, + ); final serverIndex = servers.indexOf(s); for (final device in server.devices) { diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 24caac1e..15c10f37 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -233,7 +233,8 @@ class SettingsProvider extends ChangeNotifier { systemLocale, ); _snoozedUntil = - DateTime.tryParse(data[kHiveSnoozedUntil]) ?? defaultSnoozedUntil; + DateTime.tryParse((data[kHiveSnoozedUntil] as String?) ?? '') ?? + defaultSnoozedUntil; _notificationClickBehavior = NotificationClickBehavior.values[ data[kHiveNotificationClickBehavior] ?? kDefaultNotificationClickBehavior.index]; diff --git a/lib/utils/video_player.dart b/lib/utils/video_player.dart index d1059096..0f8e8a1e 100644 --- a/lib/utils/video_player.dart +++ b/lib/utils/video_player.dart @@ -86,12 +86,13 @@ class UnityPlayers with ChangeNotifier { /// [onlyIfTimedOut], if true, the device will only be reloaded if it's timed out static void reloadAll({bool onlyIfTimedOut = false}) { for (final entry in players.entries) { - final device = entry.key; final player = entry.value; if (onlyIfTimedOut) { if (!player.isImageOld) continue; } - reloadDevice(Device.fromUUID(device)); + final deviceUUID = entry.key; + final device = Device.fromUUID(deviceUUID); + if (device != null) reloadDevice(device); } } } diff --git a/lib/widgets/device_grid/desktop/desktop_device_grid.dart b/lib/widgets/device_grid/desktop/desktop_device_grid.dart index 0a8140fb..2b65074a 100644 --- a/lib/widgets/device_grid/desktop/desktop_device_grid.dart +++ b/lib/widgets/device_grid/desktop/desktop_device_grid.dart @@ -203,8 +203,10 @@ class LayoutView extends StatelessWidget { if (amountOfItemsOnScreen > foldedDevices.length) { // final diff = amountOfItemsOnScreen - foldedDevices.length; while (amountOfItemsOnScreen > foldedDevices.length) { - final lastFullFold = - foldedDevices.firstWhere((fold) => fold.length > 1); + final lastFullFold = foldedDevices.firstWhere( + (fold) => fold.length > 1, + orElse: () => foldedDevices.first, + ); final foldIndex = foldedDevices.indexOf(lastFullFold); foldedDevices.insert( (foldIndex - 1).clamp(0, foldedDevices.length).toInt(), diff --git a/lib/widgets/device_grid/mobile/mobile_device_grid.dart b/lib/widgets/device_grid/mobile/mobile_device_grid.dart index dafa4d38..cc3eac99 100644 --- a/lib/widgets/device_grid/mobile/mobile_device_grid.dart +++ b/lib/widgets/device_grid/mobile/mobile_device_grid.dart @@ -80,7 +80,12 @@ class _MobileDeviceGridState extends State { child: PageTransitionSwitcher( child: view.devices.keys .map((key) => _MobileDeviceGridChild(tab: key)) - .elementAt(view.tab.clamp(0, view.devices.length - 1)), + .elementAt( + view.devices.keys + .toList() + .indexOf(view.tab) + .clamp(0, view.devices.length - 1), + ), transitionBuilder: (child, primaryAnimation, secondaryAnimation) { return FadeThroughTransition( animation: primaryAnimation, diff --git a/lib/widgets/events_timeline/events_playback.dart b/lib/widgets/events_timeline/events_playback.dart index 2705bbe2..9109e20a 100644 --- a/lib/widgets/events_timeline/events_playback.dart +++ b/lib/widgets/events_timeline/events_playback.dart @@ -88,8 +88,13 @@ class _EventsPlaybackState extends EventsScreenState { continue; } - final device = - event.server.devices.firstWhere((d) => d.id == event.deviceID); + final device = event.server.devices.firstWhere( + (d) => d.id == event.deviceID, + orElse: () => Device.dump( + name: event.deviceName, + id: event.deviceID, + ), + ); devices[device] ??= []; if (devices[device]!.any((e) { diff --git a/lib/widgets/servers/edit_server.dart b/lib/widgets/servers/edit_server.dart index 25ebaf1b..47a52d0a 100644 --- a/lib/widgets/servers/edit_server.dart +++ b/lib/widgets/servers/edit_server.dart @@ -67,6 +67,10 @@ class _EditServerState extends State { Server get server { return ServersProvider.instance.servers.firstWhere( (s) => s.ip == widget.serverIp && s.port == widget.serverPort, + orElse: () => Server.dump( + ip: widget.serverIp, + port: widget.serverPort, + ), ); }