diff --git a/static/js/feeds.js b/static/js/feeds.js index 6780b41..431f322 100644 --- a/static/js/feeds.js +++ b/static/js/feeds.js @@ -1047,22 +1047,33 @@ if (e.key === 'Escape' && readerOpen()) closeReader(); }); - // diora Reader has no tab bar of its own: a small one for books and feeds. + // diora Reader has no tab bar of its own: a small one. With the navigation (nav.js) it + // holds the sections of Lesen itself — a row of them to swipe is no good on e-ink. if (READER_APP && !document.getElementById('nui-tabbar')) { + const NAV = window.DioraNav; const dock = document.createElement('div'); dock.id = 'nui-dock'; - dock.innerHTML = ''; + dock.innerHTML = ''; document.body.appendChild(dock); - const mark = () => dock.querySelectorAll('button').forEach(b => - b.classList.toggle('nui-active', typeof _currentTopTab !== 'undefined' && b.dataset.tab === _currentTopTab)); + const mark = () => dock.querySelectorAll('button').forEach(b => b.classList.toggle('nui-active', NAV + ? b.dataset.nav === NAV.current() + : typeof _currentTopTab !== 'undefined' && b.dataset.tab === _currentTopTab)); dock.addEventListener('click', e => { const b = e.target.closest('button'); if (!b) return; - showTab(b.dataset.tab); + if (NAV) NAV.go(b.dataset.nav); + else showTab(b.dataset.tab); window.scrollTo(0, 0); }); + if (NAV) { + document.documentElement.classList.add('nav-flat'); // every section in the bar: no row on top + NAV.onChange(mark); + NAV.barsReady(); + } const orig = window.showTab; window.showTab = function (name) { orig.apply(this, arguments); diff --git a/static/js/nav.js b/static/js/nav.js index d37733a..6918fa1 100644 --- a/static/js/nav.js +++ b/static/js/nav.js @@ -200,7 +200,9 @@ } if (segs) { const g = cur ? gs.filter(x => x.id === cur.group)[0] : null; - const show = !!g && g.sections.length > 1 && html.classList.contains('nav-bars'); + // Not where the bar has every section already (the sidebar, diora Reader's bar). + const show = !!g && g.sections.length > 1 && html.classList.contains('nav-bars') && + !html.classList.contains('nav-flat') && !html.classList.contains('nui-sidebar'); segs.hidden = !show; segs.innerHTML = show ? g.sections.map(id => button(id, byId[id].label, 'nav-seg', current === id)).join('') : ''; } @@ -217,7 +219,7 @@ first.parentNode.insertBefore(segs, first); segs.addEventListener('click', onClick); } - if (tabs && !nativeUi()) { + if (tabs && !nativeUi() && !readerApp()) { // diora Reader brings its own (feeds.js) html.classList.add('nav-bars'); // the page's own bar knows the sections tabs.addEventListener('click', onClick); } @@ -265,7 +267,7 @@ // Wide web page: every section is in the bar, the row would repeat it. '@media (min-width: 721px) { html:not(.nui-radio) #nav-segments { display: none; } }', // The sidebar (apps, wide): the sections are in it. - 'html.nui-sidebar #nav-segments { display: none; }', + 'html.nui-sidebar #nav-segments, html.nav-flat #nav-segments { display: none; }', ].join('\n'); document.head.appendChild(style); })(); diff --git a/static/js/sw.js b/static/js/sw.js index ea59ca9..98d1f66 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-v115'; +const CACHE = 'diora-v116'; const SHELL = [ '/static/css/app.css', '/static/js/app/01-core.js', diff --git a/static/podcasts/native-podcast.js b/static/podcasts/native-podcast.js index 64ddadf..0dda5ff 100644 --- a/static/podcasts/native-podcast.js +++ b/static/podcasts/native-podcast.js @@ -1,4 +1,4 @@ -// Copied from diora-android 7b1d500 2026-10-16: web-native/static/native-podcast.js +// Copied from diora-android 26f5019 2026-10-16: 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. @@ -42,6 +42,9 @@ {id: 'queue', label: 'Podcasts: Warteschlange'}, {id: 'inbox', label: 'Podcasts: Neu'}, {id: 'radio', label: 'Radio'}, + // Sections of the page's navigation (nav.js), where the page has them. + window.DioraNav && DioraNav.sections().some(s => s.id === 'audiobooks') && {id: 'audiobooks', label: 'Hörbücher'}, + window.DioraNav && DioraNav.sections().some(s => s.id === 'news') && {id: 'news', label: 'Nachrichten'}, ].filter(Boolean); function startPage() { let v = null; @@ -2877,9 +2880,10 @@ // One player for podcasts and radio: the radio's own bar steps aside. document.documentElement.classList.add('nui-one-player'); - // A "Podcasts" button in the bottom bar, between books and radio. + // A "Podcasts" button in the bottom bar, between books and radio (with the page's + // navigation, nav.js, the bar has the podcasts as a section already). const tabbar = $id('nui-tabbar'); - if (tabbar && !tabbar.querySelector('[data-tab="podcasts"]')) { + if (tabbar && !window.DioraNav && !tabbar.querySelector('[data-tab="podcasts"]')) { const b = el('button'); b.type = 'button'; b.dataset.tab = 'podcasts'; diff --git a/static/podcasts/podcast-ui.css b/static/podcasts/podcast-ui.css index fd2cd1c..dede26a 100644 --- a/static/podcasts/podcast-ui.css +++ b/static/podcasts/podcast-ui.css @@ -1,4 +1,4 @@ -/* Copied from diora-android 7b1d500 2026-10-16: the podcast parts of web-native/static/native.css +/* Copied from diora-android 26f5019 2026-10-16: 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. */