Serve the userscript from the backend; card + loading fixes #8

Merged
sulthan merged 6 commits from userscript-download-url into main 2026-07-28 18:28:28 +07:00
Showing only changes of commit d2916d4403 - Show all commits
+12 -12
View File
@@ -1094,20 +1094,18 @@
const sub = behind const sub = behind
? "Read: " + (b.last_chapter || "—") + " · Latest: " + b.latest_chapter ? "Read: " + (b.last_chapter || "—") + " · Latest: " + b.latest_chapter
: (b.last_chapter || "—") + " · " + b.site; : (b.last_chapter || "—") + " · " + b.site;
// Cover and text are one link: the card body *is* the continue button, so // Cover and title are the only continue links. The subtitle and the action
// there is no separate one. The action row is a sibling of that link, never // row live in the same text column but are not navigation targets — a thumb
// a child — a thumb that misses ★ must not land on a navigation target, and // that misses ★ must not land on one, and Remove must never be one.
// Remove must never be one.
return el("div", { class: "item" }, [ return el("div", { class: "item" }, [
el("a", { class: "go", href: cont }, [ el("a", { class: "go", href: cont }, [
b.cover b.cover
? el("img", { class: "cover", src: b.cover, loading: "lazy", alt: "" }) ? el("img", { class: "cover", src: b.cover, loading: "lazy", alt: "" })
: el("div", { class: "cover ph" }), : el("div", { class: "cover ph" }),
]),
el("div", { class: "meta" }, [ el("div", { class: "meta" }, [
el("div", { class: "t", text: b.title || b.series_id }), el("a", { class: "go-t t", href: cont, text: b.title || b.series_id }),
el("div", { class: "c" + (behind ? " behind" : ""), text: sub }), el("div", { class: "c" + (behind ? " behind" : ""), text: sub }),
]),
]),
el("div", { class: "actions" }, [ el("div", { class: "actions" }, [
el("button", { el("button", {
class: "btn small star" + (b.favorite ? " on" : ""), class: "btn small star" + (b.favorite ? " on" : ""),
@@ -1126,6 +1124,7 @@
onclick: () => confirmRemove(b), onclick: () => confirmRemove(b),
}), }),
]), ]),
]),
]); ]);
} }
@@ -1382,16 +1381,17 @@
#list { overflow-y: auto; flex: 1; padding: 8px 0; } #list { overflow-y: auto; flex: 1; padding: 8px 0; }
.empty { color: #9a9aa5; text-align: center; padding: 30px 16px; font-size: 14px; } .empty { color: #9a9aa5; text-align: center; padding: 30px 16px; font-size: 14px; }
.item { .item {
display: flex; flex-direction: column; gap: 8px; display: flex; flex-direction: row; gap: 10px;
padding: 10px 16px; border-bottom: 1px solid #2a2a33; padding: 10px 16px; border-bottom: 1px solid #2a2a33;
} }
.go { display: flex; gap: 10px; text-decoration: none; color: inherit; } .go { display: block; flex: none; }
.go:active { opacity: .7; } .go:active, .go-t:active { opacity: .7; }
.go-t { display: block; text-decoration: none; color: inherit; }
.cover { width: 46px; height: 62px; object-fit: cover; border-radius: 4px; flex: none; background: #333; } .cover { width: 46px; height: 62px; object-fit: cover; border-radius: 4px; flex: none; background: #333; }
.cover.ph { display: block; } .cover.ph { display: block; }
.meta { min-width: 0; flex: 1; } .meta { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 6px; }
.t { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .t { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.c { color: #9a9aa5; font-size: 12px; margin: 2px 0 0; } .c { color: #9a9aa5; font-size: 12px; margin: 0; }
.c.behind { color: #c4b5fd; } .c.behind { color: #c4b5fd; }
.actions { display: flex; gap: 6px; flex-wrap: wrap; } .actions { display: flex; gap: 6px; flex-wrap: wrap; }
.btn { .btn {