fix: move ghostLayers decl before useLayoutEffect to fix TDZ
This commit is contained in:
+58
-57
@@ -4612,6 +4612,64 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
|
|||||||
const [isLooping, setIsLooping] = React.useState(false);
|
const [isLooping, setIsLooping] = React.useState(false);
|
||||||
const [showGhostNotes, setShowGhostNotes] = React.useState(true);
|
const [showGhostNotes, setShowGhostNotes] = React.useState(true);
|
||||||
const [sessionSyncMode, setSessionSyncMode] = React.useState(true);
|
const [sessionSyncMode, setSessionSyncMode] = React.useState(true);
|
||||||
|
|
||||||
|
const allMidiItems = React.useMemo(() => {
|
||||||
|
const result = [];
|
||||||
|
(activeTracks || []).forEach(t => {
|
||||||
|
if (!t.midiItems || !t.midiItems.length) return;
|
||||||
|
t.midiItems.forEach(m => {
|
||||||
|
var extended = Object.assign({}, m, { _trackId: t.id, _trackName: t.name });
|
||||||
|
result.push(extended);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}, [activeTracks]);
|
||||||
|
|
||||||
|
const ghostLayers = React.useMemo(function() {
|
||||||
|
if (!activeTracks || !st || !st.target_id) return [];
|
||||||
|
var fn = window.SonicGhost && window.SonicGhost.extractGhostLayers;
|
||||||
|
return fn ? fn(activeTracks, st.trackId, st.target_id, parseInt(bpm) || 120) : [];
|
||||||
|
}, [activeTracks, st.trackId, st.target_id, bpm]);
|
||||||
|
|
||||||
|
const secondsPerBar = (60.0 / (parseInt(bpm) || 120)) * 4;
|
||||||
|
const activeTargetItem = React.useMemo(function() {
|
||||||
|
if (!activeTracks || !st) return null;
|
||||||
|
var trk = activeTracks.find(function(t) { return t.id === st.trackId; });
|
||||||
|
return trk ? (trk.midiItems || []).find(function(m) { return m.id === st.target_id; }) : null;
|
||||||
|
}, [activeTracks, st.trackId, st.target_id]);
|
||||||
|
const sessionStartBar = sessionSyncMode && activeTargetItem
|
||||||
|
? (activeTargetItem.startTime / secondsPerBar) : 0;
|
||||||
|
|
||||||
|
const handleSwitchMidiItem = React.useCallback(function(itemId) {
|
||||||
|
if (itemId === st.target_id) return;
|
||||||
|
if (st.isDirty) {
|
||||||
|
onSaveNotes(st.id, st.trackId, st.target_id, notes);
|
||||||
|
}
|
||||||
|
var match = allMidiItems.find(function(m) { return m.id === itemId; });
|
||||||
|
if (!match) return;
|
||||||
|
var trk = (activeTracks || []).find(function(t) { return t.id === match._trackId; });
|
||||||
|
setSubTabs(function(prev) {
|
||||||
|
return prev.map(function(s) {
|
||||||
|
if (s.id !== st.id) return s;
|
||||||
|
return Object.assign({}, s, {
|
||||||
|
trackId: match._trackId,
|
||||||
|
target_id: match.id,
|
||||||
|
label: 'Piano Roll: ' + (match.name || 'MIDI'),
|
||||||
|
notes: match.notes || [],
|
||||||
|
duration: match.duration || 4,
|
||||||
|
instrumentProgram: trk ? trk.instrumentProgram : undefined,
|
||||||
|
instrumentName: trk ? trk.instrumentName : undefined,
|
||||||
|
note_selection: [],
|
||||||
|
currentTime: 0,
|
||||||
|
isDirty: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
setSelectedNoteIds([]);
|
||||||
|
setLoopStartBeat(null);
|
||||||
|
setLoopEndBeat(null);
|
||||||
|
}, [st.id, st.target_id, st.isDirty, allMidiItems, activeTracks, onSaveNotes, notes]);
|
||||||
|
|
||||||
const rulerDragRef = React.useRef(null);
|
const rulerDragRef = React.useRef(null);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const handler = (e) => {
|
const handler = (e) => {
|
||||||
@@ -5678,63 +5736,6 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
|
|||||||
const [showCC, setShowCC] = React.useState(true);
|
const [showCC, setShowCC] = React.useState(true);
|
||||||
const [ccHeight, setCcHeight] = React.useState(80);
|
const [ccHeight, setCcHeight] = React.useState(80);
|
||||||
|
|
||||||
const allMidiItems = React.useMemo(() => {
|
|
||||||
const result = [];
|
|
||||||
(activeTracks || []).forEach(t => {
|
|
||||||
if (!t.midiItems || !t.midiItems.length) return;
|
|
||||||
t.midiItems.forEach(m => {
|
|
||||||
var extended = Object.assign({}, m, { _trackId: t.id, _trackName: t.name });
|
|
||||||
result.push(extended);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}, [activeTracks]);
|
|
||||||
|
|
||||||
const ghostLayers = React.useMemo(function() {
|
|
||||||
if (!activeTracks || !st || !st.target_id) return [];
|
|
||||||
var fn = window.SonicGhost && window.SonicGhost.extractGhostLayers;
|
|
||||||
return fn ? fn(activeTracks, st.trackId, st.target_id, parseInt(bpm) || 120) : [];
|
|
||||||
}, [activeTracks, st.trackId, st.target_id, bpm]);
|
|
||||||
|
|
||||||
const secondsPerBar = (60.0 / (parseInt(bpm) || 120)) * 4;
|
|
||||||
const activeTargetItem = React.useMemo(function() {
|
|
||||||
if (!activeTracks || !st) return null;
|
|
||||||
var trk = activeTracks.find(function(t) { return t.id === st.trackId; });
|
|
||||||
return trk ? (trk.midiItems || []).find(function(m) { return m.id === st.target_id; }) : null;
|
|
||||||
}, [activeTracks, st.trackId, st.target_id]);
|
|
||||||
const sessionStartBar = sessionSyncMode && activeTargetItem
|
|
||||||
? (activeTargetItem.startTime / secondsPerBar) : 0;
|
|
||||||
|
|
||||||
const handleSwitchMidiItem = React.useCallback(function(itemId) {
|
|
||||||
if (itemId === st.target_id) return;
|
|
||||||
if (st.isDirty) {
|
|
||||||
onSaveNotes(st.id, st.trackId, st.target_id, notes);
|
|
||||||
}
|
|
||||||
var match = allMidiItems.find(function(m) { return m.id === itemId; });
|
|
||||||
if (!match) return;
|
|
||||||
var trk = (activeTracks || []).find(function(t) { return t.id === match._trackId; });
|
|
||||||
setSubTabs(function(prev) {
|
|
||||||
return prev.map(function(s) {
|
|
||||||
if (s.id !== st.id) return s;
|
|
||||||
return Object.assign({}, s, {
|
|
||||||
trackId: match._trackId,
|
|
||||||
target_id: match.id,
|
|
||||||
label: 'Piano Roll: ' + (match.name || 'MIDI'),
|
|
||||||
notes: match.notes || [],
|
|
||||||
duration: match.duration || 4,
|
|
||||||
instrumentProgram: trk ? trk.instrumentProgram : undefined,
|
|
||||||
instrumentName: trk ? trk.instrumentName : undefined,
|
|
||||||
note_selection: [],
|
|
||||||
currentTime: 0,
|
|
||||||
isDirty: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
setSelectedNoteIds([]);
|
|
||||||
setLoopStartBeat(null);
|
|
||||||
setLoopEndBeat(null);
|
|
||||||
}, [st.id, st.target_id, st.isDirty, allMidiItems, activeTracks, onSaveNotes, notes]);
|
|
||||||
|
|
||||||
const snapPitchToScale = (pitch, scale) => {
|
const snapPitchToScale = (pitch, scale) => {
|
||||||
if (!scale) return pitch;
|
if (!scale) return pitch;
|
||||||
const octave = Math.floor(pitch / 12);
|
const octave = Math.floor(pitch / 12);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user