From 637ce60fafddb64c21a80722c8f4e6f8088e3d5c Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Tue, 23 Apr 2024 18:39:32 -0300 Subject: [PATCH 1/3] fix: Do not fail to parse devices if necessary information is not provideed If not provided, it is marked as OFFLINE --- lib/models/device.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/models/device.dart b/lib/models/device.dart index c5d0ed0e..a40bddd6 100644 --- a/lib/models/device.dart +++ b/lib/models/device.dart @@ -172,11 +172,11 @@ class Device { factory Device.fromServerJson(Map map, Server server) { return Device( - name: map['device_name'], - id: int.tryParse(map['id']) ?? 0, + name: map['device_name'] ?? map['device'] ?? 'Unkown Device', + id: int.tryParse('${map['id']}') ?? 0, status: map['status'] == 'OK', - resolutionX: int.tryParse(map['resolutionX']), - resolutionY: int.tryParse(map['resolutionY']), + resolutionX: int.tryParse('${map['resolutionX']}'), + resolutionY: int.tryParse('${map['resolutionY']}'), server: server, hasPTZ: map['ptz_control_protocol'] != null, ); From 7dd956a34de3e306166e2ab789c9c346dd90c7ed Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Tue, 23 Apr 2024 18:39:45 -0300 Subject: [PATCH 2/3] feat: Use "Unknown" when resolution is not found --- lib/screens/layouts/desktop/device_info_dialog.dart | 8 ++++++-- lib/screens/layouts/desktop/stream_data.dart | 5 ++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/screens/layouts/desktop/device_info_dialog.dart b/lib/screens/layouts/desktop/device_info_dialog.dart index cc76d7fb..d2ba4580 100644 --- a/lib/screens/layouts/desktop/device_info_dialog.dart +++ b/lib/screens/layouts/desktop/device_info_dialog.dart @@ -63,8 +63,12 @@ class _DeviceInfoDialogState extends State { ), ), _buildInfoTile(loc.uri, widget.device.uri), - _buildInfoTile(loc.resolution, - '${widget.device.resolutionX}x${widget.device.resolutionY}'), + _buildInfoTile( + loc.resolution, + '${widget.device.resolutionX ?? '${loc.unknown} '}' + 'x' + '${widget.device.resolutionY ?? ' ${loc.unknown}'}', + ), _buildInfoTile( loc.isPtzSupported, widget.device.hasPTZ ? loc.yes : loc.no), _buildInfoTileWidget( diff --git a/lib/screens/layouts/desktop/stream_data.dart b/lib/screens/layouts/desktop/stream_data.dart index f7f0c65b..b49a4f70 100644 --- a/lib/screens/layouts/desktop/stream_data.dart +++ b/lib/screens/layouts/desktop/stream_data.dart @@ -112,9 +112,8 @@ class _StreamDataState extends State { const borderSize = 4.0; - //This, basically, would - // contain all the information about this stream - and provide - // more options, such as adding/changing overlays. + // This, basically, would contain all the information about this stream - + // and provide more options, such as adding/changing overlays. return AlertDialog( title: RichText( text: TextSpan( From 8ec08f68769c53c93b789038002a1acaeaa0a630 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Tue, 23 Apr 2024 19:21:21 -0300 Subject: [PATCH 3/3] fix: Display the correct "Certificates not passed" message when untrusted domains are allowed --- lib/providers/settings_provider.dart | 13 +++++++ lib/screens/direct_camera.dart | 16 +++++--- .../events_browser/events_screen_mobile.dart | 15 +++++--- lib/screens/layouts/desktop/sidebar.dart | 15 +++++--- lib/screens/settings/shared/server_tile.dart | 37 ++++++++++++------- lib/widgets/device_selector.dart | 18 ++++++--- 6 files changed, 80 insertions(+), 34 deletions(-) diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 9fe29d6b..32eceed5 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -19,6 +19,7 @@ import 'dart:io'; +import 'package:bluecherry_client/models/server.dart'; import 'package:bluecherry_client/providers/app_provider_interface.dart'; import 'package:bluecherry_client/providers/downloads_provider.dart'; import 'package:bluecherry_client/providers/update_provider.dart'; @@ -573,6 +574,18 @@ class SettingsProvider extends UnityProvider { await settings.delete(); await initialize(); } + + /// Check if the server certificates passes + /// + /// If [kAllowUntrustedCertificates] is enabled, it will return true. + /// Otherwise, it will return the server's [Server.passedCertificates] value. + bool checkServerCertificates(Server server) { + if (kAllowUntrustedCertificates.value) { + return true; + } + + return server.passedCertificates; + } } enum NotificationClickBehavior { diff --git a/lib/screens/direct_camera.dart b/lib/screens/direct_camera.dart index 308e3e7d..6cf533e7 100644 --- a/lib/screens/direct_camera.dart +++ b/lib/screens/direct_camera.dart @@ -20,6 +20,7 @@ import 'package:bluecherry_client/models/device.dart'; import 'package:bluecherry_client/models/server.dart'; import 'package:bluecherry_client/providers/server_provider.dart'; +import 'package:bluecherry_client/providers/settings_provider.dart'; import 'package:bluecherry_client/utils/constants.dart'; import 'package:bluecherry_client/utils/extensions.dart'; import 'package:bluecherry_client/utils/theme.dart'; @@ -108,17 +109,22 @@ class _DevicesForServer extends StatelessWidget { final theme = Theme.of(context); final loc = AppLocalizations.of(context); final servers = context.watch(); + final settings = context.watch(); final isLoading = servers.isServerLoading(server); final serverIndicator = SubHeader( server.name, materialType: MaterialType.canvas, - subtext: !server.passedCertificates - ? loc.certificateNotPassed - : server.online - ? loc.nDevices(server.devices.length) - : loc.offline, + subtext: () { + if (!settings.checkServerCertificates(server)) { + return loc.certificateNotPassed; + } else if (server.online) { + return loc.nDevices(server.devices.length); + } else { + return loc.offline; + } + }(), subtextStyle: TextStyle( color: !server.online ? theme.colorScheme.error : null, ), diff --git a/lib/screens/events_browser/events_screen_mobile.dart b/lib/screens/events_browser/events_screen_mobile.dart index f58f21cd..da6ff465 100644 --- a/lib/screens/events_browser/events_screen_mobile.dart +++ b/lib/screens/events_browser/events_screen_mobile.dart @@ -55,6 +55,7 @@ class _EventsScreenMobileState extends State { final theme = Theme.of(context); final servers = context.watch(); final loc = AppLocalizations.of(context); + final settings = context.watch(); final isLoading = context.watch().isLoadingFor( UnityLoadingReason.fetchingEventsHistory, @@ -137,11 +138,15 @@ class _EventsScreenMobileState extends State { style: const TextStyle(fontWeight: FontWeight.bold), ), subtitle: Text( - !server.passedCertificates - ? loc.certificateNotPassed - : server.online - ? loc.nEvents(serverEvents.length) - : loc.offline, + () { + if (!settings.checkServerCertificates(server)) { + return loc.certificateNotPassed; + } else if (server.online) { + return loc.nEvents(serverEvents.length); + } else { + return loc.offline; + } + }(), ), trailing: !server.online ? Icon( diff --git a/lib/screens/layouts/desktop/sidebar.dart b/lib/screens/layouts/desktop/sidebar.dart index bee2b45c..fb460ac9 100644 --- a/lib/screens/layouts/desktop/sidebar.dart +++ b/lib/screens/layouts/desktop/sidebar.dart @@ -43,6 +43,7 @@ class _DesktopSidebarState extends State { final servers = context.watch(); final view = context.watch(); + final settings = context.watch(); return SafeArea( top: false, @@ -99,11 +100,15 @@ class _DesktopSidebarState extends State { child: SubHeader( server.name, materialType: MaterialType.canvas, - subtext: !server.passedCertificates - ? loc.certificateNotPassed - : server.online - ? loc.nDevices(devices.length) - : loc.offline, + subtext: () { + if (!settings.checkServerCertificates(server)) { + return loc.certificateNotPassed; + } else if (server.online) { + return loc.nDevices(devices.length); + } else { + return loc.offline; + } + }(), subtextStyle: TextStyle( color: !server.online ? theme.colorScheme.error diff --git a/lib/screens/settings/shared/server_tile.dart b/lib/screens/settings/shared/server_tile.dart index 2474f6c2..05d582ba 100644 --- a/lib/screens/settings/shared/server_tile.dart +++ b/lib/screens/settings/shared/server_tile.dart @@ -203,12 +203,11 @@ class ServerTile extends StatelessWidget { !isLoading ? [ if (server.name != server.ip) server.ip, - if (!server.passedCertificates) - loc.certificateNotPassed - else if (server.online) + if (server.online) loc.nDevices(server.devices.length) else loc.offline, + if (!server.passedCertificates) loc.certificateNotPassed ].join(' • ') : loc.gettingDevices, overflow: TextOverflow.ellipsis, @@ -246,6 +245,7 @@ class ServerCard extends StatelessWidget { final loc = AppLocalizations.of(context); final theme = Theme.of(context); final servers = context.watch(); + final settings = context.watch(); final isLoading = servers.isServerLoading(server); @@ -299,17 +299,28 @@ class ServerCard extends StatelessWidget { style: theme.textTheme.bodySmall, ), Text( - !server.passedCertificates - ? loc.certificateNotPassed - : !server.online - ? loc.offline - : !isLoading - ? loc.nDevices(server.devices.length) - : '', + () { + if (!settings.checkServerCertificates(server)) { + return loc.certificateNotPassed; + } else if (!server.online) { + return loc.offline; + } else if (!isLoading) { + return loc.nDevices(server.devices.length); + } + + return ''; + }(), style: TextStyle( - color: !server.online || !server.passedCertificates - ? theme.colorScheme.error - : null, + color: () { + if (settings.checkServerCertificates(server)) { + return theme.colorScheme.error; + } + if (!server.online) { + return theme.colorScheme.error; + } + + return null; + }(), ), textAlign: TextAlign.center, ), diff --git a/lib/widgets/device_selector.dart b/lib/widgets/device_selector.dart index 558d1b61..62c76034 100644 --- a/lib/widgets/device_selector.dart +++ b/lib/widgets/device_selector.dart @@ -19,6 +19,7 @@ import 'package:bluecherry_client/models/device.dart'; import 'package:bluecherry_client/providers/server_provider.dart'; +import 'package:bluecherry_client/providers/settings_provider.dart'; import 'package:bluecherry_client/utils/extensions.dart'; import 'package:bluecherry_client/utils/theme.dart'; import 'package:bluecherry_client/widgets/error_warning.dart'; @@ -80,9 +81,10 @@ class DeviceSelector extends StatelessWidget { @override Widget build(BuildContext context) { final theme = Theme.of(context); - final servers = context.watch(); final loc = AppLocalizations.of(context); final viewPadding = MediaQuery.viewPaddingOf(context); + final servers = context.watch(); + final settings = context.watch(); return Scaffold( appBar: AppBar( @@ -109,11 +111,15 @@ class DeviceSelector extends StatelessWidget { child: SubHeader( server.name, materialType: MaterialType.canvas, - subtext: !server.passedCertificates - ? loc.certificateNotPassed - : server.online - ? loc.nDevices(server.devices.length) - : loc.offline, + subtext: () { + if (!settings.checkServerCertificates(server)) { + return loc.certificateNotPassed; + } else if (server.online) { + return loc.nDevices(server.devices.length); + } else { + return loc.offline; + } + }(), subtextStyle: TextStyle( color: !server.online || !server.passedCertificates ? theme.colorScheme.error