From 899030184abcf2e9a8e6c024df7c4d6c031185aa Mon Sep 17 00:00:00 2001 From: isaac <> Date: Tue, 2 Jun 2026 14:23:28 +0200 Subject: [PATCH] InstantPageUI: fix photo gallery open transition flying off-screen InstantImageGalleryItem.animateIn animated the transition surface-copy view to transformedCopyViewFinalFrame (a point in the gallery item node's own coordinate space) instead of transformedSurfaceFinalFrame (that point expressed in the transition surface's space). ChatImageGalleryItem and UniversalVideoGalleryItem both use the surface-space frame here; only InstantImageGalleryItem (the InstantView photo item) had the slip. It was harmless in V1's full-page Instant View because the surface was window-scale and roughly aligned with the gallery, but in the V2 rich-data chat bubble the surface is the bubble's container inside the scrolled, flipped chat list (observed window frame ~ y:-1097 h:2107), so the gallery-space target landed ~1100pt off-screen and the photo snapshot flew away on open. Video used UniversalVideoGalleryItem and was unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) --- submodules/InstantPageUI/Sources/InstantImageGalleryItem.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/InstantPageUI/Sources/InstantImageGalleryItem.swift b/submodules/InstantPageUI/Sources/InstantImageGalleryItem.swift index cd1fc49ef7..e81269ba8b 100644 --- a/submodules/InstantPageUI/Sources/InstantImageGalleryItem.swift +++ b/submodules/InstantPageUI/Sources/InstantImageGalleryItem.swift @@ -247,7 +247,7 @@ final class InstantImageGalleryItemNode: ZoomableContentGalleryItemNode { copyView.layer.animate(from: NSValue(caTransform3D: CATransform3DIdentity), to: NSValue(caTransform3D: CATransform3DMakeScale(scale.width, scale.height, 1.0)), keyPath: "transform", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.25, removeOnCompletion: false) if let transformedSurfaceFrame = transformedSurfaceFrame, let transformedSurfaceFinalFrame = transformedSurfaceFinalFrame { - surfaceCopyView.layer.animatePosition(from: CGPoint(x: transformedSurfaceFrame.midX, y: transformedSurfaceFrame.midY), to: CGPoint(x: transformedCopyViewFinalFrame.midX, y: transformedCopyViewFinalFrame.midY), duration: positionDuration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { [weak surfaceCopyView] _ in + surfaceCopyView.layer.animatePosition(from: CGPoint(x: transformedSurfaceFrame.midX, y: transformedSurfaceFrame.midY), to: CGPoint(x: transformedSurfaceFinalFrame.midX, y: transformedSurfaceFinalFrame.midY), duration: positionDuration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { [weak surfaceCopyView] _ in surfaceCopyView?.removeFromSuperview() }) let scale = CGSize(width: transformedSurfaceFinalFrame.size.width / transformedSurfaceFrame.size.width, height: transformedSurfaceFinalFrame.size.height / transformedSurfaceFrame.size.height)