mejora vista de votación: modal, alineación y auto-reproducción del ganador

- Tarjetas de votación ahora abren el modal de canciones al hacer clic en la imagen/nombre
- Botón "Votar" siempre alineado al fondo independiente del alto de cada tarjeta
- Muestra descripción de la playlist en modo votación
- Emoji de playlist escala proporcionalmente usando container queries (55cqi)
- Al cerrar la votación, reproduce automáticamente la playlist con más votos

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-23 13:59:06 -04:00
parent a1b9c0139d
commit 94cda7293f
2 changed files with 29 additions and 5 deletions
+27 -4
View File
@@ -243,9 +243,18 @@ async function fetchVotingStatus() {
const res = await fetch('/voting/status');
const data = await res.json();
const wasOpen = votingOpen;
votingOpen = data.is_open;
myVotedPlaylistId = data.my_last_vote_playlist_id;
if (wasOpen && !votingOpen && data.playlists?.length) {
const totalVotes = data.playlists.reduce((s, p) => s + p.votes, 0);
if (totalVotes > 0) {
const winner = data.playlists.reduce((best, p) => p.votes > best.votes ? p : best);
playItem(winner.spotify_id, winner.spotify_type);
}
}
// Solo sincronizar cooldown desde servidor si no hay timer local activo
if (cooldownRemaining <= 0 && data.cooldown_remaining > 0) {
startCooldownTick(data.cooldown_remaining);
@@ -291,9 +300,12 @@ function renderPlaylists(playlists, isVoting, myVote) {
const btnLabel = cooldownRemaining > 0 ? `${cooldownRemaining}s` : '👍 Votar';
const btnDisabled = cooldownRemaining > 0 ? 'disabled' : '';
return `
<div class="playlist-card clickable voting-card ${isVoted ? 'voted' : ''}">
${img}
<div class="playlist-card-name">${pl.name}</div>
<div class="playlist-card voting-card ${isVoted ? 'voted' : ''}">
<div class="voting-card-top clickable" onclick='openTracksModal(${JSON.stringify(pl)})'>
${img}
<div class="playlist-card-name">${pl.name}</div>
${pl.description ? `<div class="playlist-card-desc">${pl.description}</div>` : ''}
</div>
<div class="vote-bar-wrap"><div class="vote-bar" style="width:${pct}%"></div></div>
<div class="vote-info">
<span class="vote-count">${pl.votes} votos</span>
@@ -416,7 +428,18 @@ setInterval(fetchVotingStatus, 5000);
gap: .5rem;
}
.voting-card { cursor: pointer; position: relative; }
.voting-card { position: relative; }
.voting-card-top { cursor: pointer; flex: 1; width: 100%; display: flex; flex-direction: column; align-items: center; gap: 0.4rem; }
.voting-card-top:hover .playlist-card-name { color: var(--green); }
.playlist-card-desc {
font-size: 0.7rem;
color: var(--text-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
text-align: center;
}
.voting-card.voted { border: 2px solid var(--green); }
.vote-bar-wrap {