Added smart translation to scan
This commit is contained in:
parent
a84560d86e
commit
b3f3ddf60e
|
@ -13,12 +13,12 @@ interface Props {
|
|||
}
|
||||
|
||||
export default function LanguageSwitcher(props: Props): JSX.Element {
|
||||
const { locales, localesIndex, setLocalesIndex } = props;
|
||||
const { locales, className, localesIndex, setLocalesIndex } = props;
|
||||
|
||||
return (
|
||||
<ToolTip
|
||||
content={
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className={`flex flex-col gap-2 ${className}`}>
|
||||
{[...locales].map(([locale, value], index) => (
|
||||
<>
|
||||
{locale && (
|
||||
|
@ -35,7 +35,7 @@ export default function LanguageSwitcher(props: Props): JSX.Element {
|
|||
</div>
|
||||
}
|
||||
>
|
||||
<Button badgeNumber={locales.size}>
|
||||
<Button badgeNumber={locales.size > 1 ? locales.size : undefined}>
|
||||
<span className="material-icons">translate</span>
|
||||
</Button>
|
||||
</ToolTip>
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
import Img, { getAssetURL, ImageQuality } from "components/Img";
|
||||
import LanguageSwitcher from "components/LanguageSwitcher";
|
||||
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 { Dispatch, SetStateAction, useEffect, useMemo, useState } from "react";
|
||||
|
||||
interface Props {
|
||||
setLightboxOpen: Dispatch<SetStateAction<boolean>>;
|
||||
setLightboxImages: Dispatch<SetStateAction<string[]>>;
|
||||
setLightboxIndex: Dispatch<SetStateAction<number>>;
|
||||
scanSet: Exclude<
|
||||
Exclude<
|
||||
Exclude<
|
||||
Exclude<
|
||||
Exclude<
|
||||
GetLibraryItemScansQuery["libraryItems"],
|
||||
null | undefined
|
||||
>["data"][number]["attributes"],
|
||||
null | undefined
|
||||
>["contents"],
|
||||
null | undefined
|
||||
>["data"][number]["attributes"],
|
||||
null | undefined
|
||||
>["scan_set"],
|
||||
null | undefined
|
||||
>;
|
||||
slug: string;
|
||||
title: string;
|
||||
languages: AppStaticProps["languages"];
|
||||
}
|
||||
|
||||
export default function ScanSet(props: Props): JSX.Element {
|
||||
const {
|
||||
setLightboxOpen,
|
||||
setLightboxImages,
|
||||
setLightboxIndex,
|
||||
scanSet,
|
||||
slug,
|
||||
title,
|
||||
languages,
|
||||
} = props;
|
||||
const appLayout = useAppLayout();
|
||||
const router = useRouter();
|
||||
|
||||
const [selectedScan, setSelectedScan] = useState<Props["scanSet"][number]>();
|
||||
const scanLocales: Map<string, number> = new Map();
|
||||
|
||||
const [selectedScanIndex, setSelectedScanIndex] = useState<
|
||||
number | undefined
|
||||
>();
|
||||
|
||||
scanSet.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(scanSet[selectedScanIndex]);
|
||||
}, [selectedScanIndex]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex flex-row place-items-center gap-4 text-base pb-6 pt-10 first-of-type:pt-0">
|
||||
<h2
|
||||
id={slug}
|
||||
className="text-2xl"
|
||||
>
|
||||
{title}
|
||||
</h2>
|
||||
<LanguageSwitcher
|
||||
languages={languages}
|
||||
locales={scanLocales}
|
||||
localesIndex={selectedScanIndex}
|
||||
setLocalesIndex={setSelectedScanIndex}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(10rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0">
|
||||
{selectedScan?.pages?.data.map((page, index) => (
|
||||
<div
|
||||
key={page.id}
|
||||
className="drop-shadow-shade-lg hover:scale-[1.02] cursor-pointer transition-transform"
|
||||
onClick={() => {
|
||||
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 && (
|
||||
<Img image={page.attributes} quality={ImageQuality.Small} />
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import AppLayout from "components/AppLayout";
|
||||
import Img, { getAssetURL, ImageQuality } from "components/Img";
|
||||
import LanguageSwitcher from "components/LanguageSwitcher";
|
||||
import ScanSet from "components/Library/ScanSet";
|
||||
import LightBox from "components/LightBox";
|
||||
import NavOption from "components/PanelComponents/NavOption";
|
||||
import ReturnButton, {
|
||||
|
@ -34,7 +33,7 @@ interface Props extends AppStaticProps {
|
|||
}
|
||||
|
||||
export default function LibrarySlug(props: Props): JSX.Element {
|
||||
const { item, langui } = props;
|
||||
const { item, langui, languages } = props;
|
||||
const appLayout = useAppLayout();
|
||||
|
||||
sortContent(item?.contents);
|
||||
|
@ -90,61 +89,16 @@ export default function LibrarySlug(props: Props): JSX.Element {
|
|||
/>
|
||||
{item?.contents?.data.map((content) => (
|
||||
<>
|
||||
<h2
|
||||
id={content.attributes?.slug}
|
||||
key={`h2${content.id}`}
|
||||
className="text-2xl pb-2 pt-10 first-of-type:pt-0 flex flex-row place-items-center gap-2"
|
||||
>
|
||||
{prettySlug(content.attributes?.slug, item.slug)}
|
||||
</h2>
|
||||
|
||||
{content.attributes?.scan_set?.[0] ? (
|
||||
<div
|
||||
key={`items${content.id}`}
|
||||
className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(10rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0"
|
||||
>
|
||||
{content.attributes.scan_set[0].pages?.data.map((page, index) => (
|
||||
<div
|
||||
key={page.id}
|
||||
className="drop-shadow-shade-lg hover:scale-[1.02] cursor-pointer transition-transform"
|
||||
onClick={() => {
|
||||
setLightboxOpen(true);
|
||||
if (content.attributes?.scan_set?.[0]?.pages) {
|
||||
const images: string[] = [];
|
||||
content.attributes.scan_set[0].pages.data.map((image) => {
|
||||
if (image.attributes?.url)
|
||||
images.push(
|
||||
getAssetURL(
|
||||
image.attributes.url,
|
||||
ImageQuality.Large
|
||||
)
|
||||
);
|
||||
});
|
||||
setLightboxImages(images);
|
||||
}
|
||||
|
||||
setLightboxIndex(index);
|
||||
}}
|
||||
>
|
||||
{page.attributes && (
|
||||
<Img image={page.attributes} quality={ImageQuality.Small} />
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="pb-12 border-b-[3px] border-dotted last-of-type:border-0">
|
||||
{content.attributes?.scan_set_languages && (
|
||||
<LanguageSwitcher
|
||||
locales={content.attributes.scan_set_languages.map(
|
||||
(language) => language?.language?.data?.attributes?.code
|
||||
)}
|
||||
languages={props.languages}
|
||||
langui={props.langui}
|
||||
href={`#${content.attributes.slug}`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{content.attributes?.scan_set?.[0] && (
|
||||
<ScanSet
|
||||
scanSet={content.attributes.scan_set}
|
||||
setLightboxImages={setLightboxImages}
|
||||
setLightboxIndex={setLightboxIndex}
|
||||
setLightboxOpen={setLightboxOpen}
|
||||
slug={content.attributes.slug}
|
||||
title={prettySlug(content.attributes.slug, item.slug)}
|
||||
languages={languages}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
))}
|
||||
|
|
Loading…
Reference in New Issue