Skip to content

fix: wire all AI tool actions to new floating panels#589

Merged
ChuxiJ merged 1 commit intomainfrom
fix/v0.0.21-wire-ai-tools-correctly
Mar 20, 2026
Merged

fix: wire all AI tool actions to new floating panels#589
ChuxiJ merged 1 commit intomainfrom
fix/v0.0.21-wire-ai-tools-correctly

Conversation

@ChuxiJ
Copy link
Copy Markdown

@ChuxiJ ChuxiJ commented Mar 20, 2026

Summary

  • CanvasContextMenu: "Music Enhancer" → opens MusicEnhancerPanel, "Add a Layer" → opens AddLayerPanel (was incorrectly calling setShowGenerationPanel)
  • Select window right-click: Now shows CanvasContextMenu with full AI Tools submenu (replaced old RegionContextMenu that only had "Regenerate Selected Region...")
  • Clip context menu "Create Cover...": Opens MusicEnhancerPanel floating panel (was opening old CoverModal)
  • Clip context menu "Add Layer here...": Opens AddLayerPanel via uiStore (was using local state + old AddLayerModal)
  • Double-click empty track area: Directly opens AddLayerPanel for stems/sample tracks (was showing confusing LaneContextMenu popup with "Create Quick Sampler..." / "Add Layer...")

Test plan

  • npx tsc --noEmit — 0 errors
  • npm test — 1854 tests pass
  • Right-click on select window → AI Tools submenu → Music Enhancer → floating panel opens
  • Right-click on clip → Create Cover... → MusicEnhancerPanel opens (not old modal)
  • Right-click on clip → Add Layer here... → AddLayerPanel opens (not old modal)
  • Double-click empty area on stems track → AddLayerPanel opens directly

🤖 Generated with Claude Code

- CanvasContextMenu: "Music Enhancer" now opens MusicEnhancerPanel,
  "Add a Layer" now opens AddLayerPanel (was calling old setShowGenerationPanel)
- Timeline: right-click on select window now shows CanvasContextMenu
  with AI Tools submenu (replaced old RegionContextMenu with single item)
- ClipBlock: "Create Cover..." opens MusicEnhancerPanel instead of old CoverModal
- ClipBlock: "Add Layer here..." opens AddLayerPanel via uiStore instead of
  local modal state
- TrackLane: double-click on empty stems/sample area opens AddLayerPanel
  directly instead of showing confusing LaneContextMenu popup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 20, 2026 16:59
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates timeline/context-menu AI tool entry points so they open the newer floating panels (AddLayerPanel, MusicEnhancerPanel) and unifies the select-window context menu with the existing canvas context menu.

Changes:

  • Double-click on empty stems/sample/audio track space now opens AddLayerPanel.
  • Select-window right-click now uses CanvasContextMenu (instead of RegionContextMenu).
  • Clip context menu actions “Add Layer here...” / “Create Cover...” now open floating panels via uiStore.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/components/timeline/TrackLane.tsx Double-click behavior updated to open AddLayerPanel.
src/components/timeline/Timeline.tsx Select-window context menu swapped to CanvasContextMenu.
src/components/timeline/ClipBlock.tsx Clip context menu actions rewired to open floating panels via uiStore.
src/components/timeline/CanvasContextMenu.tsx AI Tools submenu actions updated to open AddLayerPanel / MusicEnhancerPanel.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +572 to 579
{/* Region context menu — right-click on select window → same as canvas context menu with AI Tools */}
{regionCtxMenu && selectWindow && (
<RegionContextMenu
<CanvasContextMenu
x={regionCtxMenu.x}
y={regionCtxMenu.y}
onRegenerateRegion={() => {
setRegionCtxMenu(null);
setRegionRegenerateTarget({
startTime: selectWindow.startTime,
endTime: selectWindow.endTime,
trackIds: selectWindow.trackIds,
});
}}
onClose={() => setRegionCtxMenu(null)}
hasReadyClips={
project.tracks.some((t) =>
selectWindow.trackIds.includes(t.id) &&
t.clips.some((c) => {
const clipEnd = c.startTime + c.duration;
return Math.min(selectWindow.endTime, clipEnd) > Math.max(selectWindow.startTime, c.startTime)
&& c.generationStatus === 'ready';
}),
)
}
/>
)}
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CanvasContextMenu no longer provides a way to trigger region regeneration, but Timeline still renders RegionRegenerateModal and keeps setRegionRegenerateTarget/regionRegenerateTarget state. After this change nothing in the codebase calls setRegionRegenerateTarget, so the modal becomes unreachable (and related imports/hooks become dead code). Either add a region-specific action back into this context menu (e.g., set the target from selectWindow before opening the modal) or remove the unused modal wiring/imports/state if the feature is intentionally deprecated.

Copilot uses AI. Check for mistakes.
onConsolidate={() => { void handleConsolidate(); }}
onDelete={() => { closeCtxMenu(); removeClip(clip.id); }}
onAddLayer={() => { closeCtxMenu(); setAddLayerOpen(true); }}
onAddLayer={() => { closeCtxMenu(); useUIStore.getState().setAddLayerOpen(true); }}
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opening AddLayerPanel here no longer sets a selection/range for the action. Previously this menu action had clip-local context (startTime/duration); now AddLayerPanel will fall back to the existing selectWindow (or the whole song if none), which makes "Add Layer here..." likely operate on the wrong time range. Consider setting selectWindow to { startTime: clip.startTime, endTime: clip.startTime + clip.duration, trackIds: [track.id] } (or an appropriate range) before opening the panel.

Suggested change
onAddLayer={() => { closeCtxMenu(); useUIStore.getState().setAddLayerOpen(true); }}
onAddLayer={() => {
closeCtxMenu();
// Ensure Add Layer operates on this clip's time range and track
useProjectStore.getState().setSelectWindow({
startTime: clip.startTime,
endTime: clip.startTime + clip.duration,
trackIds: [track.id],
});
useUIStore.getState().setAddLayerOpen(true);
}}

Copilot uses AI. Check for mistakes.
onCreateCover={() => {
closeCtxMenu();
setCoverModal(clip.id);
useUIStore.getState().setMusicEnhancerOpen(true);
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MusicEnhancerPanel determines the target clip from the current selectWindow (and its trackIds). This handler opens the panel but does not set/adjust selectWindow to the clicked clip’s range, so "Create Cover..." can open the panel with no selected clip (or a different clip) and prefill the wrong prompt/lyrics. Set selectWindow to the clip’s time range + track before opening, or introduce a dedicated "cover target" in uiStore that the panel can consume.

Suggested change
useUIStore.getState().setMusicEnhancerOpen(true);
const uiState = useUIStore.getState();
uiState.setSelectWindow({
startTime: clip.startTime,
endTime: clip.startTime + clip.duration,
trackIds: [track.id],
});
uiState.setMusicEnhancerOpen(true);

Copilot uses AI. Check for mistakes.
const rect = e.currentTarget.getBoundingClientRect();
const laneX = e.clientX - rect.left;
const clickTime = laneX / pixelsPerSecond;
if (hitsClip(clickTime)) return;
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now opens AddLayerPanel on double-click but does not set a time range/selection for where the layer should be generated. Since AddLayerPanel uses selectWindow to compute startTime/endTime (defaulting to the whole song when selectWindow is null), double-clicking empty space will likely open the panel targeting 0..projectDuration rather than the clicked location. Consider restoring the prior range calculation (snap click time, clamp duration) and calling useUIStore.getState().setSelectWindow(...) (and optionally trackIds: [track.id]) before setAddLayerOpen(true).

Suggested change
if (hitsClip(clickTime)) return;
if (hitsClip(clickTime)) return;
// Set a selection window around the clicked time so AddLayerPanel
// can derive an appropriate start/end range.
const rawTime = laneX / pixelsPerSecond;
const startTime = Math.max(0, snapToGrid(rawTime, project.bpm, 1));
const remaining = project.totalDuration - startTime;
const duration = Math.max(10, Math.min(30, remaining));
const end = startTime + duration;
useUIStore.getState().setSelectWindow({
start: startTime,
end,
trackIds: [track.id],
});

Copilot uses AI. Check for mistakes.
@ChuxiJ ChuxiJ merged commit 6e6c7c9 into main Mar 20, 2026
8 checks passed
@ChuxiJ ChuxiJ deleted the fix/v0.0.21-wire-ai-tools-correctly branch March 20, 2026 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants