Web: Player und Radio-Leiste sind eine Leiste unten
All checks were successful
Build and push Docker image / build (push) Successful in 16s
Test / test (push) Successful in 5m23s

Die Player-Leiste sitzt in der Radio-Leiste an der Stelle von „läuft
gerade“: am Desktop eine Zeile (Player, Lautstärke, Fokusmodus, Timer),
am Handy zwei; die Fortschritts- bzw. Live-Linie läuft über die ganze
Leiste. Der Fokusmodus zeigt den Sender weiter groß. sw v56.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mrwnslz 2026-10-02 14:18:09 +02:00
parent 1533497409
commit cd0547c2f0
3 changed files with 55 additions and 10 deletions

View file

@ -1063,13 +1063,20 @@
document.head.appendChild(link); document.head.appendChild(link);
} }
// The bottom dock the page puts its mini player in (native-radio.js builds it in the app). // The dock the page puts its player bar in (native-radio.js builds it in the app):
// here it is part of the radio bar at the bottom, in place of its "now playing",
// so radio and podcasts share one bar.
const dock = document.createElement('div'); const dock = document.createElement('div');
dock.id = 'nui-dock'; dock.id = 'nui-dock';
document.body.appendChild(dock);
// The dock sits right above the radio bar, whose height changes with the screen.
const bar = document.getElementById('now-playing-bar'); const bar = document.getElementById('now-playing-bar');
if (bar) {
bar.insertBefore(dock, bar.firstChild);
document.documentElement.classList.add('dpw-in-bar');
} else {
document.body.appendChild(dock);
}
// The page keeps clear of the bar, whose height changes with the screen.
const placeDock = () => { const placeDock = () => {
const h = bar ? bar.getBoundingClientRect().height : 0; const h = bar ? bar.getBoundingClientRect().height : 0;
document.documentElement.style.setProperty('--dpw-bar-h', Math.round(h) + 'px'); document.documentElement.style.setProperty('--dpw-bar-h', Math.round(h) + 'px');

View file

@ -2,7 +2,7 @@
* diora service worker — caches the app shell for offline use. * diora service worker — caches the app shell for offline use.
*/ */
const CACHE = 'diora-v55'; const CACHE = 'diora-v56';
const SHELL = [ const SHELL = [
'/static/css/app.css', '/static/css/app.css',
'/static/js/app.js', '/static/js/app.js',

View file

@ -55,11 +55,49 @@ html.dpw #nui-dock {
margin: 0 auto; margin: 0 auto;
} }
html.dpw body.dnd-mode #nui-dock { display: none; } html.dpw body.dnd-mode #nui-dock { display: none; }
/* One player for both: what plays (and play / stop / save) is in the bar
above; the radio bar keeps volume, votes, focus mode and the timer. */ /* One bar for both: the player (podcast or station, with play / stop / save)
html.dpw.nui-one-player #now-playing-bar .now-playing-info, sits in the radio bar in place of its "now playing"; volume, votes, focus
html.dpw.nui-one-player #play-stop-btn, mode and the timer stay on the right. Focus mode shows the station big as
html.dpw.nui-one-player #save-station-btn { display: none !important; } before. */
html.dpw.nui-one-player body:not(.dnd-mode) #now-playing-bar .now-playing-info,
html.dpw.nui-one-player body:not(.dnd-mode) #play-stop-btn,
html.dpw.nui-one-player body:not(.dnd-mode) #save-station-btn { display: none !important; }
html.dpw.dpw-in-bar #now-playing-bar > #nui-dock {
position: static;
flex: 1;
min-width: 0;
max-width: none;
margin: 0 0 0 -1.5rem; /* the cover starts at the edge, like the bar's line */
align-self: stretch;
z-index: auto;
}
html.dpw.dpw-in-bar #now-playing-bar #nui-pod-mini {
height: 100%;
min-height: 56px;
background: none;
border: none;
border-radius: 0;
box-shadow: none;
overflow: visible;
}
/* The progress (or live) line runs along the whole bar's top edge. */
html.dpw.dpw-in-bar #now-playing-bar #nui-pod-mini { position: static; }
html.dpw.dpw-in-bar #now-playing-bar .nui-pod-mini-bar { top: -1px; }
html.dpw.dpw-in-bar #now-playing-bar .nui-pod-art-mini { width: 40px; height: 40px; margin-left: 1.5rem; }
html.dpw.dpw-in-bar.nui-pod-mini-open .main-content {
padding-bottom: calc(var(--dpw-bar-h, 72px) + 2rem);
}
@media (max-width: 600px) {
/* The bar is two rows on phones: the player, then the radio's tools. */
html.dpw.dpw-in-bar #now-playing-bar > #nui-dock { width: 100%; margin: -0.5rem 0 0; flex: none; }
html.dpw.dpw-in-bar #now-playing-bar .nui-pod-art-mini { margin-left: 0; }
html.dpw.dpw-in-bar #now-playing-bar #nui-pod-mini { min-height: 52px; }
/* Below the player one row: focus mode and stations left, the timer right. */
html.dpw.dpw-in-bar body:not(.dnd-mode) #now-playing-bar { flex-direction: row; flex-wrap: wrap; row-gap: 0.25rem; }
html.dpw.dpw-in-bar body:not(.dnd-mode) #now-playing-bar .now-playing-controls { width: auto; flex: none; gap: 0.5rem; }
html.dpw.dpw-in-bar body:not(.dnd-mode) #now-playing-bar .timer-widget { margin-left: auto; }
}
html.dpw #nui-pod-mini { html.dpw #nui-pod-mini {
background: var(--dpw-surface); background: var(--dpw-surface);
border: 1px solid var(--border); border: 1px solid var(--border);