From d6e4d1d27f35c74fd6da88bffcf7c1eecb28a6c9 Mon Sep 17 00:00:00 2001
From: glax <johanna@bernloehr.eu>
Date: Wed, 2 Apr 2025 00:52:35 +0200
Subject: [PATCH] Request Limits

---
 .../src/Components/Settings/RequestLimits.tsx | 35 +++++++++++++++++++
 tranga-website/src/Settings.tsx               |  2 ++
 2 files changed, 37 insertions(+)
 create mode 100644 tranga-website/src/Components/Settings/RequestLimits.tsx

diff --git a/tranga-website/src/Components/Settings/RequestLimits.tsx b/tranga-website/src/Components/Settings/RequestLimits.tsx
new file mode 100644
index 0000000..708226b
--- /dev/null
+++ b/tranga-website/src/Components/Settings/RequestLimits.tsx
@@ -0,0 +1,35 @@
+import IBackendSettings from "../../api/types/IBackendSettings.ts";
+import {useCallback, useContext, useState} from "react";
+import {ApiUriContext} from "../../api/fetchApi.tsx";
+import {Accordion, AccordionDetails, AccordionSummary, ColorPaletteProp, Input, Stack, Typography} from "@mui/joy";
+import {RequestLimitType} from "../../api/types/EnumRequestLimitType.ts";
+import {UpdateRequestLimit} from "../../api/BackendSettings.tsx";
+
+export default function RequestLimits({backendSettings}: {backendSettings?: IBackendSettings}) {
+    const apiUri = useContext(ApiUriContext);
+
+    const [color, setColor] = useState<ColorPaletteProp>("neutral");
+    const [loading, setLoading] = useState(false);
+    const Update = useCallback((target: HTMLInputElement, limit : RequestLimitType) => {
+        setLoading(true);
+        UpdateRequestLimit(apiUri, limit, Number.parseInt(target.value))
+            .then(() => setColor("success"))
+            .catch(() => setColor("danger"))
+            .finally(() => setLoading(false));
+    },[apiUri])
+
+    return (
+        <Accordion>
+            <AccordionSummary>Request Limits</AccordionSummary>
+            <AccordionDetails>
+                <Stack spacing={1} direction="column">
+                    <Input slotProps={{input: {min: 0, max: 360}}} color={color} startDecorator={<Typography>Default</Typography>} disabled={loading} type={"number"} defaultValue={backendSettings?.requestLimits.Default} placeholder={"Default"} required onKeyDown={(e) => { if(e.key == "Enter") Update(e.target as HTMLInputElement, RequestLimitType.Default);}} />
+                    <Input slotProps={{input: {min: 0, max: 360}}} color={color} startDecorator={<Typography>Image</Typography>} disabled={loading} type={"number"} defaultValue={backendSettings?.requestLimits.MangaImage} placeholder={"MangaImage"} required onKeyDown={(e) => { if(e.key == "Enter") Update(e.target as HTMLInputElement, RequestLimitType.MangaImage);}} />
+                    <Input slotProps={{input: {min: 0, max: 360}}} color={color} startDecorator={<Typography>Info</Typography>} disabled={loading} type={"number"} defaultValue={backendSettings?.requestLimits.MangaInfo} placeholder={"MangaInfo"} required onKeyDown={(e) => { if(e.key == "Enter") Update(e.target as HTMLInputElement, RequestLimitType.MangaInfo);}} />
+                    <Input slotProps={{input: {min: 0, max: 360}}} color={color} startDecorator={<Typography>Image</Typography>} endDecorator={<img src={"https://mangadex.org/favicon.ico"} />} disabled={loading} type={"number"} defaultValue={backendSettings?.requestLimits.MangaDexImage} placeholder={"MangaDexImage"} required onKeyDown={(e) => { if(e.key == "Enter") Update(e.target as HTMLInputElement, RequestLimitType.MangaDexImage);}} />
+                    <Input slotProps={{input: {min: 0, max: 360}}} color={color} startDecorator={<Typography>Feed</Typography>} endDecorator={<img src={"https://mangadex.org/favicon.ico"} />} disabled={loading} type={"number"} defaultValue={backendSettings?.requestLimits.MangaDexFeed} placeholder={"MangaDexFeed"} required onKeyDown={(e) => { if(e.key == "Enter") Update(e.target as HTMLInputElement, RequestLimitType.MangaDexFeed);}} />
+                </Stack>
+            </AccordionDetails>
+        </Accordion>
+    );
+}
\ No newline at end of file
diff --git a/tranga-website/src/Settings.tsx b/tranga-website/src/Settings.tsx
index 90fd20e..44894a0 100644
--- a/tranga-website/src/Settings.tsx
+++ b/tranga-website/src/Settings.tsx
@@ -18,6 +18,7 @@ import UserAgent from "./Components/Settings/UserAgent.tsx";
 import ImageProcessing from "./Components/Settings/ImageProcessing.tsx";
 import ChapterNamingScheme from "./Components/Settings/ChapterNamingScheme.tsx";
 import AprilFoolsMode from './Components/Settings/AprilFoolsMode.tsx';
+import RequestLimits from "./Components/Settings/RequestLimits.tsx";
 
 const checkConnection  = async (apiUri: string): Promise<boolean> =>{
     return fetch(`${apiUri}/swagger/v2/swagger.json`,
@@ -107,6 +108,7 @@ export default function Settings({open, setOpen, setApiUri, setConnected}:{open:
                     <ImageProcessing backendSettings={backendSettings} />
                     <ChapterNamingScheme backendSettings={backendSettings} />
                     <AprilFoolsMode backendSettings={backendSettings} />
+                    <RequestLimits backendSettings={backendSettings} />
                 </AccordionGroup>
             </DialogContent>
         </Drawer>