stream: switch queue and history with glossy tabs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
nemunaire 2026-07-04 11:13:45 +08:00
commit d30f687185

View file

@ -71,9 +71,39 @@
}
.actions button:hover, .actions a:hover { background: rgba(155,140,255,.3); }
.actions button:disabled { opacity: .5; cursor: default; }
.history, .queue { margin-top: 1.75rem; text-align: left; }
.history h2, .queue h2 { font-size: .7rem; letter-spacing: .2em; text-transform: uppercase;
color: #7d768f; margin: 0 0 .4rem; font-weight: 600; }
/* Onglets « glossy » pour basculer entre file d'attente et historique :
une barre pilule au fond translucide, l'onglet actif surligné par un
dégradé lumineux et un léger reflet en haut pour l'effet vernis. */
.tabs { margin-top: 1.75rem; text-align: left; }
.tab-bar {
display: flex; gap: .35rem; padding: .3rem;
background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.08);
border-radius: 12px; box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
}
.tab-btn {
flex: 1; position: relative; overflow: hidden; cursor: pointer;
padding: .55rem .7rem; font-size: .7rem; font-weight: 600;
letter-spacing: .15em; text-transform: uppercase; color: #8b849c;
background: transparent; border: 1px solid transparent; border-radius: 9px;
transition: color .2s, background .2s, box-shadow .2s, border-color .2s;
}
.tab-btn:hover { color: #cfc9de; }
.tab-btn.active {
color: #f2f0f7;
background: linear-gradient(180deg, rgba(155,140,255,.45), rgba(123,110,220,.22));
border-color: rgba(155,140,255,.5);
box-shadow: inset 0 1px 0 rgba(255,255,255,.35),
0 4px 14px rgba(123,110,220,.35);
}
/* Reflet vitreux : une bande claire sur la moitié haute de l'onglet actif. */
.tab-btn.active::before {
content: ""; position: absolute; inset: 0 0 50%;
background: linear-gradient(180deg, rgba(255,255,255,.28), transparent);
pointer-events: none;
}
.tab-panel { margin-top: 1rem; text-align: left; }
.tab-panel[hidden] { display: none; }
.history, .queue { text-align: left; }
.history ul, .queue ul { list-style: none; margin: 0; padding: 0; }
.history li, .queue li { border-top: 1px solid rgba(255,255,255,.06); }
.history .h-row {
@ -120,14 +150,18 @@
<input id="streamUrl" type="text" readonly>
<button id="copyBtn" type="button">Copier</button>
</div>
<section class="queue">
<h2>File d'attente</h2>
<ul id="queueList"></ul>
</section>
<section class="history">
<h2>Historique</h2>
<ul id="historyList"></ul>
</section>
<div class="tabs">
<div class="tab-bar" role="tablist">
<button class="tab-btn active" id="tabHistory" type="button" role="tab" aria-selected="true" aria-controls="panelHistory">Historique</button>
<button class="tab-btn" id="tabQueue" type="button" role="tab" aria-selected="false" aria-controls="panelQueue">File d'attente</button>
</div>
<section class="tab-panel history" id="panelHistory" role="tabpanel" aria-labelledby="tabHistory">
<ul id="historyList"></ul>
</section>
<section class="tab-panel queue" id="panelQueue" role="tabpanel" aria-labelledby="tabQueue" hidden>
<ul id="queueList"></ul>
</section>
</div>
</main>
<script>
// Nom de la station, modifiable ici (repris dans le logo et le titre de l'onglet).
@ -408,6 +442,24 @@
setTimeout(() => { skipBtn.disabled = false; poll(); pollHistory(); pollQueue(); }, 900);
});
// Onglets File d'attente / Historique : l'historique est affiché par
// défaut. On bascule l'état actif et la visibilité des panneaux ; les deux
// continuent d'être rafraîchis en arrière-plan, seul l'affichage change.
const tabs = [
{ btn: document.getElementById("tabHistory"), panel: document.getElementById("panelHistory") },
{ btn: document.getElementById("tabQueue"), panel: document.getElementById("panelQueue") },
];
tabs.forEach(({ btn }, i) => {
btn.addEventListener("click", () => {
tabs.forEach(({ btn: b, panel: p }, j) => {
const on = i === j;
b.classList.toggle("active", on);
b.setAttribute("aria-selected", on ? "true" : "false");
p.hidden = !on;
});
});
});
poll();
pollHistory();
pollQueue();