Store: one tab combining books, free audiobooks and radio, plus My Store for your own books, music, apps and sandboxed extensions
build-container / build (push) Successful in 7m39s
build-container / build (push) Successful in 7m39s
- Store tab with sections; the book store, LibriVox and radio finder are shown inside it (old entry points redirect) - My Store: admin uploads files or copies from Seafile; books go to a person's shelf, music plays in the player, apps download - Extensions: one HTML file run in a sandboxed frame with a small storage/toast/user bridge; example in docs/extensions Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
176b1b8169
commit
f292294ad7
16 files changed
+439
-24
No files matched your search
@@ -46,13 +46,13 @@ function lvPlay(b, at) {
|
||||
lvApi('/shelf', lvOpt('POST', { id: b.id })).catch(() => {}); // a book you start is kept on your shelf
|
||||
}
|
||||
|
||||
async function viewFreeBooks() {
|
||||
const v = $('#view'); v.innerHTML = '<div class="wrap"><h1>Free audiobooks</h1><p class="empty">Loading…</p></div>';
|
||||
async function viewFreeBooks(host) { // host: { el, hash } when shown inside the Store tab
|
||||
const v = host ? host.el : $('#view'), here = () => location.hash.startsWith(host ? host.hash : '#/audio/free'); v.innerHTML = '<div class="wrap"><h1>Free audiobooks</h1><p class="empty">Loading…</p></div>';
|
||||
try { lvShelf = await lvApi('/shelf'); await lvLoadProg(); } catch (e) { v.innerHTML = `<div class="wrap"><a class="btn ghost" href="#/audio">${icon('back')}Audiobooks</a><p class="err">${esc(e.message)}</p></div>`; return; }
|
||||
if (!location.hash.startsWith('#/audio/free')) return;
|
||||
if (!here()) return;
|
||||
const S = { q: '', page: 1, items: [], more: false, busy: false, seq: 0 };
|
||||
const card = b => lvCard(b);
|
||||
v.innerHTML = `<div class="wrap"><div class="ptop"><a class="btn ghost" href="#/audio">${icon('back')}Audiobooks</a><h1 style="margin:0">Free audiobooks</h1></div>
|
||||
v.innerHTML = `<div class="wrap">${host ? '' : `<div class="ptop"><a class="btn ghost" href="#/audio">${icon('back')}Audiobooks</a><h1 style="margin:0">Free audiobooks</h1></div>`}
|
||||
<p class="sub">Public-domain books read aloud by volunteers (LibriVox). Free, with no sign-in. A book you start is kept on your shelf.</p>
|
||||
<input type="search" id="lvq" placeholder="Search by title or author" autocomplete="off" autocapitalize="off" style="width:100%"><div id="lvnote"></div><div id="lvbody"></div><div id="lvmore" class="bar" style="justify-content:center"></div></div>`;
|
||||
const known = new Map(lvShelf.map(b => [b.id, b]));
|
||||
|
||||
Reference in new issue
Block a user