Download Dialog

This commit is contained in:
2025-07-22 16:26:58 +02:00
parent cd566f01e1
commit 476762a30f
4 changed files with 31 additions and 12 deletions

View File

@@ -4,7 +4,7 @@ import {Link, Tooltip, Typography} from "@mui/joy";
import {MangaConnectorContext} from "../App.tsx"; import {MangaConnectorContext} from "../App.tsx";
import {ApiContext} from "../apiClient/ApiContext.tsx"; import {ApiContext} from "../apiClient/ApiContext.tsx";
export default function MangaConnectorLink({MangaConnectorId, imageStyle} : {MangaConnectorId : MangaMangaConnectorId | ChapterMangaConnectorId, imageStyle? : CSSProperties}) : ReactNode{ export default function MangaConnectorLink({MangaConnectorId, imageStyle, printName} : {MangaConnectorId : MangaMangaConnectorId | ChapterMangaConnectorId, imageStyle? : CSSProperties, printName?: boolean}) : ReactNode{
const mangaConnectorContext = useContext(MangaConnectorContext); const mangaConnectorContext = useContext(MangaConnectorContext);
const [mangaConnector, setMangaConnector] = useState<MangaConnector | undefined>(mangaConnectorContext?.find(c => c.name == MangaConnectorId.mangaConnectorName)); const [mangaConnector, setMangaConnector] = useState<MangaConnector | undefined>(mangaConnectorContext?.find(c => c.name == MangaConnectorId.mangaConnectorName));
const imageRef = useRef<HTMLImageElement | null>(null); const imageRef = useRef<HTMLImageElement | null>(null);
@@ -13,19 +13,20 @@ export default function MangaConnectorLink({MangaConnectorId, imageStyle} : {Man
const connector = mangaConnectorContext?.find(c => c.name == MangaConnectorId.mangaConnectorName); const connector = mangaConnectorContext?.find(c => c.name == MangaConnectorId.mangaConnectorName);
setMangaConnector(connector); setMangaConnector(connector);
if (imageRef?.current != null) if (imageRef?.current != null)
imageRef.current.setHTMLUnsafe("<img ref={imageRef} src={mangaConnector?.iconUrl} style={imageStyle}/>"); imageRef.current.setHTMLUnsafe(`<img ref=${imageRef} src=${mangaConnector?.iconUrl} style=${imageStyle}/>`);
}, []); }, []);
return ( return (
<Tooltip title={<Typography>{MangaConnectorId.mangaConnectorName}: <Link href={MangaConnectorId.websiteUrl as string}>{MangaConnectorId.websiteUrl}</Link></Typography>}> <Tooltip title={<Typography>{MangaConnectorId.mangaConnectorName}: <Link href={MangaConnectorId.websiteUrl as string}>{MangaConnectorId.websiteUrl}</Link></Typography>}>
<Link href={MangaConnectorId.websiteUrl as string}> <Link href={MangaConnectorId.websiteUrl as string}>
<img ref={imageRef} src={mangaConnector?.iconUrl} style={imageStyle}/> <img ref={imageRef} src={mangaConnector?.iconUrl} style={imageStyle}/>
{printName ? <Typography>{mangaConnector?.name}</Typography> : null}
</Link> </Link>
</Tooltip> </Tooltip>
); );
} }
export function MangaConnectorLinkFromId({MangaConnectorIdId} : {MangaConnectorIdId: string}) : ReactNode { export function MangaConnectorLinkFromId({MangaConnectorIdId, imageStyle, printName} : {MangaConnectorIdId: string, imageStyle? : CSSProperties, printName?: boolean}) : ReactNode {
const Api = useContext(ApiContext); const Api = useContext(ApiContext);
const [node, setNode] = useState<ReactNode>(null); const [node, setNode] = useState<ReactNode>(null);
@@ -33,7 +34,7 @@ export function MangaConnectorLinkFromId({MangaConnectorIdId} : {MangaConnectorI
useEffect(() => { useEffect(() => {
Api.queryMangaMangaConnectorIdDetail(MangaConnectorIdId).then(response => { Api.queryMangaMangaConnectorIdDetail(MangaConnectorIdId).then(response => {
if (response.ok) if (response.ok)
setNode(<MangaConnectorLink key={response.data.key} MangaConnectorId={response.data} imageStyle={{width: "25px"}}/>); setNode(<MangaConnectorLink key={response.data.key} MangaConnectorId={response.data} imageStyle={{...imageStyle, width: "25px"}} printName={printName} />);
}); });
}, []); }, []);

View File

@@ -63,12 +63,12 @@ export function MangaModal({manga, open, setOpen, children}: {manga: Manga | und
<Typography level={"h4"} width={"fit-content"}>{manga?.name}</Typography> <Typography level={"h4"} width={"fit-content"}>{manga?.name}</Typography>
</Tooltip> </Tooltip>
<Stack direction={"row"} spacing={2}> <Stack direction={"row"} spacing={2}>
<Box className={"manga-card"}> <Box key={"Cover"} className={"manga-card"}>
<MangaCover manga={manga} /> <MangaCover manga={manga} />
</Box> </Box>
<Stack direction={"column"} sx={{width: "calc(100% - 230px)"}}> <Stack key={"Description"} direction={"column"} sx={{width: "calc(100% - 230px)"}}>
<Stack direction={"row"} flexWrap={"wrap"} useFlexGap spacing={0.5}> <Stack key={"Tags"} direction={"row"} flexWrap={"wrap"} useFlexGap spacing={0.5}>
{manga?.mangaConnectorIdsIds?.map((idid) => <MangaConnectorLinkFromId MangaConnectorIdId={idid} />)} {manga?.mangaConnectorIdsIds?.map((idid) => <MangaConnectorLinkFromId key={idid} MangaConnectorIdId={idid} />)}
{manga?.mangaTags?.map((tag) => <Chip key={tag.tag}>{tag.tag}</Chip>)} {manga?.mangaTags?.map((tag) => <Chip key={tag.tag}>{tag.tag}</Chip>)}
{manga?.links?.map((link) => <Chip key={link.key}><Link href={link.linkUrl}>{link.linkProvider}</Link></Chip>)} {manga?.links?.map((link) => <Chip key={link.key}><Link href={link.linkUrl}>{link.linkProvider}</Link></Chip>)}
</Stack> </Stack>

View File

@@ -7,7 +7,7 @@ import {MangaConnectorLinkFromId} from "../MangaConnectorLink.tsx";
export default function MangaConnectorBadge ({manga, children} : {manga: Manga, children? : ReactElement<any, any> | ReactElement<any,any>[] | undefined}) { export default function MangaConnectorBadge ({manga, children} : {manga: Manga, children? : ReactElement<any, any> | ReactElement<any,any>[] | undefined}) {
return ( return (
<Badge badgeContent={manga.mangaConnectorIdsIds?.map(id => <MangaConnectorLinkFromId MangaConnectorIdId={id} />)}> <Badge badgeContent={manga.mangaConnectorIdsIds?.map(id => <MangaConnectorLinkFromId key={id} MangaConnectorIdId={id} />)}>
{children} {children}
</Badge> </Badge>
); );

View File

@@ -1,11 +1,12 @@
import {Manga} from "../../apiClient/data-contracts.ts"; import {Manga} from "../../apiClient/data-contracts.ts";
import {Dispatch, ReactNode, useContext, useState} from "react"; import {ChangeEvent, Dispatch, ReactNode, useContext, useState} from "react";
import {Button, Checkbox, Option, Select, Stack, Typography} from "@mui/joy"; import {Button, Checkbox, Option, Select, Stack, Typography} from "@mui/joy";
import Drawer from "@mui/joy/Drawer"; import Drawer from "@mui/joy/Drawer";
import ModalClose from "@mui/joy/ModalClose"; import ModalClose from "@mui/joy/ModalClose";
import {MangaConnectorLinkFromId} from "../MangaConnectorLink.tsx"; import {MangaConnectorLinkFromId} from "../MangaConnectorLink.tsx";
import Sheet from "@mui/joy/Sheet"; import Sheet from "@mui/joy/Sheet";
import {FileLibraryContext} from "../../App.tsx"; import {FileLibraryContext} from "../../App.tsx";
import {ApiContext} from "../../apiClient/ApiContext.tsx";
export default function ({manga} : {manga: Manga}) : ReactNode{ export default function ({manga} : {manga: Manga}) : ReactNode{
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
@@ -20,13 +21,20 @@ export default function ({manga} : {manga: Manga}) : ReactNode{
function DownloadDrawer({manga, open, setOpen}: {manga: Manga, open: boolean, setOpen: Dispatch<boolean>}): ReactNode { function DownloadDrawer({manga, open, setOpen}: {manga: Manga, open: boolean, setOpen: Dispatch<boolean>}): ReactNode {
const fileLibraries = useContext(FileLibraryContext); const fileLibraries = useContext(FileLibraryContext);
const Api = useContext(ApiContext);
const onLibraryChange = (_ :any, value: ({} | null)) => {
if (value === undefined)
return;
Api.mangaChangeLibraryCreate(manga.key as string, value as string);
}
return ( return (
<Drawer open={open} onClose={() => setOpen(false)}> <Drawer open={open} onClose={() => setOpen(false)}>
<ModalClose /> <ModalClose />
<Sheet sx={{width: "calc(95% - 60px)", margin: "30px"}}> <Sheet sx={{width: "calc(95% - 60px)", margin: "30px"}}>
<Typography>Download to Library:</Typography> <Typography>Download to Library:</Typography>
<Select placeholder={"Library"}> <Select placeholder={"Library"} onChange={onLibraryChange} value={manga.libraryId}>
{fileLibraries?.map(library => ( {fileLibraries?.map(library => (
<Option value={library.key} key={library.key}><Typography>{library.libraryName}</Typography> <Typography>({library.basePath})</Typography></Option> <Option value={library.key} key={library.key}><Typography>{library.libraryName}</Typography> <Typography>({library.basePath})</Typography></Option>
))} ))}
@@ -41,7 +49,17 @@ function DownloadDrawer({manga, open, setOpen}: {manga: Manga, open: boolean, se
} }
function DownloadCheckBox({mangaConnectorIdId} : {mangaConnectorIdId : string}) : ReactNode { function DownloadCheckBox({mangaConnectorIdId} : {mangaConnectorIdId : string}) : ReactNode {
const Api = useContext(ApiContext);
const onSelected = (event: ChangeEvent<HTMLInputElement>) => {
Api.queryMangaMangaConnectorIdDetail(mangaConnectorIdId).then(response => {
if (!response.ok)
return;
Api.mangaSetAsDownloadFromCreate(response.data.objId, response.data.mangaConnectorName, event.currentTarget.checked);
});
}
return ( return (
<Checkbox label={<Typography><MangaConnectorLinkFromId MangaConnectorIdId={mangaConnectorIdId} /></Typography>} /> <Checkbox onChange={onSelected} label={<Typography><MangaConnectorLinkFromId MangaConnectorIdId={mangaConnectorIdId} printName={true} /></Typography>} />
); );
} }