Podcast-Oberfläche aus diora-android 5821dfa (__dioraPlayerNow für den Bildschirmschoner); sw v101
All checks were successful
Build and push Docker image / build (push) Successful in 15s
Test / test (push) Successful in 8m21s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mrwnslz 2026-10-12 20:05:13 +02:00
parent 60dd4926cf
commit 080cdbde5a
3 changed files with 201 additions and 3 deletions

View file

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

View file

@ -1,4 +1,4 @@
// Copied from diora-android 7dcc0c6 2026-10-04: web-native/static/native-podcast.js
// Copied from diora-android 5821dfa 2026-10-12: web-native/static/native-podcast.js
// by tools/sync_podcast_ui.py. Do not edit here: change it in diora-android
// and copy again. The browser host is static/js/podcasts-web.js.
@ -4405,6 +4405,22 @@
if (epScreen && (before.episodeId !== player.episodeId || !!before.playing !== !!player.playing)) episodeScreenParts();
};
// What plays, for the screensaver (native-saver.js): the player's report and the chapter at its place.
const nowAsked = new Set();
window.__dioraPlayerNow = function () {
if (!player || player.kind !== 'podcast') return player;
const d = details.get(player.episodeId);
if (!d && player.episodeId && !nowAsked.has(player.episodeId)) {
nowAsked.add(player.episodeId);
Promise.resolve(loadDetails(player.episodeId)).catch(() => {});
}
let chapter = '';
const chapters = (d && d.chapters) || [];
const t = (player.pos || 0) / 1000;
for (const c of chapters) if ((c.start || 0) <= t + 0.5) chapter = c.title || '';
return Object.assign({}, player, {chapter: plain(chapter)});
};
// Ambient starts (app.js): an episode playing here pauses.
window.__dioraPausePlayer = function () {
if (player.kind !== 'podcast' || !player.playing || player.remote) return;

View file

@ -1,4 +1,4 @@
/* Copied from diora-android 67a915e 2026-10-03: the podcast parts of web-native/static/native.css
/* Copied from diora-android 5821dfa 2026-10-12: 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. */
@ -796,3 +796,185 @@ body.eink .nui-pod-facts a { text-decoration-color: #000; }
background: rgba(0, 0, 0, 0.55);
color: #ddd;
}
/* diora Reader (books only, native.js): no read-aloud, no cloud import. */
.nui-reader-app #reader-tts-btn,
.nui-reader-app #reader-tts-lang,
.nui-reader-app button[onclick*="toggleCloudImport"],
.nui-reader-app #cloud-browser { display: none !important; }
/* Datenverbrauch (native-ui.js showDataUsage) */
.nui-usage { padding: 4px 16px 12px; }
.nui-usage-chips { display: flex; gap: 6px; margin-bottom: 12px; }
.nui-usage-chip { padding: 6px 12px; border: 1px solid var(--border, #2a2a2a); border-radius: 16px; background: none; color: inherit; font: inherit; font-size: 13px; }
.nui-usage-chip.on { border-color: var(--accent, #e63946); color: var(--accent, #e63946); }
.nui-usage-total { display: flex; justify-content: space-between; gap: 12px; font-size: 14px; margin-bottom: 10px; }
.nui-usage-total b { color: var(--accent, #e63946); }
.nui-usage-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.nui-usage-table th { text-align: right; font-weight: 400; color: var(--nui-muted, #9a9a9a); padding: 2px 0 6px; }
.nui-usage-table td { padding: 7px 0; border-top: 1px solid var(--border, #2a2a2a); vertical-align: top; }
.nui-usage-table td + td { text-align: right; white-space: nowrap; padding-left: 10px; }
.nui-usage-bar { display: block; height: 3px; margin-top: 4px; background: #2a2a2a; border-radius: 2px; overflow: hidden; }
.nui-usage-bar > span { display: block; height: 100%; background: var(--accent, #e63946); }
.nui-usage-note { font-size: 12px; color: var(--nui-muted, #9a9a9a); margin: 10px 0 0; }
body.eink .nui-usage-bar > span { background: #000; }
body.eink .nui-usage-total b { color: #000; }
/* ---- sidebar layout (html.nui-sidebar, native-radio.js): the menu as a rail on the left,
the player bars at the bottom of the page. Always on a TV, a choice in the app menu elsewhere. ---- */
.nui-rail-brand, .nui-rail-menu { display: none; }
html.nui-sidebar { --nui-rail-w: 200px; }
html.nui-sidebar body { padding-left: var(--nui-rail-w); }
html.nui-sidebar.nui-reading body { padding-left: 0; }
html.nui-sidebar #nui-dock { left: var(--nui-rail-w); }
html.nui-sidebar #nui-tabbar {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: var(--nui-rail-w);
flex-direction: column;
padding: 18px 0 12px;
background: #0b0b0b;
border-right: 1px solid var(--border);
overflow-y: auto;
}
html.nui-sidebar #nui-tabbar button {
flex: 0 0 auto;
height: 46px;
flex-direction: row;
justify-content: flex-start;
gap: 14px;
padding: 0 22px;
font-size: 15px;
text-align: left;
}
html.nui-sidebar #nui-tabbar .nui-tab-icon { width: 22px; text-align: center; font-size: 19px; }
html.nui-sidebar #nui-tabbar button.nui-active { background: #181818; box-shadow: inset 3px 0 0 var(--accent); }
html.nui-sidebar .nui-rail-brand {
display: block;
padding: 0 22px 18px;
color: var(--accent);
font-weight: 700;
font-size: 22px;
letter-spacing: 0.08em;
}
html.nui-sidebar .nui-rail-menu { display: flex; margin-top: auto; }
/* Home's own wordmark: the rail has it already. */
html.nui-sidebar #tab-home .home-brand { display: none; }
body.eink #nui-tabbar { background: #fff; }
/* A narrow screen (a phone upright): the rail shows its signs only. */
@media (max-width: 640px) {
html.nui-sidebar { --nui-rail-w: 60px; }
html.nui-sidebar #nui-tabbar button { padding: 0; justify-content: center; font-size: 0; gap: 0; }
html.nui-sidebar #nui-tabbar .nui-tab-icon { font-size: 21px; }
html.nui-sidebar .nui-rail-brand { padding: 0 0 14px; text-align: center; font-size: 16px; letter-spacing: 0; overflow: hidden; }
}
/* ---- television (html.nui-tv, native-tv.js): a focus that the remote moves ---- */
html.nui-tv { scroll-padding: 24px 0 calc(var(--nui-dock-h, 0px) + 24px); }
html.nui-tv .nui-tv-focus {
outline: 3px solid var(--accent) !important;
outline-offset: 2px;
border-radius: 6px;
}
html.nui-tv #nui-tabbar button.nui-tv-focus { outline-offset: -3px; background: #222; }
html.nui-tv :focus:not(.nui-tv-focus) { outline: none; }
/* Books and feeds hidden on the TV (unless switched on in the app menu); Home's
sections of them: native-tv.js (:has, which the e-readers' old WebView lacks). */
html.nui-noread #nui-tabbar button[data-tab="books"],
html.nui-noread #nui-tabbar button[data-tab="feeds"] { display: none; }
/* ---- screensaver (native-saver.js): what plays, large, drifting slowly ---- */
#nui-saver {
position: fixed;
inset: 0;
z-index: 3000;
display: none;
overflow: hidden;
background: #000;
color: #fff;
cursor: none;
}
#nui-saver.nui-on { display: block; animation: nui-saver-in 1.2s ease-out; }
@keyframes nui-saver-in { from { opacity: 0; } to { opacity: 1; } }
.nui-saver-bg {
position: absolute;
inset: -10%;
background: center / cover no-repeat;
filter: blur(60px) brightness(0.32) saturate(1.3);
}
.nui-saver-stage {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
gap: 5vw;
padding: 8vh 10vw;
transition: transform 44s ease-in-out;
}
.nui-saver-art {
flex: 0 0 auto;
width: 34vmin;
height: 34vmin;
border-radius: 3vmin;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
background: #161616;
box-shadow: 0 2vmin 8vmin rgba(0, 0, 0, 0.6);
}
.nui-saver-art img { width: 100%; height: 100%; object-fit: cover; }
.nui-saver-art span { font-size: 16vmin; color: var(--accent); line-height: 1; }
.nui-saver-text { flex: 0 1 52vw; min-width: 0; display: flex; flex-direction: column; gap: 1.6vmin; }
.nui-saver-kicker, .nui-saver-sub, .nui-saver-chapter, .nui-saver-left { font-family: var(--nui-sans); letter-spacing: normal; }
.nui-saver-kicker { color: var(--accent); font-size: 2.6vmin; font-weight: 600; text-transform: uppercase; }
.nui-saver-title {
font-size: 5.4vmin;
font-weight: 700;
line-height: 1.2;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.nui-saver-sub { font-size: 3.4vmin; color: #ddd; line-height: 1.3; }
.nui-saver-chapter { font-size: 3vmin; color: var(--accent); }
.nui-saver-progress { height: 0.6vmin; border-radius: 1vmin; background: rgba(255, 255, 255, 0.18); overflow: hidden; margin-top: 1vmin; }
.nui-saver-progress span { display: block; height: 100%; background: var(--accent); transition: width 4s linear; }
.nui-saver-left { font-size: 2.6vmin; color: #bbb; }
#nui-saver [hidden] { display: none; }
.nui-saver-clock {
position: absolute;
right: 5vw;
bottom: 6vh;
font-size: 7vmin;
font-weight: 200;
color: rgba(255, 255, 255, 0.75);
font-variant-numeric: tabular-nums;
transition: transform 44s ease-in-out;
}
/* Ambient: its own picture full screen; the saver only adds the clock and the sound world. */
html.nui-saver-ambient #tab-ambient { display: block !important; }
html.nui-saver-ambient #ambient-frame {
position: fixed !important;
inset: 0;
width: 100vw !important;
height: 100vh !important;
z-index: 2999;
border: 0;
}
html.nui-saver-ambient #nui-saver { background: transparent; }
html.nui-saver-ambient .nui-saver-bg,
html.nui-saver-ambient .nui-saver-art,
html.nui-saver-ambient .nui-saver-progress,
html.nui-saver-ambient .nui-saver-left { display: none; }
html.nui-saver-ambient .nui-saver-stage { align-items: flex-start; justify-content: flex-start; }
html.nui-saver-ambient .nui-saver-title { font-size: 3.4vmin; font-weight: 300; letter-spacing: 0.1em; }