From de3ffbe05f9ad0bf3dc9b4dd613278c0d5e22d73 Mon Sep 17 00:00:00 2001 From: josedario87 Date: Tue, 14 Oct 2025 01:14:19 -0600 Subject: [PATCH] =?UTF-8?q?feat:=20agregar=20b=C3=BAsqueda=20de=20cancione?= =?UTF-8?q?s=20y=20configurar=20hook=20de=20Gitea=20Actions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Agregar componente SearchFilter.client.vue modular y expandible - Integrar búsqueda en MainContainer con contador de resultados - Implementar filtrado de canciones por nombre en pages/index.vue - Configurar hook PostToolUse para monitorear Gitea Actions - Copiar y adaptar script monitor-gitea-action.sh para repodructor --- .claude/hooks/monitor-gitea-action.sh | 197 +++++++++++++++++++++ components/MainContainer.client.vue | 11 +- components/SearchFilter.client.vue | 242 ++++++++++++++++++++++++++ pages/index.vue | 39 ++++- 4 files changed, 484 insertions(+), 5 deletions(-) create mode 100755 .claude/hooks/monitor-gitea-action.sh create mode 100644 components/SearchFilter.client.vue diff --git a/.claude/hooks/monitor-gitea-action.sh b/.claude/hooks/monitor-gitea-action.sh new file mode 100755 index 0000000..c99090d --- /dev/null +++ b/.claude/hooks/monitor-gitea-action.sh @@ -0,0 +1,197 @@ +#!/bin/bash + +# Monitor Gitea Action after git push +# Este script se ejecuta después de un git push y espera a que termine la Gitea Action + +set -euo pipefail + +# Configuración +GITEA_URL="https://gitea.nucleoriofrio.com" +OWNER="nucleo000" +REPO="repodructor" + +# Intentar cargar el token desde el entorno o desde ~/.bashrc +GITEA_TOKEN="${GITEA_TOKEN:-}" +if [ -z "$GITEA_TOKEN" ] && [ -f "$HOME/.bashrc" ]; then + # Intentar extraer el token de .bashrc + GITEA_TOKEN=$(grep -oP "export GITEA_TOKEN=['\"]?\K[^'\"]*" "$HOME/.bashrc" 2>/dev/null || echo "") +fi + +MAX_WAIT_SECONDS=600 # 10 minutos +POLL_INTERVAL=10 # Consultar cada 10 segundos + +# Leer el input JSON del hook +INPUT=$(cat) + +# Verificar si el comando fue un git push +COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""') +if [[ ! "$COMMAND" =~ git[[:space:]]+push ]]; then + # No fue un git push, salir sin hacer nada + exit 0 +fi + +# Verificar que existe el token +if [ -z "$GITEA_TOKEN" ]; then + cat < /dev/null 2>&1; then + echo "ERROR: $(echo "$response" | jq -r '.message')" >&2 + echo "" + return 1 + fi + + echo "$response" | jq -r '.workflow_runs[0] // .data[0] // empty' +} + +# Función para formatear el resultado +format_result() { + local status="$1" + local task_data="$2" + + local id=$(echo "$task_data" | jq -r '.id // "N/A"') + local workflow_name=$(echo "$task_data" | jq -r '.name // "N/A"') + local workflow_file=$(echo "$task_data" | jq -r '.workflow_id // "N/A"') + local run_number=$(echo "$task_data" | jq -r '.run_number // "N/A"') + local event=$(echo "$task_data" | jq -r '.event // "N/A"') + local branch=$(echo "$task_data" | jq -r '.head_branch // "N/A"') + local title=$(echo "$task_data" | jq -r '.display_title // "N/A"') + local created=$(echo "$task_data" | jq -r '.created_at // "N/A"') + local started=$(echo "$task_data" | jq -r '.run_started_at // .started_at // "N/A"') + local updated=$(echo "$task_data" | jq -r '.updated_at // .stopped_at // "N/A"') + local commit=$(echo "$task_data" | jq -r '.head_sha[0:8] // "N/A"') + local run_url=$(echo "$task_data" | jq -r '.url // ""') + + # Calcular duración si es posible + local duration="N/A" + if [[ "$started" != "N/A" && "$updated" != "N/A" ]]; then + local start_ts=$(date -d "$started" +%s 2>/dev/null || echo "0") + local end_ts=$(date -d "$updated" +%s 2>/dev/null || echo "0") + if [[ $start_ts -gt 0 && $end_ts -gt 0 ]]; then + local diff=$((end_ts - start_ts)) + if [[ $diff -lt 60 ]]; then + duration="${diff}s" + else + local mins=$((diff / 60)) + local secs=$((diff % 60)) + duration="${mins}m ${secs}s" + fi + fi + fi + + case "$status" in + success) + local emoji="✅" + local msg="EXITOSO" + ;; + failure) + local emoji="❌" + local msg="FALLÓ" + ;; + cancelled) + local emoji="🚫" + local msg="CANCELADO" + ;; + *) + local emoji="⚠️" + local msg="DESCONOCIDO ($status)" + ;; + esac + + # Construir URL de logs si no está disponible + if [[ -z "$run_url" || "$run_url" == "null" ]]; then + run_url="$GITEA_URL/$OWNER/$REPO/actions/runs/$id" + fi + + cat <&2 +ACTIONS_ENABLED=$(check_actions_enabled) + +if [[ "$ACTIONS_ENABLED" != "true" ]]; then + cat <&2 + +# Esperar un poco antes de la primera consulta (dar tiempo a que Gitea cree la action) +sleep 5 + +# Polling loop +elapsed=0 +while [ $elapsed -lt $MAX_WAIT_SECONDS ]; do + # Consultar el estado + TASK_DATA=$(get_latest_action_status) + + if [ -z "$TASK_DATA" ]; then + echo "⏳ Esperando que Gitea cree la action... (${elapsed}s)" >&2 + sleep $POLL_INTERVAL + elapsed=$((elapsed + POLL_INTERVAL)) + continue + fi + + STATUS=$(echo "$TASK_DATA" | jq -r '.status // "unknown"') + + echo "📊 Estado actual: $STATUS (${elapsed}s)" >&2 + + # Verificar si terminó + case "$STATUS" in + success|failure|cancelled) + # Action terminó! + format_result "$STATUS" "$TASK_DATA" + exit 0 + ;; + running|pending|waiting) + # Todavía corriendo + sleep $POLL_INTERVAL + elapsed=$((elapsed + POLL_INTERVAL)) + ;; + *) + # Estado desconocido + echo "⚠️ Estado desconocido: $STATUS" >&2 + sleep $POLL_INTERVAL + elapsed=$((elapsed + POLL_INTERVAL)) + ;; + esac +done + +# Timeout alcanzado +cat < + !!props.currentTrack) diff --git a/components/SearchFilter.client.vue b/components/SearchFilter.client.vue new file mode 100644 index 0000000..456a01f --- /dev/null +++ b/components/SearchFilter.client.vue @@ -0,0 +1,242 @@ + + + + + diff --git a/pages/index.vue b/pages/index.vue index 15f11b5..0ef447d 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -7,11 +7,13 @@ /> - { - if (isShuffled.value && shuffledIndices.value.length > 0) { - return shuffledIndices.value.map(index => tracks.value[index]) + let tracksToDisplay = tracks.value + + // Aplicar filtro de búsqueda + if (searchQuery.value.length > 0) { + tracksToDisplay = tracksToDisplay.filter(track => + track.name.toLowerCase().includes(searchQuery.value) + ) } - return tracks.value + + // Aplicar shuffle si está activado + if (isShuffled.value && shuffledIndices.value.length > 0) { + const shuffledTracks = shuffledIndices.value + .map(index => tracks.value[index]) + .filter(track => + searchQuery.value.length === 0 || + track.name.toLowerCase().includes(searchQuery.value) + ) + return shuffledTracks + } + + return tracksToDisplay +}) + +const filteredCount = computed(() => { + if (searchQuery.value.length === 0) return null + return displayTracks.value.length }) // Methods @@ -293,6 +320,10 @@ const handleRepeatChanged = (mode) => { repeatMode.value = mode } +const handleSearch = (query) => { + searchQuery.value = query +} + const handleTrackSelected = ({ track, index }) => { playTrack(track, index) }