diff --git a/assets/js/creations/file.js b/assets/js/creations/file.js index c5d0206f..6282b8c4 100644 --- a/assets/js/creations/file.js +++ b/assets/js/creations/file.js @@ -305,65 +305,10 @@ export async function parseMmpContent(xmlString) { appState.pattern.activeTrackId = appState.pattern.tracks[0]?.id || null; appState.pattern.activePatternIndex = 0; - // --- Restauração de Sessão (F5) --- - try { - const roomName = window.ROOM_NAME || "default_room"; - const tempStateJSON = sessionStorage.getItem(`temp_state_${roomName}`); - - if (tempStateJSON) { - console.log("Restaurando estado temporário da sessão..."); - const tempState = JSON.parse(tempStateJSON); - - // 1. Restaura Pattern (mantido) - appState.pattern.tracks.forEach((liveTrack) => { - const savedTrack = tempState.pattern.tracks.find( - (t) => t.id === liveTrack.id - ); - if (savedTrack) { - liveTrack.name = savedTrack.name; - liveTrack.patterns = savedTrack.patterns; - liveTrack.activePatternIndex = savedTrack.activePatternIndex; - liveTrack.volume = savedTrack.volume; - liveTrack.pan = savedTrack.pan; - if (liveTrack.volumeNode) { - liveTrack.volumeNode.volume.value = Tone.gainToDb(savedTrack.volume); - } - if (liveTrack.pannerNode) { - liveTrack.pannerNode.pan.value = savedTrack.pan; - } - } - }); - appState.pattern.tracks = appState.pattern.tracks.filter((liveTrack) => - tempState.pattern.tracks.some((t) => t.id === liveTrack.id) - ); - - // 2. 🔥 NOVO: Restaura Áudio (Clips e Tracks) no F5 - if (tempState.audio) { - console.log("Restaurando faixas de áudio e clips..."); - appState.audio.tracks = tempState.audio.tracks || []; - appState.audio.clips = tempState.audio.clips || []; - } - - // 3. Restaura Global (mantido) - document.getElementById("bpm-input").value = tempState.global.bpm; - document.getElementById("compasso-a-input").value = tempState.global.compassoA; - document.getElementById("compasso-b-input").value = tempState.global.compassoB; - document.getElementById("bars-input").value = tempState.global.bars; - - if (tempState.global.syncMode) { - appState.global.syncMode = tempState.global.syncMode; - const syncBtn = document.getElementById("sync-mode-btn"); - if (syncBtn) { - syncBtn.classList.toggle("active", tempState.global.syncMode === "global"); - syncBtn.textContent = tempState.global.syncMode === "global" ? "Global" : "Local"; - } - } - - appState.pattern.activeTrackId = tempState.pattern.activeTrackId; - } - } catch (e) { - console.error("Erro ao restaurar sessão:", e); - } + // --- SUBSTUIÇÃO DO BLOCO DE RESTAURAÇÃO --- + // Em vez daquele bloco try/catch gigante, apenas chamamos a função: + loadStateFromSession(); + // ------------------------------------------ await Promise.resolve(); renderAll(); diff --git a/assets/js/creations/state.js b/assets/js/creations/state.js index ced85a5b..827f7ba8 100644 --- a/assets/js/creations/state.js +++ b/assets/js/creations/state.js @@ -1,9 +1,8 @@ // js/state.js import { initializePatternState } from "./pattern/pattern_state.js"; -import { audioState, initializeAudioState, getAudioSnapshot, applyAudioSnapshot } from "./audio/audio_state.js"; +import { audioState, initializeAudioState } from "./audio/audio_state.js"; import { DEFAULT_VOLUME, DEFAULT_PAN } from "./config.js"; -import { generateMmpFile } from "./file.js"; // Vamos usar uma adaptação disto ou criar um helper -import { parseMmpContent } from "./file.js"; // Importante para restaurar o XML +import * as Tone from "https://esm.sh/tone"; // Adicione esta importação // Estado global da aplicação const globalState = { @@ -27,14 +26,9 @@ const globalState = { clipboard: null, lastRulerClickTime: 0, justReset: false, - // Configs Globais que devem persistir - bpm: 140, - compassoA: 4, - compassoB: 4, - bars: 1, - syncMode: "global" // Adicionado para persistir a escolha }; +// Define o ESTADO INICIAL para o pattern module const patternState = { tracks: [], activeTrackId: null, @@ -44,7 +38,7 @@ const patternState = { // Combina todos os estados em um único objeto namespaced export let appState = { global: globalState, - pattern: patternState, + pattern: patternState, audio: audioState, }; window.appState = appState; @@ -83,28 +77,26 @@ export function resetProjectState() { activePatternIndex: 0, }); - // 3. 🔥 CRÍTICO: Reseta o estado de áudio na força bruta - // Isso garante que os arrays fiquem vazios ANTES de qualquer salvamento de sessão + // 3. Reseta o estado de áudio (Força bruta para garantir limpeza na memória) if (appState.audio) { appState.audio.tracks = []; appState.audio.clips = []; appState.audio.audioEditorSeekTime = 0; } - // Chama a função original para garantir reinicialização de contextos se houver initializeAudioState(); } export function saveStateToSession() { if (!window.ROOM_NAME) return; - // 1. Limpa Tracks do Pattern + // 1. Crie uma versão "limpa" dos tracks const cleanTracks = appState.pattern.tracks.map((track) => { return { id: track.id, name: track.name, samplePath: track.samplePath, - patterns: track.patterns, + patterns: track.patterns, activePatternIndex: track.activePatternIndex, volume: track.volume, pan: track.pan, @@ -113,22 +105,21 @@ export function saveStateToSession() { }; }); - // 2. Constrói o objeto. 🔥 AQUI ADICIONAMOS O ÁUDIO + // 2. Construa o objeto de estado final para salvar const stateToSave = { pattern: { - ...appState.pattern, - tracks: cleanTracks, + ...appState.pattern, + tracks: cleanTracks, }, - // Salva o estado de Áudio para o F5 funcionar audio: { tracks: appState.audio.tracks || [], clips: appState.audio.clips || [], }, global: { - bpm: document.getElementById("bpm-input").value, - compassoA: document.getElementById("compasso-a-input").value, - compassoB: document.getElementById("compasso-b-input").value, - bars: document.getElementById("bars-input").value, + bpm: document.getElementById("bpm-input")?.value || 140, + compassoA: document.getElementById("compasso-a-input")?.value || 4, + compassoB: document.getElementById("compasso-b-input")?.value || 4, + bars: document.getElementById("bars-input")?.value || 1, syncMode: appState.global.syncMode, }, }; @@ -142,4 +133,79 @@ export function saveStateToSession() { } catch (e) { console.error("Falha ao salvar estado na sessão:", e); } +} + +// --- NOVA FUNÇÃO PARA CORRIGIR O ERRO --- +export function loadStateFromSession() { + const roomName = window.ROOM_NAME || "default_room"; + const tempStateJSON = sessionStorage.getItem(`temp_state_${roomName}`); + + if (!tempStateJSON) return false; + + console.log("Restaurando estado da sessão..."); + try { + const tempState = JSON.parse(tempStateJSON); + + // 1. Restaura Pattern Tracks + appState.pattern.tracks.forEach((liveTrack) => { + const savedTrack = tempState.pattern.tracks.find( + (t) => t.id === liveTrack.id + ); + if (savedTrack) { + liveTrack.name = savedTrack.name; + liveTrack.patterns = savedTrack.patterns; + liveTrack.activePatternIndex = savedTrack.activePatternIndex; + liveTrack.volume = savedTrack.volume; + liveTrack.pan = savedTrack.pan; + + if (liveTrack.volumeNode) { + liveTrack.volumeNode.volume.value = Tone.gainToDb(savedTrack.volume); + } + if (liveTrack.pannerNode) { + liveTrack.pannerNode.pan.value = savedTrack.pan; + } + } + }); + + // Filtra tracks que não existem mais no salvo + appState.pattern.tracks = appState.pattern.tracks.filter((liveTrack) => + tempState.pattern.tracks.some((t) => t.id === liveTrack.id) + ); + + // 2. Restaura Áudio + if (tempState.audio) { + appState.audio.tracks = tempState.audio.tracks || []; + appState.audio.clips = tempState.audio.clips || []; + } + + // 3. Restaura Global + if (tempState.global) { + const bpmInput = document.getElementById("bpm-input"); + if (bpmInput) bpmInput.value = tempState.global.bpm; + + const compassoA = document.getElementById("compasso-a-input"); + if (compassoA) compassoA.value = tempState.global.compassoA; + + const compassoB = document.getElementById("compasso-b-input"); + if (compassoB) compassoB.value = tempState.global.compassoB; + + const barsInput = document.getElementById("bars-input"); + if (barsInput) barsInput.value = tempState.global.bars; + + if (tempState.global.syncMode) { + appState.global.syncMode = tempState.global.syncMode; + const syncBtn = document.getElementById("sync-mode-btn"); + if (syncBtn) { + syncBtn.classList.toggle("active", tempState.global.syncMode === "global"); + syncBtn.textContent = tempState.global.syncMode === "global" ? "Global" : "Local"; + } + } + } + + appState.pattern.activeTrackId = tempState.pattern.activeTrackId; + return true; + } catch (e) { + console.error("Erro ao carregar estado da sessão:", e); + return false; + } } \ No newline at end of file