v1.0.13 - botao de reset funcional para limpar as salas
This commit is contained in:
1 parent
611aec9ba1
commit
c8323d56cf
9 files changed
+1593
-532
No files matched your search
+110
-16
@@ -1,12 +1,12 @@
|
||||
// js/main.js (ESM com import absoluto de socket.js + ROOM_NAME local)
|
||||
|
||||
import { appState, resetProjectState } from "./state.js";
|
||||
import { appState } from "./state.js";
|
||||
import {
|
||||
updateTransportLoop,
|
||||
restartAudioEditorIfPlaying,
|
||||
} from "./audio/audio_audio.js";
|
||||
import { initializeAudioContext } from "./audio.js";
|
||||
import { handleFileLoad, generateMmpFile } from "./file.js";
|
||||
import { handleFileLoad, generateMmpFile, BLANK_PROJECT_XML } from "./file.js";
|
||||
import {
|
||||
renderAll,
|
||||
loadAndRenderSampleBrowser,
|
||||
@@ -16,12 +16,15 @@ import {
|
||||
import { renderAudioEditor } from "./audio/audio_ui.js";
|
||||
import { adjustValue, enforceNumericInput } from "./utils.js";
|
||||
import { ZOOM_LEVELS } from "./config.js";
|
||||
import { loadProjectFromServer } from "./file.js"
|
||||
import { loadProjectFromServer } from "./file.js";
|
||||
|
||||
// ⚠️ IMPORT ABSOLUTO para evitar 404/text/html quando a página estiver em /creation/ ou fora dela.
|
||||
// Ajuste o prefixo abaixo para o caminho real onde seus assets vivem no servidor:
|
||||
import { sendAction, joinRoom, setUserName } from "./socket.js";
|
||||
|
||||
import { renderActivePatternToBlob } from "./pattern/pattern_audio.js"; // <-- ADICIONE ESTA LINHA
|
||||
import { showToast } from "./ui.js";
|
||||
|
||||
// Descobre a sala pela URL (local ao main.js) e expõe no window para debug
|
||||
const ROOM_NAME = new URLSearchParams(window.location.search).get("room");
|
||||
window.ROOM_NAME = ROOM_NAME;
|
||||
@@ -29,17 +32,18 @@ window.ROOM_NAME = ROOM_NAME;
|
||||
const PROJECT_NAME = new URLSearchParams(window.location.search).get("project");
|
||||
|
||||
if (PROJECT_NAME) {
|
||||
// O nome do projeto deve corresponder ao arquivo no servidor, por ex: "mmp/nome-do-seu-projeto-salvo.mmp"
|
||||
// O arquivo 'file.js' já espera que loadProjectFromServer receba apenas o nome
|
||||
// do arquivo dentro da pasta 'mmp/' (ex: 'nome-do-projeto.mmp').
|
||||
console.log(`[MAIN] Carregando projeto do servidor: ${PROJECT_NAME}`);
|
||||
// Adicione a extensão se ela não estiver no link
|
||||
const filename = PROJECT_NAME.endsWith('.mmp') || PROJECT_NAME.endsWith('.mmpz')
|
||||
? PROJECT_NAME
|
||||
: `${PROJECT_NAME}.mmp`;
|
||||
|
||||
// Chama a função de file.js para carregar (que já envia a ação 'LOAD_PROJECT')
|
||||
loadProjectFromServer(filename);
|
||||
// O nome do projeto deve corresponder ao arquivo no servidor, por ex: "mmp/nome-do-seu-projeto-salvo.mmp"
|
||||
// O arquivo 'file.js' já espera que loadProjectFromServer receba apenas o nome
|
||||
// do arquivo dentro da pasta 'mmp/' (ex: 'nome-do-projeto.mmp').
|
||||
console.log(`[MAIN] Carregando projeto do servidor: ${PROJECT_NAME}`);
|
||||
// Adicione a extensão se ela não estiver no link
|
||||
const filename =
|
||||
PROJECT_NAME.endsWith(".mmp") || PROJECT_NAME.endsWith(".mmpz")
|
||||
? PROJECT_NAME
|
||||
: `${PROJECT_NAME}.mmp`;
|
||||
|
||||
// Chama a função de file.js para carregar (que já envia a ação 'LOAD_PROJECT')
|
||||
loadProjectFromServer(filename);
|
||||
}
|
||||
|
||||
// ✅ NOVO: se tem sala na URL, entra já na sala (independe do áudio)
|
||||
@@ -106,6 +110,96 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
const zoomOutBtn = document.getElementById("zoom-out-btn");
|
||||
const deleteClipBtn = document.getElementById("delete-clip");
|
||||
|
||||
//envia pattern pro editor de áudio
|
||||
|
||||
const bouncePatternBtn = document.getElementById(
|
||||
"send-pattern-to-playlist-btn"
|
||||
);
|
||||
|
||||
bouncePatternBtn?.addEventListener("click", async () => {
|
||||
// 1. Verifica se existe uma pista de áudio para onde enviar
|
||||
const targetTrackId = appState.audio.tracks[0]?.id;
|
||||
if (!targetTrackId) {
|
||||
showToast(
|
||||
"Crie uma Pista de Áudio (no editor de amostras) primeiro!",
|
||||
"error"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
showToast("Renderizando pattern...", "info");
|
||||
|
||||
try {
|
||||
// 2. Chama a função de renderização que criamos
|
||||
const audioBlob = await renderActivePatternToBlob();
|
||||
|
||||
// 3. Cria uma URL local para o áudio renderizado
|
||||
const audioUrl = URL.createObjectURL(audioBlob);
|
||||
|
||||
// --- INÍCIO DA NOVA MODIFICAÇÃO (Visualização de Steps) ---
|
||||
|
||||
// 4. Pega o índice do pattern que foi renderizado
|
||||
const activePatternIndex =
|
||||
appState.pattern.tracks[0]?.activePatternIndex || 0;
|
||||
|
||||
// 5. Coleta os dados de steps de CADA trilha para esse pattern
|
||||
const patternData = appState.pattern.tracks.map((track) => {
|
||||
const pattern = track.patterns[activePatternIndex];
|
||||
// Retorna o array de steps, ou um array vazio se não houver
|
||||
return pattern && pattern.steps ? pattern.steps : [];
|
||||
});
|
||||
// --- FIM DA NOVA MODIFICAÇÃO ---
|
||||
|
||||
// 6. Prepara o nome e ID
|
||||
const patternName =
|
||||
appState.pattern.tracks[0]?.patterns[activePatternIndex]?.name ||
|
||||
"Pattern";
|
||||
const clipName = `${patternName} (Bounced).wav`;
|
||||
const clipId = `bounced_${Date.now()}`;
|
||||
|
||||
// 7. Envia a ação (a lógica ADD_AUDIO_CLIP já sabe como carregar o áudio)
|
||||
sendAction({
|
||||
type: "ADD_AUDIO_CLIP",
|
||||
filePath: audioUrl, // O player de áudio sabe ler essa URL 'blob:'
|
||||
trackId: targetTrackId, // Envia para a primeira pista de áudio
|
||||
startTimeInSeconds: 0, // Coloca no início da timeline
|
||||
clipId: clipId,
|
||||
name: clipName,
|
||||
patternData: patternData, // <-- AQUI ESTÁ A "PARTITURA"
|
||||
});
|
||||
|
||||
showToast("Pattern enviada para a Pista de Áudio!", "success");
|
||||
} catch (error) {
|
||||
console.error("Erro ao renderizar pattern:", error);
|
||||
showToast("Erro ao renderizar pattern", "error");
|
||||
}
|
||||
});
|
||||
|
||||
//Seleção de pattern
|
||||
|
||||
const globalPatternSelector = document.getElementById(
|
||||
"global-pattern-selector"
|
||||
);
|
||||
|
||||
// Adiciona o novo "ouvinte" de evento para o seletor de pattern
|
||||
globalPatternSelector?.addEventListener("change", () => {
|
||||
// Pega o novo índice (ex: 0, 1, 2...) do seletor
|
||||
const newPatternIndex = parseInt(globalPatternSelector.value, 10);
|
||||
|
||||
// --- CORREÇÃO DE LÓGICA (não precisamos mais do activeTrackId) ---
|
||||
// A ação agora é global e afeta TODAS as tracks.
|
||||
if (isNaN(newPatternIndex)) {
|
||||
console.warn("Não é possível trocar pattern: índice inválido.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Envia a ação para todos (incluindo você)
|
||||
sendAction({
|
||||
type: "SET_ACTIVE_PATTERN",
|
||||
patternIndex: newPatternIndex,
|
||||
});
|
||||
});
|
||||
|
||||
// =================================================================
|
||||
// 👇 INÍCIO DA CORREÇÃO (Botão de Sincronia - Agora envia Ação)
|
||||
// =================================================================
|
||||
@@ -193,7 +287,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
)
|
||||
)
|
||||
return;
|
||||
sendAction({ type: "RESET_PROJECT" });
|
||||
sendAction({ type: "LOAD_PROJECT", xml: BLANK_PROJECT_XML });
|
||||
});
|
||||
|
||||
addBarBtn?.addEventListener("click", () => {
|
||||
@@ -399,7 +493,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
alert(
|
||||
`Você já está na sala: ${currentParams.get(
|
||||
"room"
|
||||
)}\n\nCopie o link da barra de endereços para convidar.`
|
||||
)}\n\Copie o link da barra de endereços para convidar.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user