Added gallery and scans pages
This commit is contained in:
parent
9653747dd8
commit
470ba03402
13
TODO.md
13
TODO.md
|
@ -2,21 +2,28 @@
|
|||
|
||||
## Short term
|
||||
|
||||
- [Medias] Add Parent pages
|
||||
- [Timeline] inline links to pages not working (timeline 2026/06)
|
||||
- Fix inconsistency with material-icon in Payload (with or without material-icon prefix)
|
||||
- [Media] display filename alongside the localized title.
|
||||
- [Media] Have a title, subtitle, pretitle just like everything else
|
||||
- Background images some times lack gradient at the bottom and fade in before they could load
|
||||
- Number of audio players seems limited (on Chrome and Firefox)
|
||||
|
||||
## Mid term
|
||||
|
||||
- [Medias] Add Parent pages
|
||||
- [Scans] Adapt size of obi based on cover/dustjacket
|
||||
- [Scans] Order of cover/dustjacket/obi should be based on the book's page order.
|
||||
- [RichTextContent] Add autolink block support
|
||||
- Save cookies for longer than just the session
|
||||
- [Scripts] Can't run the scripts using node (ts-node?)
|
||||
- Support for nameless section
|
||||
- [Timeline] Error if collectible not published?
|
||||
- [Timeline] Handle no JS for footers
|
||||
- [Timeline] Add details button in footer with credits + last updated / created
|
||||
- [Collectibles] Create page for gallery
|
||||
- [Collectibles] Create page for scans
|
||||
- When the tags overflow, the tag group name should be align start (see http://localhost:12499/en/pages/magnitude-negative-chapter-1)
|
||||
- [SDK] create a initPayload() that return a payload sdk (and stop hard wirring to ENV or node-cache)
|
||||
- [Videos] see why no video on Firefox and no poster on Chrome https://v3.accords-library.com/en/videos/661b672825d380e548dbb8c8
|
||||
|
||||
## Long term
|
||||
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
---
|
||||
import Button from "components/Button.astro";
|
||||
import {
|
||||
type EndpointCredit,
|
||||
type EndpointTagsGroup,
|
||||
type PayloadImage,
|
||||
type RichTextContent,
|
||||
} from "src/shared/payload/payload-sdk";
|
||||
import RichText from "./RichText/RichText.astro";
|
||||
import TagGroups from "./TagGroups.astro";
|
||||
import Credits from "./Credits.astro";
|
||||
import DownloadButton from "./DownloadButton.astro";
|
||||
|
||||
interface Props {
|
||||
previousImageHref?: string | undefined;
|
||||
nextImageHref?: string | undefined;
|
||||
image: PayloadImage;
|
||||
title: string;
|
||||
description?: RichTextContent | undefined;
|
||||
tagGroups?: EndpointTagsGroup[] | undefined;
|
||||
credits?: EndpointCredit[] | undefined;
|
||||
filename?: string | undefined;
|
||||
}
|
||||
|
||||
const {
|
||||
nextImageHref,
|
||||
previousImageHref,
|
||||
image: { url, width, height },
|
||||
tagGroups,
|
||||
credits,
|
||||
description,
|
||||
title,
|
||||
filename,
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<div id="container">
|
||||
<div id="image-viewer" class:list={{ "with-buttons": previousImageHref || nextImageHref }}>
|
||||
<a
|
||||
class:list={{ hidden: !previousImageHref }}
|
||||
href={previousImageHref}
|
||||
data-astro-history="replace">
|
||||
<Button icon="material-symbols:chevron-left" />
|
||||
</a>
|
||||
|
||||
<a href={url} target="_blank"><img src={url} width={width} height={height} /></a>
|
||||
|
||||
<a class:list={{ hidden: !nextImageHref }} href={nextImageHref} data-astro-history="replace">
|
||||
<Button icon="material-symbols:chevron-right" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="info"
|
||||
class:list={{
|
||||
complex:
|
||||
(tagGroups && tagGroups.length > 0) || (credits && credits.length > 0) || description,
|
||||
}}>
|
||||
<h1>{title}</h1>
|
||||
{description && <RichText content={description} />}
|
||||
<div>
|
||||
{tagGroups && tagGroups.length > 0 && <TagGroups {tagGroups} />}
|
||||
{credits && credits.length > 0 && <Credits credits={credits} />}
|
||||
</div>
|
||||
{filename && <DownloadButton href={url} filename={filename} />}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
#container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3em;
|
||||
align-items: center;
|
||||
margin-top: 3em;
|
||||
|
||||
& > #image-viewer {
|
||||
&.with-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
gap: 1em;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
& > a.hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
img {
|
||||
max-height: 70vh;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
& > #info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
align-items: center;
|
||||
|
||||
&.complex {
|
||||
gap: 2em;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
& > h1 {
|
||||
max-width: 35em;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,10 +1,10 @@
|
|||
---
|
||||
import type { PayloadImage } from "src/shared/payload/payload-sdk";
|
||||
import InlineTagGroups from "pages/[locale]/collectibles/_components/ContentsSection/InlineTagGroups.astro";
|
||||
import Card from "components/Card.astro";
|
||||
import { Icon } from "astro-icon/components";
|
||||
import type { ComponentProps } from "astro/types";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import InlineTagGroups from "components/InlineTagGroups.astro";
|
||||
|
||||
interface Props {
|
||||
thumbnail?: PayloadImage | undefined;
|
||||
|
|
|
@ -173,6 +173,50 @@ export const getI18n = async (locale: string) => {
|
|||
);
|
||||
};
|
||||
|
||||
const formatScanIndexShort = (index: string) => {
|
||||
switch (index) {
|
||||
case "cover-flap-front":
|
||||
case "dustjacket-flap-front":
|
||||
case "dustjacket-inside-flap-front":
|
||||
case "obi-flap-front":
|
||||
case "obi-inside-flap-front":
|
||||
return t("collectibles.scans.shortIndex.flapFront");
|
||||
|
||||
case "cover-front":
|
||||
case "cover-inside-front":
|
||||
case "dustjacket-front":
|
||||
case "dustjacket-inside-front":
|
||||
case "obi-front":
|
||||
case "obi-inside-front":
|
||||
return t("collectibles.scans.shortIndex.front");
|
||||
|
||||
case "cover-spine":
|
||||
case "dustjacket-spine":
|
||||
case "dustjacket-inside-spine":
|
||||
case "obi-spine":
|
||||
case "obi-inside-spine":
|
||||
return t("collectibles.scans.shortIndex.spine");
|
||||
|
||||
case "cover-back":
|
||||
case "cover-inside-back":
|
||||
case "dustjacket-back":
|
||||
case "dustjacket-inside-back":
|
||||
case "obi-back":
|
||||
case "obi-inside-back":
|
||||
return t("collectibles.scans.shortIndex.back");
|
||||
|
||||
case "cover-flap-back":
|
||||
case "dustjacket-flap-back":
|
||||
case "dustjacket-inside-flap-back":
|
||||
case "obi-flap-back":
|
||||
case "obi-inside-flap-back":
|
||||
return t("collectibles.scans.shortIndex.flapBack");
|
||||
|
||||
default:
|
||||
return index;
|
||||
}
|
||||
};
|
||||
|
||||
const formatEndpointSource = (source: EndpointSource) => {
|
||||
switch (source.type) {
|
||||
case "url":
|
||||
|
@ -228,6 +272,20 @@ export const getI18n = async (locale: string) => {
|
|||
label: getLocalizedMatch(source.folder.translations).name,
|
||||
};
|
||||
|
||||
case "scans":
|
||||
return {
|
||||
href: getLocalizedUrl(`/collectibles/${source.collectible.slug}/scans`),
|
||||
typeLabel: t("global.sources.typeLabel.scans"),
|
||||
label: formatInlineTitle(getLocalizedMatch(source.collectible.translations)),
|
||||
};
|
||||
|
||||
case "gallery":
|
||||
return {
|
||||
href: getLocalizedUrl(`/collectibles/${source.collectible.slug}/gallery`),
|
||||
typeLabel: t("global.sources.typeLabel.gallery"),
|
||||
label: formatInlineTitle(getLocalizedMatch(source.collectible.translations)),
|
||||
};
|
||||
|
||||
default:
|
||||
return {
|
||||
href: "/404",
|
||||
|
@ -250,5 +308,6 @@ export const getI18n = async (locale: string) => {
|
|||
formatNumber,
|
||||
formatTimelineDate,
|
||||
formatEndpointSource,
|
||||
formatScanIndexShort,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -89,29 +89,29 @@ export type WordingKey =
|
|||
| "pages.tableOfContent.break"
|
||||
| "global.languageOverride.availableLanguages"
|
||||
| "timeline.title"
|
||||
| "timeline.description"
|
||||
| "timeline.eras.cataclysm"
|
||||
| "timeline.eras.drakengard3"
|
||||
| "timeline.eras.drakengard"
|
||||
| "timeline.eras.drakengard2"
|
||||
| "timeline.eras.drakengard3"
|
||||
| "timeline.eras.nier"
|
||||
| "timeline.eras.nierAutomata"
|
||||
| "timeline.jumpTo"
|
||||
| "timeline.notes.content"
|
||||
| "timeline.eras.cataclysm"
|
||||
| "timeline.description"
|
||||
| "timeline.notes.title"
|
||||
| "timeline.notes.content"
|
||||
| "timeline.priorCataclysmNote.title"
|
||||
| "timeline.priorCataclysmNote.content"
|
||||
| "timeline.jumpTo"
|
||||
| "timeline.year.during"
|
||||
| "timeline.eventFooter.sources"
|
||||
| "timeline.eventFooter.languages"
|
||||
| "timeline.eventFooter.sources"
|
||||
| "timeline.eventFooter.note"
|
||||
| "global.sources.typeLabel.url"
|
||||
| "global.sources.typeLabel.page"
|
||||
| "global.sources.typeLabel.collectible"
|
||||
| "global.sources.typeLabel.collectible.range.custom"
|
||||
| "global.sources.typeLabel.folder"
|
||||
| "global.sources.typeLabel.collectible.range.page"
|
||||
| "global.sources.typeLabel.collectible.range.timestamp"
|
||||
| "global.sources.typeLabel.folder"
|
||||
| "global.sources.typeLabel.page"
|
||||
| "global.sources.typeLabel.url"
|
||||
| "global.sources.typeLabel.collectible.range.custom"
|
||||
| "global.openMediaPage"
|
||||
| "global.downloadButton"
|
||||
| "global.previewTypes.video"
|
||||
|
@ -119,4 +119,24 @@ export type WordingKey =
|
|||
| "global.previewTypes.image"
|
||||
| "global.previewTypes.audio"
|
||||
| "global.previewTypes.collectible"
|
||||
| "global.previewTypes.unknown";
|
||||
| "global.previewTypes.unknown"
|
||||
| "collectibles.scans.title"
|
||||
| "collectibles.scans.subtitle"
|
||||
| "collectibles.scans.shortIndex.flapFront"
|
||||
| "collectibles.scans.shortIndex.front"
|
||||
| "collectibles.scans.shortIndex.spine"
|
||||
| "collectibles.scans.shortIndex.back"
|
||||
| "collectibles.scans.shortIndex.flapBack"
|
||||
| "collectibles.scans.cover"
|
||||
| "collectibles.scans.coverInside"
|
||||
| "collectibles.scans.dustjacket"
|
||||
| "collectibles.scans.dustjacketInside"
|
||||
| "collectibles.scans.obi"
|
||||
| "collectibles.scans.obiInside"
|
||||
| "collectibles.scans.pages"
|
||||
| "collectibles.gallery.title"
|
||||
| "collectibles.gallery.subtitle"
|
||||
| "global.sources.typeLabel.scans"
|
||||
| "collectibles.scans.dustjacket.description"
|
||||
| "collectibles.scans.obi.description"
|
||||
| "global.sources.typeLabel.gallery";
|
||||
|
|
|
@ -4,7 +4,7 @@ import RichText from "components/RichText/RichText.astro";
|
|||
import { getI18n } from "src/i18n/i18n";
|
||||
import { Collections, type EndpointCollectible } from "src/shared/payload/payload-sdk";
|
||||
import { formatInlineTitle } from "src/utils/format";
|
||||
import InlineTagGroups from "./InlineTagGroups.astro";
|
||||
import InlineTagGroups from "../../../../../../components/InlineTagGroups.astro";
|
||||
import Card from "components/Card.astro";
|
||||
import AudioPlayer from "components/AudioPlayer.astro";
|
||||
import VideoPlayer from "components/VideoPlayer.astro";
|
|
@ -3,26 +3,27 @@ interface Props {
|
|||
image: string;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
const { image, title, subtitle } = Astro.props;
|
||||
const { image, title, subtitle, href } = Astro.props;
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<div id="tile">
|
||||
<a href={href}>
|
||||
<img src={image} />
|
||||
|
||||
<div class="high-contrast-text">
|
||||
<p class="title">{title}</p>
|
||||
<p>{subtitle}</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
#tile {
|
||||
a {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
aspect-ratio: 1 / 1;
|
||||
|
@ -33,6 +34,12 @@ const { image, title, subtitle } = Astro.props;
|
|||
border-radius: 12px;
|
||||
box-shadow: 0 5px 20px -10px var(--color-shadow);
|
||||
|
||||
transition: 100ms scale;
|
||||
|
||||
&:hover {
|
||||
scale: 102%;
|
||||
}
|
||||
|
||||
& > div {
|
||||
text-align: center;
|
||||
backdrop-filter: blur(5px);
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import Lightbox from "components/Lightbox.astro";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import { payload } from "src/shared/payload/payload-sdk";
|
||||
import { fetchOr404 } from "src/utils/responses";
|
||||
|
||||
const slug = Astro.params.slug!;
|
||||
const index = Astro.params.index!;
|
||||
const { getLocalizedUrl, getLocalizedMatch } = await getI18n(Astro.locals.currentLocale);
|
||||
|
||||
const galleryImage = await fetchOr404(() => payload.getCollectibleGalleryImage(slug, index));
|
||||
if (galleryImage instanceof Response) {
|
||||
return galleryImage;
|
||||
}
|
||||
|
||||
const { parentPages, previousIndex, nextIndex, image } = galleryImage;
|
||||
|
||||
const { title, description } =
|
||||
image.translations.length > 0
|
||||
? getLocalizedMatch(image.translations)
|
||||
: { title: image.filename, description: undefined };
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<AppEmptyLayout parentPages={parentPages}>
|
||||
<Lightbox
|
||||
image={image}
|
||||
title={title}
|
||||
previousImageHref={previousIndex
|
||||
? getLocalizedUrl(`/collectibles/${slug}/gallery/${previousIndex}`)
|
||||
: undefined}
|
||||
nextImageHref={nextIndex
|
||||
? getLocalizedUrl(`/collectibles/${slug}/gallery/${nextIndex}`)
|
||||
: undefined}
|
||||
description={description}
|
||||
filename={image.filename}
|
||||
tagGroups={image.tagGroups}
|
||||
credits={image.credits}
|
||||
/>
|
||||
</AppEmptyLayout>
|
|
@ -0,0 +1,80 @@
|
|||
---
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||
import RichText from "components/RichText/RichText.astro";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import { payload } from "src/shared/payload/payload-sdk";
|
||||
import { fetchOr404 } from "src/utils/responses";
|
||||
|
||||
const slug = Astro.params.slug!;
|
||||
const { getLocalizedMatch, getLocalizedUrl } = await getI18n(Astro.locals.currentLocale);
|
||||
|
||||
const gallery = await fetchOr404(() => payload.getCollectibleGallery(slug));
|
||||
if (gallery instanceof Response) {
|
||||
return gallery;
|
||||
}
|
||||
|
||||
const { translations, parentPages, images } = gallery;
|
||||
const translation = getLocalizedMatch(translations);
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<AppEmptyLayout parentPages={parentPages}>
|
||||
<AppLayoutTitle
|
||||
title={translation.title}
|
||||
pretitle={translation.pretitle}
|
||||
subtitle={translation.subtitle}
|
||||
/>
|
||||
|
||||
{
|
||||
translation.description && (
|
||||
<div id="summary" class="high-contrast-text">
|
||||
<RichText content={translation.description} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<div>
|
||||
{
|
||||
images.map((image, index) => (
|
||||
<a href={getLocalizedUrl(`/collectibles/${slug}/gallery/${index}`)}>
|
||||
<img src={image.url} />
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</AppEmptyLayout>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
div {
|
||||
margin-top: 3em;
|
||||
display: flex;
|
||||
gap: 2em;
|
||||
flex-wrap: wrap;
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
text-align: center;
|
||||
place-items: center;
|
||||
|
||||
transition: 100ms scale;
|
||||
|
||||
&:hover {
|
||||
scale: 104%;
|
||||
}
|
||||
|
||||
& > img {
|
||||
max-height: 20em;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
width: auto;
|
||||
box-shadow: 0 5px 20px -10px var(--color-shadow);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -44,9 +44,6 @@ const {
|
|||
} = collectible;
|
||||
|
||||
const translation = getLocalizedMatch(translations);
|
||||
|
||||
const galleryFirstImage = gallery[0];
|
||||
const scansFirstImage = scans[0];
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
@ -82,21 +79,23 @@ const scansFirstImage = scans[0];
|
|||
|
||||
<div id="gallery-scans" class="when-no-print">
|
||||
{
|
||||
galleryFirstImage && (
|
||||
gallery && (
|
||||
<ImageTile
|
||||
image={galleryFirstImage.url}
|
||||
title="Gallery"
|
||||
subtitle={`${gallery.length} images`}
|
||||
image={gallery.thumbnail.url}
|
||||
title={t("collectibles.gallery.title")}
|
||||
subtitle={t("collectibles.gallery.subtitle", { count: gallery.count })}
|
||||
href={getLocalizedUrl(`/collectibles/${slug}/gallery`)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
scansFirstImage && (
|
||||
scans && (
|
||||
<ImageTile
|
||||
image={scansFirstImage.url}
|
||||
title="Scans"
|
||||
subtitle={`${scans.length} images`}
|
||||
image={scans.thumbnail.url}
|
||||
title={t("collectibles.scans.title")}
|
||||
subtitle={t("collectibles.scans.subtitle", { count: scans.count })}
|
||||
href={getLocalizedUrl(`/collectibles/${slug}/scans`)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -134,21 +133,23 @@ const scansFirstImage = scans[0];
|
|||
<div id="images">
|
||||
<div id="gallery-scans" class="when-no-print">
|
||||
{
|
||||
galleryFirstImage && (
|
||||
gallery && (
|
||||
<ImageTile
|
||||
image={galleryFirstImage.url}
|
||||
title={t("collectibles.gallery")}
|
||||
subtitle={t("collectibles.imageCount", { count: gallery.length })}
|
||||
image={gallery.thumbnail.url}
|
||||
title={t("collectibles.gallery.title")}
|
||||
subtitle={t("collectibles.gallery.subtitle", { count: gallery.count })}
|
||||
href={getLocalizedUrl(`/collectibles/${slug}/gallery`)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
scansFirstImage && (
|
||||
scans && (
|
||||
<ImageTile
|
||||
image={scansFirstImage.url}
|
||||
title={t("collectibles.scans")}
|
||||
subtitle={t("collectibles.imageCount", { count: scans.length })}
|
||||
image={scans.thumbnail.url}
|
||||
title={t("collectibles.scans.title")}
|
||||
subtitle={t("collectibles.scans.subtitle", { count: scans.count })}
|
||||
href={getLocalizedUrl(`/collectibles/${slug}/scans`)}
|
||||
/>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import Lightbox from "components/Lightbox.astro";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import { payload } from "src/shared/payload/payload-sdk";
|
||||
import { fetchOr404 } from "src/utils/responses";
|
||||
|
||||
const slug = Astro.params.slug!;
|
||||
const index = Astro.params.index!;
|
||||
const { formatScanIndexShort, getLocalizedUrl } = await getI18n(Astro.locals.currentLocale);
|
||||
|
||||
const scanPage = await fetchOr404(() => payload.getCollectibleScanPage(slug, index));
|
||||
if (scanPage instanceof Response) {
|
||||
return scanPage;
|
||||
}
|
||||
|
||||
const { parentPages, previousIndex, nextIndex, image } = scanPage;
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<AppEmptyLayout parentPages={parentPages}>
|
||||
<Lightbox
|
||||
image={image}
|
||||
title={formatScanIndexShort(index)}
|
||||
previousImageHref={previousIndex
|
||||
? getLocalizedUrl(`/collectibles/${slug}/scans/${previousIndex}`)
|
||||
: undefined}
|
||||
nextImageHref={nextIndex
|
||||
? getLocalizedUrl(`/collectibles/${slug}/scans/${nextIndex}`)
|
||||
: undefined}
|
||||
filename={image.filename}
|
||||
/>
|
||||
</AppEmptyLayout>
|
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import type { EndpointScanImage } from "src/shared/payload/payload-sdk";
|
||||
|
||||
interface Props {
|
||||
scan: EndpointScanImage;
|
||||
collectibleSlug: string;
|
||||
}
|
||||
|
||||
const {
|
||||
scan: { url, index, width, height },
|
||||
collectibleSlug,
|
||||
} = Astro.props;
|
||||
|
||||
const { getLocalizedUrl, formatScanIndexShort } = await getI18n(Astro.locals.currentLocale);
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<a href={getLocalizedUrl(`/collectibles/${collectibleSlug}/scans/${index}`)}>
|
||||
<img width={width} height={height} src={url} alt={index} />
|
||||
<p>{formatScanIndexShort(index)}</p>
|
||||
</a>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
a {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
text-align: center;
|
||||
place-items: center;
|
||||
|
||||
transition: 100ms scale;
|
||||
|
||||
&:hover {
|
||||
scale: 104%;
|
||||
}
|
||||
|
||||
& > img {
|
||||
max-height: 20em;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
width: auto;
|
||||
box-shadow: 0 5px 20px -10px var(--color-shadow);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,215 @@
|
|||
---
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||
import Credits from "components/Credits.astro";
|
||||
import RichText from "components/RichText/RichText.astro";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import { payload } from "src/shared/payload/payload-sdk";
|
||||
import { fetchOr404 } from "src/utils/responses";
|
||||
import ScanPreview from "./_components/ScanPreview.astro";
|
||||
|
||||
const slug = Astro.params.slug!;
|
||||
const { getLocalizedMatch, t } = await getI18n(Astro.locals.currentLocale);
|
||||
|
||||
const scans = await fetchOr404(() => payload.getCollectibleScans(slug));
|
||||
if (scans instanceof Response) {
|
||||
return scans;
|
||||
}
|
||||
|
||||
const { translations, credits, cover, pages, dustjacket, obi, parentPages } = scans;
|
||||
|
||||
const translation = getLocalizedMatch(translations);
|
||||
|
||||
const hasInsideCover = cover ? Object.keys(cover).some((value) => value.includes("inside")) : false;
|
||||
const hasOutsideCover = cover
|
||||
? Object.keys(cover).some((value) => !value.includes("inside"))
|
||||
: false;
|
||||
|
||||
const hasInsideDustjacket = dustjacket
|
||||
? Object.keys(dustjacket).some((value) => value.includes("inside"))
|
||||
: false;
|
||||
const hasOutsideDustjacket = dustjacket
|
||||
? Object.keys(dustjacket).some((value) => !value.includes("inside"))
|
||||
: false;
|
||||
|
||||
const hasInsideObi = obi ? Object.keys(obi).some((value) => value.includes("inside")) : false;
|
||||
const hasOutsideObi = obi ? Object.keys(obi).some((value) => !value.includes("inside")) : false;
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<AppEmptyLayout parentPages={parentPages}>
|
||||
<AppLayoutTitle
|
||||
title={translation.title}
|
||||
pretitle={translation.pretitle}
|
||||
subtitle={translation.subtitle}
|
||||
/>
|
||||
|
||||
{
|
||||
translation.description && (
|
||||
<div id="summary" class="high-contrast-text">
|
||||
<RichText content={translation.description} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
{credits.length > 0 && <Credits credits={credits} />}
|
||||
|
||||
{
|
||||
cover && (
|
||||
<>
|
||||
{hasOutsideCover && (
|
||||
<section>
|
||||
<h2>{t("collectibles.scans.cover")}</h2>
|
||||
<div>
|
||||
{cover.flapFront && <ScanPreview collectibleSlug={slug} scan={cover.flapFront} />}
|
||||
{cover.front && <ScanPreview collectibleSlug={slug} scan={cover.front} />}
|
||||
{cover.spine && <ScanPreview collectibleSlug={slug} scan={cover.spine} />}
|
||||
{cover.back && <ScanPreview collectibleSlug={slug} scan={cover.back} />}
|
||||
{cover.flapBack && <ScanPreview collectibleSlug={slug} scan={cover.flapBack} />}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
{hasInsideCover && (
|
||||
<section>
|
||||
<h2>{t("collectibles.scans.coverInside")}</h2>
|
||||
<div>
|
||||
{cover.insideFlapFront && (
|
||||
<ScanPreview collectibleSlug={slug} scan={cover.insideFlapFront} />
|
||||
)}
|
||||
{cover.insideFront && <ScanPreview collectibleSlug={slug} scan={cover.insideFront} />}
|
||||
{cover.insideBack && <ScanPreview collectibleSlug={slug} scan={cover.insideBack} />}
|
||||
{cover.insideFlapBack && (
|
||||
<ScanPreview collectibleSlug={slug} scan={cover.insideFlapBack} />
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
dustjacket && (
|
||||
<>
|
||||
{hasOutsideDustjacket && (
|
||||
<section>
|
||||
<h2>{t("collectibles.scans.dustjacket")}</h2>
|
||||
<p class="prose">{t("collectibles.scans.dustjacket.description")}</p>
|
||||
<div>
|
||||
{dustjacket.flapFront && (
|
||||
<ScanPreview collectibleSlug={slug} scan={dustjacket.flapFront} />
|
||||
)}
|
||||
{dustjacket.front && <ScanPreview collectibleSlug={slug} scan={dustjacket.front} />}
|
||||
{dustjacket.spine && <ScanPreview collectibleSlug={slug} scan={dustjacket.spine} />}
|
||||
{dustjacket.back && <ScanPreview collectibleSlug={slug} scan={dustjacket.back} />}
|
||||
{dustjacket.flapBack && (
|
||||
<ScanPreview collectibleSlug={slug} scan={dustjacket.flapBack} />
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
{hasInsideDustjacket && (
|
||||
<section>
|
||||
<h2>{t("collectibles.scans.dustjacketInside")}</h2>
|
||||
<div>
|
||||
{dustjacket.insideFlapFront && (
|
||||
<ScanPreview collectibleSlug={slug} scan={dustjacket.insideFlapFront} />
|
||||
)}
|
||||
{dustjacket.insideFront && (
|
||||
<ScanPreview collectibleSlug={slug} scan={dustjacket.insideFront} />
|
||||
)}
|
||||
{dustjacket.insideSpine && (
|
||||
<ScanPreview collectibleSlug={slug} scan={dustjacket.insideSpine} />
|
||||
)}
|
||||
{dustjacket.insideBack && (
|
||||
<ScanPreview collectibleSlug={slug} scan={dustjacket.insideBack} />
|
||||
)}
|
||||
{dustjacket.insideFlapBack && (
|
||||
<ScanPreview collectibleSlug={slug} scan={dustjacket.insideFlapBack} />
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
obi && (
|
||||
<>
|
||||
{hasOutsideObi && (
|
||||
<section>
|
||||
<h2>{t("collectibles.scans.obi")}</h2>
|
||||
<p class="prose">{t("collectibles.scans.obi.description")}</p>
|
||||
<div>
|
||||
{obi.flapFront && <ScanPreview collectibleSlug={slug} scan={obi.flapFront} />}
|
||||
{obi.front && <ScanPreview collectibleSlug={slug} scan={obi.front} />}
|
||||
{obi.spine && <ScanPreview collectibleSlug={slug} scan={obi.spine} />}
|
||||
{obi.back && <ScanPreview collectibleSlug={slug} scan={obi.back} />}
|
||||
{obi.flapBack && <ScanPreview collectibleSlug={slug} scan={obi.flapBack} />}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
{hasInsideObi && (
|
||||
<section>
|
||||
<h2>{t("collectibles.scans.obiInside")}</h2>
|
||||
<div>
|
||||
{obi.insideFlapFront && (
|
||||
<ScanPreview collectibleSlug={slug} scan={obi.insideFlapFront} />
|
||||
)}
|
||||
{obi.insideFront && <ScanPreview collectibleSlug={slug} scan={obi.insideFront} />}
|
||||
{obi.insideSpine && <ScanPreview collectibleSlug={slug} scan={obi.insideSpine} />}
|
||||
{obi.insideBack && <ScanPreview collectibleSlug={slug} scan={obi.insideBack} />}
|
||||
{obi.insideFlapBack && (
|
||||
<ScanPreview collectibleSlug={slug} scan={obi.insideFlapBack} />
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
pages.length > 0 && (
|
||||
<section>
|
||||
<h2>{t("collectibles.scans.pages")}</h2>
|
||||
<div>
|
||||
{pages.map((image) => (
|
||||
<ScanPreview collectibleSlug={slug} scan={image} />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
</AppEmptyLayout>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
#summary {
|
||||
margin-block: 2.5em;
|
||||
}
|
||||
|
||||
section {
|
||||
margin-block: 6em;
|
||||
|
||||
& > h2 {
|
||||
font-family: var(--font-serif);
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
& > p {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
& > div {
|
||||
margin-top: 1em;
|
||||
display: flex;
|
||||
gap: 2em;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,9 +1,6 @@
|
|||
---
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import Credits from "components/Credits.astro";
|
||||
import DownloadButton from "components/DownloadButton.astro";
|
||||
import RichText from "components/RichText/RichText.astro";
|
||||
import TagGroups from "components/TagGroups.astro";
|
||||
import Lightbox from "components/Lightbox.astro";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import { payload } from "src/shared/payload/payload-sdk";
|
||||
import { fetchOr404 } from "src/utils/responses";
|
||||
|
@ -15,7 +12,7 @@ if (image instanceof Response) {
|
|||
}
|
||||
|
||||
const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale);
|
||||
const { url, width, height, filename, translations, tagGroups, credits } = image;
|
||||
const { filename, translations, tagGroups, credits } = image;
|
||||
|
||||
const { title, description } =
|
||||
translations.length > 0
|
||||
|
@ -26,57 +23,12 @@ const { title, description } =
|
|||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<AppEmptyLayout>
|
||||
<div id="container">
|
||||
<a href={url} target="_blank">
|
||||
<img src={url} width={width} height={height} />
|
||||
</a>
|
||||
|
||||
<div>
|
||||
<h1>{title}</h1>
|
||||
{description && <RichText content={description} />}
|
||||
<div>
|
||||
{tagGroups.length > 0 && <TagGroups {tagGroups} />}
|
||||
{credits.length > 0 && <Credits credits={credits} />}
|
||||
</div>
|
||||
<DownloadButton href={url} filename={filename} />
|
||||
</div>
|
||||
</div>
|
||||
<Lightbox
|
||||
image={image}
|
||||
title={title}
|
||||
description={description}
|
||||
filename={filename}
|
||||
tagGroups={tagGroups}
|
||||
credits={credits}
|
||||
/>
|
||||
</AppEmptyLayout>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
#container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6em;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
max-height: 60vh;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
max-width: 35em;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2em;
|
||||
align-items: start;
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
gap: 2em 6em;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -23,27 +23,27 @@ export interface Config {
|
|||
pages: Page;
|
||||
collectibles: Collectible;
|
||||
folders: Folder;
|
||||
'chronology-events': ChronologyEvent;
|
||||
"chronology-events": ChronologyEvent;
|
||||
images: Image;
|
||||
audios: Audio;
|
||||
'media-thumbnails': MediaThumbnail;
|
||||
"media-thumbnails": MediaThumbnail;
|
||||
videos: Video;
|
||||
'videos-subtitles': VideoSubtitle;
|
||||
'videos-channels': VideosChannel;
|
||||
"videos-subtitles": VideoSubtitle;
|
||||
"videos-channels": VideosChannel;
|
||||
scans: Scan;
|
||||
tags: Tag;
|
||||
'tags-groups': TagsGroup;
|
||||
'credits-roles': CreditsRole;
|
||||
"tags-groups": TagsGroup;
|
||||
"credits-roles": CreditsRole;
|
||||
recorders: Recorder;
|
||||
languages: Language;
|
||||
currencies: Currency;
|
||||
wordings: Wording;
|
||||
'generic-contents': GenericContent;
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
"generic-contents": GenericContent;
|
||||
"payload-preferences": PayloadPreference;
|
||||
"payload-migrations": PayloadMigration;
|
||||
};
|
||||
globals: {
|
||||
'website-config': WebsiteConfig;
|
||||
"website-config": WebsiteConfig;
|
||||
};
|
||||
}
|
||||
/**
|
||||
|
@ -70,8 +70,8 @@ export interface Page {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -85,8 +85,8 @@ export interface Page {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -100,7 +100,7 @@ export interface Page {
|
|||
updatedBy: string | Recorder;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
_status?: ("draft" | "published") | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
@ -120,8 +120,8 @@ export interface Image {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -225,7 +225,7 @@ export interface Recorder {
|
|||
username: string;
|
||||
avatar?: string | Image | null;
|
||||
languages?: (string | Language)[] | null;
|
||||
role?: ('Admin' | 'Recorder' | 'Api')[] | null;
|
||||
role?: ("Admin" | "Recorder" | "Api")[] | null;
|
||||
anonymize: boolean;
|
||||
email: string;
|
||||
resetPasswordToken?: string | null;
|
||||
|
@ -256,8 +256,8 @@ export interface Folder {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -281,23 +281,23 @@ export interface Folder {
|
|||
files?:
|
||||
| (
|
||||
| {
|
||||
relationTo: 'collectibles';
|
||||
relationTo: "collectibles";
|
||||
value: string | Collectible;
|
||||
}
|
||||
| {
|
||||
relationTo: 'pages';
|
||||
relationTo: "pages";
|
||||
value: string | Page;
|
||||
}
|
||||
| {
|
||||
relationTo: 'videos';
|
||||
relationTo: "videos";
|
||||
value: string | Video;
|
||||
}
|
||||
| {
|
||||
relationTo: 'images';
|
||||
relationTo: "images";
|
||||
value: string | Image;
|
||||
}
|
||||
| {
|
||||
relationTo: 'audios';
|
||||
relationTo: "audios";
|
||||
value: string | Audio;
|
||||
}
|
||||
)[]
|
||||
|
@ -313,7 +313,7 @@ export interface Collectible {
|
|||
id: string;
|
||||
slug: string;
|
||||
thumbnail?: string | Image | null;
|
||||
nature: 'Physical' | 'Digital';
|
||||
nature: "Physical" | "Digital";
|
||||
languages?: (string | Language)[] | null;
|
||||
tags?: (string | Tag)[] | null;
|
||||
translations: {
|
||||
|
@ -329,8 +329,8 @@ export interface Collectible {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -419,8 +419,8 @@ export interface Collectible {
|
|||
pageInfoEnabled?: boolean | null;
|
||||
pageInfo?: {
|
||||
pageCount: number;
|
||||
bindingType?: ('Paperback' | 'Hardcover') | null;
|
||||
pageOrder?: ('Left to right' | 'Right to left') | null;
|
||||
bindingType?: ("Paperback" | "Hardcover") | null;
|
||||
pageOrder?: ("Left to right" | "Right to left") | null;
|
||||
};
|
||||
folders?: (string | Folder)[] | null;
|
||||
parentItems?: (string | Collectible)[] | null;
|
||||
|
@ -429,19 +429,19 @@ export interface Collectible {
|
|||
| {
|
||||
content:
|
||||
| {
|
||||
relationTo: 'pages';
|
||||
relationTo: "pages";
|
||||
value: string | Page;
|
||||
}
|
||||
| {
|
||||
relationTo: 'generic-contents';
|
||||
relationTo: "generic-contents";
|
||||
value: string | GenericContent;
|
||||
}
|
||||
| {
|
||||
relationTo: 'audios';
|
||||
relationTo: "audios";
|
||||
value: string | Audio;
|
||||
}
|
||||
| {
|
||||
relationTo: 'videos';
|
||||
relationTo: "videos";
|
||||
value: string | Video;
|
||||
};
|
||||
range?:
|
||||
|
@ -451,14 +451,14 @@ export interface Collectible {
|
|||
end: number;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'pageRange';
|
||||
blockType: "pageRange";
|
||||
}
|
||||
| {
|
||||
start: string;
|
||||
end: string;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'timeRange';
|
||||
blockType: "timeRange";
|
||||
}
|
||||
| {
|
||||
translations: {
|
||||
|
@ -471,8 +471,8 @@ export interface Collectible {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -482,7 +482,7 @@ export interface Collectible {
|
|||
}[];
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'other';
|
||||
blockType: "other";
|
||||
}
|
||||
)[]
|
||||
| null;
|
||||
|
@ -492,7 +492,7 @@ export interface Collectible {
|
|||
updatedBy: string | Recorder;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
_status?: ("draft" | "published") | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
@ -568,8 +568,8 @@ export interface Audio {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -640,8 +640,8 @@ export interface Video {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -720,8 +720,8 @@ export interface ChronologyEvent {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -735,8 +735,8 @@ export interface ChronologyEvent {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -750,7 +750,7 @@ export interface ChronologyEvent {
|
|||
updatedBy: string | Recorder;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
_status?: ("draft" | "published") | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
@ -760,7 +760,7 @@ export interface UrlBlock {
|
|||
url: string;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'urlBlock';
|
||||
blockType: "urlBlock";
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
@ -774,13 +774,13 @@ export interface CollectibleBlock {
|
|||
page: number;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'page';
|
||||
blockType: "page";
|
||||
}
|
||||
| {
|
||||
timestamp: string;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'timestamp';
|
||||
blockType: "timestamp";
|
||||
}
|
||||
| {
|
||||
translations: {
|
||||
|
@ -790,13 +790,13 @@ export interface CollectibleBlock {
|
|||
}[];
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'other';
|
||||
blockType: "other";
|
||||
}
|
||||
)[]
|
||||
| null;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'collectibleBlock';
|
||||
blockType: "collectibleBlock";
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
@ -806,7 +806,7 @@ export interface PageBlock {
|
|||
page: string | Page;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'pageBlock';
|
||||
blockType: "pageBlock";
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
@ -830,7 +830,7 @@ export interface Wording {
|
|||
export interface PayloadPreference {
|
||||
id: string;
|
||||
user: {
|
||||
relationTo: 'recorders';
|
||||
relationTo: "recorders";
|
||||
value: string | Recorder;
|
||||
};
|
||||
key?: string | null;
|
||||
|
@ -898,8 +898,8 @@ export interface LineBlock {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -907,7 +907,7 @@ export interface LineBlock {
|
|||
};
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'lineBlock';
|
||||
blockType: "lineBlock";
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
@ -922,8 +922,8 @@ export interface CueBlock {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -931,7 +931,7 @@ export interface CueBlock {
|
|||
};
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'cueBlock';
|
||||
blockType: "cueBlock";
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
@ -941,17 +941,17 @@ export interface TranscriptBlock {
|
|||
lines: (LineBlock | CueBlock)[];
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'transcriptBlock';
|
||||
blockType: "transcriptBlock";
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "BreakBlock".
|
||||
*/
|
||||
export interface BreakBlock {
|
||||
type: 'Scene break' | 'Empty space' | 'Solid line' | 'Dotted line';
|
||||
type: "Scene break" | "Empty space" | "Solid line" | "Dotted line";
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'breakBlock';
|
||||
blockType: "breakBlock";
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
@ -966,8 +966,8 @@ export interface SectionBlock {
|
|||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
direction: ("ltr" | "rtl") | null;
|
||||
format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
|
@ -975,11 +975,10 @@ export interface SectionBlock {
|
|||
};
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'sectionBlock';
|
||||
blockType: "sectionBlock";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////// CONSTANTS ///////////////
|
||||
|
||||
|
||||
|
@ -1495,8 +1494,8 @@ export type EndpointCollectible = {
|
|||
languages: string[];
|
||||
backgroundImage?: EndpointImage;
|
||||
nature: CollectibleNature;
|
||||
gallery: EndpointImage[];
|
||||
scans: PayloadImage[];
|
||||
gallery?: { count: number; thumbnail: EndpointImage };
|
||||
scans?: { count: number; thumbnail: PayloadImage };
|
||||
urls: { url: string; label: string }[];
|
||||
price?: {
|
||||
amount: number;
|
||||
|
@ -1560,6 +1559,104 @@ export type EndpointCollectible = {
|
|||
parentPages: EndpointSource[];
|
||||
};
|
||||
|
||||
export type EndpointCollectibleScans = {
|
||||
slug: string;
|
||||
thumbnail?: EndpointImage;
|
||||
translations: {
|
||||
language: string;
|
||||
pretitle?: string;
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
description?: RichTextContent;
|
||||
}[];
|
||||
credits: EndpointCredit[];
|
||||
cover?: {
|
||||
front?: EndpointScanImage;
|
||||
spine?: EndpointScanImage;
|
||||
back?: EndpointScanImage;
|
||||
insideFront?: EndpointScanImage;
|
||||
insideBack?: EndpointScanImage;
|
||||
flapFront?: EndpointScanImage;
|
||||
flapBack?: EndpointScanImage;
|
||||
insideFlapFront?: EndpointScanImage;
|
||||
insideFlapBack?: EndpointScanImage;
|
||||
};
|
||||
dustjacket?: {
|
||||
front?: EndpointScanImage;
|
||||
spine?: EndpointScanImage;
|
||||
back?: EndpointScanImage;
|
||||
insideFront?: EndpointScanImage;
|
||||
insideSpine?: EndpointScanImage;
|
||||
insideBack?: EndpointScanImage;
|
||||
flapFront?: EndpointScanImage;
|
||||
flapBack?: EndpointScanImage;
|
||||
insideFlapFront?: EndpointScanImage;
|
||||
insideFlapBack?: EndpointScanImage;
|
||||
};
|
||||
obi?: {
|
||||
front?: EndpointScanImage;
|
||||
spine?: EndpointScanImage;
|
||||
back?: EndpointScanImage;
|
||||
insideFront?: EndpointScanImage;
|
||||
insideSpine?: EndpointScanImage;
|
||||
insideBack?: EndpointScanImage;
|
||||
flapFront?: EndpointScanImage;
|
||||
flapBack?: EndpointScanImage;
|
||||
insideFlapFront?: EndpointScanImage;
|
||||
insideFlapBack?: EndpointScanImage;
|
||||
};
|
||||
pages: EndpointScanImage[];
|
||||
parentPages: EndpointSource[];
|
||||
};
|
||||
|
||||
export type EndpointCollectibleGallery = {
|
||||
slug: string;
|
||||
thumbnail?: EndpointImage;
|
||||
translations: {
|
||||
language: string;
|
||||
pretitle?: string;
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
description?: RichTextContent;
|
||||
}[];
|
||||
images: EndpointImage[];
|
||||
parentPages: EndpointSource[];
|
||||
};
|
||||
|
||||
export type EndpointCollectibleGalleryImage = {
|
||||
slug: string;
|
||||
thumbnail?: EndpointImage;
|
||||
translations: {
|
||||
language: string;
|
||||
pretitle?: string;
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
}[];
|
||||
image: EndpointImage;
|
||||
previousIndex?: string;
|
||||
nextIndex?: string;
|
||||
parentPages: EndpointSource[];
|
||||
};
|
||||
|
||||
export type EndpointCollectibleScanPage = {
|
||||
slug: string;
|
||||
thumbnail?: EndpointImage;
|
||||
translations: {
|
||||
language: string;
|
||||
pretitle?: string;
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
}[];
|
||||
image: EndpointScanImage;
|
||||
previousIndex?: string;
|
||||
nextIndex?: string;
|
||||
parentPages: EndpointSource[];
|
||||
};
|
||||
|
||||
export type EndpointScanImage = PayloadImage & {
|
||||
index: string;
|
||||
};
|
||||
|
||||
export type TableOfContentEntry = {
|
||||
prefix: string;
|
||||
title: string;
|
||||
|
@ -1599,7 +1696,9 @@ export type EndpointSource =
|
|||
| { type: "custom"; translations: { language: string; note: string }[] };
|
||||
}
|
||||
| { type: "page"; page: EndpointPage }
|
||||
| { type: "folder"; folder: EndpointFolder };
|
||||
| { type: "folder"; folder: EndpointFolder }
|
||||
| { type: "scans"; collectible: EndpointCollectible }
|
||||
| { type: "gallery"; collectible: EndpointCollectible };
|
||||
|
||||
export type EndpointMedia = {
|
||||
id: string;
|
||||
|
@ -1678,12 +1777,32 @@ export const payload = {
|
|||
await (await request(payloadApiUrl(Collections.Pages, `slug/${slug}`))).json(),
|
||||
getCollectible: async (slug: string): Promise<EndpointCollectible> =>
|
||||
await (await request(payloadApiUrl(Collections.Collectibles, `slug/${slug}`))).json(),
|
||||
getCollectibleScans: async (slug: string): Promise<EndpointCollectibleScans> =>
|
||||
await (await request(payloadApiUrl(Collections.Collectibles, `slug/${slug}/scans`))).json(),
|
||||
getCollectibleScanPage: async (
|
||||
slug: string,
|
||||
index: string
|
||||
): Promise<EndpointCollectibleScanPage> =>
|
||||
await (
|
||||
await request(payloadApiUrl(Collections.Collectibles, `slug/${slug}/scans/${index}`))
|
||||
).json(),
|
||||
getCollectibleGallery: async (slug: string): Promise<EndpointCollectibleGallery> =>
|
||||
await (await request(payloadApiUrl(Collections.Collectibles, `slug/${slug}/gallery`))).json(),
|
||||
getCollectibleGalleryImage: async (
|
||||
slug: string,
|
||||
index: string
|
||||
): Promise<EndpointCollectibleGalleryImage> =>
|
||||
await (
|
||||
await request(payloadApiUrl(Collections.Collectibles, `slug/${slug}/gallery/${index}`))
|
||||
).json(),
|
||||
getChronologyEvents: async (): Promise<EndpointChronologyEvent[]> =>
|
||||
await (await request(payloadApiUrl(Collections.ChronologyEvents, `all`))).json(),
|
||||
getChronologyEventByID: async (id: string): Promise<EndpointChronologyEvent> =>
|
||||
await (await request(payloadApiUrl(Collections.ChronologyEvents, `id/${id}`))).json(),
|
||||
getImageByID: async (id: string): Promise<EndpointImage> =>
|
||||
await (await request(payloadApiUrl(Collections.Images, `id/${id}`))).json(),
|
||||
getScanByID: async (id: string): Promise<PayloadImage> =>
|
||||
await (await request(payloadApiUrl(Collections.Scans, `id/${id}`))).json(),
|
||||
getAudioByID: async (id: string): Promise<EndpointAudio> =>
|
||||
await (await request(payloadApiUrl(Collections.Audios, `id/${id}`))).json(),
|
||||
getVideoByID: async (id: string): Promise<EndpointVideo> =>
|
||||
|
|
Loading…
Reference in New Issue