feat(swift-ios): reveal message timestamps on swipe - #5820
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This PR introduces a new user-facing feature (swipe-to-reveal timestamps) with new gesture handling, UI components, and state management. New features with this scope warrant human review. You can customize Macroscope's approvability policy. Learn more. |
|
@t3dotgg This SwiftUI PR is ready for your review. Its exact head is mergeable; repository/native CI, MacroScope, Cursor, and review-thread audits are clean with zero unresolved threads. The only red status is the unrelated Vercel marketing authorization check. |
4cb3307 to
497f54f
Compare
|
Dependency-safe rebuild is preserved at Conflict classification: stale code/history, not duplicate feature. One semantic repair was required: the old commit removed native Verification: focused 10/10; full native xcresult 365 total / 364 pass / one expected skip / zero fail; signed Debug run; integrated mixed rows/link/timestamp swipe/software-keyboard vertical dismissal/long-press proof; Evidence limitation: automation hid the visible software keyboard before the left-swipe segment, so the video does not conclusively show keyboard remaining open during timestamp reveal; source/gesture ordering tests cover non-dismissal and the video separately proves keyboard open + scoped vertical dismissal. Landing: editor/reasoning/keyboard foundations and #5972 first, then transplant only |
ad0b3dd to
a651dc6
Compare
|
Final-head conflict check (a651dc6): native text selection still presents handles and the edit menu on the timestamp implementation, so the horizontal timestamp recognizer does not steal selection. The focused timestamp/viewport suite passed (7/7). A new exact-head velocity reveal could not be captured with the semantic driver; the existing real-drag GIF in the PR remains the visual timestamp proof. The current native-CI red is the base fixture failure fixed in #6130. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9a0d36a. Configure here.


What Changed
This is intentionally SwiftUI-only. It does not change the server, wire contracts, web/desktop client, or React Native mobile client.
Why
Conversation timestamps currently require opening individual message details. This gives the native iOS client the familiar iMessage interaction: a deliberate leftward drag reveals several message times in context without leaving the thread.
The implementation stays at the transcript's existing
UICollectionViewownership seam. A dedicated pan recognizer publishes one small observable reveal value to the virtualized visible cells, while gesture arbitration leaves vertical transcript scrolling and nested horizontal content intact.Base:
t3code/rebuild-mobile-app-swiftatf98cab553546558e28d6e22f3dbe9807ecc3325f.UI Changes
Interaction
Play the 7-second final-head MP4
The recording uses a real 1.5-second swipe against the integrated app on commit
c4bb0cf8d, with two message times visible together; it is not a staged animation.Verification
Contract fixtures and native testsCI job — passed onc4bb0cf8d, including the previously failing environment-scoped provider fixtures.HomeThreadMetadataTestsand all eightTranscriptViewportGeometryTests.com.t3tools.t3code.swiftui.devon iOS 26.5.11:47 pmand11:49 pm) together and they disappeared at rest. LLDB measured translation x =-94and velocity =(-207.29, 0)on the timestamp pan; the vertical-dismissal guard evaluatedfalse.git diff --check— passed.ZStackwith a non-sizing overlay preserves the approved reveal appearance and fixes the resting row height; the already-required user doc is now indexed.c4bb0cf8d; the focused regression and exact-head gesture both verify horizontal intent does not enter that path, and the review thread is resolved with evidence.c4bb0cf8d, but exited 1 before producing a verdict because the Anthropic session limit was reached; no current-head Opus verdict is claimed. The earlier successful Opus review remains recorded above.Checklist
Built with GPT-5.6 Sol in the Codex harness.
Note
Add swipe-to-reveal message timestamps in the iOS chat transcript view
FeatureTimestampRevealState,FeatureTimestampRevealMessageView, andTranscriptTimestampRevealGeometryin ThreadDetailView.swift to manage reveal state, geometry clamping, and gesture gating.UIGestureRecognizerDelegate.FeatureMessageTimestampAccessibilityModifierso VoiceOver users receive timestamp information as custom accessibility content on all message types.keyboardDismissMode = .onDragapproach.Macroscope summarized ad0b3dd. (Automatic summaries will resume when PR exits draft mode or review begins).
Note
Low Risk
SwiftUI/UIKit transcript interaction only; no server or data changes, with geometry covered by unit tests.
Overview
Adds iMessage-style swipe-to-reveal timestamps on the native iOS chat transcript: a leftward pan drives one shared reveal distance so visible rows slide left and show trailing hour/minute labels, then animate closed on release (honoring Reduce Motion).
The transcript
UICollectionViewcoordinator owns a non-cancelling pan recognizer with gesture arbitration—only deliberate leftward horizontal pans, simultaneous recognition with scrolling, and deferral when the touch hits nested horizontal scrollers (e.g. wide Markdown). Collection cells wrap messages inFeatureTimestampRevealMessageViewbacked by sharedFeatureTimestampRevealStateandTranscriptTimestampRevealGeometryfor clamping.Keyboard and scroll behavior changes:
keyboardDismissMode = .onDragis removed; keyboard dismissal and releasing the bottom anchor now run only after meaningful vertical movement inscrollViewDidScroll. VoiceOver gets sent/received timestamp custom content on all message roles viaFeatureMessageTimestampAccessibilityModifier.Unit tests cover reveal width bounds and pan direction gating in
TranscriptViewportGeometryTests.Reviewed by Cursor Bugbot for commit ad0b3dd. Bugbot is set up for automated code reviews on this repo. Configure here.
Delivery: direct
Validated against Theo commit: f98cab5
Depends on: none
Merge order: this PR only
Validation status: Ready for human review. Current-head actionable CI, Cursor, Macroscope correctness, focused native tests, and integrated Simulator validation pass; zero unresolved threads. Macroscope approvability is neutral because new features require human review. The unrelated Vercel authorization failure is a maintainer-side gate.