89 lines
2.5 KiB
Python
89 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""Shared page-shell helpers for inline HTML templates."""
|
|
|
|
PAGE_LINKS = (
|
|
("search", "Search", "/"),
|
|
("config", "Config", "/config"),
|
|
("watchlist", "Watchlist", "/watchlist"),
|
|
)
|
|
|
|
|
|
BROWSER_API_HELPER = r"""
|
|
async function api(path, options = {}) {
|
|
const headers = new Headers(options.headers || {});
|
|
if (options.body && !headers.has("Content-Type")) {
|
|
headers.set("Content-Type", "application/json");
|
|
}
|
|
const response = await fetch(path, {
|
|
...options,
|
|
headers
|
|
});
|
|
const raw = await response.text();
|
|
let data = {};
|
|
if (raw) {
|
|
try {
|
|
data = JSON.parse(raw);
|
|
} catch (_error) {
|
|
data = { error: raw };
|
|
}
|
|
}
|
|
if (!response.ok) throw new Error(data.error || response.statusText || "Request failed");
|
|
return data;
|
|
}
|
|
"""
|
|
|
|
|
|
BROWSER_POLL_HELPER = r"""
|
|
function startSerialPoll(callback, intervalMs) {
|
|
let inFlight = false;
|
|
let active = true;
|
|
let timer = null;
|
|
const stop = () => {
|
|
active = false;
|
|
if (timer !== null) {
|
|
window.clearTimeout(timer);
|
|
timer = null;
|
|
}
|
|
};
|
|
const tick = async () => {
|
|
if (!active || inFlight) {
|
|
if (active) timer = window.setTimeout(tick, intervalMs);
|
|
return;
|
|
}
|
|
inFlight = true;
|
|
try {
|
|
await callback();
|
|
} finally {
|
|
inFlight = false;
|
|
if (active) timer = window.setTimeout(tick, intervalMs);
|
|
}
|
|
};
|
|
window.addEventListener("pagehide", stop, { once: true });
|
|
window.addEventListener("beforeunload", stop, { once: true });
|
|
timer = window.setTimeout(tick, intervalMs);
|
|
return { stop };
|
|
}
|
|
"""
|
|
|
|
|
|
def render_sidebar_brand(note, badge, badge_id=""):
|
|
badge_attr = f' id="{badge_id}"' if badge_id else ""
|
|
return (
|
|
' <div class="topline">\n'
|
|
' <div class="brand-wrap">\n'
|
|
' <h1>ani-cli <span class="brand-word">web</span></h1>\n'
|
|
f" <p class=\"shell-note\">{note}</p>\n"
|
|
" </div>\n"
|
|
f" <span class=\"badge\"{badge_attr}>{badge}</span>\n"
|
|
" </div>\n"
|
|
)
|
|
|
|
|
|
def render_page_links(active_page):
|
|
links = []
|
|
for key, label, href in PAGE_LINKS:
|
|
class_name = "page-link active" if key == active_page else "page-link"
|
|
links.append(f' <a class="{class_name}" href="{href}">{label}</a>')
|
|
return " <div class=\"page-links\">\n" + "\n".join(links) + "\n </div>\n"
|