-
Notifications
You must be signed in to change notification settings - Fork 7
fix: external audio drop creates sample track instead of Quick Sampler #918
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -266,7 +266,7 @@ export function Timeline() { | |||||||||||||
| const zoomAnchorRef = useRef<{ time: number; viewportX: number } | null>(null); | ||||||||||||||
| const zoomFrameTimeRef = useRef<number | null>(null); | ||||||||||||||
| const handledTimelineZoomRequestIdRef = useRef<number | null>(null); | ||||||||||||||
| const { importMultipleFiles, importLoopToTrack, importAssetToTrack, importAudioFileAsNewQuickSampler, importAssetAsQuickSampler } = useAudioImport(); | ||||||||||||||
| const { importAudioFile, importMultipleFiles, importLoopToTrack, importAssetToTrack, importAudioFileAsNewQuickSampler, importAssetAsQuickSampler } = useAudioImport(); | ||||||||||||||
| const isTrackListCollapsed = trackListDisplayMode === 'collapsed'; | ||||||||||||||
|
|
||||||||||||||
| const handleDragOver = useCallback((e: React.DragEvent) => { | ||||||||||||||
|
|
@@ -295,18 +295,23 @@ export function Timeline() { | |||||||||||||
| return; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Audio files -> Quick Sampler, MIDI files -> piano roll tracks | ||||||||||||||
| // Audio files -> sample track (Alt+Drop -> Quick Sampler), MIDI files -> piano roll tracks | ||||||||||||||
| const wantsQuickSampler = e.altKey; | ||||||||||||||
| const files = e.dataTransfer.files; | ||||||||||||||
| if (files.length > 0) { | ||||||||||||||
| for (const file of Array.from(files)) { | ||||||||||||||
| if (file.type.startsWith('audio/') || /\.(wav|mp3|ogg|flac|aac|m4a|webm)$/i.test(file.name)) { | ||||||||||||||
| await importAudioFileAsNewQuickSampler(file); | ||||||||||||||
| if (wantsQuickSampler) { | ||||||||||||||
| await importAudioFileAsNewQuickSampler(file); | ||||||||||||||
| } else { | ||||||||||||||
| await importAudioFile(file); | ||||||||||||||
| } | ||||||||||||||
| } else if (/\.(mid|midi)$/i.test(file.name)) { | ||||||||||||||
| await importMultipleFiles([file]); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| }, [addTrack, importMultipleFiles, importLoopToTrack, importAssetToTrack, importAudioFileAsNewQuickSampler, importAssetAsQuickSampler]); | ||||||||||||||
| }, [addTrack, importAudioFile, importMultipleFiles, importLoopToTrack, importAssetToTrack, importAudioFileAsNewQuickSampler, importAssetAsQuickSampler]); | ||||||||||||||
|
|
||||||||||||||
| const handleTrackHeaderDragStart = useCallback((trackId: string) => { | ||||||||||||||
| draggedTrackIdRef.current = trackId; | ||||||||||||||
|
|
@@ -1260,7 +1265,7 @@ function EmptyTrackRow({ slotIndex }: { slotIndex: number }) { | |||||||||||||
| const addTrack = useProjectStore((s) => s.addTrack); | ||||||||||||||
| const virtualId = getArrangementEmptyTrackId(slotIndex); | ||||||||||||||
| const isSelected = selectedTrackIds.has(virtualId); | ||||||||||||||
| const { importLoopToTrack, importAssetToTrack, importAssetAsQuickSampler, importAudioFileAsNewQuickSampler } = useAudioImport(); | ||||||||||||||
| const { importAudioFile, importLoopToTrack, importAssetToTrack, importAssetAsQuickSampler, importAudioFileAsNewQuickSampler } = useAudioImport(); | ||||||||||||||
|
|
||||||||||||||
| const laneRef = useRef<HTMLDivElement>(null); | ||||||||||||||
| const [dropGhost, setDropGhost] = useState<{ left: number; width: number; name: string } | null>(null); | ||||||||||||||
|
|
@@ -1360,15 +1365,20 @@ function EmptyTrackRow({ slotIndex }: { slotIndex: number }) { | |||||||||||||
| return; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| const wantsQuickSampler = e.altKey; | ||||||||||||||
| const files = e.dataTransfer.files; | ||||||||||||||
| if (files.length > 0) { | ||||||||||||||
| for (const file of Array.from(files)) { | ||||||||||||||
| if (file.type.startsWith('audio/') || /\.(wav|mp3|ogg|flac|aac|m4a|webm)$/i.test(file.name)) { | ||||||||||||||
| await importAudioFileAsNewQuickSampler(file); | ||||||||||||||
| if (wantsQuickSampler) { | ||||||||||||||
| await importAudioFileAsNewQuickSampler(file); | ||||||||||||||
| } else { | ||||||||||||||
| await importAudioFile(file); | ||||||||||||||
|
||||||||||||||
| await importAudioFile(file); | |
| await importAudioFile(file, { | |
| startTime, | |
| trackOrder: slotIndex + 1, | |
| displayName: file.name, | |
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The drop behavior changed (audio drop => sample track, Alt+Drop => Quick Sampler) in both the main timeline drop zone and the empty-slot drop handler, but there doesn’t appear to be any unit test coverage for these paths. Please add a Timeline drag/drop test (similar to the existing timeline/TrackLane tests) that asserts
importAudioFileis called for normal drops andimportAudioFileAsNewQuickSampleris called whenaltKeyis true.