upload de samples

This commit is contained in:
JotaChina committed 2025-12-08 12:23:43 -03:00
1 parent 826147c667
commit e38f1ea662
5 files changed
+347726 -340435

No files matched your search

+138
View File
@@ -28,6 +28,10 @@ permalink: /samples/
<button id="btn-home" class="button is-small is-info is-light mr-3" title="Voltar ao início">
<i class="fa-solid fa-house"></i>
</button>
<button id="btn-open-upload" class="button is-small is-success is-light mr-3" title="Enviar novo Sample">
<span class="icon"><i class="fa-solid fa-cloud-arrow-up"></i></span>
<span>Enviar Sample</span>
</button>
<nav class="breadcrumb is-small mb-0" aria-label="breadcrumbs">
<ul id="breadcrumb-list">
<li class="is-active"><a href="#">Raiz</a></li>
@@ -164,6 +168,56 @@ permalink: /samples/
</div>
</div>
<div id="upload-sample-modal" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Enviar Sample</p>
<button class="delete" aria-label="close" id="close-upload-modal"></button>
</header>
<section class="modal-card-body">
<form id="sample-upload-form">
<div class="field">
<label class="label">Arquivo de Áudio</label>
<div class="control">
<div class="file has-name is-fullwidth">
<label class="file-label">
<input class="file-input" type="file" name="sample_file" accept=".wav,.mp3,.ogg,.flac" required>
<span class="file-cta">
<span class="file-icon"><i class="fa-solid fa-upload"></i></span>
<span class="file-label">Escolher arquivo...</span>
</span>
<span class="file-name" id="upload-filename-display">Nenhum arquivo selecionado</span>
</label>
</div>
</div>
</div>
<div class="field">
<label class="label">Salvar na Pasta</label>
<div class="control has-icons-left">
<input class="input" type="text" name="subfolder" placeholder="Ex: Drums/Kicks (Vazio = Raiz)" id="upload-subfolder">
<span class="icon is-small is-left"><i class="fa-solid fa-folder-open"></i></span>
</div>
<p class="help">Você pode criar pastas usando barras, ex: <code>Percussion/Hats</code></p>
</div>
<progress id="upload-progress" class="progress is-small is-primary is-hidden" max="100"></progress>
<p id="upload-status" class="help is-hidden"></p>
</form>
</section>
<footer class="modal-card-foot" style="justify-content: flex-end;">
<button class="button" id="cancel-upload">Cancelar</button>
<button class="button is-success" id="confirm-upload-btn">
<span class="icon"><i class="fa-solid fa-check"></i></span>
<span>Enviar</span>
</button>
</footer>
</div>
</div>
<style>
.browser-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 15px; }
.browser-item { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 15px; border: 1px solid transparent; border-radius: 8px; cursor: pointer; transition: all 0.2s; }
@@ -440,5 +494,89 @@ document.addEventListener('DOMContentLoaded', () => {
} catch(e){} });
closeButtons.forEach(el => el.addEventListener('click', closeModal));
document.addEventListener('keydown', (e) => { if (e.key === "Escape") closeModal(); });
// === LÓGICA DE UPLOAD ===
const uploadModal = document.getElementById('upload-sample-modal');
const btnOpenUpload = document.getElementById('btn-open-upload');
const btnCloseUpload = document.getElementById('close-upload-modal');
const btnCancelUpload = document.getElementById('cancel-upload');
const fileInput = document.querySelector('#sample-upload-form input[type="file"]');
const fileNameDisplay = document.getElementById('upload-filename-display');
const subfolderInput = document.getElementById('upload-subfolder');
const confirmUploadBtn = document.getElementById('confirm-upload-btn');
const uploadProgress = document.getElementById('upload-progress');
const uploadStatus = document.getElementById('upload-status');
// Abrir/Fechar Modal
function toggleUploadModal(show) {
if(show) {
uploadModal.classList.add('is-active');
// Tenta preencher a pasta atual automaticamente baseado na navegação
const currentPath = currentPathStack.join('/');
subfolderInput.value = currentPath;
} else {
uploadModal.classList.remove('is-active');
uploadStatus.classList.add('is-hidden');
uploadProgress.classList.add('is-hidden');
}
}
if(btnOpenUpload) btnOpenUpload.onclick = () => toggleUploadModal(true);
if(btnCloseUpload) btnCloseUpload.onclick = () => toggleUploadModal(false);
if(btnCancelUpload) btnCancelUpload.onclick = () => toggleUploadModal(false);
// Atualizar nome do arquivo no input
fileInput.onchange = () => {
if (fileInput.files.length > 0) {
fileNameDisplay.textContent = fileInput.files[0].name;
}
};
// Enviar Formulário
confirmUploadBtn.onclick = async (e) => {
e.preventDefault();
if (fileInput.files.length === 0) {
alert("Selecione um arquivo primeiro.");
return;
}
const formData = new FormData(document.getElementById('sample-upload-form'));
// UI de Carregamento
confirmUploadBtn.classList.add('is-loading');
uploadProgress.classList.remove('is-hidden');
uploadStatus.classList.remove('is-hidden');
uploadStatus.textContent = "Enviando e atualizando biblioteca (pode demorar)...";
uploadStatus.className = "help has-text-info";
try {
// URL do seu servidor Python (ajuste a porta/domínio se necessário)
// Se estiver rodando localmente no navegador, use a URL pública
const response = await fetch('https://alice.ufsj.edu.br:33002/api/upload/sample', {
method: 'POST',
body: formData
});
const result = await response.json();
if (response.ok) {
uploadStatus.textContent = "Sucesso! Recarregando...";
uploadStatus.className = "help has-text-success";
// Aguarda um pouco e recarrega a página para pegar o novo manifesto
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
throw new Error(result.error || "Erro desconhecido");
}
} catch (error) {
console.error(error);
uploadStatus.textContent = "Erro: " + error.message;
uploadStatus.className = "help has-text-danger";
confirmUploadBtn.classList.remove('is-loading');
}
};
});
</script>