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 {
|
export default function LanguageSwitcher(props: Props): JSX.Element {
|
||||||
const { locales, localesIndex, setLocalesIndex } = props;
|
const { locales, className, localesIndex, setLocalesIndex } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolTip
|
<ToolTip
|
||||||
content={
|
content={
|
||||||
<div className="flex flex-col gap-2">
|
<div className={`flex flex-col gap-2 ${className}`}>
|
||||||
{[...locales].map(([locale, value], index) => (
|
{[...locales].map(([locale, value], index) => (
|
||||||
<>
|
<>
|
||||||
{locale && (
|
{locale && (
|
||||||
@ -35,7 +35,7 @@ export default function LanguageSwitcher(props: Props): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Button badgeNumber={locales.size}>
|
<Button badgeNumber={locales.size > 1 ? locales.size : undefined}>
|
||||||
<span className="material-icons">translate</span>
|
<span className="material-icons">translate</span>
|
||||||
</Button>
|
</Button>
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
|
118
src/components/Library/ScanSet.tsx
Normal file
118
src/components/Library/ScanSet.tsx
Normal file
@ -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 AppLayout from "components/AppLayout";
|
||||||
import Img, { getAssetURL, ImageQuality } from "components/Img";
|
import ScanSet from "components/Library/ScanSet";
|
||||||
import LanguageSwitcher from "components/LanguageSwitcher";
|
|
||||||
import LightBox from "components/LightBox";
|
import LightBox from "components/LightBox";
|
||||||
import NavOption from "components/PanelComponents/NavOption";
|
import NavOption from "components/PanelComponents/NavOption";
|
||||||
import ReturnButton, {
|
import ReturnButton, {
|
||||||
@ -34,7 +33,7 @@ interface Props extends AppStaticProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function LibrarySlug(props: Props): JSX.Element {
|
export default function LibrarySlug(props: Props): JSX.Element {
|
||||||
const { item, langui } = props;
|
const { item, langui, languages } = props;
|
||||||
const appLayout = useAppLayout();
|
const appLayout = useAppLayout();
|
||||||
|
|
||||||
sortContent(item?.contents);
|
sortContent(item?.contents);
|
||||||
@ -90,62 +89,17 @@ export default function LibrarySlug(props: Props): JSX.Element {
|
|||||||
/>
|
/>
|
||||||
{item?.contents?.data.map((content) => (
|
{item?.contents?.data.map((content) => (
|
||||||
<>
|
<>
|
||||||
<h2
|
{content.attributes?.scan_set?.[0] && (
|
||||||
id={content.attributes?.slug}
|
<ScanSet
|
||||||
key={`h2${content.id}`}
|
scanSet={content.attributes.scan_set}
|
||||||
className="text-2xl pb-2 pt-10 first-of-type:pt-0 flex flex-row place-items-center gap-2"
|
setLightboxImages={setLightboxImages}
|
||||||
>
|
setLightboxIndex={setLightboxIndex}
|
||||||
{prettySlug(content.attributes?.slug, item.slug)}
|
setLightboxOpen={setLightboxOpen}
|
||||||
</h2>
|
slug={content.attributes.slug}
|
||||||
|
title={prettySlug(content.attributes.slug, item.slug)}
|
||||||
{content.attributes?.scan_set?.[0] ? (
|
languages={languages}
|
||||||
<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>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user