diff --git a/pages/projetos.md b/pages/projetos.md index 4b81d290..436c57e2 100755 --- a/pages/projetos.md +++ b/pages/projetos.md @@ -462,6 +462,8 @@ document.addEventListener('DOMContentLoaded', () => { function enrichCards(data) { const mapDados = {}; + + // Mapeamento dos dados data.forEach(item => { const k1 = normalizarChaveJS(item.arquivo.replace('.wav','').replace('.mp3','')); mapDados[k1] = item; @@ -471,65 +473,83 @@ document.addEventListener('DOMContentLoaded', () => { cards.forEach(card => { const info = mapDados[normalizarChaveJS(card.dataset.title)]; - // Defaults + // --- 1. Definição de Valores Padrão (Safety First) --- let genero = "Unknown"; let estrelas = 0; let intensidade = -100; let bpm = 0; 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) { - genero = info.analise_ia?.genero_macro || "Unknown"; - intensidade = parseFloat(info.analise_tecnica?.intensidade_db || -100); - bpm = parseFloat(info.analise_tecnica?.bpm || 0); - estrelas = Math.round(info.analise_tecnica?.complexidade?.estrelas || 0); + // Dados IA + if (info.analise_ia) { + genero = info.analise_ia.genero_macro || "Unknown"; + + // Lógica de Subgêneros (Top 2) + if (Array.isArray(info.analise_ia.nuvem_tags)) { + const topTags = info.analise_ia.nuvem_tags.slice(0, 2); + topTags.forEach(t => { + // Multiplica por 100 para porcentagem legível + const scorePercent = Math.round((t.score || 0) * 100); + subTagsHTML += ` + + #${t.tag} + `; + }); + } + } - // HTML do Tom - if (info.analise_tecnica?.tom) { - const t = info.analise_tecnica.tom; - const e = info.analise_tecnica.escala === 'minor' ? 'm' : ''; - tomHtml = `🎹 ${t}${e}`; + // 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 = `🎹 ${t}${e}`; + + // 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.stars = estrelas; card.dataset.intensity = intensidade; card.dataset.bpm_real = bpm; - // Dentro do enrichCards, salve o tom 'cru' no dataset - 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" + card.dataset.key = tomRaw; // Novo dataset para o filtro de Tom - // Injeta HTML + // --- 4. Renderização no DOM --- const bpmContainer = card.querySelector('.bpm-container'); 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'); iaDiv.style.display = "flex"; iaDiv.style.flexDirection = "column"; iaDiv.style.alignItems = "center"; - iaDiv.style.gap = "6px"; // Aumentei um pouco o gap - iaDiv.className = "mt-3"; // Margem topo para separar do título + iaDiv.style.gap = "6px"; + iaDiv.className = "mt-3"; - // 1. Renderiza a Dificuldade (Nova função) + // Dificuldade const diffDiv = document.createElement('div'); diffDiv.innerHTML = renderizarDificuldade(estrelas); iaDiv.appendChild(diffDiv); - // 2. Tags (Gênero + Tom) + // Tags (Gênero Macro + Tom) 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"; if(genero !== "Unknown") { @@ -537,35 +557,24 @@ document.addEventListener('DOMContentLoaded', () => { if(genero === 'Electronic') color = 'is-info'; if(genero === 'Hip Hop') color = 'is-warning'; 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 += ` - - #${t.tag} - `; - }); - } - // Tag de Gênero tagsRow.innerHTML += `🤖 ${genero}`; } - // Adiciona o Tom se existir tagsRow.innerHTML += tomHtml; - 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 = ''; - // Re-adiciona o BPM original se necessário, ou apenas adiciona o novo bloco IA if(card.dataset.bpm_real > 0) { bpmContainer.innerHTML = `🎵 ${Math.round(card.dataset.bpm_real)} BPM`; } @@ -617,7 +626,8 @@ document.addEventListener('DOMContentLoaded', () => { const col = c.closest('.project-column'); const g = c.dataset.genre; 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 matchS = (currentMinStars === 'all' || s === parseInt(currentMinStars));