From c8c9fe0767d2c7c9f7e6450392e205d3dbb079ae Mon Sep 17 00:00:00 2001 From: Bruno D'Luka <45696119+bdlukaa@users.noreply.github.com> Date: Sun, 7 Apr 2024 18:39:32 -0400 Subject: [PATCH 1/5] feat(deps): Upgrade awesome_notifications and migrate changes --- .vscode/settings.json | 2 ++ ios/Podfile | 11 ++++++ ios/Runner.xcodeproj/project.pbxproj | 14 +++++--- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- .../ephemeral/Flutter-Generated.xcconfig | 8 ++--- .../ephemeral/flutter_export_environment.sh | 8 ++--- macos/Podfile.lock | 13 +++++-- macos/Runner.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- .../unity_multi_window/example/pubspec.lock | 34 +++++++++---------- pubspec.lock | 28 +++++++++------ pubspec.yaml | 5 ++- 12 files changed, 83 insertions(+), 46 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..7a73a41b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/ios/Podfile b/ios/Podfile index 79d1fe23..17857d55 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -50,4 +50,15 @@ post_install do |installer| ] end end + ################ Awesome Notifications pod modification ################### + awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks') + require awesome_pod_file + update_awesome_pod_build_settings(installer) + ################ Awesome Notifications pod modification ################### end + +################ Awesome Notifications pod modification ################### +awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks') +require awesome_pod_file +update_awesome_main_target_settings('Runner', File.dirname(File.realpath(__FILE__)), flutter_root) +################ Awesome Notifications pod modification ################### diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 13d42eff..a6e90228 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -160,7 +160,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -348,7 +348,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -361,6 +361,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; @@ -369,6 +370,7 @@ DEVELOPMENT_TEAM = 642TR6YWHA; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -428,7 +430,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -477,7 +479,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -492,6 +494,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; @@ -500,6 +503,7 @@ DEVELOPMENT_TEAM = 642TR6YWHA; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -517,6 +521,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; @@ -525,6 +530,7 @@ DEVELOPMENT_TEAM = 642TR6YWHA; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 96c4d1a2..636085df 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ =3.2.0-194.0.dev <4.0.0" + dart: ">=3.2.0-0 <4.0.0" flutter: ">=1.17.0" diff --git a/pubspec.lock b/pubspec.lock index ef0504e6..a6a30f27 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -61,10 +61,10 @@ packages: dependency: "direct main" description: name: awesome_notifications - sha256: "65f730f9c0e73a346039ef746384bcff1773f9f03821b859705a7ab8db977b23" + sha256: d9e46ce7f5171ee1e9b1c5bc6dc40bd77528561f592842ce97ce3a0a9ae155ef url: "https://pub.dev" source: hosted - version: "0.8.2" + version: "0.9.3+1" boolean_selector: dependency: transitive description: @@ -457,18 +457,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "04be76c4a4bb50f14904e64749237e541e7c7bcf7ec0b196907322ab5d2fc739" + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" url: "https://pub.dev" source: hosted - version: "9.0.16" + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: b06739349ec2477e943055aea30172c5c7000225f79dad4702e2ec0eda79a6ff + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "2.0.1" lints: dependency: transitive description: @@ -489,10 +497,10 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: @@ -631,10 +639,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_drawing: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 80434ea8..3ae0f977 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,7 +34,7 @@ dependencies: duration: ^3.0.13 firebase_core: 2.10.0 firebase_messaging: ^14.4.1 - awesome_notifications: ^0.8.2 + awesome_notifications: ^0.9.3 wakelock_plus: ^1.1.4 app_links: ^3.5.0 win32_registry: ^1.1.2 @@ -67,6 +67,9 @@ dev_dependencies: msix: ^3.7.0 flutter_launcher_icons: ^0.13.0 +dependency_overrides: + intl: 0.18.1 + flutter: uses-material-design: true # The following line ensures that the translations are generated before the From f5dccff7431e1c1b5a85d6b43b02a51d982e03d8 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Sun, 7 Apr 2024 19:54:54 -0300 Subject: [PATCH 2/5] fix: Align all items to the center on the device view --- lib/screens/layouts/mobile/device_view.dart | 62 ++++++++++----------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/lib/screens/layouts/mobile/device_view.dart b/lib/screens/layouts/mobile/device_view.dart index 60e6333d..69f154cc 100644 --- a/lib/screens/layouts/mobile/device_view.dart +++ b/lib/screens/layouts/mobile/device_view.dart @@ -250,46 +250,42 @@ class DeviceTileState extends State { final error = video.error; return ClipRect( - child: Stack(children: [ + child: Stack(alignment: Alignment.center, children: [ if (error != null) ErrorWarning(message: error) else if (!controller.isSeekable) - const Center( - child: CircularProgressIndicator.adaptive( - valueColor: AlwaysStoppedAnimation(Colors.white), - strokeWidth: 1.5, - ), + const CircularProgressIndicator.adaptive( + valueColor: AlwaysStoppedAnimation(Colors.white), + strokeWidth: 1.5, ), if (video.lastImageUpdate != null) - Center( - child: TweenAnimationBuilder( - tween: Tween( - begin: 0.0, - end: hover ? 1.0 : 0.0, - ), - duration: const Duration(milliseconds: 300), - builder: (context, value, child) { - return Opacity( - opacity: value, - child: child, + TweenAnimationBuilder( + tween: Tween( + begin: 0.0, + end: hover ? 1.0 : 0.0, + ), + duration: const Duration(milliseconds: 300), + builder: (context, value, child) { + return Opacity( + opacity: value, + child: child, + ); + }, + child: SquaredIconButton( + // splashRadius: 20.0, + onPressed: () async { + await Navigator.of(context).pushNamed( + '/fullscreen', + arguments: { + 'device': widget.device, + 'player': videoPlayer, + }, ); }, - child: SquaredIconButton( - // splashRadius: 20.0, - onPressed: () async { - await Navigator.of(context).pushNamed( - '/fullscreen', - arguments: { - 'device': widget.device, - 'player': videoPlayer, - }, - ); - }, - icon: const Icon( - Icons.fullscreen, - color: Colors.white, - size: 32.0, - ), + icon: const Icon( + Icons.fullscreen, + color: Colors.white, + size: 32.0, ), ), ), From 6e7c616cae3b95ce1e04e7d249db0459a6989d56 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Sun, 7 Apr 2024 20:01:14 -0300 Subject: [PATCH 3/5] fix: Do not allow to open fullscreen when the video has an error --- lib/screens/layouts/mobile/device_view.dart | 78 +++++++++------------ 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/lib/screens/layouts/mobile/device_view.dart b/lib/screens/layouts/mobile/device_view.dart index 69f154cc..9db058ac 100644 --- a/lib/screens/layouts/mobile/device_view.dart +++ b/lib/screens/layouts/mobile/device_view.dart @@ -21,7 +21,6 @@ import 'package:bluecherry_client/models/device.dart'; import 'package:bluecherry_client/providers/mobile_view_provider.dart'; import 'package:bluecherry_client/providers/settings_provider.dart'; import 'package:bluecherry_client/screens/layouts/video_status_label.dart'; -import 'package:bluecherry_client/utils/extensions.dart'; import 'package:bluecherry_client/utils/video_player.dart'; import 'package:bluecherry_client/widgets/device_selector.dart'; import 'package:bluecherry_client/widgets/error_warning.dart'; @@ -48,11 +47,7 @@ class MobileDeviceView extends StatefulWidget { final int index; /// Creates a device view used in mobile grids - const MobileDeviceView({ - super.key, - required this.tab, - required this.index, - }); + const MobileDeviceView({super.key, required this.tab, required this.index}); @override State createState() => _MobileDeviceViewState(); @@ -190,16 +185,11 @@ class DeviceTile extends StatefulWidget { final int tab; final int index; - final double width; - final double height; - const DeviceTile({ super.key, required this.device, required this.tab, required this.index, - this.width = 640.0, - this.height = 360.0, }); @override @@ -226,30 +216,32 @@ class DeviceTileState extends State { final theme = Theme.of(context); final settings = context.watch(); - return GestureDetectorWithReducedDoubleTapTime( - onTap: () { - if (mounted) setState(() => hover = !hover); - }, - // Fullscreen on double-tap. - onDoubleTap: () async { - await Navigator.of(context).pushNamed( - '/fullscreen', - arguments: { - 'device': widget.device, - 'player': videoPlayer, - }, - ); - }, - child: UnityVideoView( - heroTag: widget.device.streamURL, - player: videoPlayer, - fit: widget.device.server.additionalSettings.videoFit ?? - settings.kVideoFit.value, - paneBuilder: (context, controller) { - final video = UnityVideoView.of(context); - final error = video.error; + return UnityVideoView( + heroTag: widget.device.streamURL, + player: videoPlayer, + fit: widget.device.server.additionalSettings.videoFit ?? + settings.kVideoFit.value, + paneBuilder: (context, controller) { + final video = UnityVideoView.of(context); + final error = video.error; - return ClipRect( + return GestureDetectorWithReducedDoubleTapTime( + onTap: () { + if (mounted) setState(() => hover = !hover); + }, + // Fullscreen on double-tap. + onDoubleTap: () async { + if (error != null) { + await Navigator.of(context).pushNamed( + '/fullscreen', + arguments: { + 'device': widget.device, + 'player': videoPlayer, + }, + ); + } + }, + child: ClipRect( child: Stack(alignment: Alignment.center, children: [ if (error != null) ErrorWarning(message: error) @@ -292,17 +284,14 @@ class DeviceTileState extends State { PositionedDirectional( top: 6.0, start: 6.0, - child: VideoStatusLabel( - video: video, - device: widget.device, - ), + child: VideoStatusLabel(video: video, device: widget.device), ), PositionedDirectional( bottom: 0.0, start: 0.0, end: 0.0, child: AnimatedSlide( - offset: Offset(0, hover ? 0.0 : 1.0), + offset: Offset(0, error != null || hover ? 0.0 : 1.0), duration: const Duration(milliseconds: 200), curve: Curves.easeInOut, child: Container( @@ -324,10 +313,7 @@ class DeviceTileState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - widget.device.name - .split(' ') - .map((word) => word.uppercaseFirst) - .join(' '), + widget.device.name, style: theme.textTheme.displayLarge?.copyWith( color: Colors.white, fontSize: 14.0, @@ -356,9 +342,9 @@ class DeviceTileState extends State { ), ), ]), - ); - }, - ), + ), + ); + }, ); } } From b0f14c0a07afa58d99e61237c5346cbf5c89cd7c Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Sun, 7 Apr 2024 20:12:43 -0300 Subject: [PATCH 4/5] fix: Gestures in the device view --- lib/screens/layouts/mobile/device_view.dart | 80 +++++++++++---------- lib/widgets/misc.dart | 1 + 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/lib/screens/layouts/mobile/device_view.dart b/lib/screens/layouts/mobile/device_view.dart index 9db058ac..c43ad6d8 100644 --- a/lib/screens/layouts/mobile/device_view.dart +++ b/lib/screens/layouts/mobile/device_view.dart @@ -17,6 +17,7 @@ * along with this program. If not, see . */ +import 'package:bluecherry_client/api/api.dart'; import 'package:bluecherry_client/models/device.dart'; import 'package:bluecherry_client/providers/mobile_view_provider.dart'; import 'package:bluecherry_client/providers/settings_provider.dart'; @@ -216,36 +217,37 @@ class DeviceTileState extends State { final theme = Theme.of(context); final settings = context.watch(); - return UnityVideoView( - heroTag: widget.device.streamURL, - player: videoPlayer, - fit: widget.device.server.additionalSettings.videoFit ?? - settings.kVideoFit.value, - paneBuilder: (context, controller) { - final video = UnityVideoView.of(context); - final error = video.error; + return GestureDetectorWithReducedDoubleTapTime( + onTap: () { + if (mounted) setState(() => hover = !hover); + }, + // Fullscreen on double-tap. + onDoubleTap: () async { + if (videoPlayer.error == null) { + await Navigator.of(context).pushNamed( + '/fullscreen', + arguments: { + 'device': widget.device, + 'player': videoPlayer, + }, + ); + } + }, + child: UnityVideoView( + heroTag: widget.device.streamURL, + player: videoPlayer, + fit: widget.device.server.additionalSettings.videoFit ?? + settings.kVideoFit.value, + paneBuilder: (context, controller) { + final video = UnityVideoView.of(context); + final error = video.error; + final isLoading = !controller.isSeekable; - return GestureDetectorWithReducedDoubleTapTime( - onTap: () { - if (mounted) setState(() => hover = !hover); - }, - // Fullscreen on double-tap. - onDoubleTap: () async { - if (error != null) { - await Navigator.of(context).pushNamed( - '/fullscreen', - arguments: { - 'device': widget.device, - 'player': videoPlayer, - }, - ); - } - }, - child: ClipRect( + return ClipRect( child: Stack(alignment: Alignment.center, children: [ if (error != null) ErrorWarning(message: error) - else if (!controller.isSeekable) + else if (isLoading) const CircularProgressIndicator.adaptive( valueColor: AlwaysStoppedAnimation(Colors.white), strokeWidth: 1.5, @@ -291,21 +293,22 @@ class DeviceTileState extends State { start: 0.0, end: 0.0, child: AnimatedSlide( - offset: Offset(0, error != null || hover ? 0.0 : 1.0), + offset: Offset( + 0, + error != null || isLoading || hover ? 0.0 : 1.0, + ), duration: const Duration(milliseconds: 200), curve: Curves.easeInOut, child: Container( - height: 48.0, + padding: const EdgeInsetsDirectional.only( + start: 16.0, + top: 6.0, + bottom: 6.0, + end: 16.0, + ), alignment: AlignmentDirectional.centerEnd, color: Colors.black26, child: Row(children: [ - const SizedBox(width: 16.0), - const Icon( - Icons.videocam, - color: Colors.white, - size: 20.0, - ), - const SizedBox(width: 16.0), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -336,15 +339,14 @@ class DeviceTileState extends State { size: 20.0, semanticLabel: loc.ptzSupported, ), - const SizedBox(width: 16.0), ]), ), ), ), ]), - ), - ); - }, + ); + }, + ), ); } } diff --git a/lib/widgets/misc.dart b/lib/widgets/misc.dart index 569380a2..477f04db 100644 --- a/lib/widgets/misc.dart +++ b/lib/widgets/misc.dart @@ -92,6 +92,7 @@ class GestureDetectorWithReducedDoubleTapTime extends StatelessWidget { Widget build(BuildContext context) { return GestureDetector( key: key, + behavior: HitTestBehavior.opaque, onTap: _onTap, onTapDown: _onTapDown, onTapCancel: _onTapCancel, From f24dd1b69a0b2d0aaf45a5847bb7db82e83fad93 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Sun, 7 Apr 2024 20:24:59 -0300 Subject: [PATCH 5/5] fix: Correctly position the video status overlay on limited screens --- lib/screens/layouts/mobile/device_view.dart | 1 - lib/screens/layouts/video_status_label.dart | 38 +++++++++++---------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/lib/screens/layouts/mobile/device_view.dart b/lib/screens/layouts/mobile/device_view.dart index c43ad6d8..1baa2de8 100644 --- a/lib/screens/layouts/mobile/device_view.dart +++ b/lib/screens/layouts/mobile/device_view.dart @@ -17,7 +17,6 @@ * along with this program. If not, see . */ -import 'package:bluecherry_client/api/api.dart'; import 'package:bluecherry_client/models/device.dart'; import 'package:bluecherry_client/providers/mobile_view_provider.dart'; import 'package:bluecherry_client/providers/settings_provider.dart'; diff --git a/lib/screens/layouts/video_status_label.dart b/lib/screens/layouts/video_status_label.dart index 7f9cc39f..6eaac836 100644 --- a/lib/screens/layouts/video_status_label.dart +++ b/lib/screens/layouts/video_status_label.dart @@ -101,25 +101,27 @@ class _VideoStatusLabelState extends State { event: widget.event, ); final minHeight = label.buildTextSpans(context).length * 15; + + final willLeftOverflow = + position.dx + _DeviceVideoInfo.minWidth > constraints.maxWidth; + + final left = willLeftOverflow + ? (constraints.maxWidth - _DeviceVideoInfo.minWidth - 8.0) + : position.dx; + final top = position.dy > minHeight + 8.0 + ? null + : position.dy + boxSize.height + 8.0; + final bottom = position.dy > minHeight + 8.0 + ? constraints.maxHeight - position.dy + 8.0 + : null; + return Stack(children: [ - if (position.dy > minHeight + 8.0) - Positioned( - bottom: constraints.maxHeight - position.dy + 8.0, - right: constraints.maxWidth - position.dx - boxSize.width, - child: label, - ) - else - () { - final willLeftOverflow = position.dx + _DeviceVideoInfo.minWidth > - constraints.maxWidth; - return Positioned( - top: position.dy + boxSize.height + 8.0, - left: willLeftOverflow - ? (constraints.maxWidth - _DeviceVideoInfo.minWidth - 8.0) - : position.dx, - child: label, - ); - }(), + Positioned( + left: left, + top: top, + bottom: bottom, + child: label, + ), ]); }); });