mirror of
https://github.com/C9Glax/tranga-website.git
synced 2025-04-18 22:33:20 +02:00
MangaList
This commit is contained in:
parent
63b220bd79
commit
9e0eb0262e
@ -6,6 +6,7 @@ import {Badge, Button} from "@mui/joy";
|
|||||||
import {useState} from "react";
|
import {useState} from "react";
|
||||||
import {ApiUriContext} from "./api/fetchApi.tsx";
|
import {ApiUriContext} from "./api/fetchApi.tsx";
|
||||||
import Search from './Components/Search.tsx';
|
import Search from './Components/Search.tsx';
|
||||||
|
import MangaList from "./Components/MangaList.tsx";
|
||||||
|
|
||||||
export default function App () {
|
export default function App () {
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ export default function App () {
|
|||||||
<Settings open={showSettings} setOpen={setShowSettings} setApiUri={setApiUri} setConnected={setApiConnected} />
|
<Settings open={showSettings} setOpen={setShowSettings} setApiUri={setApiUri} setConnected={setApiConnected} />
|
||||||
<Search open={showSearch} setOpen={setShowSearch} />
|
<Search open={showSearch} setOpen={setShowSearch} />
|
||||||
<Sheet className={"app-content"}>
|
<Sheet className={"app-content"}>
|
||||||
|
<MangaList />
|
||||||
</Sheet>
|
</Sheet>
|
||||||
</Sheet>
|
</Sheet>
|
||||||
</ApiUriContext.Provider>
|
</ApiUriContext.Provider>
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
} from "@mui/joy";
|
} from "@mui/joy";
|
||||||
import IManga, {DefaultManga} from "../api/types/IManga.ts";
|
import IManga, {DefaultManga} from "../api/types/IManga.ts";
|
||||||
import {ReactElement, useCallback, useContext, useEffect, useState} from "react";
|
import {ReactElement, useCallback, useContext, useEffect, useState} from "react";
|
||||||
import {GetLatestChapterAvailable, GetMangaCoverImageUrl, SetIgnoreThreshold} from "../api/Manga.tsx";
|
import {GetLatestChapterAvailable, GetMangaById, GetMangaCoverImageUrl, SetIgnoreThreshold} from "../api/Manga.tsx";
|
||||||
import {ApiUriContext} from "../api/fetchApi.tsx";
|
import {ApiUriContext} from "../api/fetchApi.tsx";
|
||||||
import AuthorTag from "./AuthorTag.tsx";
|
import AuthorTag from "./AuthorTag.tsx";
|
||||||
import LinkTag from "./LinkTag.tsx";
|
import LinkTag from "./LinkTag.tsx";
|
||||||
@ -22,8 +22,27 @@ import IChapter from "../api/types/IChapter.ts";
|
|||||||
import MarkdownPreview from "@uiw/react-markdown-preview";
|
import MarkdownPreview from "@uiw/react-markdown-preview";
|
||||||
import {SxProps} from "@mui/joy/styles/types";
|
import {SxProps} from "@mui/joy/styles/types";
|
||||||
|
|
||||||
export function Manga({manga, children} : { manga: IManga | undefined, children?: ReactElement<any, any> | ReactElement<any, any>[] | undefined }) {
|
export function MangaFromId({mangaId, children} : { mangaId: string, children?: ReactElement<any, any> | ReactElement<any, any>[] | undefined }){
|
||||||
|
const [manga, setManga] = useState(DefaultManga);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
const apiUri = useContext(ApiUriContext);
|
||||||
|
|
||||||
|
const loadManga = useCallback(() => {
|
||||||
|
setLoading(true);
|
||||||
|
GetMangaById(apiUri, mangaId).then(setManga).finally(() => setLoading(false));
|
||||||
|
},[apiUri, mangaId]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadManga();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return <Manga manga={manga} loading={loading} children={children} />
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Manga({manga, children, loading} : { manga: IManga | undefined, children?: ReactElement<any, any> | ReactElement<any, any>[] | undefined, loading?: boolean}) {
|
||||||
const useManga = manga ?? DefaultManga;
|
const useManga = manga ?? DefaultManga;
|
||||||
|
loading = loading ?? false;
|
||||||
|
|
||||||
const apiUri = useContext(ApiUriContext);
|
const apiUri = useContext(ApiUriContext);
|
||||||
|
|
||||||
@ -79,19 +98,25 @@ export function Manga({manga, children} : { manga: IManga | undefined, children?
|
|||||||
}}/>
|
}}/>
|
||||||
<CardContent sx={{display: "flex", alignItems: "center", flexFlow: "row nowrap"}}>
|
<CardContent sx={{display: "flex", alignItems: "center", flexFlow: "row nowrap"}}>
|
||||||
<Box sx={sideSx}>
|
<Box sx={sideSx}>
|
||||||
<Link href={useManga.websiteUrl} level={"h1"} sx={{height:"min-content",width:"fit-content",color:"white",margin:"0 0 0 10px"}}>
|
<Skeleton loading={loading}>
|
||||||
{useManga.name}
|
<Link href={useManga.websiteUrl} level={"h1"} sx={{height:"min-content",width:"fit-content",color:"white",margin:"0 0 0 10px"}}>
|
||||||
</Link>
|
{useManga.name}
|
||||||
|
</Link>
|
||||||
|
</Skeleton>
|
||||||
</Box>
|
</Box>
|
||||||
{
|
{
|
||||||
expanded ?
|
expanded ?
|
||||||
<Box sx={sideSx}>
|
<Box sx={sideSx}>
|
||||||
<Stack direction={"row"} flexWrap={"wrap"} spacing={0.5}>
|
<Skeleton loading={loading} variant={"text"} level={"title-lg"}>
|
||||||
{useManga.authorIds.map(authorId => <AuthorTag key={authorId} authorId={authorId} color={"success"} />)}
|
<Stack direction={"row"} flexWrap={"wrap"} spacing={0.5}>
|
||||||
{useManga.tags.map(tag => <Chip key={tag} variant={"outlined"} size={"md"} color={"primary"}>{tag}</Chip>)}
|
{useManga.authorIds.map(authorId => <AuthorTag key={authorId} authorId={authorId} color={"success"} />)}
|
||||||
{useManga.linkIds.map(linkId => <LinkTag key={linkId} linkId={linkId} color={"danger"} />)}
|
{useManga.tags.map(tag => <Chip key={tag} variant={"outlined"} size={"md"} color={"primary"}>{tag}</Chip>)}
|
||||||
</Stack>
|
{useManga.linkIds.map(linkId => <LinkTag key={linkId} linkId={linkId} color={"danger"} />)}
|
||||||
<MarkdownPreview source={useManga.description} style={{backgroundColor: "transparent", color: "black"}} />
|
</Stack>
|
||||||
|
</Skeleton>
|
||||||
|
<Skeleton loading={loading} sx={{maxHeight:"300px"}}>
|
||||||
|
<MarkdownPreview source={useManga.description} style={{backgroundColor: "transparent", color: "black"}} />
|
||||||
|
</Skeleton>
|
||||||
</Box>
|
</Box>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
@ -99,30 +124,32 @@ export function Manga({manga, children} : { manga: IManga | undefined, children?
|
|||||||
{
|
{
|
||||||
expanded ?
|
expanded ?
|
||||||
<CardActions sx={{justifyContent:"space-between"}}>
|
<CardActions sx={{justifyContent:"space-between"}}>
|
||||||
<Input
|
<Skeleton loading={loading} sx={{maxHeight: "30px", maxWidth:"calc(100% - 40px)"}}>
|
||||||
type={"number"}
|
<Input
|
||||||
placeholder={"0.0"}
|
type={"number"}
|
||||||
startDecorator={
|
placeholder={"0.0"}
|
||||||
<>
|
startDecorator={
|
||||||
{
|
<>
|
||||||
updatingThreshold ?
|
{
|
||||||
<CircularProgress color={"primary"} size={"sm"} />
|
updatingThreshold ?
|
||||||
: <Typography>Ch.</Typography>
|
<CircularProgress color={"primary"} size={"sm"} />
|
||||||
|
: <Typography>Ch.</Typography>
|
||||||
|
}
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
</>
|
endDecorator={
|
||||||
}
|
<Typography>
|
||||||
endDecorator={
|
<Skeleton loading={maxChapterLoading}>
|
||||||
<Typography>
|
/{mangaMaxChapter?.chapterNumber??"Load Failed"}
|
||||||
<Skeleton loading={maxChapterLoading}>
|
</Skeleton>
|
||||||
/{mangaMaxChapter?.chapterNumber??"Load Failed"}
|
</Typography>
|
||||||
</Skeleton>
|
}
|
||||||
</Typography>
|
sx={{width:"min-content"}}
|
||||||
}
|
size={"md"}
|
||||||
sx={{width:"min-content"}}
|
onChange={(e) => updateIgnoreThreshhold(e.currentTarget.valueAsNumber)}
|
||||||
size={"md"}
|
/>
|
||||||
onChange={(e) => updateIgnoreThreshhold(e.currentTarget.valueAsNumber)}
|
{children}
|
||||||
/>
|
</Skeleton>
|
||||||
{children}
|
|
||||||
</CardActions>
|
</CardActions>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
36
tranga-website/src/Components/MangaList.tsx
Normal file
36
tranga-website/src/Components/MangaList.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import {Button, Stack} from "@mui/joy";
|
||||||
|
import {useCallback, useContext, useEffect, useState} from "react";
|
||||||
|
import {ApiUriContext} from "../api/fetchApi.tsx";
|
||||||
|
import {DeleteJob, GetJobsWithType} from "../api/Job.tsx";
|
||||||
|
import {JobType} from "../api/types/Jobs/IJob.ts";
|
||||||
|
import IDownloadAvailableChaptersJob from "../api/types/Jobs/IDownloadAvailableChaptersJob.ts";
|
||||||
|
import {MangaFromId} from "./Manga.tsx";
|
||||||
|
import { Remove } from "@mui/icons-material";
|
||||||
|
|
||||||
|
export default function MangaList(){
|
||||||
|
const apiUri = useContext(ApiUriContext);
|
||||||
|
|
||||||
|
const [jobList, setJobList] = useState<IDownloadAvailableChaptersJob[]>([]);
|
||||||
|
|
||||||
|
const getJobList = useCallback(() => {
|
||||||
|
GetJobsWithType(apiUri, JobType.DownloadAvailableChaptersJob).then((jl) => setJobList(jl as IDownloadAvailableChaptersJob[]));
|
||||||
|
},[apiUri]);
|
||||||
|
|
||||||
|
const deleteJob = useCallback((jobId: string) => {
|
||||||
|
DeleteJob(apiUri, jobId).finally(() => getJobList());
|
||||||
|
},[apiUri]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getJobList();
|
||||||
|
}, [apiUri]);
|
||||||
|
|
||||||
|
return(
|
||||||
|
<Stack direction="row" spacing={1}>
|
||||||
|
{jobList.map((job) => (
|
||||||
|
<MangaFromId key={job.mangaId} mangaId={job.mangaId}>
|
||||||
|
<Button color={"danger"} endDecorator={<Remove />} onClick={() => deleteJob(job.jobId)}>Delete</Button>
|
||||||
|
</MangaFromId>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
@ -149,6 +149,7 @@ export default function Search({open, setOpen}:{open:boolean, setOpen:React.Disp
|
|||||||
placeholder={"Select Library"}
|
placeholder={"Select Library"}
|
||||||
defaultValue={""}
|
defaultValue={""}
|
||||||
startDecorator={<LibraryBooks />}
|
startDecorator={<LibraryBooks />}
|
||||||
|
value={selectedLibraryId}
|
||||||
onChange={(_e, newValue) => setSelectedLibraryId(newValue!)}>
|
onChange={(_e, newValue) => setSelectedLibraryId(newValue!)}>
|
||||||
{localLibrariesLoading ?
|
{localLibrariesLoading ?
|
||||||
<Option value={""} disabled>Loading <CircularProgress color={"primary"} size={"sm"} /></Option>
|
<Option value={""} disabled>Loading <CircularProgress color={"primary"} size={"sm"} /></Option>
|
||||||
|
@ -19,19 +19,19 @@ export default interface IManga{
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const DefaultManga : IManga = {
|
export const DefaultManga : IManga = {
|
||||||
mangaId: "MangaId",
|
mangaId: "Loading",
|
||||||
idOnConnectorSite: "ID",
|
idOnConnectorSite: "Loading",
|
||||||
name: "TestManga",
|
name: "Loading",
|
||||||
description: "Wow so much text, very cool",
|
description: "Loading",
|
||||||
websiteUrl: "https://realsite.realdomain",
|
websiteUrl: "",
|
||||||
year: 1999,
|
year: 1999,
|
||||||
originalLanguage: "lindtChoccy",
|
originalLanguage: "en",
|
||||||
releaseStatus: MangaReleaseStatus.Continuing,
|
releaseStatus: MangaReleaseStatus.Continuing,
|
||||||
folderName: "uhhh",
|
folderName: "Loading",
|
||||||
ignoreChapterBefore: 0,
|
ignoreChapterBefore: 0,
|
||||||
mangaConnectorId: "MangaDex",
|
mangaConnectorId: "Loading",
|
||||||
authorIds: ["We got", "Authors"],
|
authorIds: ["Loading"],
|
||||||
tags: ["And we", "got Tags"],
|
tags: ["Loading"],
|
||||||
linkIds: ["And most", "definitely", "links"],
|
linkIds: ["Loading"],
|
||||||
altTitleIds: ["But not alt-titles."],
|
altTitleIds: ["Loading"],
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user