'use strict'; // --------------------------------------------------------------------------- // "Eingang" (docs/library.md): a cloud source marked so brings its new books into the // library by itself. When the library loads, the server says which files of such sources // no device has taken yet (and keeps them for this device ten minutes); each is fetched // through the server, encrypted here like any import, uploaded, and reported done. A book // already in the library (same title and author) is left out. The folder stays as it is. // Only where the book key is there; not in diora Reader (e-readers: battery, weak Wi-Fi). // --------------------------------------------------------------------------- const CLOUD_INBOX_EVERY_MS = 5 * 60 * 1000; let _cloudInboxBusy = false; let _cloudInboxLast = 0; function _cloudInboxKeyReady() { // getOrCreateEncKey() would make a new key when there is none: never import without the real one. try { return !!localStorage.getItem(`diora_enc_key_${window.USER_ID || 0}`); } catch (e) { return false; } } async function cloudInboxCheck(force) { if (typeof IS_AUTHENTICATED === 'undefined' || !IS_AUTHENTICATED) return; if (document.documentElement.classList.contains('nui-reader-app')) return; if (_cloudInboxBusy || !_cloudInboxKeyReady()) return; if (!force && Date.now() - _cloudInboxLast < CLOUD_INBOX_EVERY_MS) return; _cloudInboxBusy = true; _cloudInboxLast = Date.now(); const statusEl = $('book-upload-status'); const taken = []; try { const r = await fetch('/books/cloud/inbox/', {cache: 'no-store'}); if (!r.ok) return; const files = (await r.json()).files || []; for (let i = 0; i < files.length; i++) { const f = files[i]; if (statusEl) statusEl.textContent = `Eingang „${f.label}“: ${i + 1} von ${files.length} – ${f.name} …`; let result = 'failed'; try { if (f.size > DIORA_CONFIG.ebookMaxBytes) { result = 'too_big'; } else { const res = await fetch(`/books/cloud/${f.source}/fetch/?path=${encodeURIComponent(f.path)}`); if (res.ok) { const out = await _importEbookBuffer(await res.arrayBuffer(), f.name, null, {reload: false, skipKnown: true}); result = out === 'dup' ? 'known' : out ? 'imported' : 'failed'; } } } catch (e) { result = 'failed'; } if (result === 'imported') taken.push(f); await fetch(`/books/cloud/${f.source}/done/`, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({path: f.path, result}), }).catch(() => {}); } } catch (e) { // Offline or the source unreachable: next time. } finally { _cloudInboxBusy = false; } if (statusEl) { const labels = [...new Set(taken.map(f => f.label))].map(l => `„${l}“`).join(', '); statusEl.textContent = taken.length ? `${taken.length === 1 ? 'Ein neues Buch' : taken.length + ' neue Bücher'} aus ${labels} übernommen.` : ''; } if (taken.length) loadBookList(); } // After the list has loaded (and the key is known), quietly look into the inboxes. (function () { const orig = window.loadBookList; if (typeof orig !== 'function') return; window.loadBookList = async function () { const out = await orig.apply(this, arguments); setTimeout(() => cloudInboxCheck(false), 1500); return out; }; })();