Busca por patterns e indexação de tags de patterns
This commit is contained in:
parent
3e6fdfd324
commit
3e6986e07c
|
|
@ -149,35 +149,79 @@ title: "{{ page.file }}"
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{% comment %}
|
{% comment %}
|
||||||
>>> INÍCIO DA LÓGICA DE STEPS MELHORADA <<<
|
>>> INÍCIO DA LÓGICA DE STEPS CLICÁVEIS (4-steps) <<<
|
||||||
Container da grade de steps
|
(O container agora é 'row' para manter os chunks na horizontal)
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
<div style="display: flex; flex-direction: row; border: 1px solid #ccc; padding: 2px; border-radius: 2px; background-color: #f0f0f0;">
|
<div class="patterns-container" style="display: flex; flex-direction: row; flex-wrap: wrap; gap: 4px;">
|
||||||
{% for step_active in pattern_steps %}
|
{% assign total_steps = pattern_steps.size %}
|
||||||
|
{% assign chunk_size = 4 %}
|
||||||
|
|
||||||
{% comment %} Define a cor do step {% endcomment %}
|
{% comment %} Calcula quantos pedaços de 4 steps teremos {% endcomment %}
|
||||||
{% assign step_color = '#d9d9d9' %} {% comment %} Cor INATIVA (cinza claro) {% endcomment %}
|
{% assign num_chunks = total_steps | divided_by: chunk_size %}
|
||||||
{% if step_active == true or step_active == 'true' or step_active == 1 %}
|
|
||||||
{% assign step_color = '#4caf50' %} {% comment %} Cor ATIVA (verde) {% endcomment %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% comment %} Define o espaçamento (divisão do compasso) {% endcomment %}
|
{% comment %}
|
||||||
{% assign step_style = '' %}
|
FIX: Primeiro calculamos o 'resto' e salvamos numa variável
|
||||||
{% assign step_index_zero_based = forloop.index0 %}
|
{% endcomment %}
|
||||||
|
{% assign remainder = total_steps | modulo: chunk_size %}
|
||||||
|
|
||||||
{% comment %} --- Calcula o módulo *antes* do 'if' --- {% endcomment %}
|
{% comment %}
|
||||||
{% assign remainder = step_index_zero_based | modulo: 4 %}
|
FIX: Agora sim usamos a variável na comparação
|
||||||
|
{% endcomment %}
|
||||||
|
{% if remainder > 0 %}
|
||||||
|
{% assign num_chunks = num_chunks | plus: 1 %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if step_index_zero_based > 0 and remainder == 0 %}
|
{% for i in (0..num_chunks) %}
|
||||||
{% assign step_style = 'margin-left: 3px;' %}
|
{% assign start_index = i | times: chunk_size %}
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div
|
{% comment %} Pega a fatia de 4 steps {% endcomment %}
|
||||||
style="width: 5px; height: 10px; background-color: {{ step_color }}; border-radius: 1px; {{ step_style }}"
|
{% assign current_chunk_array = pattern_steps | slice: start_index, chunk_size %}
|
||||||
></div>
|
|
||||||
|
{% if current_chunk_array.size > 0 %}
|
||||||
|
|
||||||
|
{% comment %} 1. Serializa o chunk (ex: [1,0,0,1] -> "1001") {% endcomment %}
|
||||||
|
{% assign chunk_string = "" %}
|
||||||
|
{% for step in current_chunk_array %}
|
||||||
|
{% if step == true or step == 'true' or step == 1 %}
|
||||||
|
{% assign chunk_string = chunk_string | append: '1' %}
|
||||||
|
{% else %}
|
||||||
|
{% assign chunk_string = chunk_string | append: '0' %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% comment %}
|
||||||
|
2. Cria o link clicável
|
||||||
|
{% endcomment %}
|
||||||
|
{% assign search_url = '/pattern/?p=' | append: chunk_string | relative_url %}
|
||||||
|
|
||||||
|
<a href="{{ search_url }}" title="Buscar padrão {{ chunk_string }}" style="display: inline-block;">
|
||||||
|
|
||||||
|
{% comment %} 3. Renderiza o visual do step DENTRO do link {% endcomment %}
|
||||||
|
<div style="display: flex; flex-direction: row; border: 1px solid #999; padding: 2px; border-radius: 2px; background-color: #f0f0f0;">
|
||||||
|
|
||||||
|
{% for step_active in current_chunk_array %}
|
||||||
|
{% assign step_color = '#d9d9d9' %}
|
||||||
|
{% if step_active == true or step_active == 'true' or step_active == 1 %}
|
||||||
|
{% assign step_color = '#4caf50' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div style="width: 5px; height: 10px; background-color: {{ step_color }}; border-radius: 1px; margin-right: 1px;"></div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% comment %} Preenche com steps vazios se o chunk for menor que 4 {% endcomment %}
|
||||||
|
{% assign remaining_steps = chunk_size | minus: current_chunk_array.size %}
|
||||||
|
{% if remaining_steps > 0 %}
|
||||||
|
{% for j in (1..remaining_steps) %}
|
||||||
|
<div style="width: 5px; height: 10px; background-color: #d9d9d9; border-radius: 1px; margin-right: 1px;"></div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% comment %} >>> FIM DA LÓGICA DE STEPS MELHORADA <<< {% endcomment %}
|
{% comment %} >>> FIM DA LÓGICA DE STEPS CLICÁVEIS <<< {% endcomment %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,2 @@
|
||||||
|
{"level":30,"time":1762980056562,"pid":2587819,"hostname":"ubuntu","timestamp":1762980056562,"socketId":"QvekitV8wcwavNWAAAGI","action":{"type":"AUDIO_SNAPSHOT_REQUEST","__token":"1","__senderId":"QvekitV8wcwavNWAAAGI","__senderName":"Alicer-Qvek"},"msg":"action_received"}
|
||||||
|
{"level":30,"time":1762987723672,"pid":2587819,"hostname":"ubuntu","timestamp":1762987723672,"socketId":"KmizFldq5cpxphv5AAGw","action":{"type":"AUDIO_SNAPSHOT_REQUEST","__token":"1","__senderId":"KmizFldq5cpxphv5AAGw","__senderName":"Alicer-Kmiz"},"msg":"action_received"}
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,21 @@
|
||||||
|
[
|
||||||
|
"Computacao_Musical_Thiago_Rocha_de_Moraes.mmp",
|
||||||
|
"FelipeFerraz.mmp",
|
||||||
|
"Gustavo Castro.mmp",
|
||||||
|
"Iara Rodrigues.mmp",
|
||||||
|
"JoãoVitorSimão-2023008380-megaMainSong.mmp",
|
||||||
|
"Samanta Freire.mmp",
|
||||||
|
"SonsAlignígenas.mmp",
|
||||||
|
"Um começo.mmp",
|
||||||
|
"VitorAugusto.mmp",
|
||||||
|
"Wesley_Silva_Guimarães.mmp",
|
||||||
|
"beatJulioCesardeSousa.mmp",
|
||||||
|
"carlos.mmp",
|
||||||
|
"deprecado_wallace.mmp",
|
||||||
|
"eliasMendesSong.mmp",
|
||||||
|
"gabriel_gomes.mmp",
|
||||||
|
"leandro_souza_atvd1.mmp",
|
||||||
|
"teste.mmp",
|
||||||
|
"tp1 - Luiz Filipe Almada.mmp",
|
||||||
|
"tp1_MarcoAntonio.mmp"
|
||||||
|
]
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,404 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Projetos por Pattern Rítmico
|
||||||
|
permalink: /pattern/
|
||||||
|
---
|
||||||
|
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<div class="publication">{% include sidebar.html %}</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="columns is-mobile is-vcentered" style="margin-bottom: 2rem">
|
||||||
|
<div class="column is-auto">
|
||||||
|
<h2 class="title is-4">
|
||||||
|
<code>Projetos que possuem patterns similares:</code>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="column is-auto">
|
||||||
|
<button id="clearFilterButton" class="button is-small is-light">
|
||||||
|
Limpar filtro
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div> <style>
|
||||||
|
/* Estilos para o nosso sequencer de 16 steps */
|
||||||
|
.pattern-search-box {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap; /* Permite quebrar a linha se necessário */
|
||||||
|
gap: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border: 1px solid #dbdbdb;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
.search-step {
|
||||||
|
/* MODIFICADO: Steps menores para caber 16 */
|
||||||
|
width: 18px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: #d9d9d9; /* Cor INATIVA */
|
||||||
|
border: 1px solid #999;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: background-color 0.1s ease;
|
||||||
|
}
|
||||||
|
.search-step.is-active {
|
||||||
|
background-color: #4caf50; /* Cor ATIVA (verde) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOVO: Adiciona um espaço extra a cada 4 steps para legibilidade */
|
||||||
|
.search-step:nth-child(4n):not(:last-child) {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label"><code>Desenhe um pattern (até 16 steps) para buscar:</code></label>
|
||||||
|
<div id="pattern-search-box" class="pattern-search-box">
|
||||||
|
<div class="search-step" data-index="0"></div>
|
||||||
|
<div class="search-step" data-index="1"></div>
|
||||||
|
<div class="search-step" data-index="2"></div>
|
||||||
|
<div class="search-step" data-index="3"></div>
|
||||||
|
<div class="search-step" data-index="4"></div>
|
||||||
|
<div class="search-step" data-index="5"></div>
|
||||||
|
<div class="search-step" data-index="6"></div>
|
||||||
|
<div class="search-step" data-index="7"></div>
|
||||||
|
<div class="search-step" data-index="8"></div>
|
||||||
|
<div class="search-step" data-index="9"></div>
|
||||||
|
<div class="search-step" data-index="10"></div>
|
||||||
|
<div class="search-step" data-index="11"></div>
|
||||||
|
<div class="search-step" data-index="12"></div>
|
||||||
|
<div class="search-step" data-index="13"></div>
|
||||||
|
<div class="search-step" data-index="14"></div>
|
||||||
|
<div class="search-step" data-index="15"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="project-list" class="columns is-multiline">
|
||||||
|
|
||||||
|
{% comment %}
|
||||||
|
... O SEU LOOP LIQUID DE PROJETOS VEM AQUI ...
|
||||||
|
NENHUMA MUDANÇA É NECESSÁRIA NO LIQUID.
|
||||||
|
Ele continua exatamente como estava, gerando os 'project-item'
|
||||||
|
e os 'data-patterns' com chunks de 4 steps.
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
|
{% for projeto in site.data.all %}
|
||||||
|
|
||||||
|
{% assign project_patterns_flat = "" | split: "," %}
|
||||||
|
{% assign project_patterns_data = "" | split: "," %}
|
||||||
|
|
||||||
|
{% for track in projeto.tracks %}
|
||||||
|
{% if track.instruments %}
|
||||||
|
{% for instrument in track.instruments %}
|
||||||
|
|
||||||
|
{% assign display_name = instrument.instrument_name %}
|
||||||
|
{% if display_name contains "audiofileprocessor" and instrument.patterns %}
|
||||||
|
{% assign first_pattern_name = instrument.patterns | map: 'name' | first %}
|
||||||
|
{% if first_pattern_name and first_pattern_name != empty %}
|
||||||
|
{% assign display_name = first_pattern_name | remove: ".ogg" | remove: ".wav" | remove: ".flac" | remove: ".mp3" %}
|
||||||
|
{% elsif instrument.audiofileprocessor.src %}
|
||||||
|
{% assign src_parts = instrument.audiofileprocessor.src | split: '/' %}
|
||||||
|
{% assign file_name = src_parts | last %}
|
||||||
|
{% assign display_name = file_name | remove: ".ogg" | remove: ".wav" | remove: ".flac" | remove: ".mp3" %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if display_name == nil or display_name == "" %}
|
||||||
|
{% assign display_name = "Instrumento" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if instrument.patterns %}
|
||||||
|
{% for pattern in instrument.patterns %}
|
||||||
|
{% assign pattern_steps = pattern.steps %}
|
||||||
|
{% if pattern_steps and pattern_steps.size > 0 %}
|
||||||
|
|
||||||
|
{% assign total_steps = pattern_steps.size %}
|
||||||
|
{% assign chunk_size = 4 %}
|
||||||
|
{% assign num_chunks = total_steps | divided_by: chunk_size %}
|
||||||
|
|
||||||
|
{% assign remainder = total_steps | modulo: chunk_size %}
|
||||||
|
{% if remainder > 0 %}
|
||||||
|
{% assign num_chunks = num_chunks | plus: 1 %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for i in (0..num_chunks) %}
|
||||||
|
{% assign start_index = i | times: chunk_size %}
|
||||||
|
{% assign current_chunk_array = pattern_steps | slice: start_index, chunk_size %}
|
||||||
|
|
||||||
|
{% if current_chunk_array.size > 0 %}
|
||||||
|
{% assign chunk_string = "" %}
|
||||||
|
{% for step in current_chunk_array %}
|
||||||
|
{% if step == true or step == 'true' or step == 1 %}
|
||||||
|
{% assign chunk_string = chunk_string | append: '1' %}
|
||||||
|
{% else %}
|
||||||
|
{% assign chunk_string = chunk_string | append: '0' %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% assign data_pair = chunk_string | append: '::' | append: display_name %}
|
||||||
|
|
||||||
|
{% unless project_patterns_flat contains chunk_string %}
|
||||||
|
{% assign project_patterns_flat = project_patterns_flat | push: chunk_string %}
|
||||||
|
{% endunless %}
|
||||||
|
|
||||||
|
{% unless project_patterns_data contains data_pair %}
|
||||||
|
{% assign project_patterns_data = project_patterns_data | push: data_pair %}
|
||||||
|
{% endunless %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if project_patterns_flat.size > 0 %}
|
||||||
|
{% assign project_patterns_string = project_patterns_flat | join: ',' %}
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="column is-6 project-item"
|
||||||
|
data-patterns="{{ project_patterns_string }}"
|
||||||
|
>
|
||||||
|
<div class="box">
|
||||||
|
{% assign file_url = projeto.file | downcase | replace: ' ', '-' |
|
||||||
|
replace: 'ç', 'c' | replace: 'ã', 'a' | replace: 'á', 'a' | replace:
|
||||||
|
'â', 'a' | replace: 'é', 'e' | replace: 'ê', 'e' | replace: 'í', 'i' |
|
||||||
|
replace: 'ó', 'o' | replace: 'ô', 'o' | replace: 'õ', 'o' | replace:
|
||||||
|
'ú', 'u' %}
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="../mmp_pages/{{ file_url }}.html"
|
||||||
|
class="button is-link is-fullwidth"
|
||||||
|
>
|
||||||
|
{{ projeto.file }}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div style="margin-top: 1rem">
|
||||||
|
<p><strong>Patterns (4-steps):</strong></p>
|
||||||
|
<div class="tags" style="margin-top: 0.5rem;">
|
||||||
|
|
||||||
|
{% for data_pair_string in project_patterns_data %}
|
||||||
|
{% assign pair_parts = data_pair_string | split: '::' %}
|
||||||
|
{% assign p_string = pair_parts[0] %}
|
||||||
|
{% assign p_instrument = pair_parts[1] | default: '?' %}
|
||||||
|
|
||||||
|
<a href="#" class="pattern-item tag is-info is-light" data-pattern="{{ p_string }}" title="Filtrar por {{ p_string }} (de {{ p_instrument }})">
|
||||||
|
|
||||||
|
<div style="display: flex; flex-direction: row; border: 1px solid #999; padding: 2px; border-radius: 2px; background-color: #fff; margin-right: 5px;">
|
||||||
|
{% assign p_array = p_string | split: "" %}
|
||||||
|
{% for step_char in p_array %}
|
||||||
|
{% assign step_color = '#d9d9d9' %}
|
||||||
|
{% if step_char == '1' %}
|
||||||
|
{% assign step_color = '#4caf50' %}
|
||||||
|
{% endif %}
|
||||||
|
<div style="width: 5px; height: 10px; background-color: {{ step_color }}; border-radius: 1px; margin-right: 1px;"></div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span class="is-size-7" style="margin-right: 5px;">{{ p_instrument }}:</span>
|
||||||
|
<code>{{ p_string }}</code>
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
{% comment %}
|
||||||
|
SCRIPT FINAL (TOTALMENTE REESCRITO PARA 16-STEPS "AND" FILTER)
|
||||||
|
{% endcomment %}
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const projects = document.querySelectorAll(".project-item");
|
||||||
|
const allPatternItems = document.querySelectorAll(".pattern-item");
|
||||||
|
const clearFilterButton = document.querySelector("#clearFilterButton");
|
||||||
|
const searchSteps = document.querySelectorAll(".search-step"); // Agora tem 16
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Fonte da verdade": um array de chunks de 4 steps (ex: ["1001", "0010"])
|
||||||
|
* que estão ativos no filtro.
|
||||||
|
*/
|
||||||
|
let activeChunks = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pega o desenho de 16 steps e o quebra em 4 chunks.
|
||||||
|
* @returns {string[]} ex: ["1001", "0010", "0000", "0000"]
|
||||||
|
*/
|
||||||
|
function getChunksFromSearchBox() {
|
||||||
|
let fullPattern = "";
|
||||||
|
searchSteps.forEach(step => {
|
||||||
|
fullPattern += step.classList.contains("is-active") ? "1" : "0";
|
||||||
|
});
|
||||||
|
// Quebra a string "10010010..." em ["1001", "0010", ...]
|
||||||
|
return fullPattern.match(/.{1,4}/g) || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pega os chunks ativos (ex: ["1001", "0010"]) e desenha
|
||||||
|
* o pattern de 16 steps (ex: "1001001000000000") na caixa.
|
||||||
|
*/
|
||||||
|
function setSearchBoxFromChunks(chunks) {
|
||||||
|
let fullPattern = (chunks || []).join("").padEnd(16, "0");
|
||||||
|
const bits = fullPattern.split("");
|
||||||
|
|
||||||
|
searchSteps.forEach((step, index) => {
|
||||||
|
if (bits[index] === "1") {
|
||||||
|
step.classList.add("is-active");
|
||||||
|
} else {
|
||||||
|
step.classList.remove("is-active");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filtra a lista de projetos.
|
||||||
|
* Um projeto SÓ aparece se ele tiver TODOS os activeChunks.
|
||||||
|
*/
|
||||||
|
function filterByPattern(chunks) {
|
||||||
|
// Se não há chunks ativos (e não vazios), mostra tudo
|
||||||
|
const effectiveChunks = chunks.filter(c => c !== "0000");
|
||||||
|
if (effectiveChunks.length === 0) {
|
||||||
|
projects.forEach(project => project.style.display = "block");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
projects.forEach((project) => {
|
||||||
|
const projectPatterns = project
|
||||||
|
.getAttribute("data-patterns")
|
||||||
|
.split(",");
|
||||||
|
|
||||||
|
// Lógica "AND": .every() verifica se TODOS os chunks são verdadeiros
|
||||||
|
const isMatch = effectiveChunks.every(chunk =>
|
||||||
|
projectPatterns.includes(chunk)
|
||||||
|
);
|
||||||
|
|
||||||
|
project.style.display = isMatch ? "block" : "none";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destaca MÚLTIPLAS tags que estão no filtro "AND".
|
||||||
|
*/
|
||||||
|
function highlightActiveFilter(chunks) {
|
||||||
|
allPatternItems.forEach((item) => {
|
||||||
|
const itemPattern = item.getAttribute("data-pattern");
|
||||||
|
|
||||||
|
// Se o pattern da tag ESTÁ no array de chunks ativos
|
||||||
|
if (chunks.includes(itemPattern)) {
|
||||||
|
item.classList.remove("is-light"); // Fica sólido
|
||||||
|
} else {
|
||||||
|
item.classList.add("is-info", "is-light"); // Fica light
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atualiza a URL com um parâmetro ?p=1001,0010
|
||||||
|
*/
|
||||||
|
function updateUrl(chunks) {
|
||||||
|
const newUrl = new URL(window.location.href);
|
||||||
|
// Filtra "0000" antes de salvar na URL
|
||||||
|
const effectiveChunks = chunks.filter(c => c !== "0000");
|
||||||
|
|
||||||
|
if (effectiveChunks.length > 0) {
|
||||||
|
newUrl.searchParams.set("p", effectiveChunks.join(","));
|
||||||
|
} else {
|
||||||
|
newUrl.searchParams.delete("p");
|
||||||
|
}
|
||||||
|
window.history.replaceState({}, "", newUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A NOVA função principal que sincroniza tudo.
|
||||||
|
*/
|
||||||
|
function runFilter() {
|
||||||
|
// 1. Lê o desenho e pega os chunks ativos
|
||||||
|
const chunksFromBox = getChunksFromSearchBox();
|
||||||
|
activeChunks = chunksFromBox.filter(c => c !== "0000");
|
||||||
|
|
||||||
|
// 2. Filtra os projetos (lógica "AND")
|
||||||
|
filterByPattern(activeChunks);
|
||||||
|
|
||||||
|
// 3. Destaca as tags
|
||||||
|
highlightActiveFilter(activeChunks);
|
||||||
|
|
||||||
|
// 4. Atualiza a URL
|
||||||
|
updateUrl(activeChunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
// Event Listeners (Gatilhos)
|
||||||
|
// ========================================================
|
||||||
|
|
||||||
|
// 1. Ao carregar a página (lê a URL)
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
let patternFromUrl = urlParams.get("p");
|
||||||
|
|
||||||
|
if (patternFromUrl) {
|
||||||
|
activeChunks = patternFromUrl.split(","); // ex: ["1001", "0010"]
|
||||||
|
setSearchBoxFromChunks(activeChunks); // Desenha "100100100000..."
|
||||||
|
filterByPattern(activeChunks);
|
||||||
|
highlightActiveFilter(activeChunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Ao clicar numa TAG (na lista de projetos)
|
||||||
|
allPatternItems.forEach((item) => {
|
||||||
|
item.addEventListener("click", function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const selectedPattern = item.getAttribute("data-pattern");
|
||||||
|
|
||||||
|
// Lógica: Clicar numa tag a "adiciona" ao filtro "AND"
|
||||||
|
|
||||||
|
// Pega o que já está desenhado
|
||||||
|
let currentChunks = getChunksFromSearchBox().filter(c => c !== "0000");
|
||||||
|
|
||||||
|
// Se já está lá, remove (toggle)
|
||||||
|
if (currentChunks.includes(selectedPattern)) {
|
||||||
|
currentChunks = currentChunks.filter(c => c !== selectedPattern);
|
||||||
|
}
|
||||||
|
// Se não está, adiciona (se houver espaço)
|
||||||
|
else if (currentChunks.length < 4) {
|
||||||
|
currentChunks.push(selectedPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
activeChunks = currentChunks;
|
||||||
|
|
||||||
|
// Atualiza tudo
|
||||||
|
setSearchBoxFromChunks(activeChunks);
|
||||||
|
filterByPattern(activeChunks);
|
||||||
|
highlightActiveFilter(activeChunks);
|
||||||
|
updateUrl(activeChunks);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Ao clicar em um STEP da caixa de busca
|
||||||
|
searchSteps.forEach(step => {
|
||||||
|
step.addEventListener("click", function() {
|
||||||
|
// 1. Liga/desliga o step
|
||||||
|
step.classList.toggle("is-active");
|
||||||
|
|
||||||
|
// 2. Roda o filtro principal
|
||||||
|
runFilter();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4. Botão para limpar filtro
|
||||||
|
clearFilterButton.addEventListener("click", function () {
|
||||||
|
activeChunks = [];
|
||||||
|
setSearchBoxFromChunks([]); // Limpa o desenho
|
||||||
|
filterByPattern([]); // Mostra todos os projetos
|
||||||
|
highlightActiveFilter([]); // Limpa os destaques
|
||||||
|
updateUrl([]); // Limpa a URL
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
Loading…
Reference in New Issue