reforma da interface da página de projetos
Deploy / Deploy (push) Successful in 1m26s
Details
Deploy / Deploy (push) Successful in 1m26s
Details
This commit is contained in:
parent
3c8e17ab80
commit
9d2aa44851
|
|
@ -462,6 +462,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
function enrichCards(data) {
|
function enrichCards(data) {
|
||||||
const mapDados = {};
|
const mapDados = {};
|
||||||
|
|
||||||
|
// Mapeamento dos dados
|
||||||
data.forEach(item => {
|
data.forEach(item => {
|
||||||
const k1 = normalizarChaveJS(item.arquivo.replace('.wav','').replace('.mp3',''));
|
const k1 = normalizarChaveJS(item.arquivo.replace('.wav','').replace('.mp3',''));
|
||||||
mapDados[k1] = item;
|
mapDados[k1] = item;
|
||||||
|
|
@ -471,65 +473,83 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
cards.forEach(card => {
|
cards.forEach(card => {
|
||||||
const info = mapDados[normalizarChaveJS(card.dataset.title)];
|
const info = mapDados[normalizarChaveJS(card.dataset.title)];
|
||||||
|
|
||||||
// Defaults
|
// --- 1. Definição de Valores Padrão (Safety First) ---
|
||||||
let genero = "Unknown";
|
let genero = "Unknown";
|
||||||
let estrelas = 0;
|
let estrelas = 0;
|
||||||
let intensidade = -100;
|
let intensidade = -100;
|
||||||
let bpm = 0;
|
let bpm = 0;
|
||||||
let tomHtml = "";
|
let tomHtml = "";
|
||||||
|
let tomRaw = "all"; // Valor padrão para o filtro
|
||||||
|
let subTagsHTML = ""; // Para os subgêneros
|
||||||
|
|
||||||
|
// --- 2. Só tenta extrair dados SE 'info' existir ---
|
||||||
if (info) {
|
if (info) {
|
||||||
genero = info.analise_ia?.genero_macro || "Unknown";
|
// Dados IA
|
||||||
intensidade = parseFloat(info.analise_tecnica?.intensidade_db || -100);
|
if (info.analise_ia) {
|
||||||
bpm = parseFloat(info.analise_tecnica?.bpm || 0);
|
genero = info.analise_ia.genero_macro || "Unknown";
|
||||||
estrelas = Math.round(info.analise_tecnica?.complexidade?.estrelas || 0);
|
|
||||||
|
|
||||||
// HTML do Tom
|
// Lógica de Subgêneros (Top 2)
|
||||||
if (info.analise_tecnica?.tom) {
|
if (Array.isArray(info.analise_ia.nuvem_tags)) {
|
||||||
const t = info.analise_tecnica.tom;
|
const topTags = info.analise_ia.nuvem_tags.slice(0, 2);
|
||||||
const e = info.analise_tecnica.escala === 'minor' ? 'm' : '';
|
topTags.forEach(t => {
|
||||||
tomHtml = `<span class="tag is-white is-rounded border-tag">🎹 ${t}${e}</span>`;
|
// Multiplica por 100 para porcentagem legível
|
||||||
|
const scorePercent = Math.round((t.score || 0) * 100);
|
||||||
|
subTagsHTML += `
|
||||||
|
<span class="tag is-white is-rounded border-tag"
|
||||||
|
title="Confiança IA: ${scorePercent}%"
|
||||||
|
style="font-size: 0.65rem; color: #666; margin-right: 2px;">
|
||||||
|
#${t.tag}
|
||||||
|
</span>`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dados Técnicos
|
||||||
|
if (info.analise_tecnica) {
|
||||||
|
intensidade = parseFloat(info.analise_tecnica.intensidade_db || -100);
|
||||||
|
bpm = parseFloat(info.analise_tecnica.bpm || 0);
|
||||||
|
// Correção: Usando Math.round para bater com o visual
|
||||||
|
estrelas = Math.round(info.analise_tecnica.complexidade?.estrelas || 0);
|
||||||
|
|
||||||
|
// Lógica do Tom (Visual + Filtro)
|
||||||
|
if (info.analise_tecnica.tom) {
|
||||||
|
const t = info.analise_tecnica.tom;
|
||||||
|
const e = info.analise_tecnica.escala === 'minor' ? 'm' : '';
|
||||||
|
|
||||||
|
// HTML visual (Badge)
|
||||||
|
tomHtml = `<span class="tag is-white is-rounded border-tag" title="Tom detectado">🎹 ${t}${e}</span>`;
|
||||||
|
|
||||||
|
// Valor cru para o filtro (Ex: "C", "Cm", "Ab")
|
||||||
|
tomRaw = t + e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Salva no dataset para filtros
|
// --- 3. Salva no Dataset para os Filtros ---
|
||||||
card.dataset.genre = genero;
|
card.dataset.genre = genero;
|
||||||
card.dataset.stars = estrelas;
|
card.dataset.stars = estrelas;
|
||||||
card.dataset.intensity = intensidade;
|
card.dataset.intensity = intensidade;
|
||||||
card.dataset.bpm_real = bpm;
|
card.dataset.bpm_real = bpm;
|
||||||
// Dentro do enrichCards, salve o tom 'cru' no dataset
|
card.dataset.key = tomRaw; // Novo dataset para o filtro de Tom
|
||||||
let tomRaw = "Unknown";
|
|
||||||
if (info.analise_tecnica?.tom) {
|
|
||||||
// Ex: "Ab"
|
|
||||||
tomRaw = info.analise_tecnica.tom;
|
|
||||||
// Se a escala for minor, adiciona 'm'. Ex: "Ab" + "m" -> "Abm"
|
|
||||||
if (info.analise_tecnica.escala === 'minor') {
|
|
||||||
tomRaw += 'm';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
card.dataset.key = tomRaw; // Salva no HTML: data-key="Ab" ou "Cm"
|
|
||||||
|
|
||||||
// Injeta HTML
|
// --- 4. Renderização no DOM ---
|
||||||
const bpmContainer = card.querySelector('.bpm-container');
|
const bpmContainer = card.querySelector('.bpm-container');
|
||||||
if (bpmContainer) {
|
if (bpmContainer) {
|
||||||
// Limpa conteúdo anterior injetado via JS se houver (opcional)
|
|
||||||
// bpmContainer.innerHTML = ''; // Cuidado se tiver o BPM original do Liquid aqui.
|
|
||||||
|
|
||||||
const iaDiv = document.createElement('div');
|
const iaDiv = document.createElement('div');
|
||||||
iaDiv.style.display = "flex";
|
iaDiv.style.display = "flex";
|
||||||
iaDiv.style.flexDirection = "column";
|
iaDiv.style.flexDirection = "column";
|
||||||
iaDiv.style.alignItems = "center";
|
iaDiv.style.alignItems = "center";
|
||||||
iaDiv.style.gap = "6px"; // Aumentei um pouco o gap
|
iaDiv.style.gap = "6px";
|
||||||
iaDiv.className = "mt-3"; // Margem topo para separar do título
|
iaDiv.className = "mt-3";
|
||||||
|
|
||||||
// 1. Renderiza a Dificuldade (Nova função)
|
// Dificuldade
|
||||||
const diffDiv = document.createElement('div');
|
const diffDiv = document.createElement('div');
|
||||||
diffDiv.innerHTML = renderizarDificuldade(estrelas);
|
diffDiv.innerHTML = renderizarDificuldade(estrelas);
|
||||||
iaDiv.appendChild(diffDiv);
|
iaDiv.appendChild(diffDiv);
|
||||||
|
|
||||||
// 2. Tags (Gênero + Tom)
|
// Tags (Gênero Macro + Tom)
|
||||||
const tagsRow = document.createElement('div');
|
const tagsRow = document.createElement('div');
|
||||||
tagsRow.className = "tags is-centered mb-0";
|
tagsRow.className = "tags is-centered mb-1"; // mb-1 para dar espaço pros subgeneros
|
||||||
tagsRow.style.gap = "4px";
|
tagsRow.style.gap = "4px";
|
||||||
|
|
||||||
if(genero !== "Unknown") {
|
if(genero !== "Unknown") {
|
||||||
|
|
@ -537,35 +557,24 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
if(genero === 'Electronic') color = 'is-info';
|
if(genero === 'Electronic') color = 'is-info';
|
||||||
if(genero === 'Hip Hop') color = 'is-warning';
|
if(genero === 'Hip Hop') color = 'is-warning';
|
||||||
if(genero === 'Rock') color = 'is-danger';
|
if(genero === 'Rock') color = 'is-danger';
|
||||||
let subTagsHTML = "";
|
|
||||||
if (info.analise_ia?.nuvem_tags && Array.isArray(info.analise_ia.nuvem_tags)) {
|
|
||||||
// Pega os 2 primeiros
|
|
||||||
const topTags = info.analise_ia.nuvem_tags.slice(0, 2);
|
|
||||||
|
|
||||||
topTags.forEach(t => {
|
|
||||||
// Dica: Use title para mostrar o score no hover (mouse em cima)
|
|
||||||
const scorePercent = Math.round(t.score * 100);
|
|
||||||
subTagsHTML += `
|
|
||||||
<span class="tag is-white is-rounded border-tag"
|
|
||||||
title="Confiança IA: ${scorePercent}%"
|
|
||||||
style="font-size: 0.65rem; color: #666;">
|
|
||||||
#${t.tag}
|
|
||||||
</span>`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tag de Gênero
|
|
||||||
tagsRow.innerHTML += `<span class="tag ${color} is-light is-rounded" style="font-size: 0.7rem;">🤖 ${genero}</span>`;
|
tagsRow.innerHTML += `<span class="tag ${color} is-light is-rounded" style="font-size: 0.7rem;">🤖 ${genero}</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adiciona o Tom se existir
|
|
||||||
tagsRow.innerHTML += tomHtml;
|
tagsRow.innerHTML += tomHtml;
|
||||||
|
|
||||||
iaDiv.appendChild(tagsRow);
|
iaDiv.appendChild(tagsRow);
|
||||||
|
|
||||||
// Limpa o container antes de adicionar para evitar duplicatas se rodar 2x
|
// Nova Linha: Subgêneros
|
||||||
|
if (subTagsHTML) {
|
||||||
|
const subTagsRow = document.createElement('div');
|
||||||
|
subTagsRow.className = "tags is-centered mb-0";
|
||||||
|
subTagsRow.style.flexWrap = "wrap";
|
||||||
|
subTagsRow.innerHTML = subTagsHTML;
|
||||||
|
iaDiv.appendChild(subTagsRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limpa e reinsere
|
||||||
bpmContainer.innerHTML = '';
|
bpmContainer.innerHTML = '';
|
||||||
// Re-adiciona o BPM original se necessário, ou apenas adiciona o novo bloco IA
|
|
||||||
if(card.dataset.bpm_real > 0) {
|
if(card.dataset.bpm_real > 0) {
|
||||||
bpmContainer.innerHTML = `<span class="tag is-dark is-rounded is-light mb-1" style="font-size: 0.7rem; font-weight: bold; border: 1px solid #ccc;">🎵 ${Math.round(card.dataset.bpm_real)} BPM</span>`;
|
bpmContainer.innerHTML = `<span class="tag is-dark is-rounded is-light mb-1" style="font-size: 0.7rem; font-weight: bold; border: 1px solid #ccc;">🎵 ${Math.round(card.dataset.bpm_real)} BPM</span>`;
|
||||||
}
|
}
|
||||||
|
|
@ -617,7 +626,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
const col = c.closest('.project-column');
|
const col = c.closest('.project-column');
|
||||||
const g = c.dataset.genre;
|
const g = c.dataset.genre;
|
||||||
const s = parseInt(c.dataset.stars || 0);
|
const s = parseInt(c.dataset.stars || 0);
|
||||||
const k = c.dataset.key; // Pega o que salvamos ("Ab", "Cm", etc)
|
const k = c.dataset.key || 'all'; // Pega o tom salvo no card
|
||||||
|
const currentKey = document.getElementById('key-filter')?.value || 'all';
|
||||||
|
|
||||||
const matchG = (currentGenre === 'all' || g === currentGenre);
|
const matchG = (currentGenre === 'all' || g === currentGenre);
|
||||||
const matchS = (currentMinStars === 'all' || s === parseInt(currentMinStars));
|
const matchS = (currentMinStars === 'all' || s === parseInt(currentMinStars));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue