Image sizes generation
This commit is contained in:
parent
ab2032ff0c
commit
a4ad2d0f21
|
@ -7,6 +7,7 @@ import { isNotEmpty, isValidPayloadImage, isValidPayloadMedia } from "../../../u
|
||||||
import {
|
import {
|
||||||
convertAttributesToEndpointAttributes,
|
convertAttributesToEndpointAttributes,
|
||||||
convertCreditsToEndpointCredits,
|
convertCreditsToEndpointCredits,
|
||||||
|
convertMediaThumbnailToEndpointMediaThumbnail,
|
||||||
convertRTCToEndpointRTC,
|
convertRTCToEndpointRTC,
|
||||||
getLanguageId,
|
getLanguageId,
|
||||||
} from "../../../utils/endpoints";
|
} from "../../../utils/endpoints";
|
||||||
|
@ -77,6 +78,8 @@ export const convertAudioToEndpointAudio = ({
|
||||||
...(isNotEmpty(description) ? { description: convertRTCToEndpointRTC(description) } : {}),
|
...(isNotEmpty(description) ? { description: convertRTCToEndpointRTC(description) } : {}),
|
||||||
})) ?? [],
|
})) ?? [],
|
||||||
duration,
|
duration,
|
||||||
...(isValidPayloadImage(thumbnail) ? { thumbnail } : {}),
|
...(isValidPayloadImage(thumbnail)
|
||||||
|
? { thumbnail: convertMediaThumbnailToEndpointMediaThumbnail(thumbnail) }
|
||||||
|
: {}),
|
||||||
credits: convertCreditsToEndpointCredits(credits),
|
credits: convertCreditsToEndpointCredits(credits),
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
} from "../../../utils/asserts";
|
} from "../../../utils/asserts";
|
||||||
import {
|
import {
|
||||||
convertAttributesToEndpointAttributes,
|
convertAttributesToEndpointAttributes,
|
||||||
|
convertScanToEndpointScanImage,
|
||||||
convertSourceToEndpointSource,
|
convertSourceToEndpointSource,
|
||||||
getDomainFromUrl,
|
getDomainFromUrl,
|
||||||
} from "../../../utils/endpoints";
|
} from "../../../utils/endpoints";
|
||||||
|
@ -147,29 +148,34 @@ const handleGallery = (gallery: Collectible["gallery"]): EndpointCollectible["ga
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleScans = (scans: Collectible["scans"]): EndpointCollectible["scans"] => {
|
const handleScans = (scans: Collectible["scans"]): EndpointCollectible["scans"] => {
|
||||||
const result =
|
if (!scans) return;
|
||||||
scans?.pages?.flatMap(({ image }) => {
|
|
||||||
if (!isValidPayloadImage(image)) return [];
|
|
||||||
return image;
|
|
||||||
}) ?? [];
|
|
||||||
|
|
||||||
const totalCount =
|
const totalCount =
|
||||||
Object.keys(scans?.cover ?? {}).length +
|
Object.keys(scans?.cover ?? {}).length +
|
||||||
Object.keys(scans?.dustjacket ?? {}).length +
|
Object.keys(scans?.dustjacket ?? {}).length +
|
||||||
Object.keys(scans?.obi ?? {}).length +
|
Object.keys(scans?.obi ?? {}).length +
|
||||||
result.length;
|
(scans.pages ?? []).length;
|
||||||
|
|
||||||
|
const result =
|
||||||
|
scans?.pages?.flatMap(({ image, page }) => {
|
||||||
|
if (!isValidPayloadImage(image)) return [];
|
||||||
|
return { image, index: page.toString() };
|
||||||
|
}) ?? [];
|
||||||
|
|
||||||
if (isValidPayloadImage(scans?.cover?.front)) {
|
if (isValidPayloadImage(scans?.cover?.front)) {
|
||||||
result.push(scans.cover.front);
|
result.push({ image: scans.cover.front, index: "cover-front" });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isValidPayloadImage(scans?.dustjacket?.front)) {
|
if (isValidPayloadImage(scans?.dustjacket?.front)) {
|
||||||
result.push(scans.dustjacket.front);
|
result.push({ image: scans.dustjacket.front, index: "dustjacket-front" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const thumbnail = result?.[0];
|
const thumbnail = result?.[0];
|
||||||
if (!thumbnail || !isValidPayloadImage(thumbnail)) return;
|
if (!thumbnail || !isValidPayloadImage(thumbnail.image)) return;
|
||||||
return { count: totalCount, thumbnail };
|
return {
|
||||||
|
count: totalCount,
|
||||||
|
thumbnail: convertScanToEndpointScanImage(thumbnail.image, thumbnail.index),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleContents = (contents: Collectible["contents"]): EndpointCollectible["contents"] => {
|
const handleContents = (contents: Collectible["contents"]): EndpointCollectible["contents"] => {
|
||||||
|
|
|
@ -4,7 +4,10 @@ import { EndpointCollectibleScanPage } from "../../../sdk";
|
||||||
import { Collectible, Scan } from "../../../types/collections";
|
import { Collectible, Scan } from "../../../types/collections";
|
||||||
import { CollectionEndpoint } from "../../../types/payload";
|
import { CollectionEndpoint } from "../../../types/payload";
|
||||||
import { isDefined, isNotEmpty, isPayloadType, isValidPayloadImage } from "../../../utils/asserts";
|
import { isDefined, isNotEmpty, isPayloadType, isValidPayloadImage } from "../../../utils/asserts";
|
||||||
import { convertSourceToEndpointSource } from "../../../utils/endpoints";
|
import {
|
||||||
|
convertScanToEndpointScanImage,
|
||||||
|
convertSourceToEndpointSource,
|
||||||
|
} from "../../../utils/endpoints";
|
||||||
import { convertImageToEndpointImage } from "../../Images/endpoints/getByID";
|
import { convertImageToEndpointImage } from "../../Images/endpoints/getByID";
|
||||||
|
|
||||||
export const getBySlugEndpointScanPage: CollectionEndpoint = {
|
export const getBySlugEndpointScanPage: CollectionEndpoint = {
|
||||||
|
@ -51,7 +54,7 @@ export const getBySlugEndpointScanPage: CollectionEndpoint = {
|
||||||
const nextIndex = getNextIndex(index, collectible.scans);
|
const nextIndex = getNextIndex(index, collectible.scans);
|
||||||
|
|
||||||
const scanPage: EndpointCollectibleScanPage = {
|
const scanPage: EndpointCollectibleScanPage = {
|
||||||
image: { ...image, index },
|
image: convertScanToEndpointScanImage(image, index),
|
||||||
parentPages: convertSourceToEndpointSource({ scans: [collectible] }),
|
parentPages: convertSourceToEndpointSource({ scans: [collectible] }),
|
||||||
slug,
|
slug,
|
||||||
...(isValidPayloadImage(collectible.thumbnail)
|
...(isValidPayloadImage(collectible.thumbnail)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { Collectible } from "../../../types/collections";
|
||||||
import { isNotEmpty, isPayloadType, isValidPayloadImage } from "../../../utils/asserts";
|
import { isNotEmpty, isPayloadType, isValidPayloadImage } from "../../../utils/asserts";
|
||||||
import {
|
import {
|
||||||
convertCreditsToEndpointCredits,
|
convertCreditsToEndpointCredits,
|
||||||
|
convertScanToEndpointScanImage,
|
||||||
convertSourceToEndpointSource,
|
convertSourceToEndpointSource,
|
||||||
} from "../../../utils/endpoints";
|
} from "../../../utils/endpoints";
|
||||||
import { convertImageToEndpointImage } from "../../Images/endpoints/getByID";
|
import { convertImageToEndpointImage } from "../../Images/endpoints/getByID";
|
||||||
|
@ -51,7 +52,7 @@ const handleScans = ({
|
||||||
credits: convertCreditsToEndpointCredits(credits),
|
credits: convertCreditsToEndpointCredits(credits),
|
||||||
pages:
|
pages:
|
||||||
pages?.flatMap(({ image, page }) =>
|
pages?.flatMap(({ image, page }) =>
|
||||||
isValidPayloadImage(image) ? { ...image, index: page.toString() } : []
|
isValidPayloadImage(image) ? convertScanToEndpointScanImage(image, page.toString()) : []
|
||||||
) ?? [],
|
) ?? [],
|
||||||
...(coverEnabled && cover ? { cover: handleCover(cover) } : {}),
|
...(coverEnabled && cover ? { cover: handleCover(cover) } : {}),
|
||||||
...(dustjacketEnabled && dustjacket ? { dustjacket: handleDustjacket(dustjacket) } : {}),
|
...(dustjacketEnabled && dustjacket ? { dustjacket: handleDustjacket(dustjacket) } : {}),
|
||||||
|
@ -69,25 +70,35 @@ const handleCover = ({
|
||||||
insideFront,
|
insideFront,
|
||||||
spine,
|
spine,
|
||||||
}: NonNullable<NonNullable<Collectible["scans"]>["cover"]>): EndpointCollectibleScans["cover"] => ({
|
}: NonNullable<NonNullable<Collectible["scans"]>["cover"]>): EndpointCollectibleScans["cover"] => ({
|
||||||
...(isValidPayloadImage(back) ? { back: { ...back, index: "cover-back" } } : {}),
|
...(isValidPayloadImage(back)
|
||||||
...(isValidPayloadImage(flapBack) ? { flapBack: { ...flapBack, index: "cover-flap-back" } } : {}),
|
? { back: convertScanToEndpointScanImage(back, "cover-back") }
|
||||||
...(isValidPayloadImage(flapFront)
|
: {}),
|
||||||
? { flapFront: { ...flapFront, index: "cover-flap-front" } }
|
...(isValidPayloadImage(flapBack)
|
||||||
|
? { flapBack: convertScanToEndpointScanImage(flapBack, "cover-flap-back") }
|
||||||
|
: {}),
|
||||||
|
...(isValidPayloadImage(flapFront)
|
||||||
|
? { flapFront: convertScanToEndpointScanImage(flapFront, "cover-flap-front") }
|
||||||
|
: {}),
|
||||||
|
...(isValidPayloadImage(front)
|
||||||
|
? { front: convertScanToEndpointScanImage(front, "cover-front") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(front) ? { front: { ...front, index: "cover-front" } } : {}),
|
|
||||||
...(isValidPayloadImage(insideBack)
|
...(isValidPayloadImage(insideBack)
|
||||||
? { insideBack: { ...insideBack, index: "cover-inside-back" } }
|
? { insideBack: convertScanToEndpointScanImage(insideBack, "cover-inside-back") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(insideFlapBack)
|
...(isValidPayloadImage(insideFlapBack)
|
||||||
? { insideFlapBack: { ...insideFlapBack, index: "cover-inside-flap-back" } }
|
? { insideFlapBack: convertScanToEndpointScanImage(insideFlapBack, "cover-inside-flap-back") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(insideFlapFront)
|
...(isValidPayloadImage(insideFlapFront)
|
||||||
? { insideFlapFront: { ...insideFlapFront, index: "cover-inside-flap-front" } }
|
? {
|
||||||
|
insideFlapFront: convertScanToEndpointScanImage(insideFlapFront, "cover-inside-flap-front"),
|
||||||
|
}
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(insideFront)
|
...(isValidPayloadImage(insideFront)
|
||||||
? { insideFront: { ...insideFront, index: "cover-inside-front" } }
|
? { insideFront: convertScanToEndpointScanImage(insideFront, "cover-inside-front") }
|
||||||
|
: {}),
|
||||||
|
...(isValidPayloadImage(spine)
|
||||||
|
? { spine: convertScanToEndpointScanImage(spine, "cover-spine") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(spine) ? { spine: { ...spine, index: "cover-spine" } } : {}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleDustjacket = ({
|
const handleDustjacket = ({
|
||||||
|
@ -104,29 +115,45 @@ const handleDustjacket = ({
|
||||||
}: NonNullable<
|
}: NonNullable<
|
||||||
NonNullable<Collectible["scans"]>["dustjacket"]
|
NonNullable<Collectible["scans"]>["dustjacket"]
|
||||||
>): EndpointCollectibleScans["dustjacket"] => ({
|
>): EndpointCollectibleScans["dustjacket"] => ({
|
||||||
...(isValidPayloadImage(back) ? { back: { ...back, index: "dustjacket-back" } } : {}),
|
...(isValidPayloadImage(back)
|
||||||
|
? { back: convertScanToEndpointScanImage(back, "dustjacket-back") }
|
||||||
|
: {}),
|
||||||
...(isValidPayloadImage(flapBack)
|
...(isValidPayloadImage(flapBack)
|
||||||
? { flapBack: { ...flapBack, index: "dustjacket-flap-back" } }
|
? { flapBack: convertScanToEndpointScanImage(flapBack, "dustjacket-flap-back") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(flapFront)
|
...(isValidPayloadImage(flapFront)
|
||||||
? { flapFront: { ...flapFront, index: "dustjacket-flap-front" } }
|
? { flapFront: convertScanToEndpointScanImage(flapFront, "dustjacket-flap-front") }
|
||||||
|
: {}),
|
||||||
|
...(isValidPayloadImage(front)
|
||||||
|
? { front: convertScanToEndpointScanImage(front, "dustjacket-front") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(front) ? { front: { ...front, index: "dustjacket-front" } } : {}),
|
|
||||||
...(isValidPayloadImage(insideBack)
|
...(isValidPayloadImage(insideBack)
|
||||||
? { insideBack: { ...insideBack, index: "dustjacket-inside-back" } }
|
? { insideBack: convertScanToEndpointScanImage(insideBack, "dustjacket-inside-back") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(insideFlapBack)
|
...(isValidPayloadImage(insideFlapBack)
|
||||||
? { insideFlapBack: { ...insideFlapBack, index: "dustjacket-inside-flap-back" } }
|
? {
|
||||||
|
insideFlapBack: convertScanToEndpointScanImage(
|
||||||
|
insideFlapBack,
|
||||||
|
"dustjacket-inside-flap-back"
|
||||||
|
),
|
||||||
|
}
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(insideFlapFront)
|
...(isValidPayloadImage(insideFlapFront)
|
||||||
? { insideFlapFront: { ...insideFlapFront, index: "dustjacket-inside-flap-front" } }
|
? {
|
||||||
|
insideFlapFront: convertScanToEndpointScanImage(
|
||||||
|
insideFlapFront,
|
||||||
|
"dustjacket-inside-flap-front"
|
||||||
|
),
|
||||||
|
}
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(insideFront)
|
...(isValidPayloadImage(insideFront)
|
||||||
? { insideFront: { ...insideFront, index: "dustjacket-inside-front" } }
|
? { insideFront: convertScanToEndpointScanImage(insideFront, "dustjacket-inside-front") }
|
||||||
|
: {}),
|
||||||
|
...(isValidPayloadImage(spine)
|
||||||
|
? { spine: convertScanToEndpointScanImage(spine, "dustjacket-spine") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(spine) ? { spine: { ...spine, index: "dustjacket-spine" } } : {}),
|
|
||||||
...(isValidPayloadImage(insideSpine)
|
...(isValidPayloadImage(insideSpine)
|
||||||
? { insideSpine: { ...insideSpine, index: "dustjacket-inside-spine" } }
|
? { insideSpine: convertScanToEndpointScanImage(insideSpine, "dustjacket-inside-spine") }
|
||||||
: {}),
|
: {}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -142,26 +169,32 @@ const handleObi = ({
|
||||||
insideSpine,
|
insideSpine,
|
||||||
spine,
|
spine,
|
||||||
}: NonNullable<NonNullable<Collectible["scans"]>["obi"]>): EndpointCollectibleScans["obi"] => ({
|
}: NonNullable<NonNullable<Collectible["scans"]>["obi"]>): EndpointCollectibleScans["obi"] => ({
|
||||||
...(isValidPayloadImage(back) ? { back: { ...back, index: "obi-back" } } : {}),
|
...(isValidPayloadImage(back) ? { back: convertScanToEndpointScanImage(back, "obi-back") } : {}),
|
||||||
...(isValidPayloadImage(flapBack) ? { flapBack: { ...flapBack, index: "obi-flap-back" } } : {}),
|
...(isValidPayloadImage(flapBack)
|
||||||
...(isValidPayloadImage(flapFront)
|
? { flapBack: convertScanToEndpointScanImage(flapBack, "obi-flap-back") }
|
||||||
? { flapFront: { ...flapFront, index: "obi-flap-front" } }
|
: {}),
|
||||||
|
...(isValidPayloadImage(flapFront)
|
||||||
|
? { flapFront: convertScanToEndpointScanImage(flapFront, "obi-flap-front") }
|
||||||
|
: {}),
|
||||||
|
...(isValidPayloadImage(front)
|
||||||
|
? { front: convertScanToEndpointScanImage(front, "obi-front") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(front) ? { front: { ...front, index: "obi-front" } } : {}),
|
|
||||||
...(isValidPayloadImage(insideBack)
|
...(isValidPayloadImage(insideBack)
|
||||||
? { insideBack: { ...insideBack, index: "obi-inside-back" } }
|
? { insideBack: convertScanToEndpointScanImage(insideBack, "obi-inside-back") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(insideFlapBack)
|
...(isValidPayloadImage(insideFlapBack)
|
||||||
? { insideFlapBack: { ...insideFlapBack, index: "obi-inside-flap-back" } }
|
? { insideFlapBack: convertScanToEndpointScanImage(insideFlapBack, "obi-inside-flap-back") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(insideFlapFront)
|
...(isValidPayloadImage(insideFlapFront)
|
||||||
? { insideFlapFront: { ...insideFlapFront, index: "obi-inside-flap-front" } }
|
? { insideFlapFront: convertScanToEndpointScanImage(insideFlapFront, "obi-inside-flap-front") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(insideFront)
|
...(isValidPayloadImage(insideFront)
|
||||||
? { insideFront: { ...insideFront, index: "obi-inside-front" } }
|
? { insideFront: convertScanToEndpointScanImage(insideFront, "obi-inside-front") }
|
||||||
|
: {}),
|
||||||
|
...(isValidPayloadImage(spine)
|
||||||
|
? { spine: convertScanToEndpointScanImage(spine, "obi-spine") }
|
||||||
: {}),
|
: {}),
|
||||||
...(isValidPayloadImage(spine) ? { spine: { ...spine, index: "obi-spine" } } : {}),
|
|
||||||
...(isValidPayloadImage(insideSpine)
|
...(isValidPayloadImage(insideSpine)
|
||||||
? { insideSpine: { ...insideSpine, index: "obi-inside-spine" } }
|
? { insideSpine: convertScanToEndpointScanImage(insideSpine, "obi-inside-spine") }
|
||||||
: {}),
|
: {}),
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
import { Collections } from "../../constants";
|
import { Collections } from "../../constants";
|
||||||
|
import { createImageSizesRegenerationEndpoint } from "../../endpoints/imageSizesRegenerationEndpoint";
|
||||||
import { attributesField } from "../../fields/attributesField/attributesField";
|
import { attributesField } from "../../fields/attributesField/attributesField";
|
||||||
import { creditsField } from "../../fields/creditsField/creditsField";
|
import { creditsField } from "../../fields/creditsField/creditsField";
|
||||||
import { rowField } from "../../fields/rowField/rowField";
|
import { rowField } from "../../fields/rowField/rowField";
|
||||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
import { createEditor } from "../../utils/editor";
|
import { createEditor } from "../../utils/editor";
|
||||||
import { buildImageCollectionConfig } from "../../utils/imageCollectionConfig";
|
import {
|
||||||
|
buildImageCollectionConfig,
|
||||||
|
generateOpenGraphSize,
|
||||||
|
generateWebpSize,
|
||||||
|
} from "../../utils/imageCollectionConfig";
|
||||||
import { getByID } from "./endpoints/getByID";
|
import { getByID } from "./endpoints/getByID";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
|
@ -34,18 +39,17 @@ export const Images = buildImageCollectionConfig({
|
||||||
},
|
},
|
||||||
upload: {
|
upload: {
|
||||||
imageSizes: [
|
imageSizes: [
|
||||||
{
|
generateOpenGraphSize(),
|
||||||
name: "og",
|
generateWebpSize(200, 60),
|
||||||
height: 750,
|
generateWebpSize(320, 60),
|
||||||
width: 1125,
|
generateWebpSize(480, 70),
|
||||||
formatOptions: {
|
generateWebpSize(800, 70),
|
||||||
format: "jpg",
|
generateWebpSize(1280, 85),
|
||||||
options: { progressive: true, mozjpeg: true, compressionLevel: 9, quality: 60 },
|
generateWebpSize(1920, 85),
|
||||||
},
|
generateWebpSize(2560, 90),
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
endpoints: [getByID],
|
endpoints: [getByID, createImageSizesRegenerationEndpoint(Collections.Images)],
|
||||||
fields: [
|
fields: [
|
||||||
translatedFields({
|
translatedFields({
|
||||||
name: fields.translations,
|
name: fields.translations,
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
convertAttributesToEndpointAttributes,
|
convertAttributesToEndpointAttributes,
|
||||||
convertCreditsToEndpointCredits,
|
convertCreditsToEndpointCredits,
|
||||||
convertRTCToEndpointRTC,
|
convertRTCToEndpointRTC,
|
||||||
|
convertSizesToEndpointImageSize,
|
||||||
getLanguageId,
|
getLanguageId,
|
||||||
} from "../../../utils/endpoints";
|
} from "../../../utils/endpoints";
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ export const convertImageToEndpointImage = ({
|
||||||
filesize,
|
filesize,
|
||||||
id,
|
id,
|
||||||
credits,
|
credits,
|
||||||
|
sizes,
|
||||||
}: Image & PayloadImage): EndpointImage => ({
|
}: Image & PayloadImage): EndpointImage => ({
|
||||||
url,
|
url,
|
||||||
width,
|
width,
|
||||||
|
@ -79,4 +81,17 @@ export const convertImageToEndpointImage = ({
|
||||||
...(isNotEmpty(description) ? { description: convertRTCToEndpointRTC(description) } : {}),
|
...(isNotEmpty(description) ? { description: convertRTCToEndpointRTC(description) } : {}),
|
||||||
})) ?? [],
|
})) ?? [],
|
||||||
credits: convertCreditsToEndpointCredits(credits),
|
credits: convertCreditsToEndpointCredits(credits),
|
||||||
|
sizes: convertSizesToEndpointImageSize(
|
||||||
|
[
|
||||||
|
sizes?.["200w"],
|
||||||
|
sizes?.["320w"],
|
||||||
|
sizes?.["480w"],
|
||||||
|
sizes?.["800w"],
|
||||||
|
sizes?.["1280w"],
|
||||||
|
sizes?.["1920w"],
|
||||||
|
sizes?.["2560w"],
|
||||||
|
{ url, width, height, filename, filesize, mimeType },
|
||||||
|
],
|
||||||
|
[200, 320, 480, 800, 1280, 1920, 2560]
|
||||||
|
),
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
import { shownOnlyToAdmin } from "../../accesses/collections/shownOnlyToAdmin";
|
import { shownOnlyToAdmin } from "../../accesses/collections/shownOnlyToAdmin";
|
||||||
import { Collections } from "../../constants";
|
import { Collections } from "../../constants";
|
||||||
import { buildImageCollectionConfig } from "../../utils/imageCollectionConfig";
|
import { createImageSizesRegenerationEndpoint } from "../../endpoints/imageSizesRegenerationEndpoint";
|
||||||
|
import {
|
||||||
|
buildImageCollectionConfig,
|
||||||
|
generateOpenGraphSize,
|
||||||
|
generateWebpSize,
|
||||||
|
} from "../../utils/imageCollectionConfig";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
filename: "filename",
|
filename: "filename",
|
||||||
|
@ -16,17 +21,17 @@ export const MediaThumbnails = buildImageCollectionConfig({
|
||||||
plural: "Media Thumbnails",
|
plural: "Media Thumbnails",
|
||||||
},
|
},
|
||||||
admin: { defaultColumns: [fields.filename, fields.updatedAt], hidden: shownOnlyToAdmin },
|
admin: { defaultColumns: [fields.filename, fields.updatedAt], hidden: shownOnlyToAdmin },
|
||||||
|
endpoints: [createImageSizesRegenerationEndpoint(Collections.MediaThumbnails)],
|
||||||
upload: {
|
upload: {
|
||||||
imageSizes: [
|
imageSizes: [
|
||||||
{
|
generateOpenGraphSize(),
|
||||||
name: "og",
|
generateWebpSize(200, 60),
|
||||||
height: 750,
|
generateWebpSize(320, 60),
|
||||||
width: 1125,
|
generateWebpSize(480, 70),
|
||||||
formatOptions: {
|
generateWebpSize(800, 70),
|
||||||
format: "jpg",
|
generateWebpSize(1280, 85),
|
||||||
options: { progressive: true, mozjpeg: true, compressionLevel: 9, quality: 60 },
|
generateWebpSize(1920, 85),
|
||||||
},
|
generateWebpSize(2560, 90),
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
fields: [],
|
fields: [],
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { shownOnlyToAdmin } from "../../accesses/collections/shownOnlyToAdmin";
|
import { shownOnlyToAdmin } from "../../accesses/collections/shownOnlyToAdmin";
|
||||||
import { Collections } from "../../constants";
|
import { Collections } from "../../constants";
|
||||||
import { buildImageCollectionConfig } from "../../utils/imageCollectionConfig";
|
import { createImageSizesRegenerationEndpoint } from "../../endpoints/imageSizesRegenerationEndpoint";
|
||||||
|
import { buildImageCollectionConfig, generateWebpSize } from "../../utils/imageCollectionConfig";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
filename: "filename",
|
filename: "filename",
|
||||||
|
@ -19,17 +20,13 @@ export const Scans = buildImageCollectionConfig({
|
||||||
defaultColumns: [fields.filename, fields.updatedAt],
|
defaultColumns: [fields.filename, fields.updatedAt],
|
||||||
hidden: shownOnlyToAdmin,
|
hidden: shownOnlyToAdmin,
|
||||||
},
|
},
|
||||||
|
endpoints: [createImageSizesRegenerationEndpoint(Collections.Scans)],
|
||||||
upload: {
|
upload: {
|
||||||
imageSizes: [
|
imageSizes: [
|
||||||
{
|
generateWebpSize(200, 60),
|
||||||
name: "og",
|
generateWebpSize(320, 60),
|
||||||
height: 750,
|
generateWebpSize(480, 70),
|
||||||
width: 1125,
|
generateWebpSize(800, 70),
|
||||||
formatOptions: {
|
|
||||||
format: "jpg",
|
|
||||||
options: { progressive: true, mozjpeg: true, compressionLevel: 9, quality: 60 },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
fields: [],
|
fields: [],
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
import {
|
import {
|
||||||
convertAttributesToEndpointAttributes,
|
convertAttributesToEndpointAttributes,
|
||||||
convertCreditsToEndpointCredits,
|
convertCreditsToEndpointCredits,
|
||||||
|
convertMediaThumbnailToEndpointMediaThumbnail,
|
||||||
convertRTCToEndpointRTC,
|
convertRTCToEndpointRTC,
|
||||||
getLanguageId,
|
getLanguageId,
|
||||||
} from "../../../utils/endpoints";
|
} from "../../../utils/endpoints";
|
||||||
|
@ -88,7 +89,9 @@ export const convertVideoToEndpointVideo = ({
|
||||||
})) ?? [],
|
})) ?? [],
|
||||||
|
|
||||||
duration,
|
duration,
|
||||||
...(isValidPayloadImage(thumbnail) ? { thumbnail } : {}),
|
...(isValidPayloadImage(thumbnail)
|
||||||
|
? { thumbnail: convertMediaThumbnailToEndpointMediaThumbnail(thumbnail) }
|
||||||
|
: {}),
|
||||||
...(platformEnabled && isDefined(platform) && isPayloadType(platform.channel)
|
...(platformEnabled && isDefined(platform) && isPayloadType(platform.channel)
|
||||||
? {
|
? {
|
||||||
platform: {
|
platform: {
|
||||||
|
|
|
@ -7,6 +7,9 @@ import { afterChangeWebhook } from "../../hooks/afterChangeWebhook";
|
||||||
import { getConfigEndpoint } from "./endpoints/getConfigEndpoint";
|
import { getConfigEndpoint } from "./endpoints/getConfigEndpoint";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
|
homeBackgroundImage: "homeBackgroundImage",
|
||||||
|
timelineBackgroundImage: "timelineBackgroundImage",
|
||||||
|
defaultOpenGraphImage: "defaultOpenGraphImage",
|
||||||
homeFolders: "homeFolders",
|
homeFolders: "homeFolders",
|
||||||
homeFoldersDarkThumbnail: "darkThumbnail",
|
homeFoldersDarkThumbnail: "darkThumbnail",
|
||||||
homeFoldersLightThumbnail: "lightThumbnail",
|
homeFoldersLightThumbnail: "lightThumbnail",
|
||||||
|
@ -32,6 +35,26 @@ export const WebsiteConfig: GlobalConfig = {
|
||||||
afterChange: [afterChangeWebhook],
|
afterChange: [afterChangeWebhook],
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
|
rowField([
|
||||||
|
{
|
||||||
|
name: fields.homeBackgroundImage,
|
||||||
|
type: "upload",
|
||||||
|
relationTo: Collections.Images,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: fields.timelineBackgroundImage,
|
||||||
|
type: "upload",
|
||||||
|
relationTo: Collections.Images,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: fields.defaultOpenGraphImage,
|
||||||
|
type: "upload",
|
||||||
|
relationTo: Collections.Images,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
]),
|
||||||
{
|
{
|
||||||
name: fields.homeFolders,
|
name: fields.homeFolders,
|
||||||
admin: {
|
admin: {
|
||||||
|
|
|
@ -20,7 +20,13 @@ export const getConfigEndpoint: CollectionEndpoint = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { homeFolders, timeline } = await payload.findGlobal({
|
const {
|
||||||
|
homeFolders,
|
||||||
|
timeline,
|
||||||
|
defaultOpenGraphImage,
|
||||||
|
homeBackgroundImage,
|
||||||
|
timelineBackgroundImage,
|
||||||
|
} = await payload.findGlobal({
|
||||||
slug: Collections.WebsiteConfig,
|
slug: Collections.WebsiteConfig,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -43,20 +49,28 @@ export const getConfigEndpoint: CollectionEndpoint = {
|
||||||
});
|
});
|
||||||
|
|
||||||
const endpointWebsiteConfig: EndpointWebsiteConfig = {
|
const endpointWebsiteConfig: EndpointWebsiteConfig = {
|
||||||
homeFolders:
|
home: {
|
||||||
homeFolders?.flatMap(({ folder, darkThumbnail, lightThumbnail }) => {
|
...(isValidPayloadImage(homeBackgroundImage)
|
||||||
if (!isPayloadType(folder)) return [];
|
? { backgroundImage: convertImageToEndpointImage(homeBackgroundImage) }
|
||||||
return {
|
: {}),
|
||||||
...convertFolderToEndpointFolder(folder),
|
folders:
|
||||||
...(isValidPayloadImage(darkThumbnail)
|
homeFolders?.flatMap(({ folder, darkThumbnail, lightThumbnail }) => {
|
||||||
? { darkThumbnail: convertImageToEndpointImage(darkThumbnail) }
|
if (!isPayloadType(folder)) return [];
|
||||||
: {}),
|
return {
|
||||||
...(isValidPayloadImage(lightThumbnail)
|
...convertFolderToEndpointFolder(folder),
|
||||||
? { lightThumbnail: convertImageToEndpointImage(lightThumbnail) }
|
...(isValidPayloadImage(darkThumbnail)
|
||||||
: {}),
|
? { darkThumbnail: convertImageToEndpointImage(darkThumbnail) }
|
||||||
};
|
: {}),
|
||||||
}) ?? [],
|
...(isValidPayloadImage(lightThumbnail)
|
||||||
|
? { lightThumbnail: convertImageToEndpointImage(lightThumbnail) }
|
||||||
|
: {}),
|
||||||
|
};
|
||||||
|
}) ?? [],
|
||||||
|
},
|
||||||
timeline: {
|
timeline: {
|
||||||
|
...(isValidPayloadImage(timelineBackgroundImage)
|
||||||
|
? { backgroundImage: convertImageToEndpointImage(timelineBackgroundImage) }
|
||||||
|
: {}),
|
||||||
breaks: timeline?.breaks ?? [],
|
breaks: timeline?.breaks ?? [],
|
||||||
eventCount,
|
eventCount,
|
||||||
eras:
|
eras:
|
||||||
|
@ -69,6 +83,9 @@ export const getConfigEndpoint: CollectionEndpoint = {
|
||||||
};
|
};
|
||||||
}) ?? [],
|
}) ?? [],
|
||||||
},
|
},
|
||||||
|
...(isValidPayloadImage(defaultOpenGraphImage)
|
||||||
|
? { defaultOpenGraphImage: convertImageToEndpointImage(defaultOpenGraphImage) }
|
||||||
|
: {}),
|
||||||
};
|
};
|
||||||
res.status(200).json(endpointWebsiteConfig);
|
res.status(200).json(endpointWebsiteConfig);
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import payload from "payload";
|
||||||
|
import { CollectionEndpoint } from "../types/payload";
|
||||||
|
|
||||||
|
export const createImageSizesRegenerationEndpoint = (
|
||||||
|
collection: "images" | "scans" | "media-thumbnails"
|
||||||
|
): CollectionEndpoint => ({
|
||||||
|
path: `/regenerate`,
|
||||||
|
method: "get",
|
||||||
|
handler: async (req, res) => {
|
||||||
|
if (!req.user) {
|
||||||
|
return res.status(403).send({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message: "You are not allowed to perform this action.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await payload.find({
|
||||||
|
collection,
|
||||||
|
pagination: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const { id, filename } of result.docs) {
|
||||||
|
console.log("Handling", id);
|
||||||
|
|
||||||
|
if (!filename) {
|
||||||
|
throw new Error("No filename!");
|
||||||
|
}
|
||||||
|
|
||||||
|
await payload.update({
|
||||||
|
collection,
|
||||||
|
id,
|
||||||
|
filePath: `./uploads/${collection}/${filename}`,
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).send({ message: `Regenerated sizes for ${result.docs.length} images!` });
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,22 +1,8 @@
|
||||||
import { Props } from "payload/components/views/Cell";
|
import { Props } from "payload/components/views/Cell";
|
||||||
import React, { useEffect, useMemo, useState } from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import styled from "styled-components";
|
|
||||||
import { isUndefined } from "../../utils/asserts";
|
import { isUndefined } from "../../utils/asserts";
|
||||||
|
|
||||||
const Image = styled.img`
|
|
||||||
height: 3rem;
|
|
||||||
width: 3rem;
|
|
||||||
object-fit: contain;
|
|
||||||
transition: 0.2s transform;
|
|
||||||
transition-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1);
|
|
||||||
position: absolute;
|
|
||||||
transform: translateY(-50%) scale(1);
|
|
||||||
&:hover {
|
|
||||||
transform: translateY(-50%) scale(3);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const Cell = ({ cellData, field, rowData, collection }: Props): JSX.Element => {
|
export const Cell = ({ cellData, field, rowData, collection }: Props): JSX.Element => {
|
||||||
const [imageURL, setImageURL] = useState<string>();
|
const [imageURL, setImageURL] = useState<string>();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -34,5 +20,13 @@ export const Cell = ({ cellData, field, rowData, collection }: Props): JSX.Eleme
|
||||||
[collection.slug, rowData.id]
|
[collection.slug, rowData.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
return <Link to={link}>{imageURL ? <Image src={imageURL} /> : "<No Image>"}</Link>;
|
return (
|
||||||
|
<Link to={link}>
|
||||||
|
{imageURL ? (
|
||||||
|
<img className="thumbnail thumbnail--size-small file__thumbnail" src={imageURL} />
|
||||||
|
) : (
|
||||||
|
"<No Image>"
|
||||||
|
)}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
32
src/sdk.ts
32
src/sdk.ts
|
@ -53,11 +53,15 @@ export type EndpointFolder = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EndpointWebsiteConfig = {
|
export type EndpointWebsiteConfig = {
|
||||||
homeFolders: (EndpointFolder & {
|
home: {
|
||||||
lightThumbnail?: EndpointImage;
|
backgroundImage?: EndpointImage;
|
||||||
darkThumbnail?: EndpointImage;
|
folders: (EndpointFolder & {
|
||||||
})[];
|
lightThumbnail?: EndpointImage;
|
||||||
|
darkThumbnail?: EndpointImage;
|
||||||
|
})[];
|
||||||
|
};
|
||||||
timeline: {
|
timeline: {
|
||||||
|
backgroundImage?: EndpointImage;
|
||||||
breaks: number[];
|
breaks: number[];
|
||||||
eventCount: number;
|
eventCount: number;
|
||||||
eras: {
|
eras: {
|
||||||
|
@ -66,6 +70,7 @@ export type EndpointWebsiteConfig = {
|
||||||
name: string;
|
name: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
|
defaultOpenGraphImage?: EndpointImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EndpointRecorder = {
|
export type EndpointRecorder = {
|
||||||
|
@ -176,7 +181,7 @@ export type EndpointCollectible = {
|
||||||
backgroundImage?: EndpointImage;
|
backgroundImage?: EndpointImage;
|
||||||
nature: CollectibleNature;
|
nature: CollectibleNature;
|
||||||
gallery?: { count: number; thumbnail: EndpointImage };
|
gallery?: { count: number; thumbnail: EndpointImage };
|
||||||
scans?: { count: number; thumbnail: PayloadImage };
|
scans?: { count: number; thumbnail: EndpointScanImage };
|
||||||
urls: { url: string; label: string }[];
|
urls: { url: string; label: string }[];
|
||||||
price?: {
|
price?: {
|
||||||
amount: number;
|
amount: number;
|
||||||
|
@ -341,6 +346,7 @@ export type EndpointCollectibleScanPage = {
|
||||||
|
|
||||||
export type EndpointScanImage = PayloadImage & {
|
export type EndpointScanImage = PayloadImage & {
|
||||||
index: string;
|
index: string;
|
||||||
|
sizes: EndpointImageSize[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TableOfContentEntry = {
|
export type TableOfContentEntry = {
|
||||||
|
@ -405,18 +411,26 @@ export type EndpointMedia = {
|
||||||
credits: EndpointCredit[];
|
credits: EndpointCredit[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type EndpointImageSize = {
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
url: string;
|
||||||
|
wSize: number;
|
||||||
|
};
|
||||||
|
|
||||||
export type EndpointImage = EndpointMedia & {
|
export type EndpointImage = EndpointMedia & {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
sizes: EndpointImageSize[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EndpointAudio = EndpointMedia & {
|
export type EndpointAudio = EndpointMedia & {
|
||||||
thumbnail?: PayloadImage;
|
thumbnail?: EndpointMediaThumbnail;
|
||||||
duration: number;
|
duration: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EndpointVideo = EndpointMedia & {
|
export type EndpointVideo = EndpointMedia & {
|
||||||
thumbnail?: PayloadImage;
|
thumbnail?: EndpointMediaThumbnail;
|
||||||
subtitles: {
|
subtitles: {
|
||||||
language: string;
|
language: string;
|
||||||
url: string;
|
url: string;
|
||||||
|
@ -436,6 +450,10 @@ export type EndpointVideo = EndpointMedia & {
|
||||||
duration: number;
|
duration: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type EndpointMediaThumbnail = PayloadImage & {
|
||||||
|
sizes: EndpointImageSize[];
|
||||||
|
};
|
||||||
|
|
||||||
export type PayloadMedia = {
|
export type PayloadMedia = {
|
||||||
url: string;
|
url: string;
|
||||||
mimeType: string;
|
mimeType: string;
|
||||||
|
|
|
@ -159,6 +159,62 @@ export interface Image {
|
||||||
filesize?: number | null;
|
filesize?: number | null;
|
||||||
filename?: string | null;
|
filename?: string | null;
|
||||||
};
|
};
|
||||||
|
"200w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"320w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"480w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"800w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"1280w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"1920w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"2560w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -573,7 +629,31 @@ export interface Scan {
|
||||||
filesize?: number | null;
|
filesize?: number | null;
|
||||||
filename?: string | null;
|
filename?: string | null;
|
||||||
};
|
};
|
||||||
og?: {
|
"200w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"320w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"480w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"800w"?: {
|
||||||
url?: string | null;
|
url?: string | null;
|
||||||
width?: number | null;
|
width?: number | null;
|
||||||
height?: number | null;
|
height?: number | null;
|
||||||
|
@ -677,6 +757,62 @@ export interface MediaThumbnail {
|
||||||
filesize?: number | null;
|
filesize?: number | null;
|
||||||
filename?: string | null;
|
filename?: string | null;
|
||||||
};
|
};
|
||||||
|
"200w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"320w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"480w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"800w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"1280w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"1920w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
"2560w"?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -923,6 +1059,9 @@ export interface PayloadMigration {
|
||||||
*/
|
*/
|
||||||
export interface WebsiteConfig {
|
export interface WebsiteConfig {
|
||||||
id: string;
|
id: string;
|
||||||
|
homeBackgroundImage: string | Image;
|
||||||
|
timelineBackgroundImage: string | Image;
|
||||||
|
defaultOpenGraphImage: string | Image;
|
||||||
homeFolders?:
|
homeFolders?:
|
||||||
| {
|
| {
|
||||||
lightThumbnail?: string | Image | null;
|
lightThumbnail?: string | Image | null;
|
||||||
|
|
|
@ -60,3 +60,32 @@ export const isPayloadArrayType = <T extends Object>(
|
||||||
export const isPublished = <T extends { _status?: ("draft" | "published") | null }>(
|
export const isPublished = <T extends { _status?: ("draft" | "published") | null }>(
|
||||||
object: T
|
object: T
|
||||||
): boolean => object._status === "published";
|
): boolean => object._status === "published";
|
||||||
|
|
||||||
|
export type ImageSize = {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ValidImageSize = {
|
||||||
|
url: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
mimeType: string;
|
||||||
|
filesize: number;
|
||||||
|
filename: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isValidImageSize = (size: ImageSize | undefined): size is ValidImageSize => {
|
||||||
|
if (isUndefined(size)) return false;
|
||||||
|
if (isUndefined(size.url)) return false;
|
||||||
|
if (isUndefined(size.width)) return false;
|
||||||
|
if (isUndefined(size.height)) return false;
|
||||||
|
if (isUndefined(size.mimeType)) return false;
|
||||||
|
if (isUndefined(size.filesize)) return false;
|
||||||
|
if (isUndefined(size.filename)) return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
import { GeneratedTypes } from "payload";
|
||||||
import { CollectionConfig } from "payload/types";
|
import { CollectionConfig } from "payload/types";
|
||||||
import { Collections } from "../constants";
|
|
||||||
import { formatToPascalCase } from "./string";
|
import { formatToPascalCase } from "./string";
|
||||||
|
|
||||||
type CollectionConfigWithPlugins = CollectionConfig;
|
type CollectionConfigWithPlugins = CollectionConfig;
|
||||||
|
@ -8,7 +8,7 @@ export type BuildCollectionConfig = Omit<
|
||||||
CollectionConfigWithPlugins,
|
CollectionConfigWithPlugins,
|
||||||
"slug" | "typescript" | "labels"
|
"slug" | "typescript" | "labels"
|
||||||
> & {
|
> & {
|
||||||
slug: Collections;
|
slug: keyof GeneratedTypes["collections"];
|
||||||
labels: { singular: string; plural: string };
|
labels: { singular: string; plural: string };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,13 @@ import {
|
||||||
import {
|
import {
|
||||||
EndpointAttribute,
|
EndpointAttribute,
|
||||||
EndpointCredit,
|
EndpointCredit,
|
||||||
|
EndpointImageSize,
|
||||||
|
EndpointMediaThumbnail,
|
||||||
EndpointRole,
|
EndpointRole,
|
||||||
|
EndpointScanImage,
|
||||||
EndpointSource,
|
EndpointSource,
|
||||||
EndpointTag,
|
EndpointTag,
|
||||||
|
PayloadImage,
|
||||||
} from "../sdk";
|
} from "../sdk";
|
||||||
import {
|
import {
|
||||||
Audio,
|
Audio,
|
||||||
|
@ -34,18 +38,23 @@ import {
|
||||||
Folder,
|
Folder,
|
||||||
Image,
|
Image,
|
||||||
Language,
|
Language,
|
||||||
|
MediaThumbnail,
|
||||||
NumberBlock,
|
NumberBlock,
|
||||||
|
Scan,
|
||||||
Tag,
|
Tag,
|
||||||
TagsBlock,
|
TagsBlock,
|
||||||
TextBlock,
|
TextBlock,
|
||||||
Video,
|
Video,
|
||||||
} from "../types/collections";
|
} from "../types/collections";
|
||||||
import {
|
import {
|
||||||
|
ImageSize,
|
||||||
|
ValidImageSize,
|
||||||
isDefined,
|
isDefined,
|
||||||
isEmpty,
|
isEmpty,
|
||||||
isPayloadArrayType,
|
isPayloadArrayType,
|
||||||
isPayloadType,
|
isPayloadType,
|
||||||
isPublished,
|
isPublished,
|
||||||
|
isValidImageSize,
|
||||||
isValidPayloadImage,
|
isValidPayloadImage,
|
||||||
isValidPayloadMedia,
|
isValidPayloadMedia,
|
||||||
} from "./asserts";
|
} from "./asserts";
|
||||||
|
@ -272,3 +281,90 @@ const convertAttributeToEndpointAttribute = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const convertSizesToEndpointImageSize = (
|
||||||
|
sizes: (ImageSize | undefined)[],
|
||||||
|
targetSizes: number[]
|
||||||
|
): EndpointImageSize[] => {
|
||||||
|
if (!sizes) return [];
|
||||||
|
const processedSizes = sizes.filter(isValidImageSize);
|
||||||
|
|
||||||
|
const targetBins: { min: number; target: number; max: number; image: ValidImageSize }[] = [];
|
||||||
|
for (let index = 0; index < targetSizes.length; index++) {
|
||||||
|
const previous = targetSizes[index - 1];
|
||||||
|
const current = targetSizes[index]!;
|
||||||
|
const next = targetSizes[index + 1];
|
||||||
|
|
||||||
|
const min = previous ? previous + (current - previous) / 2 : 0;
|
||||||
|
const max = next ? current + (next - current) / 2 : Infinity;
|
||||||
|
|
||||||
|
const images = processedSizes
|
||||||
|
.filter(({ width }) => width > min && width <= max)
|
||||||
|
.sort((a, b) => a.filesize - b.filesize);
|
||||||
|
|
||||||
|
const smallestImage = images[0];
|
||||||
|
if (!smallestImage) continue;
|
||||||
|
|
||||||
|
targetBins.push({ min, target: current, max, image: smallestImage });
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetBins.map(({ target, image: { height, width, url } }) => ({
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
url,
|
||||||
|
wSize: target,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const convertScanToEndpointScanImage = (
|
||||||
|
{ url, width, height, mimeType, filename, filesize, sizes }: Scan & PayloadImage,
|
||||||
|
index: string
|
||||||
|
): EndpointScanImage => ({
|
||||||
|
index,
|
||||||
|
url,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
filename,
|
||||||
|
filesize,
|
||||||
|
mimeType,
|
||||||
|
sizes: convertSizesToEndpointImageSize(
|
||||||
|
[
|
||||||
|
sizes?.["200w"],
|
||||||
|
sizes?.["320w"],
|
||||||
|
sizes?.["480w"],
|
||||||
|
sizes?.["800w"],
|
||||||
|
{ url, width, height, filename, filesize, mimeType },
|
||||||
|
],
|
||||||
|
[200, 320, 480, 800]
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const convertMediaThumbnailToEndpointMediaThumbnail = ({
|
||||||
|
url,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
mimeType,
|
||||||
|
filename,
|
||||||
|
filesize,
|
||||||
|
sizes,
|
||||||
|
}: MediaThumbnail & PayloadImage): EndpointMediaThumbnail => ({
|
||||||
|
url,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
filename,
|
||||||
|
filesize,
|
||||||
|
mimeType,
|
||||||
|
sizes: convertSizesToEndpointImageSize(
|
||||||
|
[
|
||||||
|
sizes?.["200w"],
|
||||||
|
sizes?.["320w"],
|
||||||
|
sizes?.["480w"],
|
||||||
|
sizes?.["800w"],
|
||||||
|
sizes?.["1280w"],
|
||||||
|
sizes?.["1920w"],
|
||||||
|
sizes?.["2560w"],
|
||||||
|
{ url, width, height, filename, filesize, mimeType },
|
||||||
|
],
|
||||||
|
[200, 320, 480, 800, 1280, 1920, 2560]
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
|
@ -49,3 +49,35 @@ export const buildImageCollectionConfig = ({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const generateOpenGraphSize = (): ImageSize => ({
|
||||||
|
name: "og",
|
||||||
|
withoutEnlargement: true,
|
||||||
|
height: 1200,
|
||||||
|
width: 1200,
|
||||||
|
fit: "inside",
|
||||||
|
formatOptions: {
|
||||||
|
format: "jpg",
|
||||||
|
options: {
|
||||||
|
quality: 50,
|
||||||
|
optimizeScans: true,
|
||||||
|
quantizationTable: 2,
|
||||||
|
force: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const generateWebpSize = (maxWidth: number, quality: number): ImageSize => ({
|
||||||
|
name: `${maxWidth}w`,
|
||||||
|
withoutEnlargement: true,
|
||||||
|
width: maxWidth,
|
||||||
|
fit: "inside",
|
||||||
|
formatOptions: {
|
||||||
|
format: "webp",
|
||||||
|
options: {
|
||||||
|
quality,
|
||||||
|
alphaQuality: quality,
|
||||||
|
force: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue