Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
8662f381ed
1 changed files with 14 additions and 4 deletions
|
|
@ -2019,6 +2019,8 @@ let readerScrollSaveTimer = null;
|
||||||
let _resizeObserver = null;
|
let _resizeObserver = null;
|
||||||
let _currentPositionAnchor = '';
|
let _currentPositionAnchor = '';
|
||||||
let _currentBookCharCount = 0;
|
let _currentBookCharCount = 0;
|
||||||
|
// Rough characters per printed book page, used to estimate a real page count for EPUBs.
|
||||||
|
const CHARS_PER_BOOK_PAGE = 1800;
|
||||||
const bookMetaCache = {}; // id → {title, author, type}
|
const bookMetaCache = {}; // id → {title, author, type}
|
||||||
|
|
||||||
// Reading-position percentages (the progress readout, annotation "% im Buch"
|
// Reading-position percentages (the progress readout, annotation "% im Buch"
|
||||||
|
|
@ -2608,8 +2610,8 @@ async function loadBookList() {
|
||||||
try {
|
try {
|
||||||
const metaBuf = await decryptBytes(key, b.meta_iv, b.meta_ct);
|
const metaBuf = await decryptBytes(key, b.meta_iv, b.meta_ct);
|
||||||
const meta = JSON.parse(new TextDecoder().decode(metaBuf));
|
const meta = JSON.parse(new TextDecoder().decode(metaBuf));
|
||||||
bookMetaCache[b.id] = {title: meta.title || '?', author: meta.author || '', type: meta.type || 'epub', filename: meta.filename || '', folder: meta.folder || '', isbn: meta.isbn || '', shelfTag: meta.shelfTag || ''};
|
bookMetaCache[b.id] = {title: meta.title || '?', author: meta.author || '', type: meta.type || 'epub', filename: meta.filename || '', folder: meta.folder || '', isbn: meta.isbn || '', shelfTag: meta.shelfTag || '', pages: meta.pages || 0};
|
||||||
decrypted.push({id: b.id, title: meta.title || '?', author: meta.author || '', type: meta.type || 'epub', folder: meta.folder || '', isbn: meta.isbn || '', shelfTag: meta.shelfTag || '', scroll_fraction: b.scroll_fraction, position_anchor: b.position_anchor || '', uploaded_at: b.uploaded_at, last_read: b.last_read || null, keyOk: true, is_read: !!b.is_read, has_highlights: !!b.has_highlights});
|
decrypted.push({id: b.id, title: meta.title || '?', author: meta.author || '', type: meta.type || 'epub', folder: meta.folder || '', isbn: meta.isbn || '', shelfTag: meta.shelfTag || '', pages: meta.pages || 0, scroll_fraction: b.scroll_fraction, position_anchor: b.position_anchor || '', uploaded_at: b.uploaded_at, last_read: b.last_read || null, keyOk: true, is_read: !!b.is_read, has_highlights: !!b.has_highlights});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
bookMetaCache[b.id] = {title: `Buch #${b.id}`, author: '', type: 'epub', filename: '', folder: '', isbn: '', shelfTag: ''};
|
bookMetaCache[b.id] = {title: `Buch #${b.id}`, author: '', type: 'epub', filename: '', folder: '', isbn: '', shelfTag: ''};
|
||||||
decrypted.push({id: b.id, title: `Buch #${b.id}`, author: '', type: 'epub', folder: '', isbn: '', shelfTag: '', scroll_fraction: b.scroll_fraction, position_anchor: b.position_anchor || '', uploaded_at: b.uploaded_at, last_read: b.last_read || null, keyOk: false, is_read: !!b.is_read, has_highlights: !!b.has_highlights});
|
decrypted.push({id: b.id, title: `Buch #${b.id}`, author: '', type: 'epub', folder: '', isbn: '', shelfTag: '', scroll_fraction: b.scroll_fraction, position_anchor: b.position_anchor || '', uploaded_at: b.uploaded_at, last_read: b.last_read || null, keyOk: false, is_read: !!b.is_read, has_highlights: !!b.has_highlights});
|
||||||
|
|
@ -2651,7 +2653,7 @@ async function loadBookList() {
|
||||||
if (b.last_read) return 1;
|
if (b.last_read) return 1;
|
||||||
return (b.uploaded_at || '').localeCompare(a.uploaded_at || '');
|
return (b.uploaded_at || '').localeCompare(a.uploaded_at || '');
|
||||||
});
|
});
|
||||||
for (const b of cachedBooks) bookMetaCache[b.id] = {title: b.title, author: b.author, type: b.type || 'epub', filename: b.filename || '', folder: b.folder || '', isbn: b.isbn || '', shelfTag: b.shelfTag || ''};
|
for (const b of cachedBooks) bookMetaCache[b.id] = {title: b.title, author: b.author, type: b.type || 'epub', filename: b.filename || '', folder: b.folder || '', isbn: b.isbn || '', shelfTag: b.shelfTag || '', pages: b.pages || 0};
|
||||||
const uploadArea = $('book-upload-area');
|
const uploadArea = $('book-upload-area');
|
||||||
if (uploadArea) uploadArea.style.display = 'none';
|
if (uploadArea) uploadArea.style.display = 'none';
|
||||||
renderBookList(cachedBooks);
|
renderBookList(cachedBooks);
|
||||||
|
|
@ -2813,7 +2815,7 @@ function _renderBookItemHtml(b) {
|
||||||
<strong class="book-title">${escapeHtml(b.title)}${keyWarning}${b.is_read ? ' <span class="muted book-read-badge">✓ gelesen</span>' : ''}</strong>
|
<strong class="book-title">${escapeHtml(b.title)}${keyWarning}${b.is_read ? ' <span class="muted book-read-badge">✓ gelesen</span>' : ''}</strong>
|
||||||
<span class="muted book-author">${escapeHtml(b.author)}</span>
|
<span class="muted book-author">${escapeHtml(b.author)}</span>
|
||||||
<span class="book-item-meta-row">
|
<span class="book-item-meta-row">
|
||||||
${pct > 0 ? `<span class="muted book-progress">${pct} % gelesen</span>` : ''}
|
${pct > 0 ? `<span class="muted book-progress">${pct} % gelesen${b.pages ? ` (≈ ${Math.max(1, Math.round(b.pages * pct / 100))} von ${b.pages} Seiten)` : ''}</span>` : (b.pages ? `<span class="muted book-progress">ca. ${b.pages} Seiten</span>` : '')}
|
||||||
${b.shelfTag ? `<span class="book-shelf-badge" title="Regal-Kategorie">${escapeHtml(b.shelfTag)}</span>` : ''}
|
${b.shelfTag ? `<span class="book-shelf-badge" title="Regal-Kategorie">${escapeHtml(b.shelfTag)}</span>` : ''}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2940,6 +2942,7 @@ async function _updateBookMeta(bookId, overrides) {
|
||||||
isbn: cached.isbn || book.isbn || '',
|
isbn: cached.isbn || book.isbn || '',
|
||||||
folder: cached.folder || book.folder || '',
|
folder: cached.folder || book.folder || '',
|
||||||
shelfTag: cached.shelfTag || book.shelfTag || '',
|
shelfTag: cached.shelfTag || book.shelfTag || '',
|
||||||
|
pages: cached.pages || book.pages || 0,
|
||||||
...overrides,
|
...overrides,
|
||||||
};
|
};
|
||||||
const key = await getOrCreateEncKey();
|
const key = await getOrCreateEncKey();
|
||||||
|
|
@ -3889,6 +3892,13 @@ async function _openBookOnce(bookId) {
|
||||||
|
|
||||||
currentBookId = bookId;
|
currentBookId = bookId;
|
||||||
|
|
||||||
|
// Remember the book's real (PDF) or estimated (EPUB) page count in its encrypted meta so
|
||||||
|
// the book list can show it; rewritten only when it changed.
|
||||||
|
const bookPages = isPdfBook ? numPages : Math.max(1, Math.round(_currentBookCharCount / CHARS_PER_BOOK_PAGE));
|
||||||
|
if (bookPages > 0 && cachedMeta.pages !== bookPages) {
|
||||||
|
_updateBookMeta(bookId, {pages: bookPages}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
// Load bookmarks and highlights
|
// Load bookmarks and highlights
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
loadBookmarks(bookId),
|
loadBookmarks(bookId),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue