Compare commits

...

6 Commits

Author SHA1 Message Date
a59920f09d Fix results null 2025-05-18 22:42:52 +02:00
5c5f810127 MangaPopup Badge Icon 2025-05-18 22:38:40 +02:00
181d591344 useState for MangaConnector in Manga with loading from id 2025-05-18 22:26:06 +02:00
0193077377 MangaConnectorContext 2025-05-18 22:01:21 +02:00
9fa57eacdb Fix BadgeIcon-Size 2025-05-18 21:57:27 +02:00
c4cc21f866 Dependency Update 2025-05-18 20:34:47 +02:00
6 changed files with 53 additions and 53 deletions

View File

@ -8,6 +8,9 @@ import {ApiUriContext} from "./api/fetchApi.tsx";
import Search from './Components/Search.tsx';
import MangaList from "./Components/MangaList.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 () {
@ -23,38 +26,47 @@ export default function App () {
localStorage.setItem("apiUri", apiUri);
}, [apiUri]);
const [mangaConnectors, setMangaConnectors] = useState<IMangaConnector[]>([]);
useEffect(() => {
if(!apiConnected) return;
GetAllConnectors(apiUri).then(setMangaConnectors);
}, [apiConnected]);
return (
<ApiUriContext.Provider value={apiUri}>
<Sheet className={"app"}>
<Header>
<Badge color={"danger"} invisible={apiConnected} badgeContent={"!"}>
<Button onClick={() => setShowSettings(true)}>Settings</Button>
</Badge>
</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>
<MangaConnectorContext value={mangaConnectors}>
<Sheet className={"app"}>
<Header>
<Badge color={"danger"} invisible={apiConnected} badgeContent={"!"}>
<Button onClick={() => setShowSettings(true)}>Settings</Button>
</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>
</MangaConnectorContext>
</ApiUriContext.Provider>
);
}

View File

@ -12,18 +12,15 @@ import {ApiUriContext, getData} from "../api/fetchApi.tsx";
import {ReleaseStatusToPalette} from "../api/types/EnumMangaReleaseStatus.ts";
import {SxProps} from "@mui/joy/styles/types";
import MangaPopup from "./MangaPopup.tsx";
import IMangaConnector from "../api/types/IMangaConnector.ts";
import {GetConnector} from "../api/MangaConnector.tsx";
import {MangaConnectorContext} from "../api/Contexts/MangaConnectorContext.tsx";
export function MangaFromId({mangaId, children} : { mangaId: string, children?: ReactElement<any, any> | ReactElement<any, any>[] | undefined }){
const [manga, setManga] = useState<IManga>();
const [loading, setLoading] = useState(true);
const apiUri = useContext(ApiUriContext);
const loadManga = useCallback(() => {
setLoading(true);
GetMangaById(apiUri, mangaId).then(setManga).finally(() => setLoading(false));
GetMangaById(apiUri, mangaId).then(setManga);
},[apiUri, mangaId]);
useEffect(() => {
@ -32,7 +29,7 @@ export function MangaFromId({mangaId, children} : { mangaId: string, children?:
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 apiUri = useContext(ApiUriContext);
const mangaConnector = useContext(MangaConnectorContext).find(all => all.name == manga.mangaConnectorName);
const [expanded, setExpanded] = useState(false);
const [mangaConnector, setMangaConnector] = useState<IMangaConnector | undefined>(undefined);
useEffect(() => {
LoadMangaCover();
LoadMangaConnector();
}, [manga]);
}, [manga, apiUri]);
const LoadMangaCover = useCallback(() => {
if(CoverRef.current == null)
@ -66,10 +62,6 @@ export function Manga({manga: manga, children} : { manga: IManga, children?: Rea
});
}, [manga, apiUri])
const LoadMangaConnector = useCallback(() => {
GetConnector(apiUri, manga.mangaConnectorName).then(setMangaConnector);
}, [manga, apiUri]);
const coverSx : SxProps = {
height: CardHeight + "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;
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) => {
const target = e.target as HTMLElement;
if(interactiveElements.find(x => x == target.localName) == undefined)

View File

@ -9,6 +9,7 @@ import MarkdownPreview from "@uiw/react-markdown-preview";
import {CardHeight} from "./Manga.tsx";
import IChapter from "../api/types/IChapter.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}) {
@ -56,12 +57,14 @@ export default function MangaPopup({manga, open, children} : {manga: IManga | nu
SetIgnoreThreshold(apiUri, manga.mangaId, value).finally(() => setUpdatingThreshold(false));
},[manga, apiUri])
const mangaConnector = useContext(MangaConnectorContext).find(all => all.name == manga?.mangaConnectorName);
return (
<Drawer anchor="bottom" size="lg" open={open}>
<Stack direction="column" spacing={2} margin={"10px"}>
{ /* Cover and Description */ }
<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"
ref={CoverRef}
onLoad={LoadMangaCover}/>

View File

@ -44,7 +44,7 @@ export default function Search({open, setOpen}:{open:boolean, setOpen:React.Disp
GetAllConnectors(apiUri).then(setMangaConnectors).finally(() => setMangaConnectorsLoading(false));
}, [apiUri]);
const [results, setResults] = useState<IManga[]>([]);
const [results, setResults] = useState<IManga[]|undefined>([]);
const [resultsLoading, setResultsLoading] = useState<boolean>(false);
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">
3
</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}>
<Stack direction={"row"} spacing={1} flexWrap={"wrap"}>
{results.map((result) =>
{results?.map((result) =>
<Manga key={result.mangaId} manga={result}>
<Select
placeholder={"Select Library"}

View File

@ -12,8 +12,6 @@ export default interface IJob{
export enum JobType {
DownloadSingleChapterJob = "DownloadSingleChapterJob",
DownloadAvailableChaptersJob = "DownloadAvailableChaptersJob",
UpdateMetaDataJob = "UpdateMetaDataJob",
MoveFileOrFolderJob = "MoveFileOrFolderJob",
DownloadMangaCoverJob = "DownloadMangaCoverJob",
RetrieveChaptersJob = "RetrieveChaptersJob",
UpdateChaptersDownloadedJob = "UpdateChaptersDownloadedJob",

View File

@ -1,5 +0,0 @@
import IJobWithChapterId from "./IJobWithChapterId.tsx";
export default interface IUpdateChaptersDownloadedJob extends IJobWithChapterId {
}