Bücher: "Zuletzt gelesen" wieder als normale Listenansicht statt Karten-Leiste (SW v40)
Bleibt an der gleichen Stelle (fest oben, unabhängig von Ordner-Navigation und Lesefilter), nutzt jetzt aber dieselben Listeneinträge wie der Rest der Ansicht (inkl. Drei-Punkte-Menü) statt der horizontal scrollbaren Karten. Da ein Buch dadurch gleichzeitig oben bei "Zuletzt gelesen" und unten in der Ordner-/Gesamtliste gerendert werden kann, darf das Drei-Punkte-Menü nicht mehr über eine (dann doppelt vergebene) id gesucht werden — toggleBookMenu bekommt jetzt den geklickten Button und findet sein Menü relativ dazu im DOM. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011j4LcoeddwFt6Rw8Wyaknj
This commit is contained in:
parent
635fd7ef1c
commit
0de6c186fb
3 changed files with 22 additions and 51 deletions
|
|
@ -1658,50 +1658,21 @@ body.dnd-mode .timer-display {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Recently-read shelf (always pinned atop the books view) --- */
|
/* --- Recently-read section (always pinned atop the books view, plain list style) --- */
|
||||||
.book-recent-shelf {
|
.book-recent-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
|
padding-bottom: 14px;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
.book-recent-title {
|
.book-recent-title {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin: 0 0 6px;
|
margin: 0;
|
||||||
color: var(--muted, #888);
|
color: var(--muted, #888);
|
||||||
}
|
}
|
||||||
.book-recent-row {
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
overflow-x: auto;
|
|
||||||
padding-bottom: 2px;
|
|
||||||
}
|
|
||||||
.book-recent-item {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 2px;
|
|
||||||
max-width: 160px;
|
|
||||||
padding: 8px 10px;
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: var(--radius);
|
|
||||||
background: none;
|
|
||||||
color: var(--fg);
|
|
||||||
text-align: left;
|
|
||||||
cursor: pointer;
|
|
||||||
font: inherit;
|
|
||||||
}
|
|
||||||
.book-recent-item-title {
|
|
||||||
font-size: 13px;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
.book-recent-item-author {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--muted, #888);
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Book folders (single level) --- */
|
/* --- Book folders (single level) --- */
|
||||||
.book-folder-grid {
|
.book-folder-grid {
|
||||||
|
|
|
||||||
|
|
@ -3461,8 +3461,8 @@ function _renderBookItemHtml(b) {
|
||||||
<div class="book-item-actions">
|
<div class="book-item-actions">
|
||||||
<button class="btn btn-sm" onclick="openBook(${b.id})"${b.keyOk === false ? ' disabled title="Import the correct encryption key first"' : ''}>Open</button>
|
<button class="btn btn-sm" onclick="openBook(${b.id})"${b.keyOk === false ? ' disabled title="Import the correct encryption key first"' : ''}>Open</button>
|
||||||
<div class="book-item-menu">
|
<div class="book-item-menu">
|
||||||
<button class="btn btn-sm book-menu-toggle" title="Weitere Optionen" onclick="toggleBookMenu(${b.id})">⋮</button>
|
<button class="btn btn-sm book-menu-toggle" title="Weitere Optionen" onclick="toggleBookMenu(this)">⋮</button>
|
||||||
<div class="book-item-menu-list" id="book-menu-${b.id}">
|
<div class="book-item-menu-list">
|
||||||
${broken ? `<button class="book-menu-item book-menu-item--danger book-broken-btn" onclick="repairBook(${b.id})">🔧 Reparieren (Datei erneut hochladen)</button>` : ''}
|
${broken ? `<button class="book-menu-item book-menu-item--danger book-broken-btn" onclick="repairBook(${b.id})">🔧 Reparieren (Datei erneut hochladen)</button>` : ''}
|
||||||
${b.has_highlights ? `<button class="book-menu-item" onclick="downloadBookAnnotationsFromList(${b.id}, this)">⭳ Markierungen & Notizen herunterladen</button>` : ''}
|
${b.has_highlights ? `<button class="book-menu-item" onclick="downloadBookAnnotationsFromList(${b.id}, this)">⭳ Markierungen & Notizen herunterladen</button>` : ''}
|
||||||
<button class="book-menu-item" onclick="assignBookFolder(${b.id})">📁 Ordner zuweisen</button>
|
<button class="book-menu-item" onclick="assignBookFolder(${b.id})">📁 Ordner zuweisen</button>
|
||||||
|
|
@ -3475,8 +3475,11 @@ function _renderBookItemHtml(b) {
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleBookMenu(bookId) {
|
function toggleBookMenu(toggleBtn) {
|
||||||
const menu = document.getElementById(`book-menu-${bookId}`);
|
// Looked up relative to the clicked button (not by id) because the same book — and
|
||||||
|
// thus the same rendered menu — can appear twice at once: once in the "Zuletzt
|
||||||
|
// gelesen" section and again further down in the folder/unfiled list.
|
||||||
|
const menu = toggleBtn.closest('.book-item-menu')?.querySelector('.book-item-menu-list');
|
||||||
if (!menu) return;
|
if (!menu) return;
|
||||||
const willOpen = !menu.classList.contains('open');
|
const willOpen = !menu.classList.contains('open');
|
||||||
document.querySelectorAll('.book-item-menu-list.open').forEach(m => m.classList.remove('open'));
|
document.querySelectorAll('.book-item-menu-list.open').forEach(m => m.classList.remove('open'));
|
||||||
|
|
@ -3507,18 +3510,15 @@ function renderBookList(books) {
|
||||||
|
|
||||||
let html = '';
|
let html = '';
|
||||||
|
|
||||||
// Always-visible "recently read" shelf, independent of folder navigation and the
|
// Always-visible "recently read" section, independent of folder navigation and the
|
||||||
// read/unread filter below — it's a shortcut back into whatever was open last.
|
// read/unread filter below — it's a shortcut back into whatever was open last. Same
|
||||||
|
// vertical list-item look as the rest of the list (not a card shelf).
|
||||||
const recent = _recentlyReadBooks(books);
|
const recent = _recentlyReadBooks(books);
|
||||||
if (recent.length) {
|
if (recent.length) {
|
||||||
html += '<div class="book-recent-shelf">'
|
html += '<div class="book-recent-section">'
|
||||||
+ '<h3 class="book-recent-title">Zuletzt gelesen</h3>'
|
+ '<h3 class="book-recent-title">Zuletzt gelesen</h3>'
|
||||||
+ '<div class="book-recent-row">'
|
+ recent.map(_renderBookItemHtml).join('')
|
||||||
+ recent.map(b => `<button class="book-recent-item" onclick="openBook(${b.id})" title="${escapeHtml(b.title)}">
|
+ '</div>';
|
||||||
<span class="book-recent-item-title">${escapeHtml(b.title)}</span>
|
|
||||||
${b.author ? `<span class="book-recent-item-author">${escapeHtml(b.author)}</span>` : ''}
|
|
||||||
</button>`).join('')
|
|
||||||
+ '</div></div>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const visible = _bookShowRead ? books : books.filter(b => !b.is_read);
|
const visible = _bookShowRead ? books : books.filter(b => !b.is_read);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* diora service worker — caches the app shell for offline use.
|
* diora service worker — caches the app shell for offline use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const CACHE = 'diora-v39';
|
const CACHE = 'diora-v40';
|
||||||
const PODCAST_CACHE = 'diora-podcast-v1';
|
const PODCAST_CACHE = 'diora-podcast-v1';
|
||||||
const SHELL = [
|
const SHELL = [
|
||||||
'/static/css/app.css',
|
'/static/css/app.css',
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue