diff --git a/NucleicRemote/NucleicRemote/Views/SessionDetailView.swift b/NucleicRemote/NucleicRemote/Views/SessionDetailView.swift index 0a866ab..26b57fb 100644 --- a/NucleicRemote/NucleicRemote/Views/SessionDetailView.swift +++ b/NucleicRemote/NucleicRemote/Views/SessionDetailView.swift @@ -617,6 +617,16 @@ struct TranscriptList: View { scrollPhase == .interacting || scrollPhase == .decelerating } + /// True from an explicit jump (chevron / send) until the scroll actually reaches the bottom. + /// While set, the unfollow branch is suppressed entirely: phase changes and geometry + /// emissions are delivered on separate callbacks with no ordering guarantee, so a stopping + /// fling could emit one last far-from-bottom reading whose *recorded* phase was still + /// user-driven (`.decelerating`) — landing after the tap's "follow again" and disengaging it, + /// which left the chevron up until a second tap. The latch outlives any stale emission and + /// clears on arrival at the bottom, or the moment the user genuinely grabs the transcript + /// again (`.interacting`), so a mid-jump scroll-away still works. + @State private var jumpingToBottom = false + var body: some View { ScrollViewReader { proxy in ScrollView {