Handle new crediting system

This commit is contained in:
DrMint 2024-04-08 23:18:24 +02:00
parent ec70acdf50
commit c36bef29b9
9 changed files with 142 additions and 123 deletions

View File

@ -1,41 +1,41 @@
--- ---
import type { EndpointRecorder } from "src/shared/payload/payload-sdk"; import type { EndpointCredit } from "src/shared/payload/payload-sdk";
import Metadata from "./Metadata.astro"; import Metadata from "./Metadata.astro";
import { getI18n } from "src/i18n/i18n"; import { getI18n } from "src/i18n/i18n";
interface Props { interface Props {
translators?: EndpointRecorder[] | undefined; credits: EndpointCredit[];
transcribers?: EndpointRecorder[] | undefined;
proofreaders?: EndpointRecorder[] | undefined;
authors?: EndpointRecorder[] | undefined;
} }
const { translators = [], transcribers = [], proofreaders = [], authors = [] } = Astro.props; const { credits } = Astro.props;
const { t } = await getI18n(Astro.locals.currentLocale); const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale);
--- ---
{/* ------------------------------------------- HTML ------------------------------------------- */} {/* ------------------------------------------- HTML ------------------------------------------- */}
<Metadata <div>
icon="material-symbols:person-outline" {
title={t("global.credits.translators")} credits.map(({ recorders, role: { icon, translations } }) => (
values={translators.map(({ username }) => username)} <Metadata
/> icon={icon}
title={getLocalizedMatch(translations).name}
values={recorders.map(({ username }) => username)}
/>
))
}
</div>
<Metadata {/* ------------------------------------------- CSS -------------------------------------------- */}
icon="material-symbols:person-edit-outline"
title={t("global.credits.transcribers")}
values={transcribers.map(({ username }) => username)}
/>
<Metadata <style>
icon="material-symbols:person-check-outline" div {
title={t("global.credits.proofreaders")} display: grid;
values={proofreaders.map(({ username }) => username)} gap: 2em;
/> margin-block: 2em;
<Metadata @media (max-width: 35rem) {
icon="material-symbols:person-check-outline" gap: 3.5em;
title={t("global.credits.authors")} margin-block: 3.5em;
values={authors.map(({ username }) => username)} }
/> }
</style>

View File

@ -1,48 +1,23 @@
--- ---
import type { EndpointRecorder } from "src/shared/payload/payload-sdk"; import type { EndpointCredit } from "src/shared/payload/payload-sdk";
import { getI18n } from "src/i18n/i18n"; import { getI18n } from "src/i18n/i18n";
interface Props { interface Props {
translators?: EndpointRecorder[] | undefined; credits: EndpointCredit[];
transcribers?: EndpointRecorder[] | undefined;
proofreaders?: EndpointRecorder[] | undefined;
} }
const { translators = [], transcribers = [], proofreaders = [] } = Astro.props; const { credits } = Astro.props;
const { t } = await getI18n(Astro.locals.currentLocale); const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale);
const tagGroups = [];
if (translators.length > 0) {
tagGroups.push({
name: t("global.credits.translators"),
values: translators,
});
}
if (transcribers.length > 0) {
tagGroups.push({
name: t("global.credits.transcribers"),
values: transcribers,
});
}
if (proofreaders.length > 0) {
tagGroups.push({
name: t("global.credits.proofreaders"),
values: proofreaders,
});
}
--- ---
{/* ------------------------------------------- HTML ------------------------------------------- */} {/* ------------------------------------------- HTML ------------------------------------------- */}
<div id="tags"> <div id="credits">
{ {
tagGroups.map(({ name, values }) => ( credits.map(({ recorders, role: { translations } }) => (
<div> <div>
<p>{name}</p> <p>{getLocalizedMatch(translations).name}</p>
{values.map(({ username }) => username).join(", ")} {recorders.map(({ username }) => username).join(", ")}
</div> </div>
)) ))
} }
@ -51,7 +26,7 @@ if (proofreaders.length > 0) {
{/* ------------------------------------------- CSS -------------------------------------------- */} {/* ------------------------------------------- CSS -------------------------------------------- */}
<style> <style>
#tags { #credits {
margin-top: 0.5em; margin-top: 0.5em;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -59,7 +59,7 @@ const translation = getLocalizedMatch(page.translations);
) )
} }
<TagGroups tagGroups={page.tagGroups} /> {page.tagGroups.length > 0 && <TagGroups tagGroups={page.tagGroups} />}
<div class="when-not-large meta-container"> <div class="when-not-large meta-container">
{ {
@ -73,11 +73,7 @@ const translation = getLocalizedMatch(page.translations);
/> />
) )
} }
<Credits {translation.credits.length > 0 && <Credits credits={translation.credits} />}
translators={translation.translators}
proofreaders={translation.proofreaders}
authors={page.authors}
/>
</div> </div>
{ {
@ -118,12 +114,7 @@ const translation = getLocalizedMatch(page.translations);
/> />
) )
} }
<Credits {translation.credits.length > 0 && <Credits credits={translation.credits} />}
translators={translation.translators}
transcribers={translation.transcribers}
proofreaders={translation.proofreaders}
authors={page.authors}
/>
</div> </div>
{translation.toc.length > 0 && <TableOfContent toc={translation.toc} />} {translation.toc.length > 0 && <TableOfContent toc={translation.toc} />}

View File

@ -25,8 +25,7 @@ const { sources, translations } = event.events[index]!;
const { getLocalizedUrl } = await getI18n(Astro.locals.currentLocale); const { getLocalizedUrl } = await getI18n(Astro.locals.currentLocale);
const { getLocalizedMatch } = await getI18n(lang); const { getLocalizedMatch } = await getI18n(lang);
const { title, description, notes, proofreaders, transcribers, translators } = const { title, description, notes, credits } = getLocalizedMatch(translations);
getLocalizedMatch(translations);
--- ---
{/* ------------------------------------------- HTML ------------------------------------------- */} {/* ------------------------------------------- HTML ------------------------------------------- */}
@ -40,9 +39,7 @@ const { title, description, notes, proofreaders, transcribers, translators } =
<TimelineLanguageOverride <TimelineLanguageOverride
availableLanguages={translations.map(({ language }) => language)} availableLanguages={translations.map(({ language }) => language)}
currentLang={lang} currentLang={lang}
proofreaders={proofreaders} credits={credits}
transcribers={transcribers}
translators={translators}
getPartialUrl={(locale) => getPartialUrl={(locale) =>
getLocalizedUrl(`/api/timeline/partial?id=${id}&index=${index}&lang=${locale}`)} getLocalizedUrl(`/api/timeline/partial?id=${id}&index=${index}&lang=${locale}`)}
/> />

View File

@ -1,6 +1,7 @@
--- ---
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro"; import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
import AudioPlayer from "components/AudioPlayer.astro"; import AudioPlayer from "components/AudioPlayer.astro";
import Credits from "components/Credits.astro";
import DownloadButton from "components/DownloadButton.astro"; import DownloadButton from "components/DownloadButton.astro";
import RichText from "components/RichText/RichText.astro"; import RichText from "components/RichText/RichText.astro";
import TagGroups from "components/TagGroups.astro"; import TagGroups from "components/TagGroups.astro";
@ -15,7 +16,7 @@ if (audio instanceof Response) {
} }
const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale); const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale);
const { translations, tagGroups, filename, url } = audio; const { translations, tagGroups, filename, url, credits } = audio;
const { title, description } = getLocalizedMatch(translations); const { title, description } = getLocalizedMatch(translations);
--- ---
@ -29,7 +30,10 @@ const { title, description } = getLocalizedMatch(translations);
<div> <div>
<h1>{title}</h1> <h1>{title}</h1>
{description && <RichText content={description} />} {description && <RichText content={description} />}
{tagGroups.length > 0 && <TagGroups {tagGroups} />} <div>
{tagGroups.length > 0 && <TagGroups {tagGroups} />}
{credits.length > 0 && <Credits credits={credits} />}
</div>
<DownloadButton href={url} filename={filename} /> <DownloadButton href={url} filename={filename} />
</div> </div>
</div> </div>
@ -53,11 +57,19 @@ const { title, description } = getLocalizedMatch(translations);
max-width: 35em; max-width: 35em;
} }
div { & > div {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 2em; gap: 2em;
align-items: start; align-items: start;
& > div {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 2em 6em;
width: 100%;
}
} }
} }
</style> </style>

View File

@ -1,5 +1,6 @@
--- ---
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro"; import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
import Credits from "components/Credits.astro";
import DownloadButton from "components/DownloadButton.astro"; import DownloadButton from "components/DownloadButton.astro";
import RichText from "components/RichText/RichText.astro"; import RichText from "components/RichText/RichText.astro";
import TagGroups from "components/TagGroups.astro"; import TagGroups from "components/TagGroups.astro";
@ -14,7 +15,7 @@ if (image instanceof Response) {
} }
const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale); const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale);
const { url, width, height, filename, translations, tagGroups } = image; const { url, width, height, filename, translations, tagGroups, credits } = image;
const { title, description } = const { title, description } =
translations.length > 0 translations.length > 0
@ -31,7 +32,10 @@ const { title, description } =
<div> <div>
<h1>{title}</h1> <h1>{title}</h1>
{description && <RichText content={description} />} {description && <RichText content={description} />}
{tagGroups.length > 0 && <TagGroups {tagGroups} />} <div>
{tagGroups.length > 0 && <TagGroups {tagGroups} />}
{credits.length > 0 && <Credits credits={credits} />}
</div>
<DownloadButton href={url} filename={filename} /> <DownloadButton href={url} filename={filename} />
</div> </div>
</div> </div>
@ -57,11 +61,19 @@ const { title, description } =
max-width: 35em; max-width: 35em;
} }
div { & > div {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 2em; gap: 2em;
align-items: start; align-items: start;
& > div {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 2em 6em;
width: 100%;
}
} }
} }
</style> </style>

View File

@ -4,20 +4,17 @@ import InlineCredits from "components/InlineCredits.astro";
import MasoActor from "components/Maso/MasoActor.astro"; import MasoActor from "components/Maso/MasoActor.astro";
import Tooltip from "components/Tooltip.astro"; import Tooltip from "components/Tooltip.astro";
import { getI18n } from "src/i18n/i18n"; import { getI18n } from "src/i18n/i18n";
import type { EndpointRecorder } from "src/shared/payload/payload-sdk"; import type { EndpointCredit } from "src/shared/payload/payload-sdk";
import { formatLocale } from "src/utils/format"; import { formatLocale } from "src/utils/format";
interface Props { interface Props {
currentLang: string; currentLang: string;
availableLanguages: string[]; availableLanguages: string[];
getPartialUrl: (locale: string) => string; getPartialUrl: (locale: string) => string;
transcribers: EndpointRecorder[]; credits: EndpointCredit[];
translators: EndpointRecorder[];
proofreaders: EndpointRecorder[];
} }
const { availableLanguages, transcribers, proofreaders, translators, getPartialUrl, currentLang } = const { availableLanguages, credits, getPartialUrl, currentLang } = Astro.props;
Astro.props;
const { t } = await getI18n(Astro.locals.currentLocale); const { t } = await getI18n(Astro.locals.currentLocale);
--- ---
@ -36,11 +33,7 @@ const { t } = await getI18n(Astro.locals.currentLocale);
)) ))
} }
<InlineCredits {credits.length > 0 && <InlineCredits credits={credits} />}
translators={translators}
transcribers={transcribers}
proofreaders={proofreaders}
/>
</div> </div>
<div class="pressable-label"> <div class="pressable-label">
<Icon name="material-symbols:translate" /> <Icon name="material-symbols:translate" />

View File

@ -1,5 +1,6 @@
--- ---
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro"; import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
import Credits from "components/Credits.astro";
import DownloadButton from "components/DownloadButton.astro"; import DownloadButton from "components/DownloadButton.astro";
import RichText from "components/RichText/RichText.astro"; import RichText from "components/RichText/RichText.astro";
import TagGroups from "components/TagGroups.astro"; import TagGroups from "components/TagGroups.astro";
@ -15,7 +16,7 @@ if (video instanceof Response) {
} }
const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale); const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale);
const { translations, tagGroups, filename, url } = video; const { translations, tagGroups, filename, url, credits } = video;
const { title, description } = getLocalizedMatch(translations); const { title, description } = getLocalizedMatch(translations);
--- ---
@ -29,7 +30,10 @@ const { title, description } = getLocalizedMatch(translations);
<div> <div>
<h1>{title}</h1> <h1>{title}</h1>
{description && <RichText content={description} />} {description && <RichText content={description} />}
{tagGroups.length > 0 && <TagGroups {tagGroups} />} <div>
{tagGroups.length > 0 && <TagGroups {tagGroups} />}
{credits.length > 0 && <Credits credits={credits} />}
</div>
<DownloadButton href={url} filename={filename} /> <DownloadButton href={url} filename={filename} />
</div> </div>
</div> </div>
@ -55,11 +59,19 @@ const { title, description } = getLocalizedMatch(translations);
max-width: 35em; max-width: 35em;
} }
div { & > div {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 2em; gap: 2em;
align-items: start; align-items: start;
& > div {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 2em 6em;
width: 100%;
}
} }
} }
</style> </style>

View File

@ -6,6 +6,18 @@
* and re-run `payload generate:types` to regenerate this file. * and re-run `payload generate:types` to regenerate this file.
*/ */
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "Credits".
*/
export type Credits =
| {
role: string | CreditsRole;
recorders: (string | Recorder)[];
id?: string | null;
}[]
| null;
export interface Config { export interface Config {
collections: { collections: {
pages: Page; pages: Page;
@ -21,6 +33,7 @@ export interface Config {
scans: Scan; scans: Scan;
tags: Tag; tags: Tag;
"tags-groups": TagsGroup; "tags-groups": TagsGroup;
"credits-roles": CreditsRole;
recorders: Recorder; recorders: Recorder;
languages: Language; languages: Language;
currencies: Currency; currencies: Currency;
@ -40,11 +53,9 @@ export interface Config {
export interface Page { export interface Page {
id: string; id: string;
slug: string; slug: string;
type: "Content" | "Post" | "Generic";
thumbnail?: string | Image | null; thumbnail?: string | Image | null;
backgroundImage?: string | Image | null; backgroundImage?: string | Image | null;
tags?: (string | Tag)[] | null; tags?: (string | Tag)[] | null;
authors?: (string | Recorder)[] | null;
translations: { translations: {
language: string | Language; language: string | Language;
sourceLanguage: string | Language; sourceLanguage: string | Language;
@ -81,9 +92,7 @@ export interface Page {
}; };
[k: string]: unknown; [k: string]: unknown;
}; };
transcribers?: (string | Recorder)[] | null; credits?: Credits;
translators?: (string | Recorder)[] | null;
proofreaders?: (string | Recorder)[] | null;
id?: string | null; id?: string | null;
}[]; }[];
folders?: (string | Folder)[] | null; folders?: (string | Folder)[] | null;
@ -122,6 +131,7 @@ export interface Image {
}[] }[]
| null; | null;
tags?: (string | Tag)[] | null; tags?: (string | Tag)[] | null;
credits?: Credits;
updatedAt: string; updatedAt: string;
createdAt: string; createdAt: string;
url?: string | null; url?: string | null;
@ -190,6 +200,22 @@ export interface TagsGroup {
updatedAt: string; updatedAt: string;
createdAt: string; createdAt: string;
} }
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "credits-roles".
*/
export interface CreditsRole {
id: string;
slug: string;
icon?: string | null;
translations: {
language: string | Language;
name: string;
id?: string | null;
}[];
updatedAt: string;
createdAt: string;
}
/** /**
* This interface was referenced by `Config`'s JSON-Schema * This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "recorders". * via the `definition` "recorders".
@ -321,9 +347,7 @@ export interface Collectible {
| null; | null;
scansEnabled?: boolean | null; scansEnabled?: boolean | null;
scans?: { scans?: {
scanners: (string | Recorder)[]; credits?: Credits;
cleaners: (string | Recorder)[];
typesetters?: (string | Recorder)[] | null;
coverEnabled?: boolean | null; coverEnabled?: boolean | null;
cover?: { cover?: {
front?: string | Scan | null; front?: string | Scan | null;
@ -554,6 +578,7 @@ export interface Audio {
id?: string | null; id?: string | null;
}[]; }[];
tags?: (string | Tag)[] | null; tags?: (string | Tag)[] | null;
credits?: Credits;
updatedAt: string; updatedAt: string;
createdAt: string; createdAt: string;
url?: string | null; url?: string | null;
@ -626,6 +651,7 @@ export interface Video {
id?: string | null; id?: string | null;
}[]; }[];
tags?: (string | Tag)[] | null; tags?: (string | Tag)[] | null;
credits?: Credits;
platformEnabled?: boolean | null; platformEnabled?: boolean | null;
platform?: { platform?: {
channel: string | VideosChannel; channel: string | VideosChannel;
@ -716,9 +742,7 @@ export interface ChronologyEvent {
}; };
[k: string]: unknown; [k: string]: unknown;
} | null; } | null;
transcribers?: (string | Recorder)[] | null; credits?: Credits;
translators?: (string | Recorder)[] | null;
proofreaders?: (string | Recorder)[] | null;
id?: string | null; id?: string | null;
}[]; }[];
id?: string | null; id?: string | null;
@ -978,6 +1002,7 @@ export enum Collections {
VideosChannels = "videos-channels", VideosChannels = "videos-channels",
MediaThumbnails = "media-thumbnails", MediaThumbnails = "media-thumbnails",
Scans = "scans", Scans = "scans",
CreditsRole = "credits-roles",
} }
export enum CollectionGroups { export enum CollectionGroups {
@ -1034,12 +1059,6 @@ export enum CollectionStatus {
Published = "published", Published = "published",
} }
export enum PageType {
Content = "Content",
Post = "Post",
Generic = "Generic",
}
/* RICH TEXT */ /* RICH TEXT */
export type RichTextContent = { export type RichTextContent = {
@ -1428,11 +1447,22 @@ export type EndpointTagsGroup = {
tags: EndpointTag[]; tags: EndpointTag[];
}; };
export type EndpointRole = {
icon: string;
translations: {
language: string;
name: string;
}[];
};
export type EndpointCredit = {
role: EndpointRole;
recorders: EndpointRecorder[];
};
export type EndpointPage = { export type EndpointPage = {
slug: string; slug: string;
type: PageType;
thumbnail?: PayloadImage; thumbnail?: PayloadImage;
authors: EndpointRecorder[];
tagGroups: EndpointTagsGroup[]; tagGroups: EndpointTagsGroup[];
backgroundImage?: PayloadImage; backgroundImage?: PayloadImage;
translations: { translations: {
@ -1443,9 +1473,7 @@ export type EndpointPage = {
sourceLanguage: string; sourceLanguage: string;
summary?: RichTextContent; summary?: RichTextContent;
content: RichTextContent; content: RichTextContent;
transcribers: EndpointRecorder[]; credits: EndpointCredit[];
translators: EndpointRecorder[];
proofreaders: EndpointRecorder[];
toc: TableOfContentEntry[]; toc: TableOfContentEntry[];
}[]; }[];
parentPages: EndpointSource[]; parentPages: EndpointSource[];
@ -1554,9 +1582,7 @@ export type EndpointChronologyEvent = {
title?: string; title?: string;
description?: RichTextContent; description?: RichTextContent;
notes?: RichTextContent; notes?: RichTextContent;
transcribers: EndpointRecorder[]; credits: EndpointCredit[];
translators: EndpointRecorder[];
proofreaders: EndpointRecorder[];
}[]; }[];
}[]; }[];
}; };
@ -1588,6 +1614,7 @@ export type EndpointMedia = {
title: string; title: string;
description?: RichTextContent; description?: RichTextContent;
}[]; }[];
credits: EndpointCredit[];
}; };
export type EndpointImage = EndpointMedia & { export type EndpointImage = EndpointMedia & {