diff --git a/src/components/Library/ScanSet.tsx b/src/components/Library/ScanSet.tsx index 4bf255d..31ef4be 100644 --- a/src/components/Library/ScanSet.tsx +++ b/src/components/Library/ScanSet.tsx @@ -1,10 +1,14 @@ +import Button from "components/Button"; +import Chip from "components/Chip"; import Img, { getAssetURL, ImageQuality } from "components/Img"; import LanguageSwitcher from "components/LanguageSwitcher"; +import RecorderChip from "components/RecorderChip"; +import ToolTip from "components/ToolTip"; import { useAppLayout } from "contexts/AppLayoutContext"; import { GetLibraryItemScansQuery } from "graphql/generated"; import { useRouter } from "next/router"; import { AppStaticProps } from "queries/getAppStaticProps"; -import { getPreferredLanguage } from "queries/helpers"; +import { getPreferredLanguage, getStatusDescription } from "queries/helpers"; import { Dispatch, SetStateAction, useEffect, useMemo, useState } from "react"; interface Props { @@ -30,6 +34,20 @@ interface Props { slug: string; title: string; languages: AppStaticProps["languages"]; + langui: AppStaticProps["langui"]; + content: Exclude< + Exclude< + Exclude< + Exclude< + GetLibraryItemScansQuery["libraryItems"], + null | undefined + >["data"][number]["attributes"], + null | undefined + >["contents"], + null | undefined + >["data"][number]["attributes"], + null | undefined + >["content"]; } export default function ScanSet(props: Props): JSX.Element { @@ -41,6 +59,8 @@ export default function ScanSet(props: Props): JSX.Element { slug, title, languages, + langui, + content, } = props; const appLayout = useAppLayout(); const router = useRouter(); @@ -73,46 +93,137 @@ export default function ScanSet(props: Props): JSX.Element { }, [selectedScanIndex]); return ( -
-
-

- {title} -

- -
+ <> + {selectedScan && ( +
+
+

+ {title} +

-
- {selectedScan?.pages?.data.map((page, index) => ( -
{ - const images: string[] = []; - selectedScan.pages?.data.map((image) => { - if (image.attributes?.url) - images.push( - getAssetURL(image.attributes.url, ImageQuality.Large) - ); - }); - setLightboxOpen(true); - setLightboxImages(images); - setLightboxIndex(index); - }} - > - {page.attributes && ( - + + {selectedScan.language?.data?.attributes?.code === + selectedScan.source_language?.data?.attributes?.code + ? "Scan" + : "Scanlation"} + +
+ +
+ {content?.data?.attributes?.slug && ( + + )} + + + +
+

{langui.status}:

+ + {selectedScan.status} + +
+ + {selectedScan.scanners && selectedScan.scanners.data.length > 0 && ( +
+

{"Scanners"}:

+
+ {selectedScan.scanners.data.map((scanner) => ( + <> + {scanner.attributes && ( + + )} + + ))} +
+
+ )} + + {selectedScan.cleaners && selectedScan.cleaners.data.length > 0 && ( +
+

{"Cleaners"}:

+
+ {selectedScan.cleaners.data.map((cleaner) => ( + <> + {cleaner.attributes && ( + + )} + + ))} +
+
+ )} + + {selectedScan.typesetters && + selectedScan.typesetters.data.length > 0 && ( +
+

{"Typesetters"}:

+
+ {selectedScan.typesetters.data.map((typesetter) => ( + <> + {typesetter.attributes && ( + + )} + + ))} +
+
+ )} + + {selectedScan.notes && ( + + {"Notes"} + )}
- ))} -
-
+ +
+ {selectedScan.pages?.data.map((page, index) => ( +
{ + const images: string[] = []; + selectedScan.pages?.data.map((image) => { + if (image.attributes?.url) + images.push( + getAssetURL(image.attributes.url, ImageQuality.Large) + ); + }); + setLightboxOpen(true); + setLightboxImages(images); + setLightboxIndex(index); + }} + > + {page.attributes && ( + + )} +
+ ))} +
+
+ )} + ); } diff --git a/src/components/Library/ScanSetCover.tsx b/src/components/Library/ScanSetCover.tsx new file mode 100644 index 0000000..468ada1 --- /dev/null +++ b/src/components/Library/ScanSetCover.tsx @@ -0,0 +1,128 @@ +import Img, { getAssetURL, ImageQuality } from "components/Img"; +import LanguageSwitcher from "components/LanguageSwitcher"; +import { useAppLayout } from "contexts/AppLayoutContext"; +import { + GetLibraryItemScansQuery, + UploadImageFragment, +} from "graphql/generated"; +import { useRouter } from "next/router"; +import { AppStaticProps } from "queries/getAppStaticProps"; +import { getPreferredLanguage } from "queries/helpers"; +import { Dispatch, SetStateAction, useEffect, useMemo, useState } from "react"; + +interface Props { + setLightboxOpen: Dispatch>; + setLightboxImages: Dispatch>; + setLightboxIndex: Dispatch>; + images: Exclude< + Exclude< + Exclude< + GetLibraryItemScansQuery["libraryItems"], + null | undefined + >["data"][number]["attributes"], + null | undefined + >["images"], + null | undefined + >; + languages: AppStaticProps["languages"]; + langui: AppStaticProps["langui"]; +} + +export default function ScanSetCover(props: Props): JSX.Element { + const { + setLightboxOpen, + setLightboxImages, + setLightboxIndex, + images, + languages, + langui, + } = props; + const appLayout = useAppLayout(); + const router = useRouter(); + + const [selectedScan, setSelectedScan] = useState(); + const scanLocales: Map = new Map(); + + const [selectedScanIndex, setSelectedScanIndex] = useState< + number | undefined + >(); + + images.map((scan, index) => { + if (scan?.language?.data?.attributes?.code) { + scanLocales.set(scan.language.data.attributes.code, index); + } + }); + + useMemo(() => { + setSelectedScanIndex( + getPreferredLanguage( + appLayout.preferredLanguages ?? [router.locale], + scanLocales + ) + ); + }, [appLayout.preferredLanguages]); + + useEffect(() => { + if (selectedScanIndex !== undefined) + setSelectedScan(images[selectedScanIndex]); + }, [selectedScanIndex]); + + 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); + + if (coverImages.length > 0) { + return ( + <> + {selectedScan && ( +
+
+

{"Cover"}

+
+ +
+ +
+ +
+ {coverImages.map((image, index) => ( +
{ + const imgs: string[] = []; + coverImages.map((img) => { + if (img.url) + imgs.push(getAssetURL(img.url, ImageQuality.Large)); + }); + setLightboxOpen(true); + setLightboxImages(imgs); + setLightboxIndex(index); + }} + > + +
+ ))} +
+
+ )} + + ); + } + return <>; +} diff --git a/src/graphql/operations/getLibraryItemScans.graphql b/src/graphql/operations/getLibraryItemScans.graphql index 3f8f4fc..4a4b0fa 100644 --- a/src/graphql/operations/getLibraryItemScans.graphql +++ b/src/graphql/operations/getLibraryItemScans.graphql @@ -6,6 +6,63 @@ query getLibraryItemScans($slug: String, $language_code: String) { slug title subtitle + images { + cover { + full { + data { + attributes { + ...uploadImage + } + } + } + inside_full { + data { + attributes { + ...uploadImage + } + } + } + } + dust_jacket { + full { + data { + attributes { + ...uploadImage + } + } + } + inside_full { + data { + attributes { + ...uploadImage + } + } + } + } + obi_belt { + full { + data { + attributes { + ...uploadImage + } + } + } + inside_full { + data { + attributes { + ...uploadImage + } + } + } + } + language { + data { + attributes { + code + } + } + } + } thumbnail { data { attributes { @@ -29,6 +86,13 @@ query getLibraryItemScans($slug: String, $language_code: String) { ending_time } } + content { + data { + attributes { + slug + } + } + } scan_set { status language { diff --git a/src/pages/library/[slug]/scans.tsx b/src/pages/library/[slug]/scans.tsx index 08c02e9..41478fc 100644 --- a/src/pages/library/[slug]/scans.tsx +++ b/src/pages/library/[slug]/scans.tsx @@ -1,5 +1,6 @@ import AppLayout from "components/AppLayout"; import ScanSet from "components/Library/ScanSet"; +import ScanSetCover from "components/Library/ScanSetCover"; import LightBox from "components/LightBox"; import NavOption from "components/PanelComponents/NavOption"; import ReturnButton, { @@ -87,10 +88,23 @@ export default function LibrarySlug(props: Props): JSX.Element { displayOn={ReturnButtonType.mobile} className="mb-10" /> + + {item?.images && ( + + )} + {item?.contents?.data.map((content) => ( <> {content.attributes?.scan_set?.[0] && ( )}