feat(chat): flash the message a reply-quote jump lands on - #738
Merged
Conversation
Tapping a reply quote scrolled to the quoted message and stopped there, with nothing to separate it from the rows around it. The flash is a keyframe on `BubbleBackgroundView`, the chrome every bubble and cash card already shares, on its own layer above the wash and below the border. The resting opacity stays 0 so a cell recycled mid-flash can't strand a lit bubble, and `apply(fill:radii:identity:)` drops a running flash when the row changes. A jump lands right as the transcript re-dequeues rows around the arriving page, and a recycled cell loses its `CAAnimation`s, so `willDisplay` re-attaches from the original start time: a row displayed twice joins the flash in progress rather than replaying it. Two ordering bugs stopped a deferred jump, one waiting on the page that carries the row, from landing at all. The reload branch of `update(items:)` ran the opening scroll-to-bottom before the pending jump, and that scroll queues a re-anchor for the next runloop turn which pulled the transcript back off the message; the jump now runs instead of the opening scroll. Separately, `scrollToBottom`'s deferred re-anchors were fire-and-forget, so one queued by an earlier update still undid a jump that landed first. Both now give way when a `positionClaim` counter has moved.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tapping a reply quote scrolled the transcript to the quoted message and stopped there, with nothing to separate it from the rows around it.
The flash
It lives on
BubbleBackgroundView— the chrome every bubble and cash card already shares — as a keyframe on its own layer, above the wash and below the border, so it brightens the ground without washing over the text or softening the hairline edge. 0.15s rise, 0.45s hold, 0.40s fade, defined inChatMotionnext to the rest of the transcript's motion.The resting opacity stays 0 throughout; the animation carries the raised value. A cell reconfigured or recycled mid-flash therefore can't strand a lit bubble, and
apply(fill:radii:identity:)drops a running flash when the row identity changes.A jump lands exactly when the transcript is re-dequeueing rows around the page that brought the target in, and a recycled cell loses its
CAAnimations. SowillDisplayre-attaches the flash from its original start time: a row displayed twice joins the flash in progress and still ends when it would have, rather than replaying it.Two ordering bugs underneath
A deferred jump — one that has to wait for the page carrying the row — wasn't landing at all:
update(items:)ran the opening scroll-to-bottom before the pending jump. That scroll queues a re-anchor for the next runloop turn, which pulled the transcript off the message a beat after arriving on it. The jump now runs instead of the opening scroll rather than after it.scrollToBottom's deferred re-anchors were fire-and-forget, so one queued by an earlier update still undid a jump that landed before it ran. Both now capture apositionClaimcounter and give way if a jump has bumped it since.The second is the narrower of the two: it needs a jump inside the same runloop turn as the opening scroll. The first fires on any quote tap that has to page.