diff --git a/README.md b/README.md index 07bb428..7d5ed4a 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,14 @@ # Accords-library.com - [![Node.js CI](https://github.com/Accords-Library/accords-library.com/actions/workflows/node.js.yml/badge.svg?branch=main)](https://github.com/Accords-Library/accords-library.com/actions/workflows/node.js.yml) [![GitHub](https://img.shields.io/github/license/Accords-Library/accords-library.com?style=flat-square)](https://github.com/Accords-Library/accords-library.com/blob/main/LICENSE) ![Libraries.io dependency status for GitHub repo](https://img.shields.io/librariesio/github/Accords-Library/accords-library.com?style=flat-square) ## Introduction -Accord’s Library is a fan-site that aims at gathering and archiving all of Yoko Taro’s work. +Accord’s Library is a fan-site that aims at gathering and archiving all of Yoko Taro’s work. Yoko Taro is a Japanese video game director and scenario writer. He is best-known for his work on the NieR and Drakengard (Drag-on Dragoon) franchises. - ## Technologies #### [Content Management System](https://github.com/Accords-Library/strapi.accords-library.com) @@ -46,6 +44,7 @@ Yoko Taro is a Japanese video game director and scenario writer. He is best-know - Automatically generates a typesafe ready to use SDK using [graphql-request](https://www.npmjs.com/package/graphql-request) as the GraphQL client - Markdown + - Use [Marked](https://www.npmjs.com/package/marked) to convert markdown to HTML (which is then sanitized using [DOMPurify](https://www.npmjs.com/package/isomorphic-dompurify)) - Support for arbitrary React Components and Component Props using [markdown-to-jsx](https://www.npmjs.com/package/markdown-to-jsx) - Autogenerated multi-level table of content and anchor links for the different headers diff --git a/package.json b/package.json index c2865d2..36e495a 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "private": true, "scripts": { "dev": "next dev -p 12499", - "precommit": "npm run fetch-local-data && npm run icu-to-ts && npm run prettier && npm run unused-exports && npm run eslint && npm run tsc && echo ALL PRECOMMIT CHECKS PASSED SUCCESSFULLY, LET\\'S FUCKING GO!", + "precommit": "npm run fetch-local-data && npm run icu-to-ts && npm run unused-exports && npm run prettier && npm run eslint && npm run tsc && echo ALL PRECOMMIT CHECKS PASSED SUCCESSFULLY, LET\\'S FUCKING GO!", "unused-exports": "ts-unused-exports ./tsconfig.json --excludePathsFromReport=src/pages --ignoreFiles=generated", "fetch-local-data": "npm run generate && esrun src/graphql/fetchLocalData.ts --esrun", "icu-to-ts": "esrun src/graphql/icuToTypescript.ts --icu", diff --git a/src/graphql/getPostStaticProps.ts b/src/graphql/getPostStaticProps.ts index 30f89e7..a823c6f 100644 --- a/src/graphql/getPostStaticProps.ts +++ b/src/graphql/getPostStaticProps.ts @@ -1,6 +1,5 @@ import { GetStaticProps } from "next"; import { getReadySdk } from "./sdk"; -import { getLangui } from "./fetchLocalData"; import { PostWithTranslations } from "types/types"; import { getOpenGraph } from "helpers/openGraph"; import { prettyDate, prettySlug } from "helpers/formatters"; @@ -8,6 +7,7 @@ import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/local import { filterHasAttributes, isDefined } from "helpers/asserts"; import { getDescription } from "helpers/description"; import { AppLayoutRequired } from "components/AppLayout"; +import { getFormat } from "helpers/i18n"; export interface PostStaticProps extends AppLayoutRequired { post: PostWithTranslations; @@ -17,7 +17,7 @@ export const getPostStaticProps = (slug: string): GetStaticProps => async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const post = await sdk.getPost({ slug: slug, language_code: context.locale ?? "en", @@ -38,10 +38,8 @@ export const getPostStaticProps = const title = selectedTranslation?.title ?? prettySlug(slug); const description = getDescription(selectedTranslation?.excerpt, { - [langui.release_date ?? "Release date"]: [ - prettyDate(post.posts.data[0].attributes.date, context.locale), - ], - [langui.category ?? "Categories"]: filterHasAttributes( + [format("release_date")]: [prettyDate(post.posts.data[0].attributes.date, context.locale)], + [format("category", { count: Infinity })]: filterHasAttributes( post.posts.data[0].attributes.categories?.data, ["attributes"] as const ).map((category) => category.attributes.short), @@ -53,7 +51,7 @@ export const getPostStaticProps = const props: PostStaticProps = { post: post.posts.data[0].attributes as PostWithTranslations, - openGraph: getOpenGraph(langui, title, description, thumbnail), + openGraph: getOpenGraph(format, title, description, thumbnail), }; return { props: props, diff --git a/src/helpers/i18n.ts b/src/helpers/i18n.ts new file mode 100644 index 0000000..8310dbc --- /dev/null +++ b/src/helpers/i18n.ts @@ -0,0 +1,79 @@ +import { IntlMessageFormat } from "intl-messageformat"; +import { LibraryItemMetadataDynamicZone } from "graphql/generated"; +import { ICUParams } from "graphql/icuParams"; +import { isDefined, isDefinedAndNotEmpty } from "helpers/asserts"; +import { getLangui } from "graphql/fetchLocalData"; + +type WordingKey = keyof ICUParams; + +type LibraryItemType = Exclude; + +type ContentStatus = "Done" | "Draft" | "Incomplete" | "Review"; + +const componentMetadataToWording: Record = { + ComponentMetadataAudio: "audio", + ComponentMetadataBooks: "textual", + ComponentMetadataGame: "game", + ComponentMetadataGroup: "group", + ComponentMetadataVideo: "video", + ComponentMetadataOther: "other", + Error: "item", +}; + +const componentSetsTextsetStatusToWording: Record< + ContentStatus, + { label: WordingKey; description: WordingKey } +> = { + Draft: { label: "draft", description: "status_draft" }, + Incomplete: { label: "incomplete", description: "status_incomplete" }, + Review: { label: "review", description: "status_review" }, + Done: { label: "done", description: "status_done" }, +}; + +export const getFormat = ( + locale: string | undefined +): { + format: ( + key: K, + ...values: ICUParams[K] extends never ? [undefined?] : [ICUParams[K]] + ) => string; + formatLibraryItemType: (metadata: { __typename: LibraryItemType }) => string; + formatStatusLabel: (status: ContentStatus) => string; + formatStatusDescription: (status: ContentStatus) => string; +} => { + const langui = getLangui(locale); + const fallbackLangui = getLangui("en"); + + const format = ( + key: WordingKey, + values?: Record + ): string => { + const processedValues = Object.fromEntries( + Object.entries(values ?? {}).map(([oKey, value]) => [ + oKey, + isDefined(value) ? value : "undefined", + ]) + ); + const result = new IntlMessageFormat(langui[key] ?? "").format(processedValues).toString(); + if (isDefinedAndNotEmpty(result)) { + return result; + } + return new IntlMessageFormat(fallbackLangui[key] ?? "").format(processedValues).toString(); + }; + + const formatLibraryItemType = (metadata: { __typename: LibraryItemType }): string => + format(componentMetadataToWording[metadata.__typename]); + + const formatStatusLabel = (status: ContentStatus): string => + format(componentSetsTextsetStatusToWording[status].label); + + const formatStatusDescription = (status: ContentStatus): string => + format(componentSetsTextsetStatusToWording[status].description); + + return { + format, + formatLibraryItemType, + formatStatusLabel, + formatStatusDescription, + }; +}; diff --git a/src/helpers/openGraph.ts b/src/helpers/openGraph.ts index c50197b..86312e5 100644 --- a/src/helpers/openGraph.ts +++ b/src/helpers/openGraph.ts @@ -1,6 +1,6 @@ import { OgImage, getImgSizesByQuality, ImageQuality, getAssetURL } from "./img"; import { isDefinedAndNotEmpty } from "./asserts"; -import { Langui } from "./localData"; +import { getFormat } from "./i18n"; import { UploadImageFragment } from "graphql/generated"; const DEFAULT_OG_THUMBNAIL = { @@ -20,13 +20,13 @@ export interface OpenGraph { } export const getOpenGraph = ( - langui: Langui, + format: ReturnType["format"], title?: string | null | undefined, description?: string | null | undefined, thumbnail?: UploadImageFragment | null | undefined ): OpenGraph => ({ title: `${TITLE_PREFIX}${isDefinedAndNotEmpty(title) ? `${TITLE_SEPARATOR}${title}` : ""}`, - description: isDefinedAndNotEmpty(description) ? description : langui.default_description ?? "", + description: isDefinedAndNotEmpty(description) ? description : format("default_description"), thumbnail: thumbnail ? getOgImage(thumbnail) : DEFAULT_OG_THUMBNAIL, }); diff --git a/src/pages/404.tsx b/src/pages/404.tsx index f6cac38..2c4367d 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -3,9 +3,9 @@ import { AppLayout, AppLayoutRequired } from "components/AppLayout"; import { ReturnButton } from "components/PanelComponents/ReturnButton"; import { ContentPanel } from "components/Containers/ContentPanel"; import { getOpenGraph } from "helpers/openGraph"; -import { getLangui } from "graphql/fetchLocalData"; import { Img } from "components/Img"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -43,9 +43,9 @@ export default FourOhFour; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, `404 - ${langui.page_not_found}`), + openGraph: getOpenGraph(format, `404 - ${format("page_not_found")}`), }; return { props: props, diff --git a/src/pages/500.tsx b/src/pages/500.tsx index 1c81153..7d31789 100644 --- a/src/pages/500.tsx +++ b/src/pages/500.tsx @@ -3,9 +3,9 @@ import { AppLayout, AppLayoutRequired } from "components/AppLayout"; import { ReturnButton } from "components/PanelComponents/ReturnButton"; import { ContentPanel } from "components/Containers/ContentPanel"; import { getOpenGraph } from "helpers/openGraph"; -import { getLangui } from "graphql/fetchLocalData"; import { Img } from "components/Img"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -43,9 +43,10 @@ export default FiveHundred; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, "500 - Internal Server Error"), + /* TODO: Langui */ + openGraph: getOpenGraph(format, "500 - Internal Server Error"), }; return { props: props, diff --git a/src/pages/about-us/index.tsx b/src/pages/about-us/index.tsx index 5e462c8..a3077c4 100644 --- a/src/pages/about-us/index.tsx +++ b/src/pages/about-us/index.tsx @@ -5,8 +5,8 @@ import { PanelHeader } from "components/PanelComponents/PanelHeader"; import { SubPanel } from "components/Containers/SubPanel"; import { getOpenGraph } from "helpers/openGraph"; import { HorizontalLine } from "components/HorizontalLine"; -import { getLangui } from "graphql/fetchLocalData"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -47,9 +47,9 @@ export default AboutUs; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, langui.about_us ?? "About us"), + openGraph: getOpenGraph(format, format("about_us")), }; return { props: props, diff --git a/src/pages/archives/index.tsx b/src/pages/archives/index.tsx index 256b018..ddfe25f 100644 --- a/src/pages/archives/index.tsx +++ b/src/pages/archives/index.tsx @@ -5,8 +5,8 @@ import { PanelHeader } from "components/PanelComponents/PanelHeader"; import { SubPanel } from "components/Containers/SubPanel"; import { getOpenGraph } from "helpers/openGraph"; import { HorizontalLine } from "components/HorizontalLine"; -import { getLangui } from "graphql/fetchLocalData"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -39,9 +39,9 @@ export default Archives; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, langui.archives ?? "Archives"), + openGraph: getOpenGraph(format, format("archives")), }; return { props: props, diff --git a/src/pages/archives/videos/c/[uid].tsx b/src/pages/archives/videos/c/[uid].tsx index 5a43b90..d1885a2 100644 --- a/src/pages/archives/videos/c/[uid].tsx +++ b/src/pages/archives/videos/c/[uid].tsx @@ -13,7 +13,6 @@ import { SubPanel } from "components/Containers/SubPanel"; import { useDeviceSupportsHover } from "hooks/useMediaQuery"; import { getOpenGraph } from "helpers/openGraph"; import { HorizontalLine } from "components/HorizontalLine"; -import { getLangui } from "graphql/fetchLocalData"; import { CustomSearchResponse, meiliSearch } from "helpers/search"; import { MeiliIndices, MeiliVideo } from "shared/meilisearch-graphql-typings/meiliTypes"; import { PreviewCard } from "components/PreviewCard"; @@ -27,6 +26,7 @@ import { GetVideoChannelQuery } from "graphql/generated"; import { getReadySdk } from "graphql/sdk"; import { Paginator } from "components/Containers/Paginator"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭─────────────╮ @@ -275,7 +275,7 @@ export default Channel; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const channel = await sdk.getVideoChannel({ channel: context.params && isDefined(context.params.uid) ? context.params.uid.toString() : "", }); @@ -283,7 +283,7 @@ export const getStaticProps: GetStaticProps = async (context) => { const props: Props = { channel: channel.videoChannels.data[0].attributes, - openGraph: getOpenGraph(langui, channel.videoChannels.data[0].attributes.title), + openGraph: getOpenGraph(format, channel.videoChannels.data[0].attributes.title), }; return { props: props, diff --git a/src/pages/archives/videos/index.tsx b/src/pages/archives/videos/index.tsx index 0a6961c..3c85165 100644 --- a/src/pages/archives/videos/index.tsx +++ b/src/pages/archives/videos/index.tsx @@ -13,7 +13,6 @@ import { SubPanel } from "components/Containers/SubPanel"; import { useDeviceSupportsHover } from "hooks/useMediaQuery"; import { getOpenGraph } from "helpers/openGraph"; import { HorizontalLine } from "components/HorizontalLine"; -import { getLangui } from "graphql/fetchLocalData"; import { CustomSearchResponse, meiliSearch } from "helpers/search"; import { MeiliIndices, MeiliVideo } from "shared/meilisearch-graphql-typings/meiliTypes"; import { PreviewCard } from "components/PreviewCard"; @@ -25,6 +24,7 @@ import { sendAnalytics } from "helpers/analytics"; import { Button } from "components/Inputs/Button"; import { Paginator } from "components/Containers/Paginator"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭─────────────╮ @@ -267,9 +267,9 @@ export default Videos; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, langui.videos ?? "Videos"), + openGraph: getOpenGraph(format, format("videos")), }; return { props: props, diff --git a/src/pages/archives/videos/v/[uid].tsx b/src/pages/archives/videos/v/[uid].tsx index 77557b4..7f9c4b9 100644 --- a/src/pages/archives/videos/v/[uid].tsx +++ b/src/pages/archives/videos/v/[uid].tsx @@ -15,11 +15,11 @@ import { prettyDate, prettyShortenNumber } from "helpers/formatters"; import { filterHasAttributes, isDefined } from "helpers/asserts"; import { getVideoFile } from "helpers/videos"; import { getOpenGraph } from "helpers/openGraph"; -import { getLangui } from "graphql/fetchLocalData"; import { atoms } from "contexts/atoms"; import { useAtomGetter } from "helpers/atoms"; import { Link } from "components/Inputs/Link"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -144,7 +144,7 @@ export default Video; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const videos = await sdk.getVideo({ uid: context.params && isDefined(context.params.uid) ? context.params.uid.toString() : "", }); @@ -152,7 +152,7 @@ export const getStaticProps: GetStaticProps = async (context) => { const props: Props = { video: videos.videos.data[0].attributes, - openGraph: getOpenGraph(langui, videos.videos.data[0].attributes.title), + openGraph: getOpenGraph(format, videos.videos.data[0].attributes.title), }; return { props: props, diff --git a/src/pages/chronicles/[slug]/index.tsx b/src/pages/chronicles/[slug]/index.tsx index adaffca..004e553 100644 --- a/src/pages/chronicles/[slug]/index.tsx +++ b/src/pages/chronicles/[slug]/index.tsx @@ -17,10 +17,10 @@ import { getOpenGraph } from "helpers/openGraph"; import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales"; import { getDescription } from "helpers/description"; import { TranslatedChroniclesList } from "components/Chronicles/ChroniclesList"; -import { getLangui } from "graphql/fetchLocalData"; import { useScrollTopOnChange } from "hooks/useScrollTopOnChange"; import { Ids } from "types/ids"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -163,7 +163,7 @@ export default Chronicle; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const slug = context.params && isDefined(context.params.slug) ? context.params.slug.toString() : ""; const chronicle = await sdk.getChronicle({ @@ -193,11 +193,11 @@ export const getStaticProps: GetStaticProps = async (context) => { selectedContentTranslation.subtitle ), description: getDescription(selectedContentTranslation.description, { - [langui.type ?? "Type"]: [ + [format("type", { count: Infinity })]: [ chronicle.chronicles.data[0].attributes.contents.data[0].attributes.type?.data ?.attributes?.titles?.[0]?.title, ], - [langui.category ?? "Categories"]: filterHasAttributes( + [format("category", { count: Infinity })]: filterHasAttributes( chronicle.chronicles.data[0].attributes.contents.data[0].attributes.categories ?.data, ["attributes"] as const @@ -234,7 +234,7 @@ export const getStaticProps: GetStaticProps = async (context) => { const props: Props = { chronicle: chronicle.chronicles.data[0].attributes as ChronicleWithTranslations, chapters: chronicles.chroniclesChapters.data, - openGraph: getOpenGraph(langui, title, description, thumbnail), + openGraph: getOpenGraph(format, title, description, thumbnail), }; return { props: props, diff --git a/src/pages/chronicles/index.tsx b/src/pages/chronicles/index.tsx index 6517e54..2b86725 100644 --- a/src/pages/chronicles/index.tsx +++ b/src/pages/chronicles/index.tsx @@ -9,8 +9,8 @@ import { prettySlug } from "helpers/formatters"; import { getOpenGraph } from "helpers/openGraph"; import { TranslatedChroniclesList } from "components/Chronicles/ChroniclesList"; import { HorizontalLine } from "components/HorizontalLine"; -import { getLangui } from "graphql/fetchLocalData"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -62,13 +62,13 @@ export default Chronicles; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const chronicles = await sdk.getChroniclesChapters(); if (!chronicles.chroniclesChapters?.data) return { notFound: true }; const props: Props = { chapters: chronicles.chroniclesChapters.data, - openGraph: getOpenGraph(langui, langui.chronicles ?? "Chronicles"), + openGraph: getOpenGraph(format, format("chronicles")), }; return { props: props, diff --git a/src/pages/contents/[slug].tsx b/src/pages/contents/[slug].tsx index a26ec11..a3f3ad0 100644 --- a/src/pages/contents/[slug].tsx +++ b/src/pages/contents/[slug].tsx @@ -30,11 +30,11 @@ import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/local import { getDescription } from "helpers/description"; import { TranslatedPreviewLine } from "components/PreviewLine"; import { cIf } from "helpers/className"; -import { getLangui } from "graphql/fetchLocalData"; import { Ids } from "types/ids"; import { atoms } from "contexts/atoms"; import { useAtomGetter } from "helpers/atoms"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -374,7 +374,7 @@ export default Content; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const slug = context.params?.slug ? context.params.slug.toString() : ""; const content = await sdk.getContentText({ slug: slug, @@ -400,10 +400,10 @@ export const getStaticProps: GetStaticProps = async (context) => { selectedTranslation.subtitle ), description: getDescription(selectedTranslation.description, { - [langui.type ?? "Type"]: [ + [format("type", { count: Infinity })]: [ content.contents.data[0].attributes.type?.data?.attributes?.titles?.[0]?.title, ], - [langui.category ?? "Categories"]: filterHasAttributes( + [format("category", { count: Infinity })]: filterHasAttributes( content.contents.data[0].attributes.categories?.data, ["attributes"] as const ).map((category) => category.attributes.short), @@ -425,7 +425,7 @@ export const getStaticProps: GetStaticProps = async (context) => { const props: Props = { content: content.contents.data[0].attributes as ContentWithTranslations, - openGraph: getOpenGraph(langui, title, description, thumbnail), + openGraph: getOpenGraph(format, title, description, thumbnail), }; return { props: props, diff --git a/src/pages/contents/all.tsx b/src/pages/contents/all.tsx index 8bf8e53..6f0daaa 100644 --- a/src/pages/contents/all.tsx +++ b/src/pages/contents/all.tsx @@ -20,7 +20,6 @@ import { } from "helpers/asserts"; import { getOpenGraph } from "helpers/openGraph"; import { HorizontalLine } from "components/HorizontalLine"; -import { getLangui } from "graphql/fetchLocalData"; import { sendAnalytics } from "helpers/analytics"; import { containsHighlight, CustomSearchResponse, meiliSearch } from "helpers/search"; import { MeiliContent, MeiliIndices } from "shared/meilisearch-graphql-typings/meiliTypes"; @@ -29,6 +28,7 @@ import { TranslatedPreviewCard } from "components/PreviewCard"; import { prettySlug } from "helpers/formatters"; import { Paginator } from "components/Containers/Paginator"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭─────────────╮ @@ -253,10 +253,10 @@ export default Contents; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, langui.contents ?? "Contents"), + openGraph: getOpenGraph(format, format("contents")), }; return { props: props, diff --git a/src/pages/contents/folder/[slug].tsx b/src/pages/contents/folder/[slug].tsx index 6fd2deb..547d3d7 100644 --- a/src/pages/contents/folder/[slug].tsx +++ b/src/pages/contents/folder/[slug].tsx @@ -16,11 +16,11 @@ import { SubPanel } from "components/Containers/SubPanel"; import { TranslatedPreviewCard } from "components/PreviewCard"; import { HorizontalLine } from "components/HorizontalLine"; import { cJoin, cIf } from "helpers/className"; -import { getLangui } from "graphql/fetchLocalData"; import { atoms } from "contexts/atoms"; import { useAtomGetter } from "helpers/atoms"; import { TranslatedPreviewFolder } from "components/Contents/PreviewFolder"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -187,7 +187,7 @@ export default ContentsFolder; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const slug = context.params?.slug ? context.params.slug.toString() : ""; const contentsFolder = await sdk.getContentsFolder({ slug: slug, @@ -209,7 +209,7 @@ export const getStaticProps: GetStaticProps = async (context) => { const title = (() => { if (slug === "root") { - return langui.contents ?? "Contents"; + return format("contents"); } if (context.locale && context.locales) { const selectedTranslation = staticSmartLanguage({ @@ -225,7 +225,7 @@ export const getStaticProps: GetStaticProps = async (context) => { })(); const props: Props = { - openGraph: getOpenGraph(langui, title), + openGraph: getOpenGraph(format, title), folder, }; return { diff --git a/src/pages/dev/checkup/contents.tsx b/src/pages/dev/checkup/contents.tsx index b8deb85..287a65f 100644 --- a/src/pages/dev/checkup/contents.tsx +++ b/src/pages/dev/checkup/contents.tsx @@ -9,8 +9,8 @@ import { getReadySdk } from "graphql/sdk"; import { filterDefined, filterHasAttributes } from "helpers/asserts"; import { Report, Severity } from "types/Report"; import { getOpenGraph } from "helpers/openGraph"; -import { getLangui } from "graphql/fetchLocalData"; import { sJoin } from "helpers/formatters"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -83,11 +83,11 @@ export default CheckupContents; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const contents = await sdk.devGetContents(); const props: Props = { contents: contents, - openGraph: getOpenGraph(langui, "Checkup Contents"), + openGraph: getOpenGraph(format, "Checkup Contents"), }; return { props: props, diff --git a/src/pages/dev/checkup/libraryitems.tsx b/src/pages/dev/checkup/libraryitems.tsx index 0efd694..ba1fc76 100644 --- a/src/pages/dev/checkup/libraryitems.tsx +++ b/src/pages/dev/checkup/libraryitems.tsx @@ -11,8 +11,8 @@ import { import { getReadySdk } from "graphql/sdk"; import { Report, Severity } from "types/Report"; import { getOpenGraph } from "helpers/openGraph"; -import { getLangui } from "graphql/fetchLocalData"; import { sJoin } from "helpers/formatters"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -85,12 +85,12 @@ export default CheckupLibraryItems; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const libraryItems = await sdk.devGetLibraryItems(); const props: Props = { libraryItems: libraryItems, - openGraph: getOpenGraph(langui, "Checkup Library Items"), + openGraph: getOpenGraph(format, "Checkup Library Items"), }; return { props: props, diff --git a/src/pages/dev/editor.tsx b/src/pages/dev/editor.tsx index ff921af..8b41dd1 100644 --- a/src/pages/dev/editor.tsx +++ b/src/pages/dev/editor.tsx @@ -8,7 +8,7 @@ import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/Cont import { Popup } from "components/Containers/Popup"; import { ToolTip } from "components/ToolTip"; import { getOpenGraph } from "helpers/openGraph"; -import { getLangui } from "graphql/fetchLocalData"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -404,9 +404,9 @@ export default Editor; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, "Markdawn Editor"), + openGraph: getOpenGraph(format, "Markdawn Editor"), }; return { props: props, diff --git a/src/pages/dev/showcase/design-system.tsx b/src/pages/dev/showcase/design-system.tsx index acad7f3..2d0323a 100644 --- a/src/pages/dev/showcase/design-system.tsx +++ b/src/pages/dev/showcase/design-system.tsx @@ -3,7 +3,6 @@ import { GetStaticProps } from "next"; import { ReactNode, useState } from "react"; import Slider from "rc-slider"; import { AppLayout, AppLayoutRequired } from "components/AppLayout"; -import { getLangui } from "graphql/fetchLocalData"; import { getOpenGraph } from "helpers/openGraph"; import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel"; import { Button } from "components/Inputs/Button"; @@ -19,6 +18,7 @@ import { PreviewCard } from "components/PreviewCard"; import { PreviewLine } from "components/PreviewLine"; import { ChroniclePreview } from "components/Chronicles/ChroniclePreview"; import { PreviewFolder } from "components/Contents/PreviewFolder"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -880,9 +880,9 @@ export default DesignSystem; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, "Design System"), + openGraph: getOpenGraph(format, "Design System"), }; return { props: props, diff --git a/src/pages/dev/transcript.tsx b/src/pages/dev/transcript.tsx index 9401a65..f47e37f 100644 --- a/src/pages/dev/transcript.tsx +++ b/src/pages/dev/transcript.tsx @@ -6,7 +6,7 @@ import { ButtonGroup } from "components/Inputs/ButtonGroup"; import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel"; import { ToolTip } from "components/ToolTip"; import { getOpenGraph } from "helpers/openGraph"; -import { getLangui } from "graphql/fetchLocalData"; +import { getFormat } from "helpers/i18n"; /* * ╭─────────────╮ @@ -533,9 +533,9 @@ export default Transcript; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, "Japanese Transcription Tool"), + openGraph: getOpenGraph(format, "Japanese Transcription Tool"), }; return { props: props, diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 8240587..6a2c163 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,17 +1,16 @@ import { PostPage } from "components/PostPage"; import { getPostStaticProps, PostStaticProps } from "graphql/getPostStaticProps"; -import { getOpenGraph } from "helpers/openGraph"; import { Terminal } from "components/Cli/Terminal"; import { atoms } from "contexts/atoms"; import { useAtomGetter } from "helpers/atoms"; +import { TITLE_PREFIX } from "helpers/openGraph"; /* * ╭────────╮ * ──────────────────────────────────────────╯ PAGE ╰───────────────────────────────────────────── */ -const Home = ({ ...otherProps }: PostStaticProps): JSX.Element => { - const langui = useAtomGetter(atoms.localData.langui); +const Home = (props: PostStaticProps): JSX.Element => { const isTerminalMode = useAtomGetter(atoms.layout.terminalMode); if (isTerminalMode) { @@ -34,7 +33,7 @@ const Home = ({ ...otherProps }: PostStaticProps): JSX.Element => { return (
{
} displayTitle={false} - openGraph={getOpenGraph(langui)} + openGraph={{ ...props.openGraph, title: TITLE_PREFIX }} displayLanguageSwitcher /> ); diff --git a/src/pages/library/[slug]/index.tsx b/src/pages/library/[slug]/index.tsx index 338a1a6..bbddbb5 100644 --- a/src/pages/library/[slug]/index.tsx +++ b/src/pages/library/[slug]/index.tsx @@ -48,12 +48,12 @@ import { getOpenGraph } from "helpers/openGraph"; import { getDescription } from "helpers/description"; import { useIntersectionList } from "hooks/useIntersectionList"; import { HorizontalLine } from "components/HorizontalLine"; -import { getLangui } from "graphql/fetchLocalData"; import { Ids } from "types/ids"; import { atoms } from "contexts/atoms"; import { useAtomGetter } from "helpers/atoms"; import { Link } from "components/Inputs/Link"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭─────────────╮ @@ -576,7 +576,7 @@ export default LibrarySlug; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const item = await sdk.getLibraryItem({ slug: context.params && isDefined(context.params.slug) ? context.params.slug.toString() : "", language_code: context.locale ?? "en", @@ -589,14 +589,14 @@ export const getStaticProps: GetStaticProps = async (context) => { const description = getDescription( item.libraryItems.data[0].attributes.descriptions?.[0]?.description, { - [langui.category ?? "Categories"]: filterHasAttributes( + [format("category", { count: Infinity })]: filterHasAttributes( item.libraryItems.data[0].attributes.categories?.data, ["attributes.short"] ).map((category) => category.attributes.short), - [langui.type ?? "Type"]: item.libraryItems.data[0].attributes.metadata?.[0] + [format("type", { count: Infinity })]: item.libraryItems.data[0].attributes.metadata?.[0] ? [prettyItemSubType(item.libraryItems.data[0].attributes.metadata[0])] : [], - [langui.release_date ?? "Release date"]: [ + [format("release_date")]: [ item.libraryItems.data[0].attributes.release_date ? prettyDate(item.libraryItems.data[0].attributes.release_date, context.locale) : undefined, @@ -607,7 +607,7 @@ export const getStaticProps: GetStaticProps = async (context) => { const props: Props = { item: item.libraryItems.data[0].attributes, itemId: item.libraryItems.data[0].id, - openGraph: getOpenGraph(langui, title, description, thumbnail?.data?.attributes), + openGraph: getOpenGraph(format, title, description, thumbnail?.data?.attributes), }; return { props: props, diff --git a/src/pages/library/[slug]/reader.tsx b/src/pages/library/[slug]/reader.tsx index 67bd004..a43d3ee 100644 --- a/src/pages/library/[slug]/reader.tsx +++ b/src/pages/library/[slug]/reader.tsx @@ -14,7 +14,6 @@ import { getReadySdk } from "graphql/sdk"; import { sortRangedContent } from "helpers/others"; import { filterHasAttributes, isDefined, isDefinedAndNotEmpty } from "helpers/asserts"; import { getOpenGraph } from "helpers/openGraph"; -import { getLangui } from "graphql/fetchLocalData"; import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel"; import { Img } from "components/Img"; import { getAssetFilename, ImageQuality } from "helpers/img"; @@ -41,6 +40,7 @@ import { FilterSettings, useReaderSettings } from "hooks/useReaderSettings"; import { useIsWebkit } from "hooks/useIsWebkit"; import { useTypedRouter } from "hooks/useTypedRouter"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; type BookType = "book" | "manga"; type DisplayMode = "double" | "single"; @@ -577,7 +577,7 @@ export default LibrarySlug; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const item = await sdk.getLibraryItemScans({ slug: context.params && isDefined(context.params.slug) ? context.params.slug.toString() : "", language_code: context.locale ?? "en", @@ -658,7 +658,7 @@ export const getStaticProps: GetStaticProps = async (context) => { itemSlug: item.libraryItems.data[0].attributes.slug, pageRatio: `${pages[0]?.width ?? 21} / ${pages[0]?.height ?? 29.7}`, openGraph: getOpenGraph( - langui, + format, item.libraryItems.data[0].attributes.title, undefined, item.libraryItems.data[0].attributes.thumbnail?.data?.attributes diff --git a/src/pages/library/index.tsx b/src/pages/library/index.tsx index 364add9..42ba853 100644 --- a/src/pages/library/index.tsx +++ b/src/pages/library/index.tsx @@ -23,7 +23,6 @@ import { } from "helpers/asserts"; import { getOpenGraph } from "helpers/openGraph"; import { HorizontalLine } from "components/HorizontalLine"; -import { getLangui } from "graphql/fetchLocalData"; import { sendAnalytics } from "helpers/analytics"; import { containsHighlight, CustomSearchResponse, meiliSearch } from "helpers/search"; import { MeiliIndices, MeiliLibraryItem } from "shared/meilisearch-graphql-typings/meiliTypes"; @@ -35,6 +34,7 @@ import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs"; import { useLibraryItemUserStatus } from "hooks/useLibraryItemUserStatus"; import { Paginator } from "components/Containers/Paginator"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭─────────────╮ @@ -454,9 +454,9 @@ export default Library; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, langui.library ?? "Library"), + openGraph: getOpenGraph(format, format("library")), }; return { props: props, diff --git a/src/pages/merch/index.tsx b/src/pages/merch/index.tsx deleted file mode 100644 index 51f8993..0000000 --- a/src/pages/merch/index.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { GetStaticProps } from "next"; -import { AppLayout, AppLayoutRequired } from "components/AppLayout"; -import { PanelHeader } from "components/PanelComponents/PanelHeader"; -import { SubPanel } from "components/Containers/SubPanel"; -import { getOpenGraph } from "helpers/openGraph"; -import { getLangui } from "graphql/fetchLocalData"; -import { useFormat } from "hooks/useFormat"; - -/* - * ╭────────╮ - * ──────────────────────────────────────────╯ PAGE ╰───────────────────────────────────────────── - */ - -interface Props extends AppLayoutRequired {} -const Merch = (props: Props): JSX.Element => { - const { format } = useFormat(); - return ( - - - - } - {...props} - /> - ); -}; -export default Merch; - -/* - * ╭──────────────────────╮ - * ───────────────────────────────────╯ NEXT DATA FETCHING ╰────────────────────────────────────── - */ - -export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); - const props: Props = { - openGraph: getOpenGraph(langui, langui.merch ?? "Merch"), - }; - return { - props: props, - }; -}; diff --git a/src/pages/news/index.tsx b/src/pages/news/index.tsx index 14c93a5..ff245d4 100644 --- a/src/pages/news/index.tsx +++ b/src/pages/news/index.tsx @@ -20,7 +20,6 @@ import { import { getOpenGraph } from "helpers/openGraph"; import { TranslatedPreviewCard } from "components/PreviewCard"; import { HorizontalLine } from "components/HorizontalLine"; -import { getLangui } from "graphql/fetchLocalData"; import { sendAnalytics } from "helpers/analytics"; import { Terminal } from "components/Cli/Terminal"; import { atoms } from "contexts/atoms"; @@ -31,6 +30,7 @@ import { useTypedRouter } from "hooks/useTypedRouter"; import { prettySlug } from "helpers/formatters"; import { Paginator } from "components/Containers/Paginator"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭─────────────╮ @@ -225,9 +225,9 @@ export default News; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, langui.news ?? "News"), + openGraph: getOpenGraph(format, format("news")), }; return { props: props, diff --git a/src/pages/wiki/[slug]/index.tsx b/src/pages/wiki/[slug]/index.tsx index e23cc28..fc75338 100644 --- a/src/pages/wiki/[slug]/index.tsx +++ b/src/pages/wiki/[slug]/index.tsx @@ -19,12 +19,12 @@ import { getOpenGraph } from "helpers/openGraph"; import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales"; import { getDescription } from "helpers/description"; import { cIf, cJoin } from "helpers/className"; -import { getLangui } from "graphql/fetchLocalData"; import { Terminal } from "components/Cli/Terminal"; import { prettyTerminalBoxedTitle, prettyTerminalUnderlinedTitle } from "helpers/terminal"; import { atoms } from "contexts/atoms"; import { useAtomGetter } from "helpers/atoms"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -231,7 +231,7 @@ export default WikiPage; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const slug = context.params && isDefined(context.params.slug) ? context.params.slug.toString() : ""; const page = await sdk.getWikiPage({ @@ -242,12 +242,12 @@ export const getStaticProps: GetStaticProps = async (context) => { const { title, description } = (() => { const chipsGroups = { - [langui.tags ?? "Tags"]: filterHasAttributes(page.wikiPages.data[0].attributes.tags?.data, [ + [format("tags")]: filterHasAttributes(page.wikiPages.data[0].attributes.tags?.data, [ "attributes", ] as const).map( (tag) => tag.attributes.titles?.[0]?.title ?? prettySlug(tag.attributes.slug) ), - [langui.category ?? "Categories"]: filterHasAttributes( + [format("category", { count: Infinity })]: filterHasAttributes( page.wikiPages.data[0].attributes.categories?.data, ["attributes"] as const ).map((category) => category.attributes.short), @@ -277,7 +277,7 @@ export const getStaticProps: GetStaticProps = async (context) => { const props: Props = { page: page.wikiPages.data[0].attributes as WikiPageWithTranslations, - openGraph: getOpenGraph(langui, title, description, thumbnail), + openGraph: getOpenGraph(format, title, description, thumbnail), }; return { props: props, diff --git a/src/pages/wiki/chronology.tsx b/src/pages/wiki/chronology.tsx index f4ffc19..0bc1533 100644 --- a/src/pages/wiki/chronology.tsx +++ b/src/pages/wiki/chronology.tsx @@ -25,8 +25,8 @@ import { TranslatedProps } from "types/TranslatedProps"; import { TranslatedNavOption } from "components/PanelComponents/NavOption"; import { useIntersectionList } from "hooks/useIntersectionList"; import { HorizontalLine } from "components/HorizontalLine"; -import { getLangui } from "graphql/fetchLocalData"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭────────╮ @@ -117,7 +117,7 @@ export default Chronology; export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const chronologyItems = await sdk.getChronologyItems(); const chronologyEras = await sdk.getEras(); if (!chronologyItems.chronologyItems || !chronologyEras.chronologyEras) return { notFound: true }; @@ -125,7 +125,7 @@ export const getStaticProps: GetStaticProps = async (context) => { const props: Props = { chronologyItems: chronologyItems.chronologyItems.data, chronologyEras: chronologyEras.chronologyEras.data, - openGraph: getOpenGraph(langui, langui.chronology ?? "Chronology"), + openGraph: getOpenGraph(format, format("chronology")), }; return { props: props, diff --git a/src/pages/wiki/index.tsx b/src/pages/wiki/index.tsx index cf92bf2..3a87483 100644 --- a/src/pages/wiki/index.tsx +++ b/src/pages/wiki/index.tsx @@ -17,13 +17,13 @@ import { filterHasAttributes, isDefined, isDefinedAndNotEmpty } from "helpers/as import { prettySlug } from "helpers/formatters"; import { getOpenGraph } from "helpers/openGraph"; import { TranslatedPreviewCard } from "components/PreviewCard"; -import { getLangui } from "graphql/fetchLocalData"; import { sendAnalytics } from "helpers/analytics"; import { useTypedRouter } from "hooks/useTypedRouter"; import { MeiliIndices, MeiliWikiPage } from "shared/meilisearch-graphql-typings/meiliTypes"; import { containsHighlight, CustomSearchResponse, meiliSearch } from "helpers/search"; import { Paginator } from "components/Containers/Paginator"; import { useFormat } from "hooks/useFormat"; +import { getFormat } from "helpers/i18n"; /* * ╭─────────────╮ @@ -211,9 +211,9 @@ export default Wiki; */ export const getStaticProps: GetStaticProps = (context) => { - const langui = getLangui(context.locale); + const { format } = getFormat(context.locale); const props: Props = { - openGraph: getOpenGraph(langui, langui.wiki ?? "Wiki"), + openGraph: getOpenGraph(format, format("wiki")), }; return { props: props,