1(function(){ 2 const SUPA_URL = window.SUPABASE_URL || (window.RS_CONFIG && window.RS_CONFIG.SUPABASE_URL); 3 const SUPA_KEY = window.SUPABASE_ANON_KEY || (window.RS_CONFIG && window.RS_CONFIG.SUPABASE_ANON_KEY); 4 function voterHash(){ 5 let h = localStorage.getItem('rs-voter-id'); 6 if(!h){ h = crypto.randomUUID(); localStorage.setItem('rs-voter-id', h); } 7 return h; 8 } 9 async function castVote(trackKey, vote, btnEl){ 10 var origLabel = null; 11 if (btnEl) { 12 origLabel = btnEl.textContent; 13 btnEl.disabled = true; 14 btnEl.textContent = 'Submitting...'; 15 } 16 try{ 17 const r = await fetch(`${SUPA_URL}/rest/v1/rpc/cast_vote`, { 18 method:'POST', 19 headers:{apikey:SUPA_KEY, Authorization:`Bearer ${SUPA_KEY}`, 'Content-Type':'application/json'}, 20 body: JSON.stringify({ p_track_key: trackKey, p_vote: vote, p_voter_hash: voterHash() }) 21 }); 22 if (btnEl) { 23 btnEl.textContent = r.ok ? 'Voted!' : 'Try again'; 24 if (r.ok) btnEl.classList.add('rsv-voted'); 25 setTimeout(function(){ 26 btnEl.textContent = origLabel; 27 btnEl.disabled = false; 28 btnEl.classList.remove('rsv-voted'); 29 }, 1500); 30 } 31 return r.ok; 32 } catch(e){ 33 console.error('castVote', e); 34 if (btnEl) { 35 btnEl.textContent = 'Try again'; 36 setTimeout(function(){ btnEl.textContent = origLabel; btnEl.disabled = false; }, 1500); 37 } 38 return false; 39 } 40 } 41 let _snapshot = null; 42 async function loadSnapshot(){ 43 try { 44 const r = await fetch('/data/song-votes.json', {cache:'no-store'}); 45 _snapshot = await r.json(); 46 } catch(e){ _snapshot = { top: [] }; } 47 } 48 function showScore(trackKey){ 49 const el = document.getElementById('rsp-vote-score'); 50 if (!el) return; 51 if (!_snapshot) { loadSnapshot().then(function(){ renderScore(trackKey); }); return; } 52 renderScore(trackKey); 53 }
54 function renderScore(trackKey){ 55 const el = document.getElementById('rsp-vote-score'); 56 if (!el || !_snapshot) return; 57 const row = (_snapshot.top||[]).find(t => t.track_key === trackKey); 58 el.textContent = row ? (row.score>0?'+':'') + row.score : ''; 59 } 60 window.RSVote = { castVote, showScore }; 61})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.