120 lines
5.4 KiB
HTML
Executable File
120 lines
5.4 KiB
HTML
Executable File
---
|
|
layout: default
|
|
title: "Detalhes do Projeto"
|
|
---
|
|
|
|
<div id="project-root">
|
|
<div class="section has-text-centered py-6">
|
|
<button class="button is-loading is-large is-ghost">
|
|
Carregando projeto...
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="module">
|
|
import { InstrumentFactory } from '{{ "/assets/js/audio/InstrumentFactory.js" | relative_url }}';
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
const factory = new InstrumentFactory();
|
|
const params = new URLSearchParams(window.location.search);
|
|
const projectId = params.get("id");
|
|
|
|
if (!projectId) {
|
|
window.location.href = '{{ "/projetos/" | relative_url }}';
|
|
return;
|
|
}
|
|
|
|
fetch(
|
|
'{{ "src_mmpSearch/saida_analises/db_final_completo.json" | relative_url }}',
|
|
)
|
|
.then((r) => r.json())
|
|
.then((data) => {
|
|
const p = data.find(
|
|
(item) =>
|
|
item.file === projectId ||
|
|
(item.arquivo &&
|
|
item.arquivo.replace(".ogg", "").replace(".mp3", "") ===
|
|
projectId),
|
|
);
|
|
|
|
if (!p) {
|
|
document.getElementById("project-root").innerHTML =
|
|
`<div class="container py-6"><h1 class="title">Projeto não encontrado.</h1><a href="{{ '/projetos/' | relative_url }}">Voltar</a></div>`;
|
|
return;
|
|
}
|
|
renderDetails(p, factory);
|
|
});
|
|
});
|
|
|
|
function renderDetails(p, factory) {
|
|
const root = document.getElementById("project-root");
|
|
const fileName = p.file || p.arquivo || "sem-nome";
|
|
const creationUrl = `{{ 'creation.html?project=' | relative_url }}${fileName}`;
|
|
|
|
root.innerHTML = `
|
|
<div class="publication"><div class="container"><br />
|
|
<div class="box has-background-white-ter mb-5" style="border-top: 4px solid #3273dc; display: flex; align-items: center; justify-content: space-between; padding: 10px 20px;">
|
|
<div style="display: flex; align-items: center; gap: 15px">
|
|
<h1 class="title is-5 m-0"><code>${fileName}</code></h1>
|
|
<span class="tag is-dark">🎵 ${p.bpm || "N/A"} BPM</span>
|
|
</div>
|
|
<audio controls style="height: 30px;"><source src="{{ 'src_mmpSearch/wav/' | relative_url }}${fileName}.ogg" type="audio/ogg"></audio>
|
|
</div>
|
|
|
|
<div class="columns">
|
|
<div class="column is-8">
|
|
<div class="card mb-4" style="border-radius: 8px;">
|
|
<header class="card-header has-background-light"><p class="card-header-title">🎚️ Instrumentos & Patterns</p></header>
|
|
<div class="card-content">
|
|
${(p.tracks || [])
|
|
.map(
|
|
(track) => `
|
|
<div class="box mb-4">
|
|
<strong class="is-size-6">📂 ${track.bassline_name || "Track"}</strong>
|
|
<hr class="my-2">
|
|
${(track.instruments || [track])
|
|
.map(
|
|
(inst) => `
|
|
<div class="mb-3 p-2" style="border-left: 3px solid #3273dc;">
|
|
<p class="is-size-7"><strong>${inst.instrument_name || "Synth"}</strong></p>
|
|
<div class="mt-2" style="display: flex; gap: 2px;">
|
|
${(inst.patterns || [])
|
|
.flatMap(
|
|
(pat) => pat.steps || [],
|
|
)
|
|
.map(
|
|
(s) =>
|
|
`<div style="width: 4px; height: 10px; background: ${s ? "#4caf50" : "#eee"};"></div>`,
|
|
)
|
|
.join("")}
|
|
</div>
|
|
<button class="button is-small is-info is-outlined mt-2 js-play-synth" data-params='${JSON.stringify(inst)}'>Ouvir Synth</button>
|
|
</div>
|
|
`,
|
|
)
|
|
.join("")}
|
|
</div>
|
|
`,
|
|
)
|
|
.join("")}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="column is-4">
|
|
<div class="box has-background-info-light">
|
|
<h3 class="title is-6 has-text-info">🛠️ Editor</h3>
|
|
<a href="${creationUrl}" target="_blank" class="button is-info is-fullwidth mb-4">Abrir no MMPCreator</a>
|
|
<iframe src="${creationUrl}&embed=true" style="width:100%; height:300px; background:#fff; border:1px solid #ccc; border-radius:4px;"></iframe>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div></div>`;
|
|
|
|
document.querySelectorAll(".js-play-synth").forEach((btn) => {
|
|
btn.addEventListener("click", () =>
|
|
factory.play(JSON.parse(btn.dataset.params)),
|
|
);
|
|
});
|
|
}
|
|
</script>
|