Repository navigation
animation pipeline phase D: 3 cross-window composed scenes - #39
Open
borght-dev wants to merge 3 commits into
Open
borght-dev wants to merge 3 commits into
borght-dev wants to merge 3 commits into
Conversation
Adds the three cross-window animations from the spec — sidebar PR card
click → PR Detail window opens, work item palette → Work Item Detail
opens, sidebar → SQL hotkey opens SQL window. Each composes two window
apps in one canvas. The "second window opens" gesture is faked with a
CSS slide-in driven by the existing mock invoke layer: the production
invoke('open_*_window') call is intercepted by the story decorator,
which flips a state flag that animates the second window's transform
from translateX(105%) to translateX(0).
Adds SlideInCompositionFrame helper to main-window-data.tsx for the
shared composition shell.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
App.tsx fires loadSettings() in a useEffect on mount, which calls
invoke('load_settings'). The mock returned the static SETTINGS_BASELINE
(setupComplete=false) and overwrote the decorator's seeded settings,
causing App to render the SetupWizard instead of the PRs section.
Static screenshots dodged this race — animations couldn't.
Fix: invokeResponses.load_settings = () => useSettingsStore
.getState().settings for the cross-window stories — returns whatever
the seed currently has in the store, so post-load matches pre-load.
cross-pr-detail-open.gif now shows the real PR list (was wizard).
The slide-in still doesn't trigger reliably — tracked as follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… animation
Per-feedback iteration on the canary cross-window animation. Three
changes addressed three separate bugs that combined to produce a
12-frame slideshow with no visible interaction:
1. The play function failed silently. `findByText(/storybook phase 12/i)`
matched multiple elements (PR title AND branch label under the card),
throwing TestingLibraryElementError before the click ever fired.
Switched to `canvasElement.querySelectorAll('[data-pr-card]')` and
indexed to position 1 (PR #42 — second in PRS_CANONICAL). The card
title text appears in tooltip / aria nodes too, so text queries are
inherently unreliable for this list.
2. Frame rate was capped at ~2 fps. Each `page.screenshot()` at
1600×1000 with deviceScaleFactor=2 was effectively a 6.4-megapixel
capture and took 200-500 ms. The script now creates a separate
Playwright context with deviceScaleFactor=1 for the animation pass,
roughly doubling the captured frame count for the large composed
scenes and bringing simple stories (file palette etc.) up to the
declared 12 fps target.
3. Cursor was invisible. Playwright's userEvent fires DOM events but
never paints a cursor. Added `.storybook/anim-cursor.ts` with
`installCursor` / `moveCursorTo` / `clickRipple` / `hoverAt`
helpers — the cursor is a position:fixed SVG arrow with a 600 ms
transition and a click-ripple effect, so the GIF reads as a real
user interacting with the UI.
Plus a backdrop change: `SlideInCompositionFrame` now renders on a
soft purple radial gradient instead of solid #1a1a1a, with shadowed
rounded corners on each window. Reads as a desktop screenshot
rather than two windows floating on a black void.
The result for cross-pr-detail-open: 61 frames at 12 fps target,
rate ~5 fps actual, 623 KB, cursor visibly moves to PR #42, click
ripples, slide-in fires, both windows visible side-by-side. Other
animations also re-rendered with the new DSF=1 context (frame
counts doubled or tripled — most are now closer to declared fps).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This branch has not been deployed
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.
Summary
Phase D — three cross-window animations attempting to show what happens when the user clicks an action in one window that, in production, opens a separate Tauri window. Storybook can't open separate OS windows, so the second window mounts in the same canvas and slides in from the right via CSS when the trigger fires.
Depends on #38 (Phase C). Base
animation-pipeline-C; auto-rebases as the chain merges.What's in this PR
Anim_OpenPrDetailWindowApp.hero.stories.tsxcross-pr-detail-open.gifAnim_OpenWorkItemDetailWindowcomponents/work-items/CrossWindow.stories.tsxcross-work-item-detail-open.gifAnim_OpenSqlWindowHotkeyApp.hero.stories.tsxcross-sql-hotkey.gifPlus new shared infrastructure in
main-window-data.tsx:SlideInCompositionFrame— generic two-column frame with the right column transformable.CrossWindowShell— wrapsSlideInCompositionFrame, exposeswindow.__BORGDOCK_SLIDE_OPEN__()so a story play function or invoke handler can trigger the slide.Bug fixed in the chain
App.tsxre-firesloadSettings()on mount, whichinvoke('load_settings')— the staticSETTINGS_BASELINEmock return overwrote the decorator's seed and the App rendered the SetupWizard. Static screenshots dodged this race; animations didn't. Fix: cross-window stories now seedload_settingsas() => useSettingsStore.getState().settingsso post-load matches pre-load.This bug was latent in
Hero_ReadmeMaintoo but timed out before the wizard could appear.Known follow-ups
The slide-in animation for
cross-pr-detail-openandcross-work-item-detail-opendoesn't reliably trigger when the user clicks the trigger element (PR card / work item row). Production usesinvoke('open_pr_detail_window')andinvoke('open_workitem_detail_window'); the mock intercepts these but doesn't always fire the registered slide callback in time. Thecross-sql-hotkeyworks because the play function callswindow.__BORGDOCK_SLIDE_OPEN__()directly.Two options for fixing:
invoke('open_pr_detail_window')doesn't reach the mock'sslideOpenInvokeResponsecallback.The static composition shots already show both windows side-by-side (Hero_ReadmeMain), so the visual story is conveyed there. These animations would add motion polish.
Capture run
Phase E note
Per the design spec, Phase E (global hotkey toggle) was tagged "may be punted." Given the genuine difficulty of cross-window animations, I lean toward closing the rollout here at 16 animations and treating Phase E as a future addition only if a clean approach surfaces. Up to you whether to merge this and stop, or push for E.
🤖 Generated with Claude Code