Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <script>
- // ── CONFIGURACIÓN ────────────────────────────────────────────
- // Reemplaza con tu URL de Apps Script
- const WS_URL = "URL_APPS_SCRIPT";
- let wsSongs = [];
- let wsVoted = new Set(JSON.parse(localStorage.getItem('ws_voted') || '[]'));
- function wsSaveVoted() {
- localStorage.setItem('ws_voted', JSON.stringify([...wsVoted]));
- }
- async function wsGet(params) {
- const url = WS_URL + '?' + new URLSearchParams(params).toString();
- const res = await fetch(url);
- return res.json();
- }
- async function wsLoad() {
- try {
- const data = await wsGet({ action: 'list' });
- if (data.ok) {
- wsSongs = data.songs;
- wsRender();
- } else {
- wsShowError();
- }
- } catch(e) {
- wsShowError();
- }
- }
- function wsRender() {
- const container = document.getElementById('ws-songs-container');
- const countEl = document.getElementById('ws-count');
- if (!container) return;
- if (!wsSongs.length) {
- countEl && (countEl.textContent = '');
- container.innerHTML = `
- <div class="ws-empty">
- <i class="fas fa-music ws-empty-icon"></i>
- Aún no hay canciones.<br>¡Sé el primero en sugerir una!
- </div>`;
- return;
- }
- countEl && (countEl.textContent = wsSongs.length + (wsSongs.length === 1 ? ' canción' : ' canciones'));
- const sorted = [...wsSongs].sort((a, b) => b.votes - a.votes);
- container.innerHTML = `<div class="ws-songs">` +
- sorted.map((s, i) => {
- const voted = wsVoted.has(s.id.toString());
- const isTop = i === 0 && sorted.length > 1;
- return `
- <div class="ws-song ${isTop ? 'top-song' : ''}" style="animation-delay:${i*0.05}s">
- <div class="ws-rank ${isTop ? 'top' : ''}">${i + 1}</div>
- <div class="ws-song-info">
- <div class="ws-song-name">
- ${wsEsc(s.song)}
- ${isTop ? '<span class="ws-top-badge">favorita</span>' : ''}
- </div>
- <div class="ws-song-artist">${wsEsc(s.artist)}</div>
- </div>
- <button class="ws-vote ${voted ? 'voted' : ''}" onclick="wsVote('${s.id}')">
- <i class="${voted ? 'fas' : 'far'} fa-heart ws-vote-icon"></i>
- <span class="ws-vote-n">${s.votes}</span>
- </button>
- </div>`;
- }).join('') +
- `</div>`;
- }
- async function wsSongAdd() {
- const songEl = document.getElementById('ws-inp-song');
- const artistEl = document.getElementById('ws-inp-artist');
- const btn = document.getElementById('ws-btn-add');
- const song = songEl.value.trim();
- const artist = artistEl.value.trim();
- if (!song || !artist) {
- wsToast('Completa el nombre de la canción y el artista', true);
- return;
- }
- btn.disabled = true;
- btn.textContent = 'Agregando…';
- try {
- const data = await wsGet({ action: 'add', song, artist });
- if (data.ok) {
- wsSongs.push({ id: data.id, song, artist, votes: 1 });
- wsVoted.add(data.id.toString());
- wsSaveVoted();
- wsRender();
- songEl.value = '';
- artistEl.value = '';
- wsToast('¡Canción agregada!');
- } else if (data.error === 'duplicate') {
- wsToast('Esa canción ya está en la lista 😊', true);
- } else {
- wsToast('Ocurrió un error, intenta de nuevo', true);
- }
- } catch(e) {
- wsToast('Sin conexión, intenta más tarde', true);
- } finally {
- btn.disabled = false;
- btn.innerHTML = '<i class="fas fa-music"></i> Agregar a la lista';
- }
- }
- async function wsVote(id) {
- const idStr = id.toString();
- if (wsVoted.has(idStr)) {
- wsToast('Ya votaste por esta canción 💕');
- return;
- }
- const song = wsSongs.find(s => s.id.toString() === idStr);
- if (song) song.votes++;
- wsVoted.add(idStr);
- wsSaveVoted();
- wsRender();
- try {
- await wsGet({ action: 'vote', id });
- } catch(e) {
- if (song) song.votes--;
- wsVoted.delete(idStr);
- wsSaveVoted();
- wsRender();
- wsToast('No se pudo registrar el voto', true);
- }
- }
- function wsEsc(str) {
- return str.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
- }
- function wsShowError() {
- const c = document.getElementById('ws-songs-container');
- if (c) c.innerHTML = `<div class="ws-empty">No se pudo cargar la lista.<br>Recarga la página e intenta de nuevo.</div>`;
- }
- let wsToastTimer;
- function wsToast(msg, isError = false) {
- const el = document.getElementById('ws-toast');
- if (!el) return;
- el.textContent = msg;
- el.className = 'ws-toast show' + (isError ? ' error' : '');
- clearTimeout(wsToastTimer);
- wsToastTimer = setTimeout(() => el.className = 'ws-toast', 2800);
- }
- document.addEventListener('DOMContentLoaded', () => {
- ['ws-inp-song', 'ws-inp-artist'].forEach(id => {
- const el = document.getElementById(id);
- if (el) el.addEventListener('keydown', e => { if (e.key === 'Enter') wsSongAdd(); });
- });
- wsLoad();
- });
- </script>
Advertisement
Add Comment
Please, Sign In to add comment