From d0b91f9db693bf46ac6bcf20169abbbd5ca15ee0 Mon Sep 17 00:00:00 2001 From: DrMint Date: Thu, 23 Jun 2022 00:39:59 +0200 Subject: [PATCH] Continued using hooks --- src/components/AppLayout.tsx | 18 +- src/components/Library/ScanSet.tsx | 24 +- src/components/Library/ScanSetCover.tsx | 31 +- src/components/PostPage.tsx | 199 ++-- .../Chronology/ChronologyItemComponent.tsx | 1 - src/helpers/libraryItem.ts | 2 +- src/helpers/others.ts | 29 +- src/hooks/useSmartLanguage.tsx | 6 +- src/pages/404.tsx | 24 +- src/pages/500.tsx | 24 +- src/pages/about-us/index.tsx | 45 +- src/pages/archives/index.tsx | 22 +- src/pages/archives/videos/c/[uid].tsx | 126 +-- src/pages/archives/videos/index.tsx | 177 ++-- src/pages/archives/videos/v/[uid].tsx | 260 +++--- src/pages/chronicles/index.tsx | 21 +- src/pages/contents/[slug]/index.tsx | 628 +++++++------ src/pages/contents/index.tsx | 316 ++++--- src/pages/dev/checkup/contents.tsx | 109 +-- src/pages/dev/checkup/libraryitems.tsx | 109 +-- src/pages/dev/editor.tsx | 771 ++++++++-------- src/pages/library/[slug]/index.tsx | 859 +++++++++--------- src/pages/library/[slug]/scans.tsx | 153 ++-- src/pages/library/index.tsx | 392 ++++---- src/pages/merch/index.tsx | 22 +- src/pages/news/index.tsx | 130 +-- src/pages/wiki/[slug]/index.tsx | 142 +-- src/pages/wiki/chronology.tsx | 198 ++-- src/pages/wiki/index.tsx | 158 ++-- 29 files changed, 2640 insertions(+), 2356 deletions(-) diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index c8df188..ea24828 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -161,30 +161,30 @@ export function AppLayout(props: Props): JSX.Element { }, [fontSize]); const defaultPreferredLanguages = useMemo(() => { - let list: string[] = []; + let memo: string[] = []; if (isDefinedAndNotEmpty(router.locale) && router.locales) { if (router.locale === "en") { - list = [router.locale]; + memo = [router.locale]; router.locales.map((locale) => { - if (locale !== router.locale) list.push(locale); + if (locale !== router.locale) memo.push(locale); }); } else { - list = [router.locale, "en"]; + memo = [router.locale, "en"]; router.locales.map((locale) => { - if (locale !== router.locale && locale !== "en") list.push(locale); + if (locale !== router.locale && locale !== "en") memo.push(locale); }); } } - return list; + return memo; }, [router.locale, router.locales]); const currencyOptions = useMemo(() => { - const list: string[] = []; + const memo: string[] = []; filterHasAttributes(currencies).map((currentCurrency) => { if (isDefinedAndNotEmpty(currentCurrency.attributes.code)) - list.push(currentCurrency.attributes.code); + memo.push(currentCurrency.attributes.code); }); - return list; + return memo; }, [currencies]); const [currencySelect, setCurrencySelect] = useState(-1); diff --git a/src/components/Library/ScanSet.tsx b/src/components/Library/ScanSet.tsx index 5495d64..c79d7e0 100644 --- a/src/components/Library/ScanSet.tsx +++ b/src/components/Library/ScanSet.tsx @@ -157,12 +157,10 @@ export function ScanSet(props: Props): JSX.Element { {filterHasAttributes(selectedScan.cleaners.data).map( (cleaner) => ( - {cleaner.attributes && ( - - )} + ) )} @@ -178,12 +176,10 @@ export function ScanSet(props: Props): JSX.Element { {filterHasAttributes(selectedScan.typesetters.data).map( (typesetter) => ( - {typesetter.attributes && ( - - )} + ) )} @@ -218,9 +214,7 @@ export function ScanSet(props: Props): JSX.Element { openLightBox(images, index); }} > - {page.attributes && ( - - )} + ))} diff --git a/src/components/Library/ScanSetCover.tsx b/src/components/Library/ScanSetCover.tsx index 485fba4..9fd12eb 100644 --- a/src/components/Library/ScanSetCover.tsx +++ b/src/components/Library/ScanSetCover.tsx @@ -11,7 +11,7 @@ import { getAssetURL, ImageQuality } from "helpers/img"; import { filterHasAttributes, getStatusDescription } from "helpers/others"; import { useSmartLanguage } from "hooks/useSmartLanguage"; -import { Fragment } from "react"; +import { Fragment, useMemo } from "react"; interface Props { openLightBox: (images: string[], index?: number) => void; @@ -35,19 +35,22 @@ export function ScanSetCover(props: Props): JSX.Element { languageExtractor: (item) => item.language?.data?.attributes?.code, }); - const coverImages: UploadImageFragment[] = []; - if (selectedScan?.obi_belt?.full?.data?.attributes) - coverImages.push(selectedScan.obi_belt.full.data.attributes); - if (selectedScan?.obi_belt?.inside_full?.data?.attributes) - coverImages.push(selectedScan.obi_belt.inside_full.data.attributes); - if (selectedScan?.dust_jacket?.full?.data?.attributes) - coverImages.push(selectedScan.dust_jacket.full.data.attributes); - if (selectedScan?.dust_jacket?.inside_full?.data?.attributes) - coverImages.push(selectedScan.dust_jacket.inside_full.data.attributes); - if (selectedScan?.cover?.full?.data?.attributes) - coverImages.push(selectedScan.cover.full.data.attributes); - if (selectedScan?.cover?.inside_full?.data?.attributes) - coverImages.push(selectedScan.cover.inside_full.data.attributes); + const coverImages = useMemo(() => { + const memo: UploadImageFragment[] = []; + if (selectedScan?.obi_belt?.full?.data?.attributes) + memo.push(selectedScan.obi_belt.full.data.attributes); + if (selectedScan?.obi_belt?.inside_full?.data?.attributes) + memo.push(selectedScan.obi_belt.inside_full.data.attributes); + if (selectedScan?.dust_jacket?.full?.data?.attributes) + memo.push(selectedScan.dust_jacket.full.data.attributes); + if (selectedScan?.dust_jacket?.inside_full?.data?.attributes) + memo.push(selectedScan.dust_jacket.inside_full.data.attributes); + if (selectedScan?.cover?.full?.data?.attributes) + memo.push(selectedScan.cover.full.data.attributes); + if (selectedScan?.cover?.inside_full?.data?.attributes) + memo.push(selectedScan.cover.inside_full.data.attributes); + return memo; + }, [selectedScan]); if (coverImages.length > 0) { return ( diff --git a/src/components/PostPage.tsx b/src/components/PostPage.tsx index 07f8e75..9c95f07 100644 --- a/src/components/PostPage.tsx +++ b/src/components/PostPage.tsx @@ -67,105 +67,136 @@ export function PostPage(props: Props): JSX.Element { [post.slug, post.thumbnail, selectedTranslation] ); - const subPanel = - returnHref || returnTitle || displayCredits || displayToc ? ( - + const subPanel = useMemo( + () => + returnHref || returnTitle || displayCredits || displayToc ? ( + + {returnHref && returnTitle && ( + + )} + + {displayCredits && ( + <> + {selectedTranslation && ( +
+

{langui.status}:

+ + + {selectedTranslation.status} + +
+ )} + + {post.authors && post.authors.data.length > 0 && ( +
+

{"Authors"}:

+
+ {filterHasAttributes(post.authors.data).map((author) => ( + + + + ))} +
+
+ )} + + + + )} + + {displayToc && } +
+ ) : undefined, + [ + body, + displayCredits, + displayToc, + langui, + post.authors, + returnHref, + returnTitle, + selectedTranslation, + title, + ] + ); + + const contentPanel = useMemo( + () => ( + {returnHref && returnTitle && ( )} - {displayCredits && ( + {displayThumbnailHeader ? ( <> - {selectedTranslation && ( -
-

{langui.status}:

- - - {selectedTranslation.status} - -
- )} - - {post.authors && post.authors.data.length > 0 && ( -
-

{"Authors"}:

-
- {filterHasAttributes(post.authors.data).map((author) => ( - - - - ))} -
-
- )} + } + /> + ) : ( + <> + {displayLanguageSwitcher && ( +
+ +
+ )} + {displayTitle && ( +

+ {title} +

+ )} + )} - {displayToc && } -
- ) : undefined; - - const contentPanel = ( - - {returnHref && returnTitle && ( - - )} - - {displayThumbnailHeader ? ( - <> - } - /> - - - - ) : ( - <> - {displayLanguageSwitcher && ( -
- -
- )} - {displayTitle && ( -

- {title} -

- )} - - )} - - {prependBody} - - {appendBody} -
+ {prependBody} + + {appendBody} + + ), + [ + LanguageSwitcher, + appendBody, + body, + displayLanguageSwitcher, + displayThumbnailHeader, + displayTitle, + excerpt, + langui, + post.categories, + prependBody, + returnHref, + returnTitle, + thumbnail, + title, + ] ); return ( diff --git a/src/components/Wiki/Chronology/ChronologyItemComponent.tsx b/src/components/Wiki/Chronology/ChronologyItemComponent.tsx index a2af90b..0284d5a 100644 --- a/src/components/Wiki/Chronology/ChronologyItemComponent.tsx +++ b/src/components/Wiki/Chronology/ChronologyItemComponent.tsx @@ -85,7 +85,6 @@ export function ChronologyItemComponent(props: Props): JSX.Element { {translation.description && (

1 ? `mt-2 whitespace-pre-line before:ml-[-1em] before:inline-block before:w-4 before:text-dark before:content-['-']` diff --git a/src/helpers/libraryItem.ts b/src/helpers/libraryItem.ts index bada7af..19f4933 100644 --- a/src/helpers/libraryItem.ts +++ b/src/helpers/libraryItem.ts @@ -208,7 +208,7 @@ export function sortBy( orderByType: number, items: Items, currencies: AppStaticProps["currencies"] -): Items { +) { switch (orderByType) { case 0: return items.sort((a, b) => { diff --git a/src/helpers/others.ts b/src/helpers/others.ts index 64d2dce..cb5ed3c 100644 --- a/src/helpers/others.ts +++ b/src/helpers/others.ts @@ -19,23 +19,18 @@ type SortContentProps = >["contents"]; export function sortContent(contents: SortContentProps) { - if (contents) { - const newContent = { ...contents }; - newContent?.data.sort((a, b) => { - if ( - a.attributes?.range[0]?.__typename === "ComponentRangePageRange" && - b.attributes?.range[0]?.__typename === "ComponentRangePageRange" - ) { - return ( - a.attributes.range[0].starting_page - - b.attributes.range[0].starting_page - ); - } - return 0; - }); - return newContent; - } - return contents; + contents?.data.sort((a, b) => { + if ( + a.attributes?.range[0]?.__typename === "ComponentRangePageRange" && + b.attributes?.range[0]?.__typename === "ComponentRangePageRange" + ) { + return ( + a.attributes.range[0].starting_page - + b.attributes.range[0].starting_page + ); + } + return 0; + }); } export function getStatusDescription( diff --git a/src/hooks/useSmartLanguage.tsx b/src/hooks/useSmartLanguage.tsx index b3b454c..6f8d3df 100644 --- a/src/hooks/useSmartLanguage.tsx +++ b/src/hooks/useSmartLanguage.tsx @@ -38,12 +38,12 @@ export function useSmartLanguage( const router = useRouter(); const availableLocales = useMemo(() => { - const map = new Map(); + const memo = new Map(); filterDefined(items).map((elem, index) => { const result = languageExtractor(elem); - if (isDefined(result)) map.set(result, index); + if (isDefined(result)) memo.set(result, index); }); - return map; + return memo; }, [items, languageExtractor]); const [selectedTranslationIndex, setSelectedTranslationIndex] = useState< diff --git a/src/pages/404.tsx b/src/pages/404.tsx index 9ad8bfb..12938a4 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -7,21 +7,25 @@ import { ContentPanel } from "components/Panels/ContentPanel"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { GetStaticPropsContext } from "next"; +import { useMemo } from "react"; interface Props extends AppStaticProps {} export default function FourOhFour(props: Props): JSX.Element { const { langui } = props; - const contentPanel = ( - -

404 - {langui.page_not_found}

- - + const contentPanel = useMemo( + () => ( + +

404 - {langui.page_not_found}

+ +
+ ), + [langui] ); return ; } diff --git a/src/pages/500.tsx b/src/pages/500.tsx index 67c84bf..063736a 100644 --- a/src/pages/500.tsx +++ b/src/pages/500.tsx @@ -7,21 +7,25 @@ import { ContentPanel } from "components/Panels/ContentPanel"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { GetStaticPropsContext } from "next"; +import { useMemo } from "react"; interface Props extends AppStaticProps {} export default function FiveHundred(props: Props): JSX.Element { const { langui } = props; - const contentPanel = ( - -

500 - Internal Server Error

- -
+ const contentPanel = useMemo( + () => ( + +

500 - Internal Server Error

+ +
+ ), + [langui] ); return ; } diff --git a/src/pages/about-us/index.tsx b/src/pages/about-us/index.tsx index de8e770..df7cc08 100644 --- a/src/pages/about-us/index.tsx +++ b/src/pages/about-us/index.tsx @@ -6,32 +6,35 @@ import { SubPanel } from "components/Panels/SubPanel"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { GetStaticPropsContext } from "next"; +import { useMemo } from "react"; interface Props extends AppStaticProps {} export default function AboutUs(props: Props): JSX.Element { const { langui } = props; - const subPanel = ( - - - - - {/* */} - - - + const subPanel = useMemo( + () => ( + + + + + + + + ), + [langui] ); return ( diff --git a/src/pages/archives/index.tsx b/src/pages/archives/index.tsx index 00fcc7f..f4b5a48 100644 --- a/src/pages/archives/index.tsx +++ b/src/pages/archives/index.tsx @@ -6,20 +6,24 @@ import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { GetStaticPropsContext } from "next"; import { Icon } from "components/Ico"; +import { useMemo } from "react"; interface Props extends AppStaticProps {} export default function Archives(props: Props): JSX.Element { const { langui } = props; - const subPanel = ( - - - - + const subPanel = useMemo( + () => ( + + + + + ), + [langui] ); return ( diff --git a/src/pages/archives/videos/c/[uid].tsx b/src/pages/archives/videos/c/[uid].tsx index 15cb249..059dedb 100644 --- a/src/pages/archives/videos/c/[uid].tsx +++ b/src/pages/archives/videos/c/[uid].tsx @@ -20,7 +20,7 @@ import { GetStaticPathsResult, GetStaticPropsContext, } from "next"; -import { Fragment, useState } from "react"; +import { Fragment, useState, useMemo } from "react"; import { Icon } from "components/Ico"; import { useMediaHoverable } from "hooks/useMediaQuery"; import { WithLabel } from "components/Inputs/WithLabel"; @@ -37,67 +37,79 @@ export default function Channel(props: Props): JSX.Element { const [keepInfoVisible, setKeepInfoVisible] = useState(true); const hoverable = useMediaHoverable(); - const subPanel = ( - - - - - - {hoverable && ( - - } + const subPanel = useMemo( + () => ( + + - )} - + + + + {hoverable && ( + + } + /> + )} + + ), + [hoverable, keepInfoVisible, langui] ); - const contentPanel = ( - -
-

{channel?.title}

-

{channel?.subscribers.toLocaleString()} subscribers

-
-
+

{channel?.title}

+

{channel?.subscribers.toLocaleString()} subscribers

+
+
- {filterHasAttributes(channel?.videos?.data).map((video) => ( - - - - ))} -
-
+ > + {filterHasAttributes(channel?.videos?.data).map((video) => ( + + + + ))} + + + ), + [ + channel?.subscribers, + channel?.title, + channel?.videos?.data, + keepInfoVisible, + ] ); + return ( ["data"]; } +const ITEM_PER_PAGE = 50; + export default function Videos(props: Props): JSX.Element { const { langui, videos } = props; const hoverable = useMediaHoverable(); - videos - .sort((a, b) => { - const dateA = a.attributes?.published_date - ? prettyDate(a.attributes.published_date) - : "9999"; - const dateB = b.attributes?.published_date - ? prettyDate(b.attributes.published_date) - : "9999"; - return dateA.localeCompare(dateB); - }) - .reverse(); - - const itemPerPage = 50; - const paginatedVideos: Props["videos"][] = []; - for (let index = 0; itemPerPage * index < videos.length; index += 1) { - paginatedVideos.push( - videos.slice(index * itemPerPage, (index + 1) * itemPerPage) - ); - } + const paginatedVideos = useMemo(() => { + const memo = []; + for (let index = 0; ITEM_PER_PAGE * index < videos.length; index += 1) { + memo.push( + videos.slice(index * ITEM_PER_PAGE, (index + 1) * ITEM_PER_PAGE) + ); + } + return memo; + }, [videos]); const [page, setPage] = useState(0); const [keepInfoVisible, setKeepInfoVisible] = useState(true); - const subPanel = ( - - - - - - {hoverable && ( - - } + const subPanel = useMemo( + () => ( + + - )} - + + + + {hoverable && ( + + } + /> + )} + + ), + [hoverable, keepInfoVisible, langui] ); - const contentPanel = ( - - + const contentPanel = useMemo( + () => ( + + -
- {filterHasAttributes(paginatedVideos[page]).map((video) => ( - - - - ))} -
+ > + {filterHasAttributes(paginatedVideos[page]).map((video) => ( + + + + ))} + - -
+ +
+ ), + [keepInfoVisible, page, paginatedVideos, videos.length] ); return ( { + const dateA = a.attributes?.published_date + ? prettyDate(a.attributes.published_date) + : "9999"; + const dateB = b.attributes?.published_date + ? prettyDate(b.attributes.published_date) + : "9999"; + return dateA.localeCompare(dateB); + }) + .reverse(); const props: Props = { ...(await getAppStaticProps(context)), videos: videos.videos.data, diff --git a/src/pages/archives/videos/v/[uid].tsx b/src/pages/archives/videos/v/[uid].tsx index 52ea437..bd4c530 100644 --- a/src/pages/archives/videos/v/[uid].tsx +++ b/src/pages/archives/videos/v/[uid].tsx @@ -26,6 +26,7 @@ import { GetStaticPathsResult, GetStaticPropsContext, } from "next"; +import { useMemo } from "react"; interface Props extends AppStaticProps { video: NonNullable< @@ -37,145 +38,164 @@ export default function Video(props: Props): JSX.Element { const { langui, video } = props; const isMobile = useMediaMobile(); const appLayout = useAppLayout(); - const subPanel = ( - - + const subPanel = useMemo( + () => ( + + - + - appLayout.setSubPanelOpen(false)} - /> + appLayout.setSubPanelOpen(false)} + /> - appLayout.setSubPanelOpen(false)} - /> + appLayout.setSubPanelOpen(false)} + /> - appLayout.setSubPanelOpen(false)} - /> - + appLayout.setSubPanelOpen(false)} + /> + + ), + [appLayout, langui] ); - const contentPanel = ( - - + const contentPanel = useMemo( + () => ( + + -
-
- {video.gone ? ( - - ) : ( - - )} + allowFullScreen + > + )} -
-

{video.title}

-
-

- - {prettyDate(video.published_date)} -

-

- - {isMobile - ? prettyShortenNumber(video.views) - : video.views.toLocaleString()} -

- {video.channel?.data?.attributes && ( +
+

{video.title}

+

+ {prettyDate(video.published_date)} +

+

+ {isMobile - ? prettyShortenNumber(video.likes) - : video.likes.toLocaleString()} -

- )} - -
-
-
- - {video.channel?.data?.attributes && ( - -
-

{langui.channel}

-
-
-
- )} - - -
-

{langui.description}

-

{video.description}

-
-
- + + {video.channel?.data?.attributes && ( + +
+

{langui.channel}

+
+
+
+
+ )} + + +
+

{langui.description}

+

{video.description}

+
+
+
+ + ), + [ + isMobile, + langui, + video.channel?.data?.attributes, + video.description, + video.gone, + video.likes, + video.published_date, + video.source, + video.title, + video.uid, + video.views, + ] ); + return ( - - + const subPanel = useMemo( + () => ( + + + + ), + [langui] ); + return ( ); diff --git a/src/pages/contents/[slug]/index.tsx b/src/pages/contents/[slug]/index.tsx index 407e957..17fc91d 100644 --- a/src/pages/contents/[slug]/index.tsx +++ b/src/pages/contents/[slug]/index.tsx @@ -76,321 +76,349 @@ export default function Content(props: Props): JSX.Element { [content.group, content.slug] ); - const subPanel = ( - - - - {selectedTranslation?.text_set?.source_language?.data?.attributes - ?.code !== undefined && ( -
-

- {selectedTranslation.text_set.source_language.data.attributes - .code === selectedTranslation.language?.data?.attributes?.code - ? langui.transcript_notice - : langui.translation_notice} -

- - {selectedTranslation.text_set.source_language.data.attributes.code !== - selectedTranslation.language?.data?.attributes?.code && ( -
-

{langui.source_language}:

- - {prettyLanguage( - selectedTranslation.text_set.source_language.data.attributes - .code, - languages - )} - -
- )} - -
-

{langui.status}:

- - - {selectedTranslation.text_set.status} - -
- - {selectedTranslation.text_set.transcribers && - selectedTranslation.text_set.transcribers.data.length > 0 && ( -
-

{langui.transcribers}:

-
- {filterHasAttributes( - selectedTranslation.text_set.transcribers.data - ).map((recorder) => ( - - - - ))} -
-
- )} - - {selectedTranslation.text_set.translators && - selectedTranslation.text_set.translators.data.length > 0 && ( -
-

{langui.translators}:

-
- {filterHasAttributes( - selectedTranslation.text_set.translators.data - ).map((recorder) => ( - - - - ))} -
-
- )} - - {selectedTranslation.text_set.proofreaders && - selectedTranslation.text_set.proofreaders.data.length > 0 && ( -
-

{langui.proofreaders}:

-
- {filterHasAttributes( - selectedTranslation.text_set.proofreaders.data - ).map((recorder) => ( - - - - ))} -
-
- )} - - {isDefinedAndNotEmpty(selectedTranslation.text_set.notes) && ( -
-

{"Notes"}:

-
- -
-
- )} -
- )} - - {content.ranged_contents?.data && - content.ranged_contents.data.length > 0 && ( - <> - -
-

{langui.source}

-
- {content.ranged_contents.data.map((rangedContent) => { - const libraryItem = - rangedContent.attributes?.library_item?.data; - if (libraryItem?.attributes && libraryItem.id) { - return ( -
- 0 && - libraryItem.attributes.metadata[0] - ? [ - prettyItemSubType( - libraryItem.attributes.metadata[0] - ), - ] - : [] - } - bottomChips={libraryItem.attributes.categories?.data.map( - (category) => category.attributes?.short ?? "" - )} - metadata={{ - currencies: currencies, - release_date: libraryItem.attributes.release_date, - price: libraryItem.attributes.price, - position: "Bottom", - }} - infoAppend={ - - } - /> -
- ); - } - return <>; - })} -
-
- - )} - - {selectedTranslation?.text_set?.text && ( - <> - - - - )} -
- ); - const contentPanel = ( - - - -
- ( + + } + displayOn={ReturnButtonType.Desktop} + horizontalLine /> - {previousContent?.attributes && ( -
-

- {langui.previous_content} + {selectedTranslation?.text_set?.source_language?.data?.attributes + ?.code !== undefined && ( +
+

+ {selectedTranslation.text_set.source_language.data.attributes + .code === selectedTranslation.language?.data?.attributes?.code + ? langui.transcript_notice + : langui.translation_notice}

- ({ - pre_title: translation?.pre_title, - title: translation?.title, - subtitle: translation?.subtitle, - language: translation?.language?.data?.attributes?.code, - }) + + {selectedTranslation.text_set.source_language.data.attributes + .code !== + selectedTranslation.language?.data?.attributes?.code && ( +
+

{langui.source_language}:

+ + {prettyLanguage( + selectedTranslation.text_set.source_language.data.attributes + .code, + languages + )} + +
+ )} + +
+

{langui.status}:

+ + + {selectedTranslation.text_set.status} + +
+ + {selectedTranslation.text_set.transcribers && + selectedTranslation.text_set.transcribers.data.length > 0 && ( +
+

{langui.transcribers}:

+
+ {filterHasAttributes( + selectedTranslation.text_set.transcribers.data + ).map((recorder) => ( + + + + ))} +
+
)} - slug={previousContent.attributes.slug} - languages={languages} - thumbnail={previousContent.attributes.thumbnail?.data?.attributes} - thumbnailAspectRatio="3/2" - topChips={ - isMobile - ? undefined - : previousContent.attributes.type?.data?.attributes - ? [ - previousContent.attributes.type.data.attributes - .titles?.[0] - ? previousContent.attributes.type.data.attributes - .titles[0]?.title - : prettySlug( - previousContent.attributes.type.data.attributes.slug - ), - ] - : undefined - } - bottomChips={ - isMobile - ? undefined - : previousContent.attributes.categories?.data.map( - (category) => category.attributes?.short ?? "" - ) - } - /> + + {selectedTranslation.text_set.translators && + selectedTranslation.text_set.translators.data.length > 0 && ( +
+

{langui.translators}:

+
+ {filterHasAttributes( + selectedTranslation.text_set.translators.data + ).map((recorder) => ( + + + + ))} +
+
+ )} + + {selectedTranslation.text_set.proofreaders && + selectedTranslation.text_set.proofreaders.data.length > 0 && ( +
+

{langui.proofreaders}:

+
+ {filterHasAttributes( + selectedTranslation.text_set.proofreaders.data + ).map((recorder) => ( + + + + ))} +
+
+ )} + + {isDefinedAndNotEmpty(selectedTranslation.text_set.notes) && ( +
+

{"Notes"}:

+
+ +
+
+ )}
)} - + {content.ranged_contents?.data && + content.ranged_contents.data.length > 0 && ( + <> + +
+

{langui.source}

+
+ {content.ranged_contents.data.map((rangedContent) => { + const libraryItem = + rangedContent.attributes?.library_item?.data; + if (libraryItem?.attributes && libraryItem.id) { + return ( +
+ 0 && + libraryItem.attributes.metadata[0] + ? [ + prettyItemSubType( + libraryItem.attributes.metadata[0] + ), + ] + : [] + } + bottomChips={libraryItem.attributes.categories?.data.map( + (category) => category.attributes?.short ?? "" + )} + metadata={{ + currencies: currencies, + release_date: libraryItem.attributes.release_date, + price: libraryItem.attributes.price, + position: "Bottom", + }} + infoAppend={ + + } + /> +
+ ); + } + return <>; + })} +
+
+ + )} - - - {nextContent?.attributes && ( + {selectedTranslation?.text_set?.text && ( <> -

- {langui.followup_content} -

- ({ - pre_title: translation?.pre_title, - title: translation?.title, - subtitle: translation?.subtitle, - language: translation?.language?.data?.attributes?.code, - }) + category.attributes?.short ?? "" - ) - } /> )} -

- +
+ ), + [ + content.ranged_contents?.data, + currencies, + languages, + langui, + selectedTranslation, + ] + ); + + const contentPanel = useMemo( + () => ( + + + +
+ } + /> + + {previousContent?.attributes && ( +
+

+ {langui.previous_content} +

+ ({ + pre_title: translation?.pre_title, + title: translation?.title, + subtitle: translation?.subtitle, + language: translation?.language?.data?.attributes?.code, + }) + )} + slug={previousContent.attributes.slug} + languages={languages} + thumbnail={ + previousContent.attributes.thumbnail?.data?.attributes + } + thumbnailAspectRatio="3/2" + topChips={ + isMobile + ? undefined + : previousContent.attributes.type?.data?.attributes + ? [ + previousContent.attributes.type.data.attributes + .titles?.[0] + ? previousContent.attributes.type.data.attributes + .titles[0]?.title + : prettySlug( + previousContent.attributes.type.data.attributes + .slug + ), + ] + : undefined + } + bottomChips={ + isMobile + ? undefined + : previousContent.attributes.categories?.data.map( + (category) => category.attributes?.short ?? "" + ) + } + /> +
+ )} + + + + + + {nextContent?.attributes && ( + <> + +

+ {langui.followup_content} +

+ ({ + pre_title: translation?.pre_title, + title: translation?.title, + subtitle: translation?.subtitle, + language: translation?.language?.data?.attributes?.code, + }) + )} + slug={nextContent.attributes.slug} + languages={languages} + thumbnail={nextContent.attributes.thumbnail?.data?.attributes} + thumbnailAspectRatio="3/2" + topChips={ + isMobile + ? undefined + : nextContent.attributes.type?.data?.attributes + ? [ + nextContent.attributes.type.data.attributes.titles?.[0] + ? nextContent.attributes.type.data.attributes + .titles[0]?.title + : prettySlug( + nextContent.attributes.type.data.attributes.slug + ), + ] + : undefined + } + bottomChips={ + isMobile + ? undefined + : nextContent.attributes.categories?.data.map( + (category) => category.attributes?.short ?? "" + ) + } + /> + + )} +
+
+ ), + [ + LanguageSwitcher, + content.categories, + content.thumbnail?.data?.attributes, + content.type, + isMobile, + languages, + langui, + nextContent?.attributes, + previousContent?.attributes, + selectedTranslation, + ] ); return ( diff --git a/src/pages/contents/index.tsx b/src/pages/contents/index.tsx index 4f3fcfe..ad9133e 100644 --- a/src/pages/contents/index.tsx +++ b/src/pages/contents/index.tsx @@ -71,166 +71,188 @@ export default function Contents(props: Props): JSX.Element { [combineRelatedContent, searchName.length] ); - const subPanel = ( - - + const subPanel = useMemo( + () => ( + + - + - - } - /> - - 1} - input={ - - } - /> - - {hoverable && ( +