mirror of
https://github.com/C9Glax/tranga-website.git
synced 2025-05-31 01:23:02 +02:00
Compare commits
6 Commits
f391ace9b2
...
a59920f09d
Author | SHA1 | Date | |
---|---|---|---|
a59920f09d | |||
5c5f810127 | |||
181d591344 | |||
0193077377 | |||
9fa57eacdb | |||
c4cc21f866 |
@ -8,6 +8,9 @@ import {ApiUriContext} from "./api/fetchApi.tsx";
|
|||||||
import Search from './Components/Search.tsx';
|
import Search from './Components/Search.tsx';
|
||||||
import MangaList from "./Components/MangaList.tsx";
|
import MangaList from "./Components/MangaList.tsx";
|
||||||
import {CardHeight, CardWidth} from "./Components/Manga.tsx";
|
import {CardHeight, CardWidth} from "./Components/Manga.tsx";
|
||||||
|
import {MangaConnectorContext} from "./api/Contexts/MangaConnectorContext.tsx";
|
||||||
|
import IMangaConnector from "./api/types/IMangaConnector.ts";
|
||||||
|
import {GetAllConnectors} from "./api/MangaConnector.tsx";
|
||||||
|
|
||||||
export default function App () {
|
export default function App () {
|
||||||
|
|
||||||
@ -23,38 +26,47 @@ export default function App () {
|
|||||||
localStorage.setItem("apiUri", apiUri);
|
localStorage.setItem("apiUri", apiUri);
|
||||||
}, [apiUri]);
|
}, [apiUri]);
|
||||||
|
|
||||||
|
const [mangaConnectors, setMangaConnectors] = useState<IMangaConnector[]>([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(!apiConnected) return;
|
||||||
|
GetAllConnectors(apiUri).then(setMangaConnectors);
|
||||||
|
}, [apiConnected]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ApiUriContext.Provider value={apiUri}>
|
<ApiUriContext.Provider value={apiUri}>
|
||||||
<Sheet className={"app"}>
|
<MangaConnectorContext value={mangaConnectors}>
|
||||||
<Header>
|
<Sheet className={"app"}>
|
||||||
<Badge color={"danger"} invisible={apiConnected} badgeContent={"!"}>
|
<Header>
|
||||||
<Button onClick={() => setShowSettings(true)}>Settings</Button>
|
<Badge color={"danger"} invisible={apiConnected} badgeContent={"!"}>
|
||||||
</Badge>
|
<Button onClick={() => setShowSettings(true)}>Settings</Button>
|
||||||
</Header>
|
|
||||||
<Settings open={showSettings} setOpen={setShowSettings} setApiUri={setApiUri} setConnected={setApiConnected} />
|
|
||||||
<Search open={showSearch} setOpen={setShowSearch} />
|
|
||||||
<Sheet className={"app-content"}>
|
|
||||||
<MangaList connected={apiConnected}>
|
|
||||||
<Badge invisible sx={{margin: "8px !important"}}>
|
|
||||||
<Card onClick={() => setShowSearch(true)} sx={{height:"fit-content",width:"fit-content"}}>
|
|
||||||
<CardCover sx={{margin:"var(--Card-padding)"}}>
|
|
||||||
<img src={"/blahaj.png"} style={{height: CardHeight + "px", width: CardWidth + 10 + "px"}} />
|
|
||||||
</CardCover>
|
|
||||||
<CardCover sx={{
|
|
||||||
background: 'rgba(234, 119, 246, 0.14)',
|
|
||||||
backdropFilter: 'blur(6.9px)',
|
|
||||||
webkitBackdropFilter: 'blur(6.9px)',
|
|
||||||
}}/>
|
|
||||||
<CardContent>
|
|
||||||
<Box style={{height: CardHeight + "px", width: CardWidth + 10 + "px"}} >
|
|
||||||
<Typography level={"h1"}>Search</Typography>
|
|
||||||
</Box>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</Badge>
|
</Badge>
|
||||||
</MangaList>
|
</Header>
|
||||||
|
<Settings open={showSettings} setOpen={setShowSettings} setApiUri={setApiUri} setConnected={setApiConnected} />
|
||||||
|
<Search open={showSearch} setOpen={setShowSearch} />
|
||||||
|
<Sheet className={"app-content"}>
|
||||||
|
<MangaList connected={apiConnected}>
|
||||||
|
<Badge invisible sx={{margin: "8px !important"}}>
|
||||||
|
<Card onClick={() => setShowSearch(true)} sx={{height:"fit-content",width:"fit-content"}}>
|
||||||
|
<CardCover sx={{margin:"var(--Card-padding)"}}>
|
||||||
|
<img src={"/blahaj.png"} style={{height: CardHeight + "px", width: CardWidth + 10 + "px"}} />
|
||||||
|
</CardCover>
|
||||||
|
<CardCover sx={{
|
||||||
|
background: 'rgba(234, 119, 246, 0.14)',
|
||||||
|
backdropFilter: 'blur(6.9px)',
|
||||||
|
webkitBackdropFilter: 'blur(6.9px)',
|
||||||
|
}}/>
|
||||||
|
<CardContent>
|
||||||
|
<Box style={{height: CardHeight + "px", width: CardWidth + 10 + "px"}} >
|
||||||
|
<Typography level={"h1"}>Search</Typography>
|
||||||
|
</Box>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Badge>
|
||||||
|
</MangaList>
|
||||||
|
</Sheet>
|
||||||
</Sheet>
|
</Sheet>
|
||||||
</Sheet>
|
</MangaConnectorContext>
|
||||||
</ApiUriContext.Provider>
|
</ApiUriContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -12,18 +12,15 @@ import {ApiUriContext, getData} from "../api/fetchApi.tsx";
|
|||||||
import {ReleaseStatusToPalette} from "../api/types/EnumMangaReleaseStatus.ts";
|
import {ReleaseStatusToPalette} from "../api/types/EnumMangaReleaseStatus.ts";
|
||||||
import {SxProps} from "@mui/joy/styles/types";
|
import {SxProps} from "@mui/joy/styles/types";
|
||||||
import MangaPopup from "./MangaPopup.tsx";
|
import MangaPopup from "./MangaPopup.tsx";
|
||||||
import IMangaConnector from "../api/types/IMangaConnector.ts";
|
import {MangaConnectorContext} from "../api/Contexts/MangaConnectorContext.tsx";
|
||||||
import {GetConnector} from "../api/MangaConnector.tsx";
|
|
||||||
|
|
||||||
export function MangaFromId({mangaId, children} : { mangaId: string, 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<IManga>();
|
const [manga, setManga] = useState<IManga>();
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
|
|
||||||
const apiUri = useContext(ApiUriContext);
|
const apiUri = useContext(ApiUriContext);
|
||||||
|
|
||||||
const loadManga = useCallback(() => {
|
const loadManga = useCallback(() => {
|
||||||
setLoading(true);
|
GetMangaById(apiUri, mangaId).then(setManga);
|
||||||
GetMangaById(apiUri, mangaId).then(setManga).finally(() => setLoading(false));
|
|
||||||
},[apiUri, mangaId]);
|
},[apiUri, mangaId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -32,7 +29,7 @@ export function MangaFromId({mangaId, children} : { mangaId: string, children?:
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{loading || manga === undefined ? <></> : <Manga manga={manga} children={children} /> }
|
{manga === undefined ? <></> : <Manga manga={manga} children={children} /> }
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -44,14 +41,13 @@ export function Manga({manga: manga, children} : { manga: IManga, children?: Rea
|
|||||||
const CoverRef = useRef<HTMLImageElement>(null);
|
const CoverRef = useRef<HTMLImageElement>(null);
|
||||||
|
|
||||||
const apiUri = useContext(ApiUriContext);
|
const apiUri = useContext(ApiUriContext);
|
||||||
|
const mangaConnector = useContext(MangaConnectorContext).find(all => all.name == manga.mangaConnectorName);
|
||||||
|
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
const [mangaConnector, setMangaConnector] = useState<IMangaConnector | undefined>(undefined);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
LoadMangaCover();
|
LoadMangaCover();
|
||||||
LoadMangaConnector();
|
}, [manga, apiUri]);
|
||||||
}, [manga]);
|
|
||||||
|
|
||||||
const LoadMangaCover = useCallback(() => {
|
const LoadMangaCover = useCallback(() => {
|
||||||
if(CoverRef.current == null)
|
if(CoverRef.current == null)
|
||||||
@ -66,10 +62,6 @@ export function Manga({manga: manga, children} : { manga: IManga, children?: Rea
|
|||||||
});
|
});
|
||||||
}, [manga, apiUri])
|
}, [manga, apiUri])
|
||||||
|
|
||||||
const LoadMangaConnector = useCallback(() => {
|
|
||||||
GetConnector(apiUri, manga.mangaConnectorName).then(setMangaConnector);
|
|
||||||
}, [manga, apiUri]);
|
|
||||||
|
|
||||||
const coverSx : SxProps = {
|
const coverSx : SxProps = {
|
||||||
height: CardHeight + "px",
|
height: CardHeight + "px",
|
||||||
width: CardWidth + "px",
|
width: CardWidth + "px",
|
||||||
@ -86,7 +78,7 @@ export function Manga({manga: manga, children} : { manga: IManga, children?: Rea
|
|||||||
const mangaName = manga.name.length > 30 ? manga.name.substring(0, 27) + "..." : manga.name;
|
const mangaName = manga.name.length > 30 ? manga.name.substring(0, 27) + "..." : manga.name;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Badge sx={{margin:"8px !important"}} badgeContent={mangaConnector ? <img src={mangaConnector.iconUrl} /> : manga.mangaConnectorName} color={ReleaseStatusToPalette(manga.releaseStatus)} size={"lg"}>
|
<Badge sx={{margin:"8px !important"}} badgeContent={mangaConnector ? <img width={"24pt"} height={"24pt"} src={mangaConnector.iconUrl} /> : manga.mangaConnectorName} color={ReleaseStatusToPalette(manga.releaseStatus)} size={"lg"}>
|
||||||
<Card sx={{height:"fit-content",width:"fit-content"}} onClick={(e) => {
|
<Card sx={{height:"fit-content",width:"fit-content"}} onClick={(e) => {
|
||||||
const target = e.target as HTMLElement;
|
const target = e.target as HTMLElement;
|
||||||
if(interactiveElements.find(x => x == target.localName) == undefined)
|
if(interactiveElements.find(x => x == target.localName) == undefined)
|
||||||
|
@ -9,6 +9,7 @@ import MarkdownPreview from "@uiw/react-markdown-preview";
|
|||||||
import {CardHeight} from "./Manga.tsx";
|
import {CardHeight} from "./Manga.tsx";
|
||||||
import IChapter from "../api/types/IChapter.ts";
|
import IChapter from "../api/types/IChapter.ts";
|
||||||
import {MangaReleaseStatus, ReleaseStatusToPalette} from "../api/types/EnumMangaReleaseStatus.ts";
|
import {MangaReleaseStatus, ReleaseStatusToPalette} from "../api/types/EnumMangaReleaseStatus.ts";
|
||||||
|
import {MangaConnectorContext} from "../api/Contexts/MangaConnectorContext.tsx";
|
||||||
|
|
||||||
|
|
||||||
export default function MangaPopup({manga, open, children} : {manga: IManga | null, open: boolean, children?: ReactElement<any, any> | ReactElement<any, any>[] | undefined}) {
|
export default function MangaPopup({manga, open, children} : {manga: IManga | null, open: boolean, children?: ReactElement<any, any> | ReactElement<any, any>[] | undefined}) {
|
||||||
@ -56,12 +57,14 @@ export default function MangaPopup({manga, open, children} : {manga: IManga | nu
|
|||||||
SetIgnoreThreshold(apiUri, manga.mangaId, value).finally(() => setUpdatingThreshold(false));
|
SetIgnoreThreshold(apiUri, manga.mangaId, value).finally(() => setUpdatingThreshold(false));
|
||||||
},[manga, apiUri])
|
},[manga, apiUri])
|
||||||
|
|
||||||
|
const mangaConnector = useContext(MangaConnectorContext).find(all => all.name == manga?.mangaConnectorName);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer anchor="bottom" size="lg" open={open}>
|
<Drawer anchor="bottom" size="lg" open={open}>
|
||||||
<Stack direction="column" spacing={2} margin={"10px"}>
|
<Stack direction="column" spacing={2} margin={"10px"}>
|
||||||
{ /* Cover and Description */ }
|
{ /* Cover and Description */ }
|
||||||
<Stack direction="row" spacing={2} margin={"10px"}>
|
<Stack direction="row" spacing={2} margin={"10px"}>
|
||||||
<Badge sx={{margin:"8px !important"}} badgeContent={manga?.mangaConnectorName} color={ReleaseStatusToPalette(manga?.releaseStatus??MangaReleaseStatus.Unreleased)} size={"lg"}>
|
<Badge sx={{margin:"8px !important"}} badgeContent={mangaConnector ? <img width={"24pt"} height={"24pt"} src={mangaConnector.iconUrl} /> : manga?.mangaConnectorName} color={ReleaseStatusToPalette(manga?.releaseStatus??MangaReleaseStatus.Unreleased)} size={"lg"}>
|
||||||
<img src="/blahaj.png" alt="Manga Cover"
|
<img src="/blahaj.png" alt="Manga Cover"
|
||||||
ref={CoverRef}
|
ref={CoverRef}
|
||||||
onLoad={LoadMangaCover}/>
|
onLoad={LoadMangaCover}/>
|
||||||
|
@ -44,7 +44,7 @@ export default function Search({open, setOpen}:{open:boolean, setOpen:React.Disp
|
|||||||
GetAllConnectors(apiUri).then(setMangaConnectors).finally(() => setMangaConnectorsLoading(false));
|
GetAllConnectors(apiUri).then(setMangaConnectors).finally(() => setMangaConnectorsLoading(false));
|
||||||
}, [apiUri]);
|
}, [apiUri]);
|
||||||
|
|
||||||
const [results, setResults] = useState<IManga[]>([]);
|
const [results, setResults] = useState<IManga[]|undefined>([]);
|
||||||
const [resultsLoading, setResultsLoading] = useState<boolean>(false);
|
const [resultsLoading, setResultsLoading] = useState<boolean>(false);
|
||||||
|
|
||||||
const StartSearch = useCallback((mangaConnector : IMangaConnector | undefined, value: string)=>{
|
const StartSearch = useCallback((mangaConnector : IMangaConnector | undefined, value: string)=>{
|
||||||
@ -143,10 +143,10 @@ export default function Search({open, setOpen}:{open:boolean, setOpen:React.Disp
|
|||||||
<StepIndicator variant={step==3?"solid":"outlined"} color="primary">
|
<StepIndicator variant={step==3?"solid":"outlined"} color="primary">
|
||||||
3
|
3
|
||||||
</StepIndicator>}>
|
</StepIndicator>}>
|
||||||
<Typography endDecorator={<Chip size={"sm"} color={"primary"}>{results.length}</Chip>}>Results</Typography>
|
<Typography endDecorator={<Chip size={"sm"} color={"primary"}>{results?.length}</Chip>}>Results</Typography>
|
||||||
<Skeleton loading={resultsLoading}>
|
<Skeleton loading={resultsLoading}>
|
||||||
<Stack direction={"row"} spacing={1} flexWrap={"wrap"}>
|
<Stack direction={"row"} spacing={1} flexWrap={"wrap"}>
|
||||||
{results.map((result) =>
|
{results?.map((result) =>
|
||||||
<Manga key={result.mangaId} manga={result}>
|
<Manga key={result.mangaId} manga={result}>
|
||||||
<Select
|
<Select
|
||||||
placeholder={"Select Library"}
|
placeholder={"Select Library"}
|
||||||
|
@ -12,8 +12,6 @@ export default interface IJob{
|
|||||||
export enum JobType {
|
export enum JobType {
|
||||||
DownloadSingleChapterJob = "DownloadSingleChapterJob",
|
DownloadSingleChapterJob = "DownloadSingleChapterJob",
|
||||||
DownloadAvailableChaptersJob = "DownloadAvailableChaptersJob",
|
DownloadAvailableChaptersJob = "DownloadAvailableChaptersJob",
|
||||||
UpdateMetaDataJob = "UpdateMetaDataJob",
|
|
||||||
MoveFileOrFolderJob = "MoveFileOrFolderJob",
|
|
||||||
DownloadMangaCoverJob = "DownloadMangaCoverJob",
|
DownloadMangaCoverJob = "DownloadMangaCoverJob",
|
||||||
RetrieveChaptersJob = "RetrieveChaptersJob",
|
RetrieveChaptersJob = "RetrieveChaptersJob",
|
||||||
UpdateChaptersDownloadedJob = "UpdateChaptersDownloadedJob",
|
UpdateChaptersDownloadedJob = "UpdateChaptersDownloadedJob",
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
import IJobWithChapterId from "./IJobWithChapterId.tsx";
|
|
||||||
|
|
||||||
export default interface IUpdateChaptersDownloadedJob extends IJobWithChapterId {
|
|
||||||
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user