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. */