mirror of
https://github.com/immich-app/immich.git
synced 2026-05-22 23:52:32 -04:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ed06dc40d1 | |||
| 14193b82df | |||
| 5271863291 | |||
| 6b3e07dc52 |
@@ -49,6 +49,9 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||||||
|
|
||||||
bool _showingDetails = false;
|
bool _showingDetails = false;
|
||||||
bool _isZoomed = false;
|
bool _isZoomed = false;
|
||||||
|
// Frozen during dismiss drag + settle to prevent widget tree swap mid-animation.
|
||||||
|
bool _frozenMotionPlaying = false;
|
||||||
|
bool _dismissSettling = false;
|
||||||
|
|
||||||
final _scrollController = SnapScrollController();
|
final _scrollController = SnapScrollController();
|
||||||
double _snapOffset = 0.0;
|
double _snapOffset = 0.0;
|
||||||
@@ -136,6 +139,9 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||||||
> 0 => _DragIntent.dismiss,
|
> 0 => _DragIntent.dismiss,
|
||||||
_ => _DragIntent.none,
|
_ => _DragIntent.none,
|
||||||
};
|
};
|
||||||
|
if (_dragIntent == _DragIntent.dismiss) {
|
||||||
|
_frozenMotionPlaying = ref.read(isPlayingMotionVideoProvider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (_dragIntent) {
|
switch (_dragIntent) {
|
||||||
@@ -173,12 +179,18 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||||||
context.maybePop();
|
context.maybePop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_viewController?.animateMultiple(
|
|
||||||
position: _initialPhotoViewState.position,
|
|
||||||
scale: _viewController?.initialScale ?? _initialPhotoViewState.scale,
|
|
||||||
rotation: _initialPhotoViewState.rotation,
|
|
||||||
);
|
|
||||||
_viewer.setOpacity(1.0);
|
_viewer.setOpacity(1.0);
|
||||||
|
_dismissSettling = true;
|
||||||
|
_viewController
|
||||||
|
?.animateMultiple(
|
||||||
|
position: _initialPhotoViewState.position,
|
||||||
|
scale: _viewController?.initialScale ?? _initialPhotoViewState.scale,
|
||||||
|
rotation: _initialPhotoViewState.rotation,
|
||||||
|
)
|
||||||
|
.whenComplete(() {
|
||||||
|
if (!mounted) return;
|
||||||
|
setState(() => _dismissSettling = false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +368,10 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||||||
final currentHeroTag = ref.watch(assetViewerProvider.select((s) => s.currentAsset?.heroTag));
|
final currentHeroTag = ref.watch(assetViewerProvider.select((s) => s.currentAsset?.heroTag));
|
||||||
_showingDetails = ref.watch(assetViewerProvider.select((s) => s.showingDetails));
|
_showingDetails = ref.watch(assetViewerProvider.select((s) => s.showingDetails));
|
||||||
final stackIndex = ref.watch(assetViewerProvider.select((s) => s.stackIndex));
|
final stackIndex = ref.watch(assetViewerProvider.select((s) => s.stackIndex));
|
||||||
final isPlayingMotionVideo = ref.watch(isPlayingMotionVideoProvider);
|
final liveMotionPlaying = ref.watch(isPlayingMotionVideoProvider);
|
||||||
|
final isPlayingMotionVideo = (_dragIntent == _DragIntent.dismiss || _dismissSettling)
|
||||||
|
? _frozenMotionPlaying
|
||||||
|
: liveMotionPlaying;
|
||||||
|
|
||||||
final asset = ref.read(timelineServiceProvider).getAssetSafe(widget.index);
|
final asset = ref.read(timelineServiceProvider).getAssetSafe(widget.index);
|
||||||
if (asset == null) {
|
if (asset == null) {
|
||||||
|
|||||||
@@ -38,12 +38,13 @@ abstract class PhotoViewControllerBase<T extends PhotoViewControllerValue> {
|
|||||||
/// Closes streams and removes eventual listeners.
|
/// Closes streams and removes eventual listeners.
|
||||||
void dispose();
|
void dispose();
|
||||||
|
|
||||||
void positionAnimationBuilder(void Function(Offset)? value);
|
void positionAnimationBuilder(Future<void> Function(Offset)? value);
|
||||||
void scaleAnimationBuilder(void Function(double)? value);
|
void scaleAnimationBuilder(Future<void> Function(double)? value);
|
||||||
void rotationAnimationBuilder(void Function(double)? value);
|
void rotationAnimationBuilder(Future<void> Function(double)? value);
|
||||||
|
|
||||||
/// Animates multiple fields of the state
|
/// Animates multiple fields of the state. The returned future completes
|
||||||
void animateMultiple({Offset? position, double? scale, double? rotation});
|
/// when all underlying animations have settled.
|
||||||
|
Future<void> animateMultiple({Offset? position, double? scale, double? rotation});
|
||||||
|
|
||||||
/// Add a listener that will ignore updates made internally
|
/// Add a listener that will ignore updates made internally
|
||||||
///
|
///
|
||||||
@@ -148,9 +149,9 @@ class PhotoViewController implements PhotoViewControllerBase<PhotoViewController
|
|||||||
@override
|
@override
|
||||||
ScaleBoundaries? scaleBoundaries;
|
ScaleBoundaries? scaleBoundaries;
|
||||||
|
|
||||||
late void Function(Offset)? _animatePosition;
|
late Future<void> Function(Offset)? _animatePosition;
|
||||||
late void Function(double)? _animateScale;
|
late Future<void> Function(double)? _animateScale;
|
||||||
late void Function(double)? _animateRotation;
|
late Future<void> Function(double)? _animateRotation;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<PhotoViewControllerValue> get outputStateStream => _outputCtrl.stream;
|
Stream<PhotoViewControllerValue> get outputStateStream => _outputCtrl.stream;
|
||||||
@@ -159,17 +160,17 @@ class PhotoViewController implements PhotoViewControllerBase<PhotoViewController
|
|||||||
late PhotoViewControllerValue prevValue;
|
late PhotoViewControllerValue prevValue;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void positionAnimationBuilder(void Function(Offset)? value) {
|
void positionAnimationBuilder(Future<void> Function(Offset)? value) {
|
||||||
_animatePosition = value;
|
_animatePosition = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void scaleAnimationBuilder(void Function(double)? value) {
|
void scaleAnimationBuilder(Future<void> Function(double)? value) {
|
||||||
_animateScale = value;
|
_animateScale = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void rotationAnimationBuilder(void Function(double)? value) {
|
void rotationAnimationBuilder(Future<void> Function(double)? value) {
|
||||||
_animateRotation = value;
|
_animateRotation = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,18 +194,18 @@ class PhotoViewController implements PhotoViewControllerBase<PhotoViewController
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void animateMultiple({Offset? position, double? scale, double? rotation}) {
|
Future<void> animateMultiple({Offset? position, double? scale, double? rotation}) {
|
||||||
|
final futures = <Future<void>>[];
|
||||||
if (position != null && _animatePosition != null) {
|
if (position != null && _animatePosition != null) {
|
||||||
_animatePosition!(position);
|
futures.add(_animatePosition!(position));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scale != null && _animateScale != null) {
|
if (scale != null && _animateScale != null) {
|
||||||
_animateScale!(scale);
|
futures.add(_animateScale!(scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rotation != null && _animateRotation != null) {
|
if (rotation != null && _animateRotation != null) {
|
||||||
_animateRotation!(rotation);
|
futures.add(_animateRotation!(rotation));
|
||||||
}
|
}
|
||||||
|
return Future.wait(futures);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -237,34 +237,31 @@ class PhotoViewCoreState extends State<PhotoViewCore>
|
|||||||
nextScaleState();
|
nextScaleState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void animateScale(double from, double to) {
|
Future<void> animateScale(double from, double to) {
|
||||||
if (!mounted) {
|
if (!mounted) {
|
||||||
return;
|
return Future.value();
|
||||||
}
|
}
|
||||||
_scaleAnimation = Tween<double>(begin: from, end: to).animate(_scaleAnimationController);
|
_scaleAnimation = Tween<double>(begin: from, end: to).animate(_scaleAnimationController);
|
||||||
_scaleAnimationController
|
_scaleAnimationController.value = 0.0;
|
||||||
..value = 0.0
|
return _scaleAnimationController.fling(velocity: 0.4);
|
||||||
..fling(velocity: 0.4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void animatePosition(Offset from, Offset to) {
|
Future<void> animatePosition(Offset from, Offset to) {
|
||||||
if (!mounted) {
|
if (!mounted) {
|
||||||
return;
|
return Future.value();
|
||||||
}
|
}
|
||||||
_positionAnimation = Tween<Offset>(begin: from, end: to).animate(_positionAnimationController);
|
_positionAnimation = Tween<Offset>(begin: from, end: to).animate(_positionAnimationController);
|
||||||
_positionAnimationController
|
_positionAnimationController.value = 0.0;
|
||||||
..value = 0.0
|
return _positionAnimationController.fling(velocity: 0.4);
|
||||||
..fling(velocity: 0.4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void animateRotation(double from, double to) {
|
Future<void> animateRotation(double from, double to) {
|
||||||
if (!mounted) {
|
if (!mounted) {
|
||||||
return;
|
return Future.value();
|
||||||
}
|
}
|
||||||
_rotationAnimation = Tween<double>(begin: from, end: to).animate(_rotationAnimationController);
|
_rotationAnimation = Tween<double>(begin: from, end: to).animate(_rotationAnimationController);
|
||||||
_rotationAnimationController
|
_rotationAnimationController.value = 0.0;
|
||||||
..value = 0.0
|
return _rotationAnimationController.fling(velocity: 0.4);
|
||||||
..fling(velocity: 0.4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onAnimationStatus(AnimationStatus status) {
|
void onAnimationStatus(AnimationStatus status) {
|
||||||
@@ -280,18 +277,19 @@ class PhotoViewCoreState extends State<PhotoViewCore>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _animateControllerPosition(Offset position) {
|
Future<void> _animateControllerPosition(Offset position) {
|
||||||
animatePosition(controller.position, position);
|
return animatePosition(controller.position, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _animateControllerScale(double scale) {
|
Future<void> _animateControllerScale(double scale) {
|
||||||
if (controller.scale != null) {
|
if (controller.scale != null) {
|
||||||
animateScale(controller.scale!, scale);
|
return animateScale(controller.scale!, scale);
|
||||||
}
|
}
|
||||||
|
return Future.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _animateControllerRotation(double rotation) {
|
Future<void> _animateControllerRotation(double rotation) {
|
||||||
animateRotation(controller.rotation, rotation);
|
return animateRotation(controller.rotation, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
Reference in New Issue
Block a user