diff --git a/src/components/PageGrid/index.tsx b/src/components/PageGrid/index.tsx index 35291de5..29fea9ee 100644 --- a/src/components/PageGrid/index.tsx +++ b/src/components/PageGrid/index.tsx @@ -48,6 +48,8 @@ export const PageGrid: React.FC = props => { objectFit={'cover'} src={item.cover.src} alt={item.cover.alt} + placeholder={'blur'} + blurDataURL={item.cover.blur} /> )} layout={layout} diff --git a/src/lib/meta.ts b/src/lib/meta.ts index 6763aed7..f0a84303 100644 --- a/src/lib/meta.ts +++ b/src/lib/meta.ts @@ -1,4 +1,4 @@ -import { IMeta, ImageDefinition } from 'src/types' +import { IMeta, Pic } from 'src/types' export function meta(props: Partial): IMeta { const path = props.url || '/' @@ -25,7 +25,7 @@ export function meta(props: Partial): IMeta { } export class MetaBuilder { - private image: ImageDefinition + private image: Pic private title: string private description: string private data: Partial @@ -45,7 +45,7 @@ export class MetaBuilder { return this } - setImage(param: ImageDefinition) { + setImage(param: Pic) { this.image = param return this } diff --git a/src/remote/factory.ts b/src/remote/factory.ts index 1fe3d020..de79493b 100644 --- a/src/remote/factory.ts +++ b/src/remote/factory.ts @@ -1,4 +1,4 @@ -import { ImageDefinition, IMenu, IPage, ITag, PageCardDto, Pic, Token } from "@/types"; +import { IMenu, IPage, ITag, PageCardDto, Pic, Token } from "@/types"; import { asItem } from "./lib"; import { StrapiComponentEmbed, StrapiComponent, StrapiHome, StrapiPage, StrapiPageCard, StrapiTag, StrapiMedia, StrapiMenu } from "./types"; import { typograf, markdownToHtml } from 'src/lib/text' @@ -16,15 +16,6 @@ export function isYoutubeUrl(url: string): boolean { return /youtube\.com/.test(url) } -export function getCoverImage(media?: StrapiMedia) { - return media ? createImageFromMedia(media) : { - src: 'https://hudozkacdn.tmshv.com/main_fad9fdf29a.jpg', - width: 1920, - height: 1858, - alt: '' - } -} - export function createEmbed(component: StrapiComponentEmbed): Token { if (isYoutubeUrl(component.src)) { return { @@ -51,20 +42,10 @@ export async function createPageToken(component: StrapiComponent): Promise ({ id: tag.id, name: tag.name, @@ -167,17 +150,50 @@ function isCardFeatured(card: StrapiPageCard): boolean { return card.layout === 'big' || card.layout === 'medium' } -function createImageFromMedia(media: StrapiMedia): ImageDefinition { +export async function getCoverImage(media?: StrapiMedia): Promise { + if (media) { + return createPicFromMedia(media) + } + return { - src: media.url, - width: media.width, - height: media.height, - alt: media.alternativeText ?? '', + src: 'https://hudozkacdn.tmshv.com/main_fad9fdf29a.jpg', + width: 1920, + height: 1858, + // alt: '', + // caption: '', + // blur: '', } } -export function createCardGrid(card: StrapiPageCard): PageCardDto { - const cover = getCoverImage(card.page.cover) +async function createPicFromMedia(media: StrapiMedia, overrides?: Partial): Promise { + const src = media.formats?.large?.url ?? media.url + const pic: Pic = { + src, + width: media.width, + height: media.height, + } + + const alt = overrides?.alternativeText ?? media.alternativeText ?? undefined + if (alt) { + pic.alt = alt + } + + const caption = overrides?.caption ?? media.caption ?? undefined + if (caption) { + pic.caption = caption + } + + const thumb = media.formats?.thumbnail?.url ?? media.url + const blur = await encodeImageToBlurhash(thumb) + if (blur) { + pic.blur = blur + } + + return pic +} + +export async function createCardGrid(card: StrapiPageCard): Promise { + const cover = await getCoverImage(card.page.cover) return { id: card.id, @@ -189,8 +205,10 @@ export function createCardGrid(card: StrapiPageCard): PageCardDto { } } -export function createHomeCards(data: StrapiHome): PageCardDto[] { - return data.cards +export async function createHomeCards(data: StrapiHome): Promise { + const items = await Promise.all(data.cards .map(createCardGrid) + ) + return items .filter(x => !!x.url) } diff --git a/src/types.ts b/src/types.ts index af171e00..06b8e84c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -14,14 +14,14 @@ export type PageCardDto = { title: string featured: boolean date: string | null - cover: ImageDefinition + cover: Pic } export type FileDefinition = { url: string slug: string name: string - cover?: ImageDefinition + cover?: Pic file: { name: string size: string @@ -36,7 +36,7 @@ export interface IPage { url: string data: string date: string - cover: ImageDefinition + cover: Pic description: string tokens: any[] tags: ITag[] @@ -89,13 +89,7 @@ export interface ITag { name: string slug: string href: string -} - -export type ImageDefinition = { - width: number - height: number - src: string - alt?: string + count: number } export type Pic = {