Blogs: Ordner verwalten und zuweisen wie überall; leere Bibliothek zeigt den Kopf mit +
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8f5be379fe
commit
d870ed6f9d
3 changed files with 58 additions and 1 deletions
|
|
@ -72,3 +72,19 @@ test('Abos & Quellen: one page for every subscription, reached from the feeds to
|
|||
await tab.locator('[data-filter="all"]').click();
|
||||
await expect(tab.locator('.src-chip.on')).toContainText('Alle');
|
||||
});
|
||||
|
||||
test('the library: a header with search, sort, layout and +, the add menu', async ({ page }) => {
|
||||
await page.setViewportSize({ width: 1200, height: 800 });
|
||||
await page.goto('/#books');
|
||||
const list = page.locator('#book-list');
|
||||
await expect(list.locator('.lib-h')).toHaveText('Bücher');
|
||||
await expect(list.locator('.lib-q')).toBeVisible();
|
||||
await expect(list.locator('.lib-sort')).toBeVisible();
|
||||
await expect(page.locator('#book-drop-zone')).toBeHidden(); // adding is behind +
|
||||
await list.locator('[data-lib="add"]').click();
|
||||
await expect(page.locator('.dfo-sheet')).toContainText('E-Book-Datei');
|
||||
await page.locator('.dfo-sheet [data-x]').click();
|
||||
await expect(page.locator('.dfo-sheet')).toHaveCount(0);
|
||||
await page.goto('/#magazines');
|
||||
await expect(list.locator('.lib-h')).toHaveText('Zeitschriften');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ async function loadBookList() {
|
|||
return;
|
||||
}
|
||||
if (!books.length) {
|
||||
// Drawn like any list: the page's header (with +) is how a first book gets in.
|
||||
if (window.__dioraLibraryV2) { renderBookList([]); return; }
|
||||
listEl.innerHTML = '<p class="muted">Noch keine Bücher. Zieh oben eine .epub- oder .pdf-Datei hinein.</p>';
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -309,7 +309,9 @@
|
|||
(sum(list, 'unread') ? ' <small>' + sum(list, 'unread') + '</small>' : '') + '</button>';
|
||||
h += '<div class="fd-chips">' + chip(null, 'Alle', visible) +
|
||||
folders.map(f => chip(f, f, inFolder(f))).join('') +
|
||||
(blogs.some(b => !(b.folders || []).length) ? chip('', 'Ohne Ordner', inFolder('')) : '') + '</div>';
|
||||
(blogs.some(b => !(b.folders || []).length) ? chip('', 'Ohne Ordner', inFolder('')) : '') +
|
||||
(window.DioraFolders ? '<button type="button" class="fd-chip" data-act="folders-manage" title="Ordner verwalten" aria-label="Ordner verwalten">⋯</button>' : '') +
|
||||
'</div>';
|
||||
}
|
||||
const main = st.blogFolder === null;
|
||||
const shown = main ? blogs : inFolder(st.blogFolder);
|
||||
|
|
@ -336,6 +338,7 @@
|
|||
(one.hidden ? 'Im Hauptfeed ausgeblendet' : 'Im Hauptfeed ausblenden') + '</button>' +
|
||||
'<button type="button" class="fd-chip' + (one.notify ? ' on' : '') + '" data-flag="notify" data-id="' + one.id + '" title="Benachrichtigung bei neuen Posts (App)">' +
|
||||
(one.notify ? '🔔 Glocke an' : '🔕 Glocke') + '</button>' +
|
||||
(window.DioraFolders ? '<button type="button" class="fd-chip" data-act="blog-folders" data-id="' + one.id + '">▤ In Ordner …</button>' : '') +
|
||||
'<button type="button" class="fd-chip" data-edit-open="' + one.id + '">⚙</button></div>';
|
||||
}
|
||||
if (!st.items.length) return h + '<p class="fd-note">' + (st.loading ? 'Lädt …' : (st.blogUnread ? 'Alles gelesen.' : 'Keine Artikel.')) + '</p>';
|
||||
|
|
@ -823,6 +826,42 @@
|
|||
try { await api('/feeds/refresh/', {}); } catch (err) {}
|
||||
return load();
|
||||
}
|
||||
// Folders the same way as everywhere (folders.js, docs/library.md).
|
||||
if (act === 'folders-manage' && window.DioraFolders) {
|
||||
const done = () => loadState().catch(() => {}).then(() => (st.view === 'blogs' ? load() : render()));
|
||||
window.DioraFolders.manage({
|
||||
title: 'Ordner der Blogs',
|
||||
folders: (st.state && st.state.folders) || [],
|
||||
onRename: (name, neu) => api('/feeds/folders/rename/', {name, new: neu}).catch(() => {}).then(() => {
|
||||
if (st.blogFolder !== null && st.blogFolder.toLowerCase() === name.toLowerCase()) st.blogFolder = neu;
|
||||
return done();
|
||||
}),
|
||||
onDelete: name => api('/feeds/folders/dissolve/', {name}).catch(() => {}).then(() => {
|
||||
if (st.blogFolder !== null && st.blogFolder.toLowerCase() === name.toLowerCase()) st.blogFolder = null;
|
||||
return done();
|
||||
}),
|
||||
onOrder: order => api('/feeds/folders/order/', {order}).then(d => {
|
||||
if (st.state && d && d.folders) st.state.folders = d.folders;
|
||||
render();
|
||||
}).catch(() => {}),
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (act === 'blog-folders' && window.DioraFolders) {
|
||||
const src = sources().find(x => x.id === parseInt(t.dataset.id, 10));
|
||||
if (!src) return;
|
||||
window.DioraFolders.assign({
|
||||
title: 'Ordner für „' + src.title + '“',
|
||||
folders: (st.state && st.state.folders) || [],
|
||||
selected: src.folders || [],
|
||||
onDone: async names => {
|
||||
await api('/feeds/sources/' + src.id + '/', {folders: names}).catch(() => {});
|
||||
await loadState().catch(() => {});
|
||||
load();
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (act === 'manage') {
|
||||
// Managing every subscription has its place (Abos & Quellen, docs/sources.md).
|
||||
const nav = window.DioraNav;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue