fix(userscript): show a spinner while the first fetch is in flight

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-28 17:57:49 +07:00
parent d2916d4403
commit d8fa9b651c
+20 -3
View File
@@ -852,6 +852,9 @@
// ============================================================ // ============================================================
let root, panelOpen = false; let root, panelOpen = false;
// True while refresh() is waiting on the backend. Only changes what the list
// draws when there is nothing cached to draw instead.
let loading = false;
let activeTab = "all"; // "all" | "favorites" | "archived"; resets each page, by design let activeTab = "all"; // "all" | "favorites" | "archived"; resets each page, by design
function buildUI() { function buildUI() {
@@ -1071,7 +1074,11 @@
if (s !== "reading") return false; if (s !== "reading") return false;
return activeTab !== "favorites" || b.favorite; return activeTab !== "favorites" || b.favorite;
}); });
if (items.length === 0) { if (items.length === 0 && loading) {
// Nothing cached and the fetch is still out — without this the panel
// looks frozen on the first open after a cold start.
listEl.appendChild(el("div", { class: "empty" }, [el("div", { class: "spinner" })]));
} else if (items.length === 0) {
const empty = { const empty = {
favorites: "No favourites yet.", favorites: "No favourites yet.",
archived: "Nothing archived.", archived: "Nothing archived.",
@@ -1154,12 +1161,16 @@
async function refresh() { async function refresh() {
await drain(); // push what we owe before adopting the server's view of it await drain(); // push what we owe before adopting the server's view of it
loading = true;
render();
try { try {
const list = await apiGet(); const list = await apiGet();
setList(overlayPending(list)); setList(overlayPending(list));
render();
} catch (e) { } catch (e) {
render(); // fall back to cache // Offline or backend down: keep whatever the cache holds.
} finally {
loading = false;
render();
} }
} }
@@ -1380,6 +1391,12 @@
.tab.active { color: #eee; border-bottom-color: #6d28d9; } .tab.active { color: #eee; border-bottom-color: #6d28d9; }
#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; }
.spinner {
width: 26px; height: 26px; margin: 0 auto;
border: 3px solid #33333d; border-top-color: #6d28d9; border-radius: 50%;
animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.item { .item {
display: flex; flex-direction: row; gap: 10px; display: flex; flex-direction: row; gap: 10px;
padding: 10px 16px; border-bottom: 1px solid #2a2a33; padding: 10px 16px; border-bottom: 1px solid #2a2a33;