diff --git a/.gitignore b/.gitignore index c1491a3..ba681bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # Generated content src/graphql/generated.ts +public/robots.txt + # dependencies /node_modules /.pnp diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index d6220f6..f368f18 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -2,6 +2,7 @@ import Head from "next/head"; import { useSwipeable } from "react-swipeable"; import { MaterialSymbol } from "material-symbols"; import { atom } from "jotai"; +import { useRouter } from "next/router"; import { layout } from "../../design.config"; import { Ico } from "./Ico"; import { MainPanel } from "./Panels/MainPanel"; @@ -54,6 +55,7 @@ export const AppLayout = ({ const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout); const isScreenAtLeastXs = useAtomGetter(atoms.containerQueries.isScreenAtLeastXs); const isIOS = useAtomGetter(isIOSAtom); + const router = useRouter(); const { format } = useFormat(); @@ -105,19 +107,41 @@ export const AppLayout = ({ {openGraph.title} + + + + + + + + {openGraph.audio && ( + <> + + + + )} + {openGraph.video && ( + <> + {" "} + + + )} {/* Content panel */} diff --git a/src/helpers/openGraph.ts b/src/helpers/openGraph.ts index eab5e7f..b79cb1a 100644 --- a/src/helpers/openGraph.ts +++ b/src/helpers/openGraph.ts @@ -8,7 +8,7 @@ const DEFAULT_OG_THUMBNAIL: OgImage = { image: `${process.env.NEXT_PUBLIC_URL_SELF}/default_og.jpg`, width: 1200, height: 630, - alt: "Accord's Library Logo", + alt: "Accord’s Library Logo", }; export const TITLE_PREFIX = "Accord’s Library"; @@ -18,13 +18,17 @@ export interface OpenGraph { title: string; description: string; thumbnail: OgImage; + audio?: string; + video?: string; } export const getOpenGraph = ( format: ReturnType["format"] | ReturnType["format"], title?: string | null | undefined, description?: string | null | undefined, - thumbnail?: UploadImageFragment | string | null | undefined + thumbnail?: UploadImageFragment | string | null | undefined, + audio?: string, + video?: string ): OpenGraph => ({ title: `${TITLE_PREFIX}${isDefinedAndNotEmpty(title) ? `${TITLE_SEPARATOR}${title}` : ""}`, description: isDefinedAndNotEmpty(description) @@ -33,6 +37,8 @@ export const getOpenGraph = ( : description : format("default_description"), thumbnail: thumbnail ? getOgImage(thumbnail) : DEFAULT_OG_THUMBNAIL, + ...(audio ? { audio } : {}), + ...(video ? { video } : {}), }); const getOgImage = (image: UploadImageFragment | string): OgImage => { diff --git a/src/pages/archives/videos/v/[uid].tsx b/src/pages/archives/videos/v/[uid].tsx index c075f28..bc85378 100644 --- a/src/pages/archives/videos/v/[uid].tsx +++ b/src/pages/archives/videos/v/[uid].tsx @@ -167,7 +167,11 @@ export const getStaticProps: GetStaticProps = async (context) => { getDescription(videos.videos.data[0].attributes.description, { [format("channel")]: [videos.videos.data[0].attributes.channel?.data?.attributes?.title], }), - getVideoThumbnailURL(videos.videos.data[0].attributes.uid) + getVideoThumbnailURL(videos.videos.data[0].attributes.uid), + undefined, + videos.videos.data[0].attributes.gone + ? getVideoFile(videos.videos.data[0].attributes.uid) + : undefined ), }; return { diff --git a/src/pages/contents/[slug].tsx b/src/pages/contents/[slug].tsx index bee3856..0823256 100644 --- a/src/pages/contents/[slug].tsx +++ b/src/pages/contents/[slug].tsx @@ -275,30 +275,31 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => { selectedSetType === "text_set" && selectedTranslation?.text_set?.text ? ( - ) : selectedSetType === "audio_set" && selectedTranslation?.audio_set ? ( + ) : selectedSetType === "audio_set" && + selectedTranslation?.audio_set && + selectedTranslation.language?.data?.attributes?.code ? ( ) : ( selectedSetType === "video_set" && - selectedTranslation?.video_set && ( + selectedTranslation?.video_set && + selectedTranslation.language?.data?.attributes?.code && ( ) @@ -340,7 +341,7 @@ export const getStaticProps: GetStaticProps = async (context) => { return { notFound: true }; } - const { title, description } = (() => { + const { title, description, audio, video } = (() => { if (context.locale && context.locales) { const selectedTranslation = staticSmartLanguage({ items: content.contents.data[0].attributes.translations, @@ -351,6 +352,7 @@ export const getStaticProps: GetStaticProps = async (context) => { const rawDescription = isDefinedAndNotEmpty(selectedTranslation.description) ? selectedTranslation.description : selectedTranslation.text_set?.text; + return { title: prettyInlineTitle( selectedTranslation.pre_title, @@ -366,12 +368,22 @@ export const getStaticProps: GetStaticProps = async (context) => { ["attributes"] ).map((category) => category.attributes.short), }), + audio: + selectedTranslation.language?.data?.attributes?.code && selectedTranslation.audio_set + ? getAudioURL(slug, selectedTranslation.language.data.attributes.code) + : undefined, + video: + selectedTranslation.language?.data?.attributes?.code && selectedTranslation.video_set + ? getVideoURL(slug, selectedTranslation.language.data.attributes.code) + : undefined, }; } } return { title: prettySlug(content.contents.data[0].attributes.slug), description: undefined, + audio: undefined, + video: undefined, }; })(); @@ -379,7 +391,7 @@ export const getStaticProps: GetStaticProps = async (context) => { const props: Props = { content: content.contents.data[0].attributes as ContentWithTranslations, - openGraph: getOpenGraph(format, title, description, thumbnail), + openGraph: getOpenGraph(format, title, description, thumbnail, audio, video), }; return { props: props, @@ -488,3 +500,16 @@ const RelatedContentPreview = ({ /> ); }; + +/* + * ╭───────────────────╮ + * ─────────────────────────────────────╯ PRIVATE METHODS ╰─────────────────────────────────────── + */ + +const getAudioURL = (slug: string, langCode: string): string => + `${process.env.NEXT_PUBLIC_URL_ASSETS}/contents/audios/\ +${slug}_${langCode}.mp3`; + +const getVideoURL = (slug: string, langCode: string): string => + `${process.env.NEXT_PUBLIC_URL_ASSETS}/contents/videos/\ +${slug}_${langCode}.mp4`;