plugin v1.0.1
Deploy / Deploy (push) Successful in 1m15s
Details
Deploy / Deploy (push) Successful in 1m15s
Details
This commit is contained in:
parent
c332ce07cd
commit
ef0b8428f7
|
|
@ -314,7 +314,7 @@ export async function parseMmpContent(xmlString) {
|
||||||
console.log("Restaurando estado temporário da sessão...");
|
console.log("Restaurando estado temporário da sessão...");
|
||||||
const tempState = JSON.parse(tempStateJSON);
|
const tempState = JSON.parse(tempStateJSON);
|
||||||
|
|
||||||
// 1. Restaura Pattern (código que já existia)
|
// 1. Restaura Pattern (mantido)
|
||||||
appState.pattern.tracks.forEach((liveTrack) => {
|
appState.pattern.tracks.forEach((liveTrack) => {
|
||||||
const savedTrack = tempState.pattern.tracks.find(
|
const savedTrack = tempState.pattern.tracks.find(
|
||||||
(t) => t.id === liveTrack.id
|
(t) => t.id === liveTrack.id
|
||||||
|
|
@ -325,7 +325,6 @@ export async function parseMmpContent(xmlString) {
|
||||||
liveTrack.activePatternIndex = savedTrack.activePatternIndex;
|
liveTrack.activePatternIndex = savedTrack.activePatternIndex;
|
||||||
liveTrack.volume = savedTrack.volume;
|
liveTrack.volume = savedTrack.volume;
|
||||||
liveTrack.pan = savedTrack.pan;
|
liveTrack.pan = savedTrack.pan;
|
||||||
|
|
||||||
if (liveTrack.volumeNode) {
|
if (liveTrack.volumeNode) {
|
||||||
liveTrack.volumeNode.volume.value = Tone.gainToDb(savedTrack.volume);
|
liveTrack.volumeNode.volume.value = Tone.gainToDb(savedTrack.volume);
|
||||||
}
|
}
|
||||||
|
|
@ -334,20 +333,18 @@ export async function parseMmpContent(xmlString) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Filtra tracks deletadas
|
|
||||||
appState.pattern.tracks = appState.pattern.tracks.filter((liveTrack) =>
|
appState.pattern.tracks = appState.pattern.tracks.filter((liveTrack) =>
|
||||||
tempState.pattern.tracks.some((t) => t.id === liveTrack.id)
|
tempState.pattern.tracks.some((t) => t.id === liveTrack.id)
|
||||||
);
|
);
|
||||||
|
|
||||||
// 2. 🔥 FIX: Restaura Áudio (Clips e Tracks)
|
// 2. 🔥 NOVO: Restaura Áudio (Clips e Tracks) no F5
|
||||||
if (tempState.audio) {
|
if (tempState.audio) {
|
||||||
console.log("Restaurando faixas de áudio e clips...");
|
console.log("Restaurando faixas de áudio e clips...");
|
||||||
appState.audio.tracks = tempState.audio.tracks || [];
|
appState.audio.tracks = tempState.audio.tracks || [];
|
||||||
appState.audio.clips = tempState.audio.clips || [];
|
appState.audio.clips = tempState.audio.clips || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Restaura Global
|
// 3. Restaura Global (mantido)
|
||||||
document.getElementById("bpm-input").value = tempState.global.bpm;
|
document.getElementById("bpm-input").value = tempState.global.bpm;
|
||||||
document.getElementById("compasso-a-input").value = tempState.global.compassoA;
|
document.getElementById("compasso-a-input").value = tempState.global.compassoA;
|
||||||
document.getElementById("compasso-b-input").value = tempState.global.compassoB;
|
document.getElementById("compasso-b-input").value = tempState.global.compassoB;
|
||||||
|
|
@ -355,7 +352,6 @@ export async function parseMmpContent(xmlString) {
|
||||||
|
|
||||||
if (tempState.global.syncMode) {
|
if (tempState.global.syncMode) {
|
||||||
appState.global.syncMode = tempState.global.syncMode;
|
appState.global.syncMode = tempState.global.syncMode;
|
||||||
// Atualiza visual do botão sync se existir (pode precisar disparar evento ou fazer manual)
|
|
||||||
const syncBtn = document.getElementById("sync-mode-btn");
|
const syncBtn = document.getElementById("sync-mode-btn");
|
||||||
if (syncBtn) {
|
if (syncBtn) {
|
||||||
syncBtn.classList.toggle("active", tempState.global.syncMode === "global");
|
syncBtn.classList.toggle("active", tempState.global.syncMode === "global");
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,26 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 🔥 CORREÇÃO DO PULO DE TELA (SCROLL JUMP)
|
||||||
|
// Adicionamos um listener global para capturar cliques em clips ou links vazios
|
||||||
|
document.body.addEventListener("click", (e) => {
|
||||||
|
// 1. Verifica links com href="#"
|
||||||
|
const targetLink = e.target.closest('a[href="#"]');
|
||||||
|
|
||||||
|
// 2. Verifica se clicou num clip ou container de clip
|
||||||
|
// (Mesmo sendo divs, vamos prevenir o comportamento padrão para garantir que não role)
|
||||||
|
const isAudioClip = e.target.closest('.timeline-clip') ||
|
||||||
|
e.target.closest('.audio-clip-container') ||
|
||||||
|
e.target.closest('.track-info'); // Às vezes clicar no header da track causa isso
|
||||||
|
|
||||||
|
if (targetLink || isAudioClip) {
|
||||||
|
// Impede o navegador de rolar a tela ou mudar o foco bruscamente
|
||||||
|
// Nota: O 'logic' do clique (selecionar, arrastar) ainda vai funcionar
|
||||||
|
// porque os listeners do audio_ui.js usam 'mousedown', que acontece ANTES do 'click'.
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}, { passive: false }); // passive: false é necessário para usar preventDefault
|
||||||
|
|
||||||
// Ações principais (broadcast)
|
// Ações principais (broadcast)
|
||||||
newProjectBtn?.addEventListener("click", () => {
|
newProjectBtn?.addEventListener("click", () => {
|
||||||
initializeAudioContext();
|
initializeAudioContext();
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ window.appState = appState;
|
||||||
export function resetProjectState() {
|
export function resetProjectState() {
|
||||||
console.log("Executando resetProjectState completo...");
|
console.log("Executando resetProjectState completo...");
|
||||||
|
|
||||||
|
// 1. Reseta o estado global
|
||||||
Object.assign(appState.global, {
|
Object.assign(appState.global, {
|
||||||
sliceToolActive: false,
|
sliceToolActive: false,
|
||||||
isPlaying: false,
|
isPlaying: false,
|
||||||
|
|
@ -75,34 +76,29 @@ export function resetProjectState() {
|
||||||
justReset: false,
|
justReset: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 2. Reseta o estado do pattern
|
||||||
Object.assign(appState.pattern, {
|
Object.assign(appState.pattern, {
|
||||||
tracks: [],
|
tracks: [],
|
||||||
activeTrackId: null,
|
activeTrackId: null,
|
||||||
activePatternIndex: 0,
|
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
|
||||||
|
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();
|
initializeAudioState();
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- NOVA IMPLEMENTAÇÃO DE PERSISTÊNCIA ---
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper: Gera a string XML do estado atual.
|
|
||||||
* Precisamos "emprestar" a lógica do file.js sem baixar o arquivo.
|
|
||||||
* A maneira mais limpa é importar generateXmlFromState de file.js,
|
|
||||||
* mas como ela não é exportada lá, vamos usar uma estratégia via DOM
|
|
||||||
* ou mover a lógica. Para simplificar sem quebrar o file.js,
|
|
||||||
* vamos salvar apenas o "essencial" do patternState se o XML falhar,
|
|
||||||
* mas o ideal é garantir que o XML seja gerado.
|
|
||||||
* * NOTA: Para que isso funcione perfeitamente, certifique-se de exportar
|
|
||||||
* 'generateXmlFromState' no seu file.js ou usar a lógica abaixo.
|
|
||||||
*/
|
|
||||||
import { generateXmlFromStateExported } from "./file.js"; // Vamos assumir que você vai exportar isso no file.js
|
|
||||||
|
|
||||||
export function saveStateToSession() {
|
export function saveStateToSession() {
|
||||||
if (!window.ROOM_NAME) return;
|
if (!window.ROOM_NAME) return;
|
||||||
|
|
||||||
// 1. Crie uma versão "limpa" dos tracks (PATTERN)
|
// 1. Limpa Tracks do Pattern
|
||||||
const cleanTracks = appState.pattern.tracks.map((track) => {
|
const cleanTracks = appState.pattern.tracks.map((track) => {
|
||||||
return {
|
return {
|
||||||
id: track.id,
|
id: track.id,
|
||||||
|
|
@ -117,24 +113,23 @@ export function saveStateToSession() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2. Construa o objeto de estado final para salvar
|
// 2. Constrói o objeto. 🔥 AQUI ADICIONAMOS O ÁUDIO
|
||||||
const stateToSave = {
|
const stateToSave = {
|
||||||
pattern: {
|
pattern: {
|
||||||
...appState.pattern,
|
...appState.pattern,
|
||||||
tracks: cleanTracks,
|
tracks: cleanTracks,
|
||||||
},
|
},
|
||||||
// 🔥 FIX: Salvando o estado de Áudio (Tracks e Clips)
|
// Salva o estado de Áudio para o F5 funcionar
|
||||||
audio: {
|
audio: {
|
||||||
tracks: appState.audio.tracks || [],
|
tracks: appState.audio.tracks || [],
|
||||||
clips: appState.audio.clips || [],
|
clips: appState.audio.clips || [],
|
||||||
// Adicione outras props de áudio se necessário (ex: seekTime, etc)
|
|
||||||
},
|
},
|
||||||
global: {
|
global: {
|
||||||
bpm: document.getElementById("bpm-input").value,
|
bpm: document.getElementById("bpm-input").value,
|
||||||
compassoA: document.getElementById("compasso-a-input").value,
|
compassoA: document.getElementById("compasso-a-input").value,
|
||||||
compassoB: document.getElementById("compasso-b-input").value,
|
compassoB: document.getElementById("compasso-b-input").value,
|
||||||
bars: document.getElementById("bars-input").value,
|
bars: document.getElementById("bars-input").value,
|
||||||
syncMode: appState.global.syncMode, // É bom salvar isso também
|
syncMode: appState.global.syncMode,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -148,49 +143,3 @@ export function saveStateToSession() {
|
||||||
console.error("Falha ao salvar estado na sessão:", e);
|
console.error("Falha ao salvar estado na sessão:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export async function loadStateFromSession() {
|
|
||||||
const roomName = window.ROOM_NAME;
|
|
||||||
if (!roomName) return false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const raw = sessionStorage.getItem(`mmp_backup_${roomName}`);
|
|
||||||
if (!raw) return false;
|
|
||||||
|
|
||||||
const backup = JSON.parse(raw);
|
|
||||||
console.log(`[Session] Recuperando backup de ${new Date(backup.timestamp).toLocaleTimeString()}`);
|
|
||||||
|
|
||||||
// 1. Restaura Globais
|
|
||||||
if (backup.global) {
|
|
||||||
appState.global.bpm = backup.global.bpm;
|
|
||||||
appState.global.compassoA = backup.global.compassoA;
|
|
||||||
appState.global.compassoB = backup.global.compassoB;
|
|
||||||
appState.global.bars = backup.global.bars;
|
|
||||||
appState.global.syncMode = backup.global.syncMode || "global";
|
|
||||||
|
|
||||||
// Atualiza DOM imediatamente para evitar desincronia visual
|
|
||||||
const bpmInput = document.getElementById("bpm-input");
|
|
||||||
if(bpmInput) bpmInput.value = backup.global.bpm;
|
|
||||||
// ... (outros inputs se necessário, mas o renderAll cuida da maioria)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Restaura Pattern (XML é preferível)
|
|
||||||
if (backup.xml) {
|
|
||||||
await parseMmpContent(backup.xml);
|
|
||||||
} else if (backup.patternRaw) {
|
|
||||||
// Fallback simples (menos robusto que XML)
|
|
||||||
console.warn("Restaurando de Pattern Raw (backup antigo/incompleto)");
|
|
||||||
Object.assign(appState.pattern, backup.patternRaw);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Restaura Áudio (Clipes + Gravações)
|
|
||||||
if (backup.audio) {
|
|
||||||
await applyAudioSnapshot(backup.audio);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true; // Sucesso
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Erro ao restaurar sessão:", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue