Arrumando o timmer da pattern
Deploy / Deploy (push) Successful in 35s Details

This commit is contained in:
JotaChina 2025-08-29 19:47:20 -03:00
parent 95723d1f26
commit ec4d346791
2 changed files with 33 additions and 25 deletions

View File

@ -332,7 +332,7 @@ body.sidebar-hidden .global-toolbar {
background: #555; background: #555;
} }
/* (CORREÇÃO) CSS para as marcações de compasso */
.step-wrapper { .step-wrapper {
position: relative; position: relative;
} }
@ -522,7 +522,7 @@ body.sidebar-hidden .global-toolbar {
} }
/* =============================================== */ /* =============================================== */
/* MODAL (CAIXA DE DIÁLOGO) - (REVISADO) /* MODAL (CAIXA DE DIÁLOGO)
/* =============================================== */ /* =============================================== */
.modal-overlay { .modal-overlay {
position: fixed; position: fixed;
@ -535,7 +535,7 @@ body.sidebar-hidden .global-toolbar {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 1rem; /* Adiciona um respiro nas laterais */ padding: 1rem;
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
transition: visibility 0s 0.3s, opacity 0.3s; transition: visibility 0s 0.3s, opacity 0.3s;
@ -556,13 +556,9 @@ body.sidebar-hidden .global-toolbar {
width: 100%; width: 100%;
max-width: 500px; max-width: 500px;
position: relative; position: relative;
/* (NOVO) Usando Flexbox para organizar o conteúdo interno */
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1.5rem; /* Espaçamento consistente entre as seções */ gap: 1.5rem;
/* (NOVO) Controle de altura para telas pequenas ou listas grandes */
max-height: 90vh; max-height: 90vh;
} }
@ -582,16 +578,16 @@ body.sidebar-hidden .global-toolbar {
} }
.modal-title { .modal-title {
margin: 0; /* Removido margin para usar o 'gap' do flexbox */ margin: 0;
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
border-bottom: 1px solid var(--bg-toolbar); border-bottom: 1px solid var(--bg-toolbar);
color: var(--text-light); color: var(--text-light);
text-align: center; text-align: center;
flex-shrink: 0; /* Impede que o título encolha */ flex-shrink: 0;
} }
.modal-section { .modal-section {
margin: 0; /* Removido margin para usar o 'gap' do flexbox */ margin: 0;
} }
.modal-section h3 { .modal-section h3 {
@ -601,18 +597,16 @@ body.sidebar-hidden .global-toolbar {
color: var(--text-light); color: var(--text-light);
} }
/* (NOVO) Estilos para a lista de projetos do servidor */
#server-projects-list { #server-projects-list {
max-height: 250px; /* Altura máxima para a lista */ max-height: 250px;
overflow-y: auto; /* Barra de rolagem SÓ para a lista */ overflow-y: auto;
background-color: var(--bg-toolbar); background-color: var(--bg-toolbar);
border: 1px solid var(--border-color); border: 1px solid var(--border-color);
border-radius: 4px; border-radius: 4px;
padding: 0.5rem; padding: 0.5rem;
min-height: 50px; /* Altura mínima para não colapsar se estiver vazio */ min-height: 50px;
} }
/* (REVISADO) Estilos para cada item na lista */
#server-projects-list .project-item { #server-projects-list .project-item {
background-color: var(--bg-editor); background-color: var(--bg-editor);
padding: 10px 15px; padding: 10px 15px;
@ -707,9 +701,8 @@ body.sidebar-hidden .global-toolbar {
.step-sequencer-wrapper { .step-sequencer-wrapper {
width: 100%; width: 100%;
} }
/* (REVISADO) Ajuste do modal para telas pequenas */
.modal-content { .modal-content {
max-width: 95vw; /* Usa quase toda a largura da tela */ max-width: 95vw;
padding: 1rem 1.5rem; padding: 1rem 1.5rem;
gap: 1rem; gap: 1rem;
} }

View File

@ -6,6 +6,8 @@ import { getTotalSteps } from "./utils.js";
let audioContext; let audioContext;
let mainGainNode; let mainGainNode;
const timerDisplay = document.getElementById('timer-display');
export function getAudioContext() { export function getAudioContext() {
return audioContext; return audioContext;
} }
@ -24,6 +26,14 @@ export function initializeAudioContext() {
} }
} }
function formatTime(milliseconds) {
const totalSeconds = Math.floor(milliseconds / 1000);
const minutes = Math.floor(totalSeconds / 60).toString().padStart(2, '0');
const seconds = (totalSeconds % 60).toString().padStart(2, '0');
const centiseconds = Math.floor((milliseconds % 1000) / 10).toString().padStart(2, '0');
return `${minutes}:${seconds}:${centiseconds}`;
}
export function playMetronomeSound(isDownbeat) { export function playMetronomeSound(isDownbeat) {
initializeAudioContext(); initializeAudioContext();
const oscillator = audioContext.createOscillator(); const oscillator = audioContext.createOscillator();
@ -42,38 +52,32 @@ export function playMetronomeSound(isDownbeat) {
oscillator.stop(audioContext.currentTime + 0.05); oscillator.stop(audioContext.currentTime + 0.05);
} }
// Função otimizada para usar AudioBuffers
export function playSample(filePath, trackId) { export function playSample(filePath, trackId) {
initializeAudioContext(); initializeAudioContext();
if (!filePath) return; if (!filePath) return;
const track = trackId ? appState.tracks.find((t) => t.id == trackId) : null; const track = trackId ? appState.tracks.find((t) => t.id == trackId) : null;
// Se for uma prévia (sem trilha), usa o método antigo e rápido
if (!track) { if (!track) {
const audio = new Audio(filePath); const audio = new Audio(filePath);
audio.play(); audio.play();
return; return;
} }
// Se a trilha não tiver o buffer carregado, não toca
if (!track.audioBuffer) { if (!track.audioBuffer) {
console.warn(`Buffer para a trilha ${track.name} ainda não carregado.`); console.warn(`Buffer para a trilha ${track.name} ainda não carregado.`);
return; return;
} }
// Cria uma fonte de áudio leve a partir do buffer
const source = audioContext.createBufferSource(); const source = audioContext.createBufferSource();
source.buffer = track.audioBuffer; source.buffer = track.audioBuffer;
// Conecta na cadeia de áudio da trilha (respeitando volume e pan)
if (track.gainNode) { if (track.gainNode) {
source.connect(track.gainNode); source.connect(track.gainNode);
} else { } else {
source.connect(mainGainNode); // Fallback source.connect(mainGainNode);
} }
// Toca o som imediatamente
source.start(0); source.start(0);
} }
@ -87,6 +91,13 @@ function tick() {
appState.currentStep === 0 ? totalSteps - 1 : appState.currentStep - 1; appState.currentStep === 0 ? totalSteps - 1 : appState.currentStep - 1;
highlightStep(lastStepIndex, false); highlightStep(lastStepIndex, false);
const bpm = parseInt(document.getElementById("bpm-input").value, 10) || 120;
const stepInterval = (60 * 1000) / (bpm * 4);
const currentTime = appState.currentStep * stepInterval;
if (timerDisplay) {
timerDisplay.textContent = formatTime(currentTime);
}
if (appState.metronomeEnabled) { if (appState.metronomeEnabled) {
const noteValue = const noteValue =
parseInt(document.getElementById("compasso-b-input").value, 10) || 4; parseInt(document.getElementById("compasso-b-input").value, 10) || 4;
@ -128,6 +139,9 @@ export function stopPlayback() {
appState.isPlaying = false; appState.isPlaying = false;
highlightStep(appState.currentStep - 1, false); highlightStep(appState.currentStep - 1, false);
appState.currentStep = 0; appState.currentStep = 0;
if (timerDisplay) timerDisplay.textContent = '00:00:00';
document.getElementById("play-btn").classList.remove("fa-pause"); document.getElementById("play-btn").classList.remove("fa-pause");
document.getElementById("play-btn").classList.add("fa-play"); document.getElementById("play-btn").classList.add("fa-play");
} }
@ -135,6 +149,7 @@ export function stopPlayback() {
export function rewindPlayback() { export function rewindPlayback() {
appState.currentStep = 0; appState.currentStep = 0;
if (!appState.isPlaying) { if (!appState.isPlaying) {
if (timerDisplay) timerDisplay.textContent = '00:00:00';
document document
.querySelectorAll(".step.playing") .querySelectorAll(".step.playing")
.forEach((s) => s.classList.remove("playing")); .forEach((s) => s.classList.remove("playing"));