Thread transfer impact
⚠️ The latest CI run did not produce a thread transfer result for f32aea0.
This comment will update automatically after the next completed run.
Fixes interrupted floating-preview resize gestures reported in #22988 (GitCafe mirror #22998). A lost release could leave a resize active, so later buttonless hover enlarged or moved the preview and left it stranded over the conversation. Resizing also mixed a captured frame with the live source aspect ratio, allowing a source update to change its size during the gesture.
Capture fractional geometry from the preview element at pointerdown and freeze that frame's ratio for the gesture. Each handle owns its pointer capture. Release, cancellation, capture loss, blur, and missing primary-button state end the gesture; idle moves do nothing. A new pointerdown discards stale capture state if a handle disappeared. Finish clamps position through the existing resolver while preserving the user's chosen width and interaction type.
Fixes #22988
Triaged bug via the automated issue flow; GitCafe mirror #22998.
This is gesture-only: no chat/composer inset, details-card folding, anchor, or placement-policy changes. #16831 supplied the interrupted-gesture findings; its removal of intentional inset/folding behavior was why it was closed unmerged, and those layout changes are excluded here.
Evidence re-captured as narrated before/after recordings per EVIDENCE.md. Compared before 680152e27b with after db94329f89. Captured all nine rows of the fixture matrix: evidence index · independent proof audit: SUFFICIENT.
Every recording pair has matching scripted steps and decoded-video timestamps above it. Normal gestures use native drags above the minimum size. Interruption/transition rows acquire native pointer capture before deterministic event injection. Physical outside-window release is explicitly excluded.
Blur now releases capture and holds at 355×222; before continues to 460×288 despite blur. Missing release now holds at 280×175; before continues to 318×199.
Adverse transition finding (needs maintainer review): R5 after ends with its bottom edge at 656 instead of 612, a 44 px drift absent before. R5/R6 rendered aspect ratios also change during source resizing. These recordings document failed expectations, not passing transition behaviour. Normal samples use whole-pixel geometry and do not independently distinguish the fractional-geometry fix or transient self-correcting jumps.
| Row | Script, timestamps and pair |
|---|---|
| R1 — NW normal · 1440×900 · light | Recording pair |
| R2 — E normal · 1440×900 · dark | Recording pair |
| R3 — NW blur · 1440×900 · dark | Recording pair |
| R4 — E missing release · 390×844 · light | Recording pair |
| R5 — NW source transition · 1440×900 · light | Recording pair |
| R6 — E source transition · 390×844 · dark | Recording pair |
| R7 — NW normal · 390×844 · dark | Recording pair |
| R8 — E normal · 390×844 · light | Recording pair |
| S1 — Resting · 1440×900 · light | Static pair and diffs |
Out of scope: other handle/termination/theme combinations and drag/pill/actions keep shared-controller sampling within eight pairs. Physical outside-window release, touch and native Electron/device/PDF/mobile require separate input or environments. Providers, contracts, backend and relay/tunnel paths are unchanged.
Environment: Linux x86_64, Chromium 154, DPR 2, loaded system UI sans-serif; identical isolated seeds and local static fixture. CSS viewports 1440×900 and 390×844, light/dark. Per-capture UTC clocks appear in the index. MP4 rasters are 2880×1800 and 780×1688; static PNGs show the full desktop surface downsampled to 1280×800.
Static before:
Static after:
Static delta: 10,760/1,024,000 nonzero pixels; 962 above 16/255; maximum channel delta 71. All changes lie inside streamed content. S1 includes unmasked zero-threshold ×8 and >16/255 diff images. The auditor reproduced these metrics exactly.
What else changed: the PR extracts the pointer controller, wires blur/lost-capture termination into the shared shell, adds controller tests and makes an empty-obstacle constant private. No styles, transports, contracts, providers or backend changes. Capture-only differences include stream rasterization, annotation timing and local IDs.
Capture: Codex gpt-6.1-sol; proof audit: Claude Opus 5.5.
Model/harness: GPT-6.1-Sol through Codex in T3 Code; independent GPT-6.1-Sol/Codex and Claude Opus 5.5 reviews and evidence audits.
Review completed
Skipped - Not affected
Added 3 commits
⚠️ The latest CI run did not produce a thread transfer result for f32aea0.
This comment will update automatically after the next completed run.
Added 1 commit
Verdict: Approved at db94329
Macroscope's review found this PR approvable — This is a focused fix to existing floating-preview drag and resize lifecycle handling, including interrupted pointer gestures and aspect-ratio jumps. Changes remain isolated to the preview interaction and its tests, with no schema, default, infrastructure, or sensitive-data impact.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review. 🎉
37ca73cb-f778-43b2-b2c9-a7e51b4334ffReviewing files that changed from the base of the PR and between 680152e27b2a961686389ca69a1557cbb2c55f08 and db94329f8965c9893796d82bb78a92c93764ef5f.
apps/web/src/components/preview/ThreadPreviewMiniPlayer.tsxapps/web/src/components/preview/previewMiniPlayerGesture.test.tsapps/web/src/components/preview/previewMiniPlayerGesture.tsapps/web/src/components/preview/previewMiniPlayerLayout.tsIncluded review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.
The mini-player’s drag and resize handling now uses a dedicated gesture controller. The controller validates and tracks pointer gestures, while the shell commits frame updates and handles gesture termination.
Changes: Preview mini-player gestures
| Layer / File(s) | Summary |
|---|---|
Gesture controller and behavior tests apps/web/src/components/preview/previewMiniPlayerGesture.ts, apps/web/src/components/preview/previewMiniPlayerGesture.test.ts | A new controller handles drag and resize calculations, pointer capture, gesture termination, and touch taps. Tests cover geometry, pointer types, capture failures, and gesture completion. |
Mini-player shell integration apps/web/src/components/preview/ThreadPreviewMiniPlayer.tsx, apps/web/src/components/preview/previewMiniPlayerLayout.ts | MiniPlayerShell delegates gesture handling to the controller and commits frame updates to the store. It ends gestures on blur and lost pointer capture. The obstacle constant is no longer exported. |
Priority: ⬇️ Low
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix · Severity of issue fixed: Low
| 1 | sequenceDiagram |
| 2 | participant Pointer |
| 3 | participant MiniPlayerShell |
| 4 | participant GestureController |
| 5 | participant MiniPlayerStore |
| 6 | Pointer->>MiniPlayerShell: Send drag or resize events |
| 7 | MiniPlayerShell->>GestureController: Begin, update, or end gesture |
| 8 | GestureController->>MiniPlayerStore: Commit updated frame |
Possibly related issues
pingdotgg/t3code#22988: Reports unexpected resizing and a gesture that remains stuck after pointer release; this change handles gesture termination and final geometry.Possibly related PRs
Suggested reviewers: maria-rcks
db943This change makes floating preview drag and resize gestures end cleanly when interrupted. No actionable merge-blocking risk remains after review, and the stale-gesture edge case is handled by the next pointerdown.
| Check name | Status | Explanation |
|---|---|---|
| Title check | Passed | The title is concise, specific, and accurately summarizes the main change: interrupted floating preview resize gestures now end cleanly without scale jumps. |
| Linked Issues check | Passed | Check skipped because no linked issues were found for this pull request. |
| Out of Scope Changes check | Passed | Check skipped because no linked issues were found for this pull request. |
| Description check | Passed | The description is complete and follows the required sections. It clearly explains the problem, implementation, scope, approval context, verification results, evidence, environment, limitations, and a… |
Explanation
The description is complete and follows the required sections. It clearly explains the problem, implementation, scope, approval context, verification results, evidence, environment, limitations, and agent details. It also reports an adverse transition finding for maintainer review.
Comment @coderabbitai help to get the list of available commands.