Save source descriptions, add "Why it's #N", fix IGDB studio names
Descriptions
- Items keep the source's description (TMDB/TheTVDB overview, IGDB
summary, Wikipedia intro) in a new items.description column
(migration 3); editable in the item form
- Deezer/MusicBrainz track counts and album names are now display-only
hints, not saved as descriptions
Why it's #N
- The owner's note is presented as "Why it's #N" in the editor and the
public detail view, above an "About" section with the description
IGDB developers
- IGDB credits internal divisions ("Nintendo EAD", "Nintendo EPD
Production Group No. 8"). A developer whose name shares its first word
with its parent company is credited to the parent ("Nintendo");
independently named studios keep their name (Retro Studios, Naughty
Dog, Landfall Games)
- Fall back to the publisher when IGDB lists no developer
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3923444b3b
commit
7320e3f707
16 files changed
+207
-44
No files matched your search
@@ -271,7 +271,7 @@ function renderResults(res) {
|
||||
h("div", { style: { minWidth: 0 } },
|
||||
h("div", { class: "result-title" }, r.title),
|
||||
sub && h("div", { class: "result-sub" }, sub),
|
||||
r.overview && h("div", { class: "result-overview" }, r.overview),
|
||||
(r.overview || r.hint) && h("div", { class: "result-overview" }, r.overview || r.hint),
|
||||
),
|
||||
action,
|
||||
);
|
||||
@@ -294,6 +294,7 @@ function fromResult(r) {
|
||||
return {
|
||||
title: r.title, subtitle: r.subtitle, year: r.year, externalUrl: r.externalUrl,
|
||||
imageUrl: r.imageUrl, provider: r.provider, providerId: r.providerId, extra: { ...(r.extra || {}) },
|
||||
description: r.overview || "",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -344,7 +345,10 @@ function openItemForm({ item, result }) {
|
||||
const title = h("input", { required: true, maxlength: 500, value: src.title || "" });
|
||||
const subtitle = h("input", { maxlength: 500, value: src.subtitle || "" });
|
||||
const year = h("input", { maxlength: 20, value: src.year || "", inputmode: "numeric", style: { maxWidth: "140px" } });
|
||||
const note = h("textarea", { rows: 3, maxlength: 10000, value: item?.note || "", placeholder: "Why it's here. Shown to visitors." });
|
||||
const description = h("textarea", { rows: 4, maxlength: 10000, value: src.description || "", placeholder: "What it is, in a few sentences." });
|
||||
const note = h("textarea", { rows: 3, maxlength: 10000, value: item?.note || "", placeholder: "What earns it this spot? Shown to visitors." });
|
||||
const source = { tmdb: "TMDB", tvdb: "TheTVDB", igdb: "IGDB", wikipedia: "Wikipedia" }[src.provider];
|
||||
const rankLabel = editing ? `#${item.rank}` : `#${list.itemCount + 1}`;
|
||||
const link = h("input", { type: "url", maxlength: 2000, value: src.externalUrl || "", placeholder: "https://" });
|
||||
|
||||
// Theater production gets top billing with suggestions.
|
||||
@@ -438,7 +442,8 @@ function openItemForm({ item, result }) {
|
||||
field(cat.key === "theater" ? "Year (of this production)" : "Year", year),
|
||||
),
|
||||
extraInputs.length > 0 && h("div", { class: "row" }, extraInputs.map((x) => field(x.label, x.input))),
|
||||
field("Your note", note),
|
||||
field("Description", description, source ? `From ${source}. Edit it if you like.` : "Optional. Shown to visitors."),
|
||||
field(`Why it's ${rankLabel}`, note, "Your take on why it earns its place in the ranking."),
|
||||
field("Link", link, "Where the title links to on your page."),
|
||||
error,
|
||||
),
|
||||
@@ -461,7 +466,7 @@ function openItemForm({ item, result }) {
|
||||
if (production) newExtra.production = production.value.trim();
|
||||
for (const x of extraInputs) newExtra[x.key] = x.input.value.trim();
|
||||
const body = {
|
||||
title: title.value, subtitle: subtitle.value, year: year.value, note: note.value,
|
||||
title: title.value, subtitle: subtitle.value, year: year.value, note: note.value, description: description.value,
|
||||
externalUrl: link.value.trim(), extra: newExtra,
|
||||
imageUrl: clearImage ? "" : imageUrl.value.trim(), clearImage,
|
||||
};
|
||||
|
||||
@@ -84,7 +84,7 @@ function profileSection() {
|
||||
h("div", { class: "row" }, field("Your name", ownerName, "Shown as the page heading."), field("Site title", siteTitle, "Shown in the header and browser tab. Leave blank to use “Your name's Canon”.")),
|
||||
field("Tagline", tagline),
|
||||
field("Entries per list on the home page", preview, "Visitors see the full list on each list's page. 0 shows only the heading."),
|
||||
h("label", { class: "check" }, notes, "Show my notes to visitors"),
|
||||
h("label", { class: "check" }, notes, "Show why each entry is ranked where it is"),
|
||||
h("div", { class: "settings-actions" }, save),
|
||||
);
|
||||
form.addEventListener("submit", async (e) => {
|
||||
|
||||
@@ -38,7 +38,12 @@ function renderDialog(list, idx) {
|
||||
sub && h("p", { class: "dlg-sub" }, sub),
|
||||
it.badge && h("span", { class: "badge" }, it.badge),
|
||||
meta.length > 0 && h("dl", { class: "dlg-meta" }, meta.map((m) => [h("dt", {}, m.label), h("dd", {}, m.value)])),
|
||||
it.note && h("blockquote", { class: "dlg-note" }, it.note),
|
||||
it.note && h("section", { class: "dlg-why" },
|
||||
h("h3", {}, `Why it's #${it.rank}`),
|
||||
h("blockquote", { class: "dlg-note" }, it.note)),
|
||||
it.description && h("section", { class: "dlg-about" },
|
||||
h("h3", {}, "About"),
|
||||
h("p", { class: "dlg-desc" }, it.description)),
|
||||
h("div", { class: "dlg-actions" },
|
||||
it.link && h("a", { class: "btn btn--sm", href: it.link, target: "_blank", rel: "noopener noreferrer" },
|
||||
icon("external"), it.source ? `View on ${it.source}` : "Learn more"),
|
||||
|
||||
Reference in new issue
Block a user