← back to Scarlet Riverboat Masquerade
Music controller: full-archive browse — loads the most-played Dead shows by default (18k+ shows), a Year selector (1965-1995) to browse any year, plus search; shows total count
394ecd102e260be0bff0e08bd69a9db8b3d5352d · 2026-09-02 07:44:29 -0700 · Steve Abrams
Files touched
Diff
commit 394ecd102e260be0bff0e08bd69a9db8b3d5352d
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Sep 2 07:44:29 2026 -0700
Music controller: full-archive browse — loads the most-played Dead shows by default (18k+ shows), a Year selector (1965-1995) to browse any year, plus search; shows total count
---
index.html | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/index.html b/index.html
index bf4ecc9..05c9f58 100644
--- a/index.html
+++ b/index.html
@@ -153,6 +153,7 @@
.mrbody{padding:0 14px 14px}
.mr-search{width:100%;background:rgba(40,12,16,.8);color:var(--ink);border:1px solid var(--panel-edge);border-radius:9px;padding:8px 10px;font-size:12px;margin-bottom:8px}
.mr-search::placeholder{color:var(--ink-dim)}
+ .mr-year{width:100%;background:rgba(40,12,16,.8);color:var(--ink);border:1px solid var(--panel-edge);border-radius:9px;padding:7px 9px;font-size:12px;margin-bottom:8px;cursor:pointer}
.mr-results{max-height:150px;overflow:auto;margin-bottom:8px;display:flex;flex-direction:column;gap:2px}
.mr-results:empty{display:none}
.mr-result{display:flex;gap:9px;align-items:baseline;width:100%;text-align:left;background:none;border:0;color:var(--ink-dim);font-family:var(--sans);font-size:11.5px;padding:5px 6px;cursor:pointer;border-radius:6px}
@@ -242,6 +243,7 @@
</header>
<div class="mrbody" id="mrbody">
<input class="mr-search" id="mrSearch" type="search" placeholder="🔍 Search the whole Dead archive — date, city, song…" aria-label="Search the Grateful Dead archive">
+ <select class="mr-year" id="mrYear" aria-label="Browse by year"></select>
<div class="mr-results" id="mrResults" role="list"></div>
<div class="mr-picks">Curated nights:</div>
<select class="mr-show" id="mrShow" aria-label="Choose a recording from the Live Music Archive"></select>
@@ -1500,18 +1502,22 @@ async function loadShow(i, opts){ if(sel) sel.value=String(i); return loadShowRe
// Search the WHOLE Grateful Dead collection on archive.org — type anything (date, venue, city, song)
let searchTimer=null;
+// Browse the WHOLE Grateful Dead collection — empty = most-popular shows; text and/or a year narrow it.
async function searchArchive(q){
const res=$('mrResults'); if(!res) return;
q=(q||'').trim();
- if(!q){ res.innerHTML=''; return; }
- res.innerHTML='<div class="mr-hint">Searching the archive…</div>';
+ const yr=($('mrYear')&&$('mrYear').value)||'';
+ const filters=[]; if(q) filters.push('('+q+')'); if(yr) filters.push('year:'+yr);
+ const query = filters.length ? 'collection:GratefulDead AND '+filters.join(' AND ') : 'collection:GratefulDead';
+ res.innerHTML='<div class="mr-hint">'+(filters.length?'Searching the archive…':'Loading the most-played shows…')+'</div>';
+ const sort = (q||yr) ? 'downloads+desc' : 'downloads+desc';
try{
- const url='https://archive.org/advancedsearch.php?q='+encodeURIComponent('collection:GratefulDead AND ('+q+')')+
- '&fl[]=identifier&fl[]=title&fl[]=date&fl[]=venue&fl[]=coverage&sort[]=downloads+desc&rows=25&output=json';
+ const url='https://archive.org/advancedsearch.php?q='+encodeURIComponent(query)+
+ '&fl[]=identifier&fl[]=title&fl[]=date&fl[]=venue&fl[]=coverage&fl[]=downloads&sort[]='+sort+'&rows=40&output=json';
const r=await fetch(url,{mode:'cors'}); const j=await r.json();
- const docs=(j.response&&j.response.docs)||[];
+ const docs=(j.response&&j.response.docs)||[]; const total=(j.response&&j.response.numFound)||0;
if(!docs.length){ res.innerHTML='<div class="mr-hint">No shows found. Try a date (1977-05-08), a city, or a song.</div>'; return; }
- res.innerHTML='';
+ res.innerHTML=`<div class="mr-hint">${total.toLocaleString()} shows in the archive${filters.length?' matching':''} · showing ${docs.length}</div>`;
docs.forEach(d=>{
const date=(d.date||'').slice(0,10), place=d.venue||d.coverage||d.title||d.identifier;
const b=document.createElement('button'); b.type='button'; b.className='mr-result'; b.setAttribute('role','listitem');
@@ -1519,7 +1525,7 @@ async function searchArchive(q){
b.addEventListener('click',()=>loadShowRef({id:d.identifier, date:date, title:d.venue||d.title||'Grateful Dead', sub:d.coverage||''}, {play:true}));
res.appendChild(b);
});
- }catch(e){ res.innerHTML='<div class="mr-hint">Search is unavailable right now (open over http, not file://).</div>'; }
+ }catch(e){ res.innerHTML='<div class="mr-hint">Archive browse unavailable right now (open over http, not file://).</div>'; }
}
function fallbackEmbed(s){
@@ -1639,10 +1645,17 @@ seek.addEventListener('change',()=>{ const d=audio.duration||0; if(d>0) audio.cu
sel.addEventListener('change',()=>loadShow(+sel.value,{play:true}));
// archive search wiring — type anything, debounced; Enter searches immediately
-const searchEl=$('mrSearch');
+const searchEl=$('mrSearch'), yearEl=$('mrYear');
+if(yearEl){
+ let opts='<option value="">All years · most played</option>';
+ for(let y=1965;y<=1995;y++) opts+=`<option value="${y}">${y}</option>`;
+ yearEl.innerHTML=opts;
+ yearEl.addEventListener('change',()=>searchArchive(searchEl?searchEl.value:''));
+}
if(searchEl){
searchEl.addEventListener('input',()=>{ clearTimeout(searchTimer); searchTimer=setTimeout(()=>searchArchive(searchEl.value),450); });
searchEl.addEventListener('keydown',e=>{ if(e.key==='Enter'){ e.preventDefault(); clearTimeout(searchTimer); searchArchive(searchEl.value); } });
+ searchArchive(''); // populate the most-played shows from the whole archive on load
}
$('mrTracksToggle').addEventListener('click',()=>{
← ced8032 Back-link: room now links '← The Main Stage' (stage.agentabr
·
back to Scarlet Riverboat Masquerade
·
riverboat: interactive touring-history year map (bars sized 6ceafcc →