From c20329aba63a779a3178ca34318daa95703d7f15 Mon Sep 17 00:00:00 2001 From: Mati Date: Mon, 30 Oct 2023 18:47:26 -0300 Subject: [PATCH 1/2] feat(video preview): re-organizes the layout for the shared file page PE-4710 --- .../components/fs_entry_preview_widget.dart | 356 ++++++++++++------ 1 file changed, 233 insertions(+), 123 deletions(-) diff --git a/lib/pages/drive_detail/components/fs_entry_preview_widget.dart b/lib/pages/drive_detail/components/fs_entry_preview_widget.dart index 18018e536c..a2c01df828 100644 --- a/lib/pages/drive_detail/components/fs_entry_preview_widget.dart +++ b/lib/pages/drive_detail/components/fs_entry_preview_widget.dart @@ -52,6 +52,7 @@ class _FsEntryPreviewWidgetState extends State { return VideoPlayerWidget( filename: (widget.state as FsEntryPreviewVideo).filename, videoUrl: (widget.state as FsEntryPreviewVideo).previewUrl, + isSharePage: widget.isSharePage, ); } } @@ -83,10 +84,14 @@ String getTimeString(Duration duration) { class VideoPlayerWidget extends StatefulWidget { final String videoUrl; final String filename; + final bool isSharePage; - const VideoPlayerWidget( - {Key? key, required this.filename, required this.videoUrl}) - : super(key: key); + const VideoPlayerWidget({ + Key? key, + required this.filename, + required this.videoUrl, + required this.isSharePage, + }) : super(key: key); @override // ignore: library_private_types_in_public_api @@ -179,6 +184,7 @@ class _VideoPlayerWidgetState extends State }); } }, + isSharePage: widget.isSharePage, ), ), ); @@ -260,82 +266,117 @@ class _VideoPlayerWidgetState extends State style: ArDriveTypography.body .smallBold700(color: colors.themeFgDefault)), const SizedBox(height: 8), - SliderTheme( - data: SliderThemeData( - trackHeight: 4, - trackShape: - _NoAdditionalHeightRoundedRectSliderTrackShape(), - inactiveTrackColor: colors.themeBgSubtle, - disabledThumbColor: colors.themeAccentBrand, - disabledInactiveTrackColor: colors.themeBgSubtle, - overlayShape: SliderComponentShape.noOverlay, - thumbShape: const RoundSliderThumbShape( - enabledThumbRadius: 8, - )), - child: Slider( - value: min( - videoValue.position.inMilliseconds.toDouble(), - videoValue.duration.inMilliseconds.toDouble()), - secondaryTrackValue: bufferedValue, - min: 0.0, - max: videoValue.duration.inMilliseconds.toDouble(), - onChangeStart: !controlsEnabled - ? null - : (v) async { - if (_videoPlayerController.value.duration > - Duration.zero) { - _wasPlaying = - _videoPlayerController.value.isPlaying; - if (_wasPlaying) { + Row( + children: [ + ScreenTypeLayout.builder( + desktop: (context) => Row(children: [ + Text(currentTime), + const SizedBox(width: 8), + ]), + mobile: (context) => const SizedBox.shrink(), + ), + Expanded( + child: SliderTheme( + data: SliderThemeData( + trackHeight: 4, + trackShape: + _NoAdditionalHeightRoundedRectSliderTrackShape(), + inactiveTrackColor: colors.themeBgSubtle, + disabledThumbColor: colors.themeAccentBrand, + disabledInactiveTrackColor: colors.themeBgSubtle, + overlayShape: SliderComponentShape.noOverlay, + thumbShape: const RoundSliderThumbShape( + enabledThumbRadius: 8, + )), + child: Slider( + value: min( + videoValue.position.inMilliseconds.toDouble(), + videoValue.duration.inMilliseconds.toDouble()), + secondaryTrackValue: bufferedValue, + min: 0.0, + max: videoValue.duration.inMilliseconds.toDouble(), + onChangeStart: !controlsEnabled + ? null + : (v) async { + if (_videoPlayerController.value.duration > + Duration.zero) { + _wasPlaying = + _videoPlayerController.value.isPlaying; + if (_wasPlaying) { + await _lock.synchronized(() async { + await _videoPlayerController + .pause() + .catchError((e) { + logger.e('Error pausing video: $e'); + }); + }); + setState(() {}); + } + } + }, + onChanged: !controlsEnabled + ? null + : (v) async { + setState(() { + final milliseconds = v.toInt(); + + if (_videoPlayerController.value.duration > + Duration.zero) { + _videoPlayerController.seekTo( + Duration(milliseconds: milliseconds)); + } + }); + }, + onChangeEnd: !controlsEnabled + ? null + : (v) async { + if (_videoPlayerController.value.duration > + Duration.zero && + _wasPlaying) { await _lock.synchronized(() async { await _videoPlayerController - .pause() + .play() .catchError((e) { - logger.e('Error pausing video: $e'); + logger.e('Error playing video: $e'); }); }); setState(() {}); } - } - }, - onChanged: !controlsEnabled - ? null - : (v) async { - setState(() { - final milliseconds = v.toInt(); - - if (_videoPlayerController.value.duration > - Duration.zero) { - _videoPlayerController.seekTo( - Duration(milliseconds: milliseconds)); - } - }); - }, - onChangeEnd: !controlsEnabled - ? null - : (v) async { - if (_videoPlayerController.value.duration > - Duration.zero && - _wasPlaying) { - await _lock.synchronized(() async { - await _videoPlayerController - .play() - .catchError((e) { - logger.e('Error playing video: $e'); - }); - }); - setState(() {}); - } - })), - const SizedBox(height: 4), - Row( - children: [ - Text(currentTime), - const Expanded(child: SizedBox.shrink()), - Text(duration) + }, + ), + ), + ), + ScreenTypeLayout.builder( + desktop: (context) => Row(children: [ + const SizedBox(width: 8), + Text(duration), + ]), + mobile: (context) => const SizedBox.shrink(), + ), ], ), - const SizedBox(height: 8), + const SizedBox(height: 4), + ScreenTypeLayout.builder( + mobile: (BuildContext context) => const SizedBox.shrink(), + desktop: (BuildContext context) { + if (widget.isSharePage) { + return const SizedBox.shrink(); + } + + return Column( + children: [ + Row( + children: [ + Text(currentTime), + const Expanded(child: SizedBox.shrink()), + Text(duration) + ], + ), + const SizedBox(height: 8), + ], + ); + }, + ), MouseRegion( onExit: (event) { setState(() { @@ -350,14 +391,36 @@ class _VideoPlayerWidgetState extends State child: Align( alignment: Alignment.centerLeft, child: ScreenTypeLayout.builder( - mobile: (context) => IconButton( - onPressed: !controlsEnabled - ? null - : () { - goFullScreen(); - }, - icon: const Icon(Icons.fullscreen_outlined, - size: 24)), + mobile: (context) { + if (widget.isSharePage) { + return IconButton( + onPressed: () { + _displaySpeedOptionsModal(context, (v) { + setState(() { + _videoPlayerController + .setPlaybackSpeed(v); + }); + }); + }, + icon: const Icon( + Icons.settings_outlined, + size: 24, + ), + ); + } else { + return IconButton( + onPressed: !controlsEnabled + ? null + : () { + goFullScreen(); + }, + icon: const Icon( + Icons.fullscreen_outlined, + size: 24, + ), + ); + } + }, desktop: (context) => VolumeSliderWidget( volume: _videoPlayerController.value.volume, setVolume: (v) { @@ -373,6 +436,20 @@ class _VideoPlayerWidgetState extends State }, ), ))), + if (widget.isSharePage) + ScreenTypeLayout.builder( + desktop: (context) => IconButton.outlined( + onPressed: () { + setState(() { + _videoPlayerController.seekTo( + _videoPlayerController.value.position - + const Duration(seconds: 10)); + }); + }, + icon: const Icon(Icons.replay_10, size: 24), + ), + mobile: (_) => const SizedBox.shrink(), + ), MaterialButton( onPressed: !controlsEnabled ? null @@ -424,6 +501,20 @@ class _VideoPlayerWidgetState extends State color: colors.themeFgOnAccent, )), ), + if (widget.isSharePage) + ScreenTypeLayout.builder( + desktop: (context) => IconButton.outlined( + onPressed: () { + setState(() { + _videoPlayerController.seekTo( + _videoPlayerController.value.position + + const Duration(seconds: 10)); + }); + }, + icon: const Icon(Icons.forward_10, size: 24), + ), + mobile: (context) => const SizedBox.shrink(), + ), Expanded( child: Align( alignment: Alignment.centerRight, @@ -431,41 +522,52 @@ class _VideoPlayerWidgetState extends State mainAxisAlignment: MainAxisAlignment.end, children: [ ScreenTypeLayout.builder( - desktop: (context) => MenuAnchor( - menuChildren: [ - ..._speedOptions.map((v) { - return ListTile( - tileColor: colors.themeBgSurface, - onTap: () { - setState(() { - _videoPlayerController - .setPlaybackSpeed(v); - _menuController.close(); - }); - }, - title: Text( - v == 1.0 - ? appLocalizationsOf(context) - .normal - : '$v', - style: ArDriveTypography.body - .buttonNormalBold( - color: colors - .themeFgDefault), - ), - ); - }) - ], - controller: _menuController, - child: IconButton( - onPressed: () { - _menuController.open(); + desktop: (context) => MenuAnchor( + menuChildren: [ + ..._speedOptions.map((v) { + return ListTile( + tileColor: colors.themeBgSurface, + onTap: () { + setState(() { + _videoPlayerController + .setPlaybackSpeed(v); + _menuController.close(); + }); + }, + title: Text( + v == 1.0 + ? appLocalizationsOf(context).normal + : '$v', + style: ArDriveTypography.body + .buttonNormalBold( + color: colors.themeFgDefault), + ), + ); + }) + ], + controller: _menuController, + child: IconButton( + onPressed: () { + _menuController.open(); + }, + icon: const Icon(Icons.settings_outlined, + size: 24)), + ), + mobile: (context) { + if (widget.isSharePage) { + return IconButton( + onPressed: !controlsEnabled + ? null + : () { + goFullScreen(); }, - icon: const Icon( - Icons.settings_outlined, - size: 24)), + icon: const Icon( + Icons.fullscreen_outlined, + size: 24, ), - mobile: (context) => IconButton( + ); + } else { + return IconButton( onPressed: () { _displaySpeedOptionsModal(context, (v) { setState(() { @@ -474,8 +576,14 @@ class _VideoPlayerWidgetState extends State }); }); }, - icon: const Icon(Icons.settings_outlined, - size: 24))), + icon: const Icon( + Icons.settings_outlined, + size: 24, + ), + ); + } + }, + ), ScreenTypeLayout.builder( desktop: (context) => IconButton( onPressed: !controlsEnabled @@ -508,16 +616,18 @@ class FullScreenVideoPlayerWidget extends StatefulWidget { final bool initialIsPlaying; final double initialVolume; final Function(Duration, bool, double) onClose; + final bool isSharePage; - const FullScreenVideoPlayerWidget( - {Key? key, - required this.filename, - required this.videoUrl, - required this.initialPosition, - required this.initialIsPlaying, - required this.initialVolume, - required this.onClose}) - : super(key: key); + const FullScreenVideoPlayerWidget({ + Key? key, + required this.filename, + required this.videoUrl, + required this.initialPosition, + required this.initialIsPlaying, + required this.initialVolume, + required this.onClose, + required this.isSharePage, + }) : super(key: key); @override // ignore: library_private_types_in_public_api @@ -816,7 +926,7 @@ class _FullScreenVideoPlayerWidgetState } }))), const SizedBox(width: 8), - Text(duration) + Text(duration), ], ), const SizedBox(height: 8), From e04a1cc6191bd1f4c81e146a676cbc8bf98ed4ab Mon Sep 17 00:00:00 2001 From: Mati Date: Thu, 2 Nov 2023 12:10:12 -0300 Subject: [PATCH 2/2] feat(preview widget): corrects the duplicate time indicators for video preview in drive explorer PE-4928 --- .../components/fs_entry_preview_widget.dart | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/lib/pages/drive_detail/components/fs_entry_preview_widget.dart b/lib/pages/drive_detail/components/fs_entry_preview_widget.dart index dd952f22ca..d7e3985607 100644 --- a/lib/pages/drive_detail/components/fs_entry_preview_widget.dart +++ b/lib/pages/drive_detail/components/fs_entry_preview_widget.dart @@ -273,13 +273,14 @@ class _VideoPlayerWidgetState extends State const SizedBox(height: 8), Row( children: [ - ScreenTypeLayout.builder( - desktop: (context) => Row(children: [ - Text(currentTime), - const SizedBox(width: 8), - ]), - mobile: (context) => const SizedBox.shrink(), - ), + if (widget.isSharePage) + ScreenTypeLayout.builder( + desktop: (context) => Row(children: [ + Text(currentTime), + const SizedBox(width: 8), + ]), + mobile: (context) => const SizedBox.shrink(), + ), Expanded( child: SliderTheme( data: SliderThemeData( @@ -351,13 +352,14 @@ class _VideoPlayerWidgetState extends State ), ), ), - ScreenTypeLayout.builder( - desktop: (context) => Row(children: [ - const SizedBox(width: 8), - Text(duration), - ]), - mobile: (context) => const SizedBox.shrink(), - ), + if (widget.isSharePage) + ScreenTypeLayout.builder( + desktop: (context) => Row(children: [ + const SizedBox(width: 8), + Text(duration), + ]), + mobile: (context) => const SizedBox.shrink(), + ), ], ), const SizedBox(height: 4),