feat: User input visualization (click replay) when time traveling#361
Conversation
- Remove unused Snapshot import from backend index - Fix snapShot.ts JSDoc (fiberRoot param) - Shorten content script comments and reference implementation doc Co-authored-by: Cursor <cursoragent@cursor.com>
|
@Agboolafeyikemi is attempting to deploy a commit to the Reactime Team on Vercel. A member of the Team first needs to authorize it. |
marsbird
left a comment
There was a problem hiding this comment.
Thanks for this PR, Feyi! The click-replay / laser pointer concept is a great addition to the time-travel flow. This is already really solid, but before I merge, I just have a few pieces that could use a second pass.
- hideClickReplay is called redundantly. In background.js, after a new snapshot is stored, hideClickReplay is sent in three separate places — once for a duplicate snapshot, once for a reloaded tab, and once in the if (didAddSnapshot) block below. The first two guard cases are correct on their own, but the third call is already redundant with them since the else branch (which sets
didAddSnapshot = true) is mutually exclusive with the earlier guards. More importantly, hideClickReplay is also sent at the very top of the sendSnapshots handler (before the duplicate/reload checks). Please audit and consolidate these so the intent is clear and there's no risk of a hide firing at an unexpected time. - the way it's written currently, I believe clientX/clientY coordinates will be wrong after any scroll. userEventCapture.ts stores
e.clientXande.clientY, which are viewport-relative. If the user scrolls between the click and the time-travel jump, the pointer overlay will render at the wrong position on screen. Could you instead store pageX/pageY (document-relative) instead and then offsetting by window.scrollX/scrollY at render time in the content script? - lastUserEvent type cast in snapShot.ts is a bit fragile. Using (
payload as { lastUserEvent?: ReturnType<typeof getLastUserEvent> }) to attach a property to the snapshot is a workaround for the fact that lastUserEvent isn't part of the Snapshot type definition. It would be cleaner to extend the Snapshot type in backendTypes.ts to include an optional lastUserEvent field, which would also give you proper type safety downstream in the content script. - one small non-blocking suggestion: the pointerRippleRef null check in updateClickReplayPointer (
if (ripple)) is unnecessary since pointerRippleRef is always assigned alongside pointerDotRef in getOrCreatePointerOverlay. I think this could be simplified, but I'm happy to leave it if you disagree
Overall this is a feature I'm excited to get into the project - address the items above and this will be in great shape for merge!
Thanks so much for the thorough review, really appreciate the careful read. I've pushed commits addressing all four points: |
🔗 Linked issue
Description
When time traveling through snapshots, it’s not always obvious which user action led to each state. This PR adds click replay: the extension records the last click in the target app and, when you jump to a snapshot, shows a pointer overlay at that click position so you can see what interaction caused the state change.
Checklist
I've followed the Contributing guidelines
[x ] I've titled my PR according to the Conventional Commits spec
I've linked an open issue
I've added tests that fail without this PR but pass with it
[ x] I've linted and tested my code
I've updated documentation (if appropriate)