From 7c87343e66f58fad0d8869850b961e94ed48dc51 Mon Sep 17 00:00:00 2001 From: mrwnslz Date: Fri, 2 Oct 2026 13:12:59 +0200 Subject: [PATCH] =?UTF-8?q?Web:=20ein=20Player=20f=C3=BCr=20Radio=20und=20?= =?UTF-8?q?Podcasts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Podcast-Leiste und der Vollbild-Player zeigen auch den Sender (Logo, „● Live“, Stopp behält den Sender, speichern, Sleep-Timer, Sender wechseln); die Radio-Leiste behält nur Lautstärke, Votes, Fokusmodus und Timer. Podcast-Oberfläche aus diora-android e6761d0, sw v55. Co-Authored-By: Claude Opus 5.5 --- static/js/podcasts-web.js | 54 +++++++++++++++++++++++++++++++- static/js/sw.js | 2 +- static/podcasts/podcast-ui.css | 3 +- static/podcasts/podcasts-web.css | 5 +++ 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/static/js/podcasts-web.js b/static/js/podcasts-web.js index 491ce27..075b08c 100644 --- a/static/js/podcasts-web.js +++ b/static/js/podcasts-web.js @@ -791,10 +791,62 @@ const playStation = window.playStation; window.playStation = function () { putAway(); - return playStation.apply(this, arguments); + const r = playStation.apply(this, arguments); + radioChanged(); + return r; }; } + // ---- the radio in the same player (in the app native-radio.js does this) ---------- + // The podcast page's bar and full player show the station too; app.js keeps + // playing it, its own bar keeps only volume, votes, focus mode and timer. + + function radioChanged() { + if (window.__dioraRadioChanged) window.__dioraRadioChanged(); + } + + function radioSaved(url) { + return [...document.querySelectorAll('#saved-tbody tr[data-url]')].some(r => r.dataset.url === url); + } + + function radioLogo(st) { + const all = [].concat(typeof INITIAL_SAVED !== 'undefined' ? INITIAL_SAVED : [], + typeof INITIAL_FEATURED !== 'undefined' ? INITIAL_FEATURED : []); + const s = all.find(x => x && x.url === st.url); + return (s && s.favicon_url) || ''; + } + + const radioPlaying = () => typeof isPlaying !== 'undefined' && !!isPlaying; + + window.__dioraRadioNow = function () { + const st = typeof currentStation !== 'undefined' ? currentStation : null; + if (!st) return null; + return { + name: st.name || '', + logo: radioLogo(st), + track: typeof currentTrack !== 'undefined' ? currentTrack : '', + playing: radioPlaying(), + buffering: false, + saved: radioSaved(st.url), + }; + }; + // Stop keeps the station (like a paused episode): the bar stays with ▶. + window.__dioraRadioToggle = () => (radioPlaying() ? stopPlayback(false) : togglePlayStop()); + window.__dioraRadioSave = () => saveCurrentStation(); + + for (const name of ['stopPlayback', 'updateNowPlayingUI', 'saveCurrentStation']) { + const fn = window[name]; + if (typeof fn !== 'function') continue; + window[name] = function () { + const r = fn.apply(this, arguments); + if (r && typeof r.then === 'function') r.then(radioChanged, radioChanged); + else radioChanged(); + return r; + }; + } + const savedRows = document.getElementById('saved-tbody'); + if (savedRows) new MutationObserver(radioChanged).observe(savedRows, {childList: true}); + // ---- what the page and the lock screen see --------------------------------------------- const decoder = document.createElement('textarea'); diff --git a/static/js/sw.js b/static/js/sw.js index 94ffcac..0f42750 100644 --- a/static/js/sw.js +++ b/static/js/sw.js @@ -2,7 +2,7 @@ * diora service worker — caches the app shell for offline use. */ -const CACHE = 'diora-v54'; +const CACHE = 'diora-v55'; const SHELL = [ '/static/css/app.css', '/static/js/app.js', diff --git a/static/podcasts/podcast-ui.css b/static/podcasts/podcast-ui.css index b3367d6..57ae8df 100644 --- a/static/podcasts/podcast-ui.css +++ b/static/podcasts/podcast-ui.css @@ -1,4 +1,4 @@ -/* Copied from diora-android 6c2b071 2026-10-02: the podcast parts of web-native/static/native.css +/* Copied from diora-android e6761d0 2026-10-02: the podcast parts of web-native/static/native.css (bottom sheet, podcasts) by tools/sync_podcast_ui.py. Do not edit here. The web's own additions are in podcasts-web.css. */ @@ -291,6 +291,7 @@ html.nui-radio.nui-pod-mini-open body { border-bottom: 1px solid var(--border); } #nui-pod-mini[hidden] { display: none; } +#nui-pod-mini [hidden] { display: none !important; } .nui-pod-mini-bar { position: absolute; left: 0; right: 0; top: -1px; height: 2px; background: #2a2a2a; } .nui-pod-mini-bar span { display: block; height: 100%; background: var(--accent); } .nui-pod-skip { font-size: 20px; } diff --git a/static/podcasts/podcasts-web.css b/static/podcasts/podcasts-web.css index de7c0cc..612a73f 100644 --- a/static/podcasts/podcasts-web.css +++ b/static/podcasts/podcasts-web.css @@ -55,6 +55,11 @@ html.dpw #nui-dock { margin: 0 auto; } 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. */ +html.dpw.nui-one-player #now-playing-bar .now-playing-info, +html.dpw.nui-one-player #play-stop-btn, +html.dpw.nui-one-player #save-station-btn { display: none !important; } html.dpw #nui-pod-mini { background: var(--dpw-surface); border: 1px solid var(--border);