From fa11a9a01b839f37f783a758a72bfbeebef0cf7b Mon Sep 17 00:00:00 2001 From: LeLunZ <31982496+LeLunZ@users.noreply.github.com> Date: Tue, 21 Apr 2026 18:15:48 +0200 Subject: [PATCH] fix(mobile): keep zoom consistent when scale boundaries change --- .../photo_view/src/core/photo_view_core.dart | 33 ++++++++++++++----- .../photo_view/src/photo_view_wrappers.dart | 1 - 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart b/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart index 2f775f57e2..574e7b2bdf 100644 --- a/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart +++ b/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart @@ -139,8 +139,6 @@ class PhotoViewCoreState extends State PhotoViewHeroAttributes? get heroAttributes => widget.heroAttributes; - late ScaleBoundaries cachedScaleBoundaries = widget.scaleBoundaries; - void handleScaleAnimation() { scale = _scaleAnimation!.value; } @@ -303,7 +301,12 @@ class PhotoViewCoreState extends State controller.scaleAnimationBuilder(_animateControllerScale); controller.rotationAnimationBuilder(_animateControllerRotation); - cachedScaleBoundaries = widget.scaleBoundaries; + final prevBoundaries = controller.scaleBoundaries; + if (prevBoundaries != null && prevBoundaries != widget.scaleBoundaries) { + _updateScaleBoundaries(prevBoundaries); + } else { + controller.scaleBoundaries = widget.scaleBoundaries; + } _scaleAnimationController = AnimationController(vsync: this) ..addListener(handleScaleAnimation) @@ -334,14 +337,26 @@ class PhotoViewCoreState extends State widget.onTapDown?.call(context, details, controller.value); } + void _updateScaleBoundaries(ScaleBoundaries prev) { + if (controller.scale != null && prev.initialScale > 0) { + final ratio = widget.scaleBoundaries.initialScale / prev.initialScale; + controller.setScaleInvisibly(controller.scale! * ratio); + } else { + markNeedsScaleRecalc = true; + } + controller.scaleBoundaries = widget.scaleBoundaries; + } + + @override + void didUpdateWidget(PhotoViewCore oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.scaleBoundaries != oldWidget.scaleBoundaries) { + _updateScaleBoundaries(oldWidget.scaleBoundaries); + } + } + @override Widget build(BuildContext context) { - // Check if we need a recalc on the scale - if (widget.scaleBoundaries != cachedScaleBoundaries) { - markNeedsScaleRecalc = true; - cachedScaleBoundaries = widget.scaleBoundaries; - } - return StreamBuilder( stream: controller.outputStateStream, initialData: controller.prevValue, diff --git a/mobile/lib/widgets/photo_view/src/photo_view_wrappers.dart b/mobile/lib/widgets/photo_view/src/photo_view_wrappers.dart index 36e7c0411e..a9cfeb3a40 100644 --- a/mobile/lib/widgets/photo_view/src/photo_view_wrappers.dart +++ b/mobile/lib/widgets/photo_view/src/photo_view_wrappers.dart @@ -1,5 +1,4 @@ import 'package:flutter/widgets.dart'; -import 'package:immich_mobile/utils/debug_print.dart'; import 'package:immich_mobile/widgets/photo_view/photo_view.dart'; import 'package:immich_mobile/widgets/photo_view/src/core/photo_view_core.dart'; import 'package:immich_mobile/widgets/photo_view/src/photo_view_default_widgets.dart';