atualizando em tempo real as patterns no editor de patterns e playlist

This commit is contained in:
JotaChina committed 2025-12-27 15:14:50 -03:00
1 parent 7eeed3ee92
commit 443685ac72
3 files changed
+153 -98

No files matched your search

+52 -16
View File
@@ -507,6 +507,34 @@ socket.on("action_broadcast", (payload) => {
// -----------------------------------------------------------------------------
// PROCESSAR AÇÕES
// -----------------------------------------------------------------------------
const LMMS_BAR_TICKS = 192;
const STEPS_PER_BAR = 16;
function _makeEmptyPattern(idx) {
// tenta respeitar bars-input atual, mas nunca menos que 1 bar
const bars = parseInt(document.getElementById("bars-input")?.value, 10) || 1;
const stepsLen = Math.max(STEPS_PER_BAR, bars * STEPS_PER_BAR);
return {
name: `Pattern ${idx + 1}`,
steps: new Array(stepsLen).fill(false),
notes: [],
pos: idx * LMMS_BAR_TICKS,
};
}
function _ensurePatternsUpTo(patternIndex) {
appState.pattern.tracks.forEach((t) => {
if (t.type === "bassline") return;
if (!Array.isArray(t.patterns)) t.patterns = [];
while (t.patterns.length <= patternIndex) {
t.patterns.push(_makeEmptyPattern(t.patterns.length));
}
});
}
let isLoadingProject = false;
async function handleActionBroadcast(action) {
if (!action || !action.type) return;
@@ -995,29 +1023,34 @@ async function handleActionBroadcast(action) {
// Notes
case "TOGGLE_NOTE": {
const { trackIndex: ti, patternIndex: pi, stepIndex: si, isActive } = action;
const { trackIndex: ti, patternIndex: pi, stepIndex: si, isActive } = action;
// ✅ garante que o índice exista em todas as tracks (evita “silêncio” na playlist)
_ensurePatternsUpTo(pi);
const t = appState.pattern.tracks[ti];
if (t) {
t.patterns[pi] = t.patterns[pi] || _makeEmptyPattern(pi);
// mantém metadados estáveis p/ export/sync
if (t.patterns[pi].pos == null) t.patterns[pi].pos = pi * LMMS_BAR_TICKS;
if (!t.patterns[pi].name) t.patterns[pi].name = `Pattern ${pi + 1}`;
if (!Array.isArray(t.patterns[pi].notes)) t.patterns[pi].notes = [];
const t = appState.pattern.tracks[ti];
if (t) {
t.patterns[pi] = t.patterns[pi] || { steps: [] };
t.patterns[pi].steps[si] = isActive;
try { updateStepUI(ti, pi, si, isActive); } catch {}
if (!isFromSelf) schedulePatternRerender();
}
}
// ✔ ADICIONE ISTO
if (window.ROOM_NAME && isFromSelf) {
const xml = generateXmlFromStateExported();
sendAction({
type: "SYNC_PATTERN_STATE",
xml
});
}
if (window.ROOM_NAME && isFromSelf) {
const xml = generateXmlFromStateExported();
sendAction({ type: "SYNC_PATTERN_STATE", xml });
}
saveStateToSession();
break;
}
saveStateToSession();
break;
}
case "UPDATE_PATTERN_NOTES": {
const {
@@ -1102,6 +1135,9 @@ async function handleActionBroadcast(action) {
track.activePatternIndex = patternIndex;
});
// ✅ garante que TODAS as tracks tenham esse índice disponível
_ensurePatternsUpTo(patternIndex);
try {
const stepsPerBar = 16; // 4/4 em 1/16