From fa7bb1bcc5ea7c61f61cc56b5b5c7bb26f3670b6 Mon Sep 17 00:00:00 2001 From: Pratik-canopas Date: Thu, 9 Jan 2025 14:50:31 +0530 Subject: [PATCH] Fix slider updates --- .../media_preview/components/top_bar.dart | 23 +++++++--- .../video_duration_slider.dart | 46 +++++++++++-------- .../media_preview/media_preview_screen.dart | 10 +++- .../media_preview_view_model.dart | 11 ++++- .../media_preview_view_model.freezed.dart | 25 +++++++++- 5 files changed, 84 insertions(+), 31 deletions(-) diff --git a/app/lib/ui/flow/media_preview/components/top_bar.dart b/app/lib/ui/flow/media_preview/components/top_bar.dart index 4b9cfaf..5f4f7d4 100644 --- a/app/lib/ui/flow/media_preview/components/top_bar.dart +++ b/app/lib/ui/flow/media_preview/components/top_bar.dart @@ -94,7 +94,11 @@ class _PreviewTopBarState extends ConsumerState { context: context, position: RelativeRect.fromSize( Rect.fromLTRB( - context.mediaQuerySize.width, 50, 0, 0), + context.mediaQuerySize.width, + 50, + 0, + 0, + ), context.mediaQuerySize, // Size of the screen ), elevation: 1, @@ -106,23 +110,30 @@ class _PreviewTopBarState extends ConsumerState { items: [ infoAction(context, media), if (!media.sources.contains( - AppMediaSource.googleDrive) && + AppMediaSource.googleDrive, + ) && media.sources .contains(AppMediaSource.local) && state.googleAccount != null) _uploadToGoogleDriveAction(context, media), if (media.sources.contains( - AppMediaSource.googleDrive) && + AppMediaSource.googleDrive, + ) && !media.sources .contains(AppMediaSource.local) && state.googleAccount != null) _downloadFromGoogleDriveAction( - context, media), + context, + media, + ), if (media.sources.contains( - AppMediaSource.googleDrive) && + AppMediaSource.googleDrive, + ) && state.googleAccount != null) _deleteFromGoogleDriveAction( - context, media), + context, + media, + ), if (!media.sources .contains(AppMediaSource.dropbox) && media.sources diff --git a/app/lib/ui/flow/media_preview/components/video_player_components/video_duration_slider.dart b/app/lib/ui/flow/media_preview/components/video_player_components/video_duration_slider.dart index 9a76ad0..c6371e6 100644 --- a/app/lib/ui/flow/media_preview/components/video_player_components/video_duration_slider.dart +++ b/app/lib/ui/flow/media_preview/components/video_player_components/video_duration_slider.dart @@ -1,7 +1,5 @@ import 'dart:ui'; - import 'package:style/theme/theme.dart'; - import '../../../../../domain/formatter/duration_formatter.dart'; import 'package:flutter/material.dart'; import 'package:style/animations/cross_fade_animation.dart'; @@ -11,6 +9,8 @@ import 'package:style/text/app_text_style.dart'; class VideoDurationSlider extends StatelessWidget { final bool showSlider; final Duration duration; + final void Function(PointerDownEvent event) onPointerDownOnSlider; + final void Function(PointerUpEvent event) onPointerUpOnSlider; final void Function(Duration duration) onChanged; final void Function(Duration duration) onChangeEnd; final Duration position; @@ -22,6 +22,8 @@ class VideoDurationSlider extends StatelessWidget { required this.position, required this.onChangeEnd, required this.onChanged, + required this.onPointerDownOnSlider, + required this.onPointerUpOnSlider, }); @override @@ -62,24 +64,28 @@ class VideoDurationSlider extends StatelessWidget { height: 30, child: Material( color: Colors.transparent, - child: SliderTheme( - data: SliderTheme.of(context).copyWith( - trackHeight: 4, - trackShape: const RoundedRectSliderTrackShape(), - rangeTrackShape: - const RoundedRectRangeSliderTrackShape(), - thumbShape: SliderComponentShape.noThumb, - ), - child: Slider( - value: position.inSeconds.toDouble(), - max: duration.inSeconds.toDouble(), - min: 0, - activeColor: appColorSchemeDark.primary, - inactiveColor: appColorSchemeDark.outline, - onChangeEnd: (value) => onChangeEnd - .call(Duration(seconds: value.toInt())), - onChanged: (double value) => - onChanged.call(Duration(seconds: value.toInt())), + child: Listener( + onPointerDown: onPointerDownOnSlider, + onPointerUp: onPointerUpOnSlider, + child: SliderTheme( + data: SliderTheme.of(context).copyWith( + trackHeight: 4, + trackShape: const RoundedRectSliderTrackShape(), + rangeTrackShape: + const RoundedRectRangeSliderTrackShape(), + thumbShape: SliderComponentShape.noThumb, + ), + child: Slider( + value: position.inSeconds.toDouble(), + max: duration.inSeconds.toDouble(), + min: 0, + activeColor: appColorSchemeDark.primary, + inactiveColor: appColorSchemeDark.outline, + onChangeEnd: (value) => onChangeEnd + .call(Duration(seconds: value.toInt())), + onChanged: (double value) => onChanged + .call(Duration(seconds: value.toInt())), + ), ), ), ), diff --git a/app/lib/ui/flow/media_preview/media_preview_screen.dart b/app/lib/ui/flow/media_preview/media_preview_screen.dart index e74f389..c7c634a 100644 --- a/app/lib/ui/flow/media_preview/media_preview_screen.dart +++ b/app/lib/ui/flow/media_preview/media_preview_screen.dart @@ -97,7 +97,7 @@ class _MediaPreviewState extends ConsumerState { _videoPlayerController?.value.isBuffering ?? false, ); _notifier.updateVideoPosition( - _videoPlayerController?.value.position ?? Duration.zero, + position: _videoPlayerController?.value.position ?? Duration.zero, ); _notifier.updateVideoMaxDuration( _videoPlayerController?.value.duration ?? Duration.zero, @@ -452,8 +452,14 @@ class _MediaPreviewState extends ConsumerState { onChangeEnd: (duration) { _videoPlayerController?.seekTo(duration); }, + onPointerDownOnSlider: (_) { + _notifier.pointerOnSlider(true); + }, + onPointerUpOnSlider: (_) { + _notifier.pointerOnSlider(false); + }, onChanged: (duration) { - _notifier.updateVideoPosition(duration); + _notifier.updateVideoPosition(position: duration, isManual: true); }, ); }, diff --git a/app/lib/ui/flow/media_preview/media_preview_view_model.dart b/app/lib/ui/flow/media_preview/media_preview_view_model.dart index 3a2858b..6926c50 100644 --- a/app/lib/ui/flow/media_preview/media_preview_view_model.dart +++ b/app/lib/ui/flow/media_preview/media_preview_view_model.dart @@ -409,8 +409,10 @@ class MediaPreviewStateNotifier extends StateNotifier { state = state.copyWith(showActions: !state.showActions); } - void updateVideoPosition(Duration position) { - if (state.videoPosition == position) return; + void updateVideoPosition( + {required Duration position, bool isManual = false}) { + if (state.videoPosition == position || state.pointerOnSlider && !isManual) + return; state = state.copyWith(videoPosition: position); } @@ -438,6 +440,10 @@ class MediaPreviewStateNotifier extends StateNotifier { state = state.copyWith(videoMaxDuration: maxDuration); } + void pointerOnSlider(bool isPointerOnSlider) { + state = state.copyWith(pointerOnSlider: isPointerOnSlider); + } + @override void dispose() { _googleAccountSubscription?.cancel(); @@ -459,6 +465,7 @@ class MediaPreviewState with _$MediaPreviewState { @Default(false) bool isVideoInitialized, @Default(false) bool isVideoBuffering, @Default(false) bool isImageZoomed, + @Default(false) bool pointerOnSlider, @Default(0.0) double swipeDownPercentage, @Default(Duration.zero) Duration videoPosition, @Default(Duration.zero) Duration videoMaxDuration, diff --git a/app/lib/ui/flow/media_preview/media_preview_view_model.freezed.dart b/app/lib/ui/flow/media_preview/media_preview_view_model.freezed.dart index 91ea2a0..ede86d8 100644 --- a/app/lib/ui/flow/media_preview/media_preview_view_model.freezed.dart +++ b/app/lib/ui/flow/media_preview/media_preview_view_model.freezed.dart @@ -26,6 +26,7 @@ mixin _$MediaPreviewState { bool get isVideoInitialized => throw _privateConstructorUsedError; bool get isVideoBuffering => throw _privateConstructorUsedError; bool get isImageZoomed => throw _privateConstructorUsedError; + bool get pointerOnSlider => throw _privateConstructorUsedError; double get swipeDownPercentage => throw _privateConstructorUsedError; Duration get videoPosition => throw _privateConstructorUsedError; Duration get videoMaxDuration => throw _privateConstructorUsedError; @@ -60,6 +61,7 @@ abstract class $MediaPreviewStateCopyWith<$Res> { bool isVideoInitialized, bool isVideoBuffering, bool isImageZoomed, + bool pointerOnSlider, double swipeDownPercentage, Duration videoPosition, Duration videoMaxDuration, @@ -96,6 +98,7 @@ class _$MediaPreviewStateCopyWithImpl<$Res, $Val extends MediaPreviewState> Object? isVideoInitialized = null, Object? isVideoBuffering = null, Object? isImageZoomed = null, + Object? pointerOnSlider = null, Object? swipeDownPercentage = null, Object? videoPosition = null, Object? videoMaxDuration = null, @@ -139,6 +142,10 @@ class _$MediaPreviewStateCopyWithImpl<$Res, $Val extends MediaPreviewState> ? _value.isImageZoomed : isImageZoomed // ignore: cast_nullable_to_non_nullable as bool, + pointerOnSlider: null == pointerOnSlider + ? _value.pointerOnSlider + : pointerOnSlider // ignore: cast_nullable_to_non_nullable + as bool, swipeDownPercentage: null == swipeDownPercentage ? _value.swipeDownPercentage : swipeDownPercentage // ignore: cast_nullable_to_non_nullable @@ -204,6 +211,7 @@ abstract class _$$MediaPreviewStateImplCopyWith<$Res> bool isVideoInitialized, bool isVideoBuffering, bool isImageZoomed, + bool pointerOnSlider, double swipeDownPercentage, Duration videoPosition, Duration videoMaxDuration, @@ -239,6 +247,7 @@ class __$$MediaPreviewStateImplCopyWithImpl<$Res> Object? isVideoInitialized = null, Object? isVideoBuffering = null, Object? isImageZoomed = null, + Object? pointerOnSlider = null, Object? swipeDownPercentage = null, Object? videoPosition = null, Object? videoMaxDuration = null, @@ -282,6 +291,10 @@ class __$$MediaPreviewStateImplCopyWithImpl<$Res> ? _value.isImageZoomed : isImageZoomed // ignore: cast_nullable_to_non_nullable as bool, + pointerOnSlider: null == pointerOnSlider + ? _value.pointerOnSlider + : pointerOnSlider // ignore: cast_nullable_to_non_nullable + as bool, swipeDownPercentage: null == swipeDownPercentage ? _value.swipeDownPercentage : swipeDownPercentage // ignore: cast_nullable_to_non_nullable @@ -328,6 +341,7 @@ class _$MediaPreviewStateImpl implements _MediaPreviewState { this.isVideoInitialized = false, this.isVideoBuffering = false, this.isImageZoomed = false, + this.pointerOnSlider = false, this.swipeDownPercentage = 0.0, this.videoPosition = Duration.zero, this.videoMaxDuration = Duration.zero, @@ -374,6 +388,9 @@ class _$MediaPreviewStateImpl implements _MediaPreviewState { final bool isImageZoomed; @override @JsonKey() + final bool pointerOnSlider; + @override + @JsonKey() final double swipeDownPercentage; @override @JsonKey() @@ -408,7 +425,7 @@ class _$MediaPreviewStateImpl implements _MediaPreviewState { @override String toString() { - return 'MediaPreviewState(googleAccount: $googleAccount, dropboxAccount: $dropboxAccount, error: $error, actionError: $actionError, medias: $medias, currentIndex: $currentIndex, showActions: $showActions, isVideoInitialized: $isVideoInitialized, isVideoBuffering: $isVideoBuffering, isImageZoomed: $isImageZoomed, swipeDownPercentage: $swipeDownPercentage, videoPosition: $videoPosition, videoMaxDuration: $videoMaxDuration, initializedVideoPath: $initializedVideoPath, isVideoPlaying: $isVideoPlaying, uploadMediaProcesses: $uploadMediaProcesses, downloadMediaProcesses: $downloadMediaProcesses)'; + return 'MediaPreviewState(googleAccount: $googleAccount, dropboxAccount: $dropboxAccount, error: $error, actionError: $actionError, medias: $medias, currentIndex: $currentIndex, showActions: $showActions, isVideoInitialized: $isVideoInitialized, isVideoBuffering: $isVideoBuffering, isImageZoomed: $isImageZoomed, pointerOnSlider: $pointerOnSlider, swipeDownPercentage: $swipeDownPercentage, videoPosition: $videoPosition, videoMaxDuration: $videoMaxDuration, initializedVideoPath: $initializedVideoPath, isVideoPlaying: $isVideoPlaying, uploadMediaProcesses: $uploadMediaProcesses, downloadMediaProcesses: $downloadMediaProcesses)'; } @override @@ -434,6 +451,8 @@ class _$MediaPreviewStateImpl implements _MediaPreviewState { other.isVideoBuffering == isVideoBuffering) && (identical(other.isImageZoomed, isImageZoomed) || other.isImageZoomed == isImageZoomed) && + (identical(other.pointerOnSlider, pointerOnSlider) || + other.pointerOnSlider == pointerOnSlider) && (identical(other.swipeDownPercentage, swipeDownPercentage) || other.swipeDownPercentage == swipeDownPercentage) && (identical(other.videoPosition, videoPosition) || @@ -463,6 +482,7 @@ class _$MediaPreviewStateImpl implements _MediaPreviewState { isVideoInitialized, isVideoBuffering, isImageZoomed, + pointerOnSlider, swipeDownPercentage, videoPosition, videoMaxDuration, @@ -493,6 +513,7 @@ abstract class _MediaPreviewState implements MediaPreviewState { final bool isVideoInitialized, final bool isVideoBuffering, final bool isImageZoomed, + final bool pointerOnSlider, final double swipeDownPercentage, final Duration videoPosition, final Duration videoMaxDuration, @@ -523,6 +544,8 @@ abstract class _MediaPreviewState implements MediaPreviewState { @override bool get isImageZoomed; @override + bool get pointerOnSlider; + @override double get swipeDownPercentage; @override Duration get videoPosition;