criação de novas patterns de composição nos projetos
This commit is contained in:
1 parent
df0708adf3
commit
f80d6511a4
3 files changed
+144
-12
No files matched your search
@@ -47,6 +47,40 @@ import { updateStepUI, renderPatternEditor } from "./pattern/pattern_ui.js";
|
||||
import { PORT_SOCK } from "./config.js";
|
||||
import { DEFAULT_PROJECT_XML } from "./utils.js"
|
||||
|
||||
function _getRackIdFallback() {
|
||||
// 1) pega do primeiro bassline que já tenha instrumentSourceId
|
||||
const b = (appState.pattern.tracks || []).find(
|
||||
(t) => t.type === "bassline" && t.instrumentSourceId
|
||||
);
|
||||
if (b?.instrumentSourceId) return b.instrumentSourceId;
|
||||
|
||||
// 2) pega do primeiro instrumento do rack (parentBasslineId)
|
||||
const child = (appState.pattern.tracks || []).find(
|
||||
(t) => t.type !== "bassline" && t.parentBasslineId
|
||||
);
|
||||
if (child?.parentBasslineId) return child.parentBasslineId;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function _nextPatternIndex() {
|
||||
const bassMax = Math.max(
|
||||
-1,
|
||||
...(appState.pattern.tracks || [])
|
||||
.filter((t) => t.type === "bassline" && Number.isFinite(Number(t.patternIndex)))
|
||||
.map((t) => Number(t.patternIndex))
|
||||
);
|
||||
|
||||
const nonBassMax = Math.max(
|
||||
-1,
|
||||
...(appState.pattern.tracks || [])
|
||||
.filter((t) => t.type !== "bassline")
|
||||
.map((t) => (t.patterns?.length || 0) - 1)
|
||||
);
|
||||
|
||||
return Math.max(bassMax, nonBassMax) + 1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Gera um ID único otimista (ex: "track_1678886401000_abc123")
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -616,6 +650,64 @@ async function handleActionBroadcast(action) {
|
||||
break;
|
||||
}
|
||||
|
||||
case "CREATE_NEW_PATTERN": {
|
||||
const patternIndex =
|
||||
Number.isFinite(Number(action.patternIndex)) ? Number(action.patternIndex) : _nextPatternIndex();
|
||||
|
||||
const name = (action.name || "").trim() || `Beat/Bassline ${patternIndex}`;
|
||||
|
||||
// 1) garante patterns em todas as tracks reais
|
||||
_ensurePatternsUpTo(patternIndex);
|
||||
|
||||
// 2) cria bassline track container (pattern “da playlist”)
|
||||
let b = (appState.pattern.tracks || []).find(
|
||||
(t) => t.type === "bassline" && Number(t.patternIndex) === patternIndex
|
||||
);
|
||||
|
||||
if (!b) {
|
||||
b = {
|
||||
id: `bassline_${Date.now()}_${Math.random().toString(36).slice(2)}`,
|
||||
name,
|
||||
type: "bassline",
|
||||
patternIndex,
|
||||
playlist_clips: [],
|
||||
patterns: [],
|
||||
isMuted: false,
|
||||
instrumentSourceId: _getRackIdFallback(),
|
||||
volume: 1,
|
||||
pan: 0,
|
||||
};
|
||||
appState.pattern.tracks.push(b);
|
||||
} else {
|
||||
b.name = name;
|
||||
if (!b.instrumentSourceId) b.instrumentSourceId = _getRackIdFallback();
|
||||
if (!Array.isArray(b.playlist_clips)) b.playlist_clips = [];
|
||||
}
|
||||
|
||||
// 3) renomeia a “coluna” nas patterns exportáveis
|
||||
(appState.pattern.tracks || []).forEach((t) => {
|
||||
if (t.type === "bassline") return;
|
||||
if (t.patterns?.[patternIndex]) t.patterns[patternIndex].name = name;
|
||||
});
|
||||
|
||||
// 4) já seleciona essa pattern (opcional, mas fica UX boa)
|
||||
appState.pattern.activePatternIndex = patternIndex;
|
||||
(appState.pattern.tracks || []).forEach((t) => (t.activePatternIndex = patternIndex));
|
||||
|
||||
try { schedulePatternRerender(); } catch {}
|
||||
renderAll();
|
||||
saveStateToSession();
|
||||
|
||||
// 5) persiste no servidor (igual você já faz em outros updates)
|
||||
const isFromSelf = action.__senderId === socket.id;
|
||||
if (window.ROOM_NAME && isFromSelf) {
|
||||
const xml = generateXmlFromStateExported();
|
||||
sendAction({ type: "SYNC_PATTERN_STATE", xml });
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "ADD_PLAYLIST_PATTERN_CLIP": {
|
||||
const { patternIndex, pos, len, clipId, name } = action;
|
||||
|
||||
|
||||
Reference in new issue
Block a user