From 34dcd06ca956ba710865a546a92c1bf7415bb129 Mon Sep 17 00:00:00 2001 From: glax Date: Tue, 22 Jul 2025 21:55:46 +0200 Subject: [PATCH] Maintenance Settings --- tranga-website/src/Components/Loading.tsx | 32 +++++++++++++ .../src/Components/Mangas/MangaCard.tsx | 9 ++-- .../src/Components/Mangas/MangaList.tsx | 16 ++++++- .../src/Components/Mangas/MangaMerge.tsx | 38 +++++++++++++++ tranga-website/src/Components/Search.tsx | 47 ++++++++++++++----- .../Settings/AddNotificationConnector.tsx | 32 +------------ .../src/Components/Settings/Maintenance.tsx | 33 +++++++++++++ .../src/Components/Settings/Settings.tsx | 2 + .../src/apiClient/CleanupNoDownloadManga.ts | 32 +++++++++++++ tranga-website/src/apiClient/V2.ts | 30 ++++++++++++ 10 files changed, 221 insertions(+), 50 deletions(-) create mode 100644 tranga-website/src/Components/Loading.tsx create mode 100644 tranga-website/src/Components/Mangas/MangaMerge.tsx create mode 100644 tranga-website/src/Components/Settings/Maintenance.tsx create mode 100644 tranga-website/src/apiClient/CleanupNoDownloadManga.ts diff --git a/tranga-website/src/Components/Loading.tsx b/tranga-website/src/Components/Loading.tsx new file mode 100644 index 0000000..8f0c072 --- /dev/null +++ b/tranga-website/src/Components/Loading.tsx @@ -0,0 +1,32 @@ +import {Close, Done} from "@mui/icons-material"; +import {CircularProgress, ColorPaletteProp} from "@mui/joy"; +import {ReactNode} from "react"; + +export enum LoadingState { + none, + loading, + success, + failure +} + +export function StateIndicator(state : LoadingState) : ReactNode { + switch (state) { + case LoadingState.loading: + return (); + case LoadingState.failure: + return (); + case LoadingState.success: + return (); + default: return null; + } +} + +export function StateColor(state : LoadingState) : ColorPaletteProp | undefined { + switch (state) { + case LoadingState.failure: + return "danger"; + case LoadingState.success: + return "success"; + default: return undefined; + } +} \ No newline at end of file diff --git a/tranga-website/src/Components/Mangas/MangaCard.tsx b/tranga-website/src/Components/Mangas/MangaCard.tsx index 72074e2..df11ee7 100644 --- a/tranga-website/src/Components/Mangas/MangaCard.tsx +++ b/tranga-website/src/Components/Mangas/MangaCard.tsx @@ -19,7 +19,6 @@ import ModalClose from "@mui/joy/ModalClose"; import {ApiContext} from "../../apiClient/ApiContext.tsx"; import MarkdownPreview from '@uiw/react-markdown-preview'; import {MangaContext} from "../../App.tsx"; -import MangaDownloadDialog from "./MangaDownloadDialog.tsx"; import {MangaConnectorLinkFromId} from "../MangaConnectorLink.tsx"; export function MangaCardFromId({mangaId} : {mangaId: string}) { @@ -29,7 +28,7 @@ export function MangaCardFromId({mangaId} : {mangaId: string}) { return } -export function MangaCard({manga} : {manga: Manga | undefined}) { +export function MangaCard({manga, children} : {manga: Manga | undefined, children? : ReactNode}) { if (manga === undefined) return PlaceHolderCard(); @@ -47,7 +46,7 @@ export function MangaCard({manga} : {manga: Manga | undefined}) { - + {children} ); @@ -72,12 +71,12 @@ export function MangaModal({manga, open, setOpen, children}: {manga: Manga | und {manga?.mangaTags?.map((tag) => {tag.tag})} {manga?.links?.map((link) => {link.linkProvider})} - + + {children} - {children} ); diff --git a/tranga-website/src/Components/Mangas/MangaList.tsx b/tranga-website/src/Components/Mangas/MangaList.tsx index 742901b..bd347f4 100644 --- a/tranga-website/src/Components/Mangas/MangaList.tsx +++ b/tranga-website/src/Components/Mangas/MangaList.tsx @@ -3,13 +3,25 @@ import {MangaCard} from "./MangaCard.tsx"; import {Stack} from "@mui/joy"; import "./MangaList.css"; import {Manga} from "../../apiClient/data-contracts.ts"; +import MangaDownloadDialog from "./MangaDownloadDialog.tsx"; +import MangaMerge from "./MangaMerge.tsx"; export default function MangaList ({mangas, children} : {mangas: Manga[], children?: ReactNode}) { return ( - + {children} - {mangas?.map(manga => )} + {mangas?.map(manga => ( + + + + + ))} ); diff --git a/tranga-website/src/Components/Mangas/MangaMerge.tsx b/tranga-website/src/Components/Mangas/MangaMerge.tsx new file mode 100644 index 0000000..316bdad --- /dev/null +++ b/tranga-website/src/Components/Mangas/MangaMerge.tsx @@ -0,0 +1,38 @@ +import {ReactNode, useContext, useEffect, useState} from "react"; +import {Manga} from "../../apiClient/data-contracts.ts"; +import Drawer from "@mui/joy/Drawer"; +import ModalClose from "@mui/joy/ModalClose"; +import {ApiContext} from "../../apiClient/ApiContext.tsx"; +import {MangaCard} from "./MangaCard.tsx"; +import {Button} from "@mui/joy"; + +export default function ({manga} : {manga : Manga | undefined}) : ReactNode { + const Api = useContext(ApiContext); + + const [similar, setSimilar] = useState([]); + const [open, setOpen] = useState(false); + + useEffect(()=> { + if (manga === undefined || !open) + return; + Api.queryMangaSimilarNameList(manga.key as string).then(response => { + if (response.ok) + Api.mangaWithIDsCreate(response.data).then(response => { + if (response.ok) + setSimilar(response.data); + }); + }); + }, [open]); + + return ( + <> + + setOpen(false)} anchor={"bottom"}> + + {similar.map(manga => )} + + + ); +} \ No newline at end of file diff --git a/tranga-website/src/Components/Search.tsx b/tranga-website/src/Components/Search.tsx index 065dc9a..32107fe 100644 --- a/tranga-website/src/Components/Search.tsx +++ b/tranga-website/src/Components/Search.tsx @@ -1,12 +1,15 @@ import {Dispatch, KeyboardEventHandler, ReactNode, useContext, useState} from "react"; import { - Badge, Button, + Badge, + Button, Card, CardContent, - CardCover, + CardCover, Chip, Input, Modal, - ModalDialog, Option, Select, + ModalDialog, + Option, + Select, Step, StepIndicator, Stepper, @@ -17,6 +20,7 @@ import {MangaConnectorContext} from "../App.tsx"; import {Manga, MangaConnector} from "../apiClient/data-contracts.ts"; import MangaList from "./Mangas/MangaList.tsx"; import {ApiContext} from "../apiClient/ApiContext.tsx"; +import {LoadingState, StateColor, StateIndicator} from "./Loading.tsx"; export default function () : ReactNode { const [open, setOpen] = useState(false); @@ -46,6 +50,8 @@ function SearchDialog ({open, setOpen} : {open: boolean, setOpen: Dispatch(undefined); const [searchTerm, setSearchTerm] = useState(); const [searchResults, setSearchResults] = useState([]); + + const [loadingState, setLoadingState] = useState(LoadingState.none); const doTheSearch = () => { if (searchTerm === undefined || searchTerm.length < 1) @@ -53,18 +59,26 @@ function SearchDialog ({open, setOpen} : {open: boolean, setOpen: Dispatch { - if (response.ok) + if (response.ok){ setSearchResults([response.data]); - }); + setLoadingState(LoadingState.success); + }else + setLoadingState(LoadingState.failure); + }).catch(() => setLoadingState(LoadingState.failure)); else Api.searchDetail(selectedMangaConnector!.name, searchTerm) .then(response => { - if(response.ok) + if(response.ok){ setSearchResults(response.data); - }); + setLoadingState(LoadingState.success); + }else + setLoadingState(LoadingState.failure); + }).catch(() => setLoadingState(LoadingState.failure)); } const isUrl = (url: string) => { @@ -89,7 +103,9 @@ function SearchDialog ({open, setOpen} : {open: boolean, setOpen: Dispatch 1}> Connector - setSelectedMangaConnector(v as MangaConnector)}> {mangaConnectors?.map(con => (