Tint sidebar widget chips by origin; fix widgetSub host
This commit is contained in:
1 parent
4737891997
commit
f1342b8a41
3 files changed
+30
-5
No files matched your search
@@ -276,7 +276,8 @@ in three kinds:
|
|||||||
next upcoming release that carries artwork also gets a full-width hero tile
|
next upcoming release that carries artwork also gets a full-width hero tile
|
||||||
above the groups (its relayed thumb plus title and date), ringed in the same
|
above the groups (its relayed thumb plus title and date), ringed in the same
|
||||||
origin hue. Each widget gets its own sidebar button for a
|
origin hue. Each widget gets its own sidebar button for a
|
||||||
single-widget view.
|
single-widget view, its left edge tinted with the same origin hue once the
|
||||||
|
widget has returned rows (an errored or empty widget stays accent-blue).
|
||||||
- Writes are admin-only when OIDC is on, reads any session - same gate as
|
- Writes are admin-only when OIDC is on, reads any session - same gate as
|
||||||
services.
|
services.
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,8 @@ function renderSidebar() {
|
|||||||
}
|
}
|
||||||
for (const widget of state.widgets) {
|
for (const widget of state.widgets) {
|
||||||
const button = document.createElement("button");
|
const button = document.createElement("button");
|
||||||
button.className = "widget-btn" + (state.selected === widget.id ? " active" : "");
|
button.className =
|
||||||
|
"widget-btn" + widgetOriginClass(widget) + (state.selected === widget.id ? " active" : "");
|
||||||
button.title = widget.name;
|
button.title = widget.name;
|
||||||
button.innerHTML =
|
button.innerHTML =
|
||||||
`<span class="icon">${widgetIcon(widget)}</span>` +
|
`<span class="icon">${widgetIcon(widget)}</span>` +
|
||||||
@@ -161,8 +162,18 @@ function widgetSub(widget) {
|
|||||||
if (widget.kind === "notice") return (widget.body || "").slice(0, 60);
|
if (widget.kind === "notice") return (widget.body || "").slice(0, 60);
|
||||||
const data = widget.data || {};
|
const data = widget.data || {};
|
||||||
if (data.error) return `⚠ ${data.error.error}`;
|
if (data.error) return `⚠ ${data.error.error}`;
|
||||||
const host = (widget.base_url || "").split("://", 1)[1];
|
// `split("://", 1)[1]` looked like Python but JS returns a one-element array,
|
||||||
return `${(data.items || []).length} items · ${host}`;
|
// so the old code printed "undefined". URL() also keeps the port (`host`).
|
||||||
|
let host = "";
|
||||||
|
if (widget.base_url) {
|
||||||
|
try {
|
||||||
|
host = new URL(widget.base_url).host;
|
||||||
|
} catch (TypeError) {
|
||||||
|
host = widget.base_url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const count = (data.items || []).length;
|
||||||
|
return host ? `${count} item${count === 1 ? "" : "s"} · ${host}` : `${count} item${count === 1 ? "" : "s"}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderTable() {
|
function renderTable() {
|
||||||
@@ -241,6 +252,16 @@ function originClass(item) {
|
|||||||
return ORIGIN_LABEL[item ? item.origin : null] ? ` origin-${item.origin}` : "";
|
return ORIGIN_LABEL[item ? item.origin : null] ? ` origin-${item.origin}` : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A widget's app is only knowable from the rows it returned (`calendar` covers
|
||||||
|
// both Sonarr and Radarr), so the first recognised origin wins; an errored or
|
||||||
|
// empty widget stays neutral.
|
||||||
|
function widgetOriginClass(widget) {
|
||||||
|
for (const row of (widget.data || {}).items || []) {
|
||||||
|
if (ORIGIN_LABEL[row.origin]) return ` origin-${row.origin}`;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
function releaseCard(item) {
|
function releaseCard(item) {
|
||||||
const thumb = item.thumb
|
const thumb = item.thumb
|
||||||
? `<img class="widget-thumb" src="${esc(item.thumb)}" alt="${esc(item.label)}" loading="lazy" />`
|
? `<img class="widget-thumb" src="${esc(item.thumb)}" alt="${esc(item.label)}" loading="lazy" />`
|
||||||
|
|||||||
@@ -373,7 +373,10 @@ body {
|
|||||||
|
|
||||||
/* origin tints: Sonarr teal, Radarr violet, Plex orange. The merged timeline
|
/* origin tints: Sonarr teal, Radarr violet, Plex orange. The merged timeline
|
||||||
mixes apps, so the card edge, the source chip and a legend chip in the group
|
mixes apps, so the card edge, the source chip and a legend chip in the group
|
||||||
header all carry the same hue. */
|
header all carry the same hue; sidebar chips get it on their left edge too. */
|
||||||
|
.widget-btn.origin-sonarr { border-left: 3px solid var(--origin-sonarr); }
|
||||||
|
.widget-btn.origin-radarr { border-left: 3px solid var(--origin-radarr); }
|
||||||
|
.widget-btn.origin-plex { border-left: 3px solid var(--origin-plex); }
|
||||||
.release-card.origin-sonarr { border-left: 3px solid var(--origin-sonarr); }
|
.release-card.origin-sonarr { border-left: 3px solid var(--origin-sonarr); }
|
||||||
.release-card.origin-radarr { border-left: 3px solid var(--origin-radarr); }
|
.release-card.origin-radarr { border-left: 3px solid var(--origin-radarr); }
|
||||||
.release-card.origin-plex { border-left: 3px solid var(--origin-plex); }
|
.release-card.origin-plex { border-left: 3px solid var(--origin-plex); }
|
||||||
|
|||||||
Reference in new issue
Block a user