mirror of
https://github.com/C9Glax/tranga-website.git
synced 2025-10-11 13:19:49 +02:00
Fix Chapter list in MangaDetail overflowing (scroll)
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
"trailingComma": "es5",
|
"trailingComma": "es5",
|
||||||
"tabWidth": 4,
|
"tabWidth": 4,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"printWidth": 100,
|
"printWidth": 120,
|
||||||
"semi": true,
|
"semi": true,
|
||||||
"bracketSpacing": true,
|
"bracketSpacing": true,
|
||||||
"objectWrap": "collapse",
|
"objectWrap": "collapse",
|
||||||
|
@@ -38,7 +38,7 @@ export function App() {
|
|||||||
const removeManga = async (mangaKey?: string): Promise<void> => {
|
const removeManga = async (mangaKey?: string): Promise<void> => {
|
||||||
if (!mangaKey) return Promise.reject();
|
if (!mangaKey) return Promise.reject();
|
||||||
try {
|
try {
|
||||||
let r = await Api.mangaDelete(mangaKey);
|
const r = await Api.mangaDelete(mangaKey);
|
||||||
if (r.ok) return Promise.resolve();
|
if (r.ok) return Promise.resolve();
|
||||||
else return Promise.reject();
|
else return Promise.reject();
|
||||||
} catch (reason) {
|
} catch (reason) {
|
||||||
@@ -70,9 +70,7 @@ export function App() {
|
|||||||
setOpen={setDownloadDrawerOpen}
|
setOpen={setDownloadDrawerOpen}
|
||||||
mangaKey={selectedMangaKey}
|
mangaKey={selectedMangaKey}
|
||||||
downloadOpen={downloadSectionOpen}>
|
downloadOpen={downloadSectionOpen}>
|
||||||
<TButton onClick={() => removeManga(selectedMangaKey)}>
|
<TButton onClick={() => removeManga(selectedMangaKey)}>Remove</TButton>
|
||||||
Remove
|
|
||||||
</TButton>
|
|
||||||
</MangaDetail>
|
</MangaDetail>
|
||||||
</Sheet>
|
</Sheet>
|
||||||
</Sheet>
|
</Sheet>
|
||||||
|
@@ -7,9 +7,7 @@ import './loadingBorder.css';
|
|||||||
export default function TInput(props: TInputProps) {
|
export default function TInput(props: TInputProps) {
|
||||||
const [state, setState] = useState<TState>(TState.clean);
|
const [state, setState] = useState<TState>(TState.clean);
|
||||||
const [value, setValue] = useState<string | number | undefined>(props.defaultValue);
|
const [value, setValue] = useState<string | number | undefined>(props.defaultValue);
|
||||||
const [initialValue, setInitialValue] = useState<string | number | undefined>(
|
const [initialValue, setInitialValue] = useState<string | number | undefined>(props.defaultValue);
|
||||||
props.defaultValue
|
|
||||||
);
|
|
||||||
|
|
||||||
const timerRef = React.useRef<ReturnType<typeof setTimeout>>(undefined);
|
const timerRef = React.useRef<ReturnType<typeof setTimeout>>(undefined);
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { ReactNode, useContext, useEffect, useState } from 'react';
|
import { ReactNode, useContext, useEffect, useState } from 'react';
|
||||||
import { Chapter, Manga, MangaConnector, MangaConnectorId } from '../../../api/data-contracts.ts';
|
import { Chapter, Manga, MangaConnector, MangaConnectorId } from '../../../api/data-contracts.ts';
|
||||||
import { Accordion, AccordionDetails, AccordionSummary, Table, Typography } from '@mui/joy';
|
import { Accordion, AccordionDetails, AccordionSummary, Box, Table, Typography } from '@mui/joy';
|
||||||
import { ApiContext } from '../../../contexts/ApiContext.tsx';
|
import { ApiContext } from '../../../contexts/ApiContext.tsx';
|
||||||
import { MangaConnectorContext } from '../../../contexts/MangaConnectorContext.tsx';
|
import { MangaConnectorContext } from '../../../contexts/MangaConnectorContext.tsx';
|
||||||
import MangaConnectorIcon from '../MangaConnectorIcon.tsx';
|
import MangaConnectorIcon from '../MangaConnectorIcon.tsx';
|
||||||
@@ -36,13 +36,16 @@ export default function ChaptersSection(props: ChaptersSectionProps): ReactNode
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Accordion sx={{ maxHeight: '50vh' }}>
|
<Accordion sx={{ maxHeight: '50vh' }}
|
||||||
|
expanded={props.expanded}
|
||||||
|
onChange={(_, expanded) => props.onExpanded(expanded)}>
|
||||||
<AccordionSummary>
|
<AccordionSummary>
|
||||||
<Typography level={'h3'}>Chapters</Typography>
|
<Typography level={'h3'}>Chapters</Typography>
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Typography level={'body-md'}>Set source for chapter</Typography>
|
<Typography level={'body-md'}>Set source for chapter</Typography>
|
||||||
<Table>
|
<Box sx={{ overflowY: 'scroll' }}>
|
||||||
|
<Table stickyHeader={true}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Vol</th>
|
<th>Vol</th>
|
||||||
@@ -69,6 +72,7 @@ export default function ChaptersSection(props: ChaptersSectionProps): ReactNode
|
|||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
</Box>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
);
|
);
|
||||||
@@ -76,4 +80,6 @@ export default function ChaptersSection(props: ChaptersSectionProps): ReactNode
|
|||||||
|
|
||||||
export interface ChaptersSectionProps {
|
export interface ChaptersSectionProps {
|
||||||
manga?: Manga;
|
manga?: Manga;
|
||||||
|
expanded: boolean;
|
||||||
|
onExpanded: (expanded: boolean) => void;
|
||||||
}
|
}
|
||||||
|
@@ -24,9 +24,7 @@ export function DownloadSection(props: DownloadSectionProps): ReactNode {
|
|||||||
|
|
||||||
const [manga, setManga] = useState<Manga>();
|
const [manga, setManga] = useState<Manga>();
|
||||||
const [library, setLibrary] = useState<FileLibrary | undefined>();
|
const [library, setLibrary] = useState<FileLibrary | undefined>();
|
||||||
const [downloadFromMap, setDownloadFromMap] = useState<Map<MangaConnectorId, boolean>>(
|
const [downloadFromMap, setDownloadFromMap] = useState<Map<MangaConnectorId, boolean>>(new Map());
|
||||||
new Map()
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const newMap = new Map();
|
const newMap = new Map();
|
||||||
@@ -54,11 +52,7 @@ export function DownloadSection(props: DownloadSectionProps): ReactNode {
|
|||||||
if (!s) return Promise.reject();
|
if (!s) return Promise.reject();
|
||||||
}
|
}
|
||||||
for (const kv of downloadFromMap) {
|
for (const kv of downloadFromMap) {
|
||||||
const s = await Api.mangaSetAsDownloadFromCreate(
|
const s = await Api.mangaSetAsDownloadFromCreate(manga?.key, kv[0].mangaConnectorName, kv[1])
|
||||||
manga?.key,
|
|
||||||
kv[0].mangaConnectorName,
|
|
||||||
kv[1]
|
|
||||||
)
|
|
||||||
.then((result) => result.ok)
|
.then((result) => result.ok)
|
||||||
.catch(() => false);
|
.catch(() => false);
|
||||||
if (!s) return Promise.reject();
|
if (!s) return Promise.reject();
|
||||||
@@ -67,7 +61,9 @@ export function DownloadSection(props: DownloadSectionProps): ReactNode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Accordion defaultExpanded={props.downloadOpen}>
|
<Accordion
|
||||||
|
expanded={props.expanded}
|
||||||
|
onChange={(_, expanded) => props.onExpanded(expanded)}>
|
||||||
<AccordionSummary>
|
<AccordionSummary>
|
||||||
<Typography level={'h3'}>Download</Typography>
|
<Typography level={'h3'}>Download</Typography>
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
@@ -92,9 +88,7 @@ export function DownloadSection(props: DownloadSectionProps): ReactNode {
|
|||||||
</Select>
|
</Select>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Typography>
|
<Typography>Select which connectors you want to download this Manga from:</Typography>
|
||||||
Select which connectors you want to download this Manga from:
|
|
||||||
</Typography>
|
|
||||||
<List>
|
<List>
|
||||||
{props.manga?.mangaConnectorIds.map((id) => (
|
{props.manga?.mangaConnectorIds.map((id) => (
|
||||||
<ListItem key={id.key}>
|
<ListItem key={id.key}>
|
||||||
@@ -102,15 +96,8 @@ export function DownloadSection(props: DownloadSectionProps): ReactNode {
|
|||||||
defaultChecked={id.useForDownload}
|
defaultChecked={id.useForDownload}
|
||||||
onChange={(c) => downloadFromMap.set(id, c.target.checked)}
|
onChange={(c) => downloadFromMap.set(id, c.target.checked)}
|
||||||
label={
|
label={
|
||||||
<div
|
<div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
|
||||||
style={{
|
<MangaConnectorIcon mangaConnectorName={id.mangaConnectorName} />
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 5,
|
|
||||||
}}>
|
|
||||||
<MangaConnectorIcon
|
|
||||||
mangaConnectorName={id.mangaConnectorName}
|
|
||||||
/>
|
|
||||||
<Typography>{id.mangaConnectorName}</Typography>
|
<Typography>{id.mangaConnectorName}</Typography>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -127,5 +114,6 @@ export function DownloadSection(props: DownloadSectionProps): ReactNode {
|
|||||||
}
|
}
|
||||||
export interface DownloadSectionProps {
|
export interface DownloadSectionProps {
|
||||||
manga?: Manga;
|
manga?: Manga;
|
||||||
downloadOpen: boolean;
|
expanded: boolean;
|
||||||
|
onExpanded: (expanded: boolean) => void;
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,6 @@
|
|||||||
import { ReactNode, useContext, useEffect, useState } from 'react';
|
import { ReactNode, useContext, useEffect, useState } from 'react';
|
||||||
import { FileLibrary, Manga } from '../../../api/data-contracts.ts';
|
import { FileLibrary, Manga } from '../../../api/data-contracts.ts';
|
||||||
import {
|
import { Accordion, AccordionDetails, AccordionSummary, Option, Select, Stack, Typography } from '@mui/joy';
|
||||||
Accordion,
|
|
||||||
AccordionDetails,
|
|
||||||
AccordionSummary,
|
|
||||||
Option,
|
|
||||||
Select,
|
|
||||||
Stack,
|
|
||||||
Typography,
|
|
||||||
} from '@mui/joy';
|
|
||||||
import { ApiContext } from '../../../contexts/ApiContext.tsx';
|
import { ApiContext } from '../../../contexts/ApiContext.tsx';
|
||||||
import { FileLibraryContext } from '../../../contexts/FileLibraryContext.tsx';
|
import { FileLibraryContext } from '../../../contexts/FileLibraryContext.tsx';
|
||||||
import TButton from '../../Inputs/TButton.tsx';
|
import TButton from '../../Inputs/TButton.tsx';
|
||||||
@@ -31,7 +23,7 @@ export function LibrarySection(props: LibrarySectionProps): ReactNode {
|
|||||||
const submit = async (): Promise<void> => {
|
const submit = async (): Promise<void> => {
|
||||||
if (!props.manga || !library) return Promise.reject();
|
if (!props.manga || !library) return Promise.reject();
|
||||||
try {
|
try {
|
||||||
let result = await Api.mangaChangeLibraryCreate(props.manga?.key, library?.key);
|
const result = await Api.mangaChangeLibraryCreate(props.manga?.key, library?.key);
|
||||||
if (!result.ok) return Promise.reject();
|
if (!result.ok) return Promise.reject();
|
||||||
else return Promise.resolve();
|
else return Promise.resolve();
|
||||||
} catch (reason) {
|
} catch (reason) {
|
||||||
@@ -40,7 +32,9 @@ export function LibrarySection(props: LibrarySectionProps): ReactNode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Accordion sx={{ maxHeight: '50vh' }}>
|
<Accordion sx={{ maxHeight: '50vh' }}
|
||||||
|
expanded={props.expanded}
|
||||||
|
onChange={(_, expanded) => props.onExpanded(expanded)}>
|
||||||
<AccordionSummary>
|
<AccordionSummary>
|
||||||
<Typography level={'h3'}>Library</Typography>
|
<Typography level={'h3'}>Library</Typography>
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
@@ -70,4 +64,6 @@ export function LibrarySection(props: LibrarySectionProps): ReactNode {
|
|||||||
|
|
||||||
export interface LibrarySectionProps {
|
export interface LibrarySectionProps {
|
||||||
manga?: Manga;
|
manga?: Manga;
|
||||||
|
expanded: boolean;
|
||||||
|
onExpanded: (expanded: boolean) => void;
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Dispatch, ReactNode, useContext, useEffect, useState } from 'react';
|
import { Dispatch, ReactNode, useContext, useEffect, useState } from 'react';
|
||||||
import { Card, CardCover, Chip, Modal, ModalDialog, Stack, Typography, useTheme } from '@mui/joy';
|
import { AccordionGroup, Card, CardCover, Chip, Modal, ModalDialog, Stack, Typography, useTheme } from '@mui/joy';
|
||||||
import ModalClose from '@mui/joy/ModalClose';
|
import ModalClose from '@mui/joy/ModalClose';
|
||||||
import { Manga } from '../../../api/data-contracts.ts';
|
import { Manga } from '../../../api/data-contracts.ts';
|
||||||
import { ApiContext } from '../../../contexts/ApiContext.tsx';
|
import { ApiContext } from '../../../contexts/ApiContext.tsx';
|
||||||
@@ -23,6 +23,8 @@ export default function MangaDetail(props: MangaDetailProps): ReactNode {
|
|||||||
Manga.GetManga(props.mangaKey).then(setManga);
|
Manga.GetManga(props.mangaKey).then(setManga);
|
||||||
}, [Api, Manga, props]);
|
}, [Api, Manga, props]);
|
||||||
|
|
||||||
|
const [expanded, setExpanded] = useState(props.downloadOpen ? 1 : 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={props.open}
|
open={props.open}
|
||||||
@@ -41,13 +43,7 @@ export default function MangaDetail(props: MangaDetailProps): ReactNode {
|
|||||||
className={'manga-card'}
|
className={'manga-card'}
|
||||||
sx={{ flexShrink: 0 }}>
|
sx={{ flexShrink: 0 }}>
|
||||||
<CardCover className={'manga-card-cover'}>
|
<CardCover className={'manga-card-cover'}>
|
||||||
<img
|
<img src={manga ? `${Api.baseUrl}/v2/Manga/${manga.key}/Cover/Medium` : '/blahaj.png'} />
|
||||||
src={
|
|
||||||
manga
|
|
||||||
? `${Api.baseUrl}/v2/Manga/${manga.key}/Cover/Medium`
|
|
||||||
: '/blahaj.png'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</CardCover>
|
</CardCover>
|
||||||
</Card>
|
</Card>
|
||||||
<Stack
|
<Stack
|
||||||
@@ -98,12 +94,32 @@ export default function MangaDetail(props: MangaDetailProps): ReactNode {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
<AccordionGroup>
|
||||||
<DownloadSection
|
<DownloadSection
|
||||||
downloadOpen={props.downloadOpen ?? false}
|
expanded={expanded == 1}
|
||||||
|
onExpanded={(e) => {
|
||||||
|
if (e) setExpanded(1);
|
||||||
|
else setExpanded(0);
|
||||||
|
}}
|
||||||
manga={manga}
|
manga={manga}
|
||||||
/>
|
/>
|
||||||
<LibrarySection manga={manga} />
|
<LibrarySection
|
||||||
<ChaptersSection manga={manga} />
|
expanded={expanded == 2}
|
||||||
|
onExpanded={(e) => {
|
||||||
|
if (e) setExpanded(2);
|
||||||
|
else setExpanded(0);
|
||||||
|
}}
|
||||||
|
manga={manga}
|
||||||
|
/>
|
||||||
|
<ChaptersSection
|
||||||
|
expanded={expanded == 3}
|
||||||
|
onExpanded={(e) => {
|
||||||
|
if (e) setExpanded(3);
|
||||||
|
else setExpanded(0);
|
||||||
|
}}
|
||||||
|
manga={manga}
|
||||||
|
/>
|
||||||
|
</AccordionGroup>
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
@@ -1,12 +1,4 @@
|
|||||||
import {
|
import { Badge, Card, CardContent, CardCover, ColorPaletteProp, Skeleton, Typography } from '@mui/joy';
|
||||||
Badge,
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
CardCover,
|
|
||||||
ColorPaletteProp,
|
|
||||||
Skeleton,
|
|
||||||
Typography,
|
|
||||||
} from '@mui/joy';
|
|
||||||
import { EventHandler, ReactNode, useContext } from 'react';
|
import { EventHandler, ReactNode, useContext } from 'react';
|
||||||
import './MangaCard.css';
|
import './MangaCard.css';
|
||||||
import MangaConnectorIcon from './MangaConnectorIcon.tsx';
|
import MangaConnectorIcon from './MangaConnectorIcon.tsx';
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
import { ChangeEventHandler, ReactNode, useContext, useState } from 'react';
|
import { ChangeEventHandler, ReactNode, useContext, useState } from 'react';
|
||||||
import { SettingsContext, SettingsItem } from './Settings.tsx';
|
import { SettingsContext, SettingsItem } from './Settings.tsx';
|
||||||
import { ApiContext } from '../../contexts/ApiContext.tsx';
|
import { ApiContext } from '../../contexts/ApiContext.tsx';
|
||||||
import TButton from "../Inputs/TButton.tsx";
|
import TButton from '../Inputs/TButton.tsx';
|
||||||
import {LibraryRefreshSetting, PatchLibraryRefreshRecord} from "../../api/data-contracts.ts";
|
import { LibraryRefreshSetting, PatchLibraryRefreshRecord } from '../../api/data-contracts.ts';
|
||||||
import {Input, Radio, RadioGroup, Typography} from "@mui/joy";
|
import { Input, Radio, RadioGroup, Typography } from '@mui/joy';
|
||||||
|
|
||||||
export default function LibraryRefresh(): ReactNode {
|
export default function LibraryRefresh(): ReactNode {
|
||||||
const settings = useContext(SettingsContext);
|
const settings = useContext(SettingsContext);
|
||||||
|
|
||||||
const [value, setValue] = useState<PatchLibraryRefreshRecord>({
|
const [value, setValue] = useState<PatchLibraryRefreshRecord>({
|
||||||
setting: settings?.libraryRefreshSetting ?? LibraryRefreshSetting.AfterAllFinished,
|
setting: settings?.libraryRefreshSetting ?? LibraryRefreshSetting.AfterAllFinished,
|
||||||
refreshLibraryWhileDownloadingEveryMinutes: settings?.refreshLibraryWhileDownloadingEveryMinutes
|
refreshLibraryWhileDownloadingEveryMinutes: settings?.refreshLibraryWhileDownloadingEveryMinutes,
|
||||||
});
|
});
|
||||||
|
|
||||||
const Api = useContext(ApiContext);
|
const Api = useContext(ApiContext);
|
||||||
@@ -27,22 +27,34 @@ export default function LibraryRefresh(): ReactNode {
|
|||||||
|
|
||||||
const onSettingChanged: ChangeEventHandler<HTMLInputElement> = (e) => {
|
const onSettingChanged: ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||||
setValue({ ...value, setting: LibraryRefreshSetting[e.target.value as keyof typeof LibraryRefreshSetting] });
|
setValue({ ...value, setting: LibraryRefreshSetting[e.target.value as keyof typeof LibraryRefreshSetting] });
|
||||||
}
|
};
|
||||||
|
|
||||||
const onMinutesChanged: ChangeEventHandler<HTMLInputElement> = (e) => {
|
const onMinutesChanged: ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||||
setValue({...value, refreshLibraryWhileDownloadingEveryMinutes: e.target.valueAsNumber})
|
setValue({ ...value, refreshLibraryWhileDownloadingEveryMinutes: e.target.valueAsNumber });
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingsItem title={'Library Refresh'}>
|
<SettingsItem title={'Library Refresh'}>
|
||||||
<Typography level={"body-md"}>Refresh after</Typography>
|
<Typography level={'body-md'}>Refresh after</Typography>
|
||||||
<RadioGroup value={value.setting} onChange={onSettingChanged}>
|
<RadioGroup
|
||||||
{Object.keys(LibraryRefreshSetting).map(e => (
|
value={value.setting}
|
||||||
<Radio key={e} value={e} label={e} />
|
onChange={onSettingChanged}>
|
||||||
|
{Object.keys(LibraryRefreshSetting).map((e) => (
|
||||||
|
<Radio
|
||||||
|
key={e}
|
||||||
|
value={e}
|
||||||
|
label={e}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
<Typography level={"body-md"}>When {LibraryRefreshSetting.WhileDownloading} refresh every x-minutes:</Typography>
|
<Typography level={'body-md'}>
|
||||||
<Input value={value.refreshLibraryWhileDownloadingEveryMinutes??undefined} onChange={onMinutesChanged} type={"number"} />
|
When {LibraryRefreshSetting.WhileDownloading} refresh every x-minutes:
|
||||||
|
</Typography>
|
||||||
|
<Input
|
||||||
|
value={value.refreshLibraryWhileDownloadingEveryMinutes ?? undefined}
|
||||||
|
onChange={onMinutesChanged}
|
||||||
|
type={'number'}
|
||||||
|
/>
|
||||||
<TButton onClick={updateSetting}>Update</TButton>
|
<TButton onClick={updateSetting}>Update</TButton>
|
||||||
</SettingsItem>
|
</SettingsItem>
|
||||||
);
|
);
|
||||||
|
@@ -8,7 +8,8 @@ import {
|
|||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Modal,
|
Modal,
|
||||||
ModalDialog, Stack,
|
ModalDialog,
|
||||||
|
Stack,
|
||||||
} from '@mui/joy';
|
} from '@mui/joy';
|
||||||
import './Settings.css';
|
import './Settings.css';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
@@ -22,7 +23,7 @@ import Maintenance from './Maintenance.tsx';
|
|||||||
import { ApiContext } from '../../contexts/ApiContext.tsx';
|
import { ApiContext } from '../../contexts/ApiContext.tsx';
|
||||||
import { TrangaSettings } from '../../api/data-contracts.ts';
|
import { TrangaSettings } from '../../api/data-contracts.ts';
|
||||||
import TInput from '../Inputs/TInput.tsx';
|
import TInput from '../Inputs/TInput.tsx';
|
||||||
import LibraryRefresh from "./LibraryRefresh.tsx";
|
import LibraryRefresh from './LibraryRefresh.tsx';
|
||||||
|
|
||||||
export const SettingsContext = createContext<TrangaSettings | undefined>(undefined);
|
export const SettingsContext = createContext<TrangaSettings | undefined>(undefined);
|
||||||
|
|
||||||
@@ -83,7 +84,9 @@ export function SettingsItem({ title, children }: { title: string; children: Rea
|
|||||||
<Accordion>
|
<Accordion>
|
||||||
<AccordionSummary>{title}</AccordionSummary>
|
<AccordionSummary>{title}</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Stack gap={1} direction="column">
|
<Stack
|
||||||
|
gap={1}
|
||||||
|
direction="column">
|
||||||
{children}
|
{children}
|
||||||
</Stack>
|
</Stack>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
|
@@ -32,9 +32,7 @@ export function Search(props: SearchModalProps): ReactNode {
|
|||||||
const [selectedConnector, setSelectedConnector] = useState<MangaConnector>();
|
const [selectedConnector, setSelectedConnector] = useState<MangaConnector>();
|
||||||
const [searchResults, setSearchResults] = useState<MinimalManga[]>([]);
|
const [searchResults, setSearchResults] = useState<MinimalManga[]>([]);
|
||||||
|
|
||||||
const startSearch = async (
|
const startSearch = async (value: string | number | readonly string[] | undefined): Promise<void> => {
|
||||||
value: string | number | readonly string[] | undefined
|
|
||||||
): Promise<void> => {
|
|
||||||
if (typeof value != 'string') return Promise.reject();
|
if (typeof value != 'string') return Promise.reject();
|
||||||
setSearchResults([]);
|
setSearchResults([]);
|
||||||
if (isUrl(value)) {
|
if (isUrl(value)) {
|
||||||
@@ -80,12 +78,7 @@ export function Search(props: SearchModalProps): ReactNode {
|
|||||||
<ListItemDecorator>
|
<ListItemDecorator>
|
||||||
<MangaConnectorIcon mangaConnector={c} />
|
<MangaConnectorIcon mangaConnector={c} />
|
||||||
</ListItemDecorator>
|
</ListItemDecorator>
|
||||||
<Typography
|
<Typography sx={c.key == selectedConnector?.key ? { fontWeight: 'bold' } : {}}>
|
||||||
sx={
|
|
||||||
c.key == selectedConnector?.key
|
|
||||||
? { fontWeight: 'bold' }
|
|
||||||
: {}
|
|
||||||
}>
|
|
||||||
{c.name}
|
{c.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
@@ -48,12 +48,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/FileLibrary
|
* @request GET:/v2/FileLibrary
|
||||||
*/
|
*/
|
||||||
fileLibraryList = (params: RequestParams = {}) =>
|
fileLibraryList = (params: RequestParams = {}) =>
|
||||||
this.request<FileLibrary[], void>({
|
this.request<FileLibrary[], void>({ path: `/v2/FileLibrary`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/FileLibrary`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -94,11 +89,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request DELETE:/v2/FileLibrary/{FileLibraryId}
|
* @request DELETE:/v2/FileLibrary/{FileLibraryId}
|
||||||
*/
|
*/
|
||||||
fileLibraryDelete = (fileLibraryId: string, params: RequestParams = {}) =>
|
fileLibraryDelete = (fileLibraryId: string, params: RequestParams = {}) =>
|
||||||
this.request<void, string>({
|
this.request<void, string>({ path: `/v2/FileLibrary/${fileLibraryId}`, method: 'DELETE', ...params });
|
||||||
path: `/v2/FileLibrary/${fileLibraryId}`,
|
|
||||||
method: 'DELETE',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -107,11 +98,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @summary Changes the !:FileLibraryId.BasePath with FileLibraryId
|
* @summary Changes the !:FileLibraryId.BasePath with FileLibraryId
|
||||||
* @request PATCH:/v2/FileLibrary/{FileLibraryId}/ChangeBasePath
|
* @request PATCH:/v2/FileLibrary/{FileLibraryId}/ChangeBasePath
|
||||||
*/
|
*/
|
||||||
fileLibraryChangeBasePathPartialUpdate = (
|
fileLibraryChangeBasePathPartialUpdate = (fileLibraryId: string, data: string, params: RequestParams = {}) =>
|
||||||
fileLibraryId: string,
|
|
||||||
data: string,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<void, string>({
|
this.request<void, string>({
|
||||||
path: `/v2/FileLibrary/${fileLibraryId}/ChangeBasePath`,
|
path: `/v2/FileLibrary/${fileLibraryId}/ChangeBasePath`,
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
@@ -127,11 +114,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @summary Changes the !:FileLibraryId.LibraryName with FileLibraryId
|
* @summary Changes the !:FileLibraryId.LibraryName with FileLibraryId
|
||||||
* @request PATCH:/v2/FileLibrary/{FileLibraryId}/ChangeName
|
* @request PATCH:/v2/FileLibrary/{FileLibraryId}/ChangeName
|
||||||
*/
|
*/
|
||||||
fileLibraryChangeNamePartialUpdate = (
|
fileLibraryChangeNamePartialUpdate = (fileLibraryId: string, data: string, params: RequestParams = {}) =>
|
||||||
fileLibraryId: string,
|
|
||||||
data: string,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<void, string>({
|
this.request<void, string>({
|
||||||
path: `/v2/FileLibrary/${fileLibraryId}/ChangeName`,
|
path: `/v2/FileLibrary/${fileLibraryId}/ChangeName`,
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
@@ -194,11 +177,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request DELETE:/v2/LibraryConnector/{LibraryConnectorId}
|
* @request DELETE:/v2/LibraryConnector/{LibraryConnectorId}
|
||||||
*/
|
*/
|
||||||
libraryConnectorDelete = (libraryConnectorId: string, params: RequestParams = {}) =>
|
libraryConnectorDelete = (libraryConnectorId: string, params: RequestParams = {}) =>
|
||||||
this.request<void, string>({
|
this.request<void, string>({ path: `/v2/LibraryConnector/${libraryConnectorId}`, method: 'DELETE', ...params });
|
||||||
path: `/v2/LibraryConnector/${libraryConnectorId}`,
|
|
||||||
method: 'DELETE',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -208,11 +187,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request POST:/v2/Maintenance/CleanupNoDownloadManga
|
* @request POST:/v2/Maintenance/CleanupNoDownloadManga
|
||||||
*/
|
*/
|
||||||
maintenanceCleanupNoDownloadMangaCreate = (params: RequestParams = {}) =>
|
maintenanceCleanupNoDownloadMangaCreate = (params: RequestParams = {}) =>
|
||||||
this.request<void, string>({
|
this.request<void, string>({ path: `/v2/Maintenance/CleanupNoDownloadManga`, method: 'POST', ...params });
|
||||||
path: `/v2/Maintenance/CleanupNoDownloadManga`,
|
|
||||||
method: 'POST',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -222,12 +197,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Manga
|
* @request GET:/v2/Manga
|
||||||
*/
|
*/
|
||||||
mangaList = (params: RequestParams = {}) =>
|
mangaList = (params: RequestParams = {}) =>
|
||||||
this.request<MinimalManga[], void>({
|
this.request<MinimalManga[], void>({ path: `/v2/Manga`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/Manga`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -237,12 +207,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Manga/Keys
|
* @request GET:/v2/Manga/Keys
|
||||||
*/
|
*/
|
||||||
mangaKeysList = (params: RequestParams = {}) =>
|
mangaKeysList = (params: RequestParams = {}) =>
|
||||||
this.request<string[], void>({
|
this.request<string[], void>({ path: `/v2/Manga/Keys`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/Manga/Keys`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -252,12 +217,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Manga/Downloading
|
* @request GET:/v2/Manga/Downloading
|
||||||
*/
|
*/
|
||||||
mangaDownloadingList = (params: RequestParams = {}) =>
|
mangaDownloadingList = (params: RequestParams = {}) =>
|
||||||
this.request<MinimalManga[], void>({
|
this.request<MinimalManga[], void>({ path: `/v2/Manga/Downloading`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/Manga/Downloading`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -284,12 +244,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Manga/{MangaId}
|
* @request GET:/v2/Manga/{MangaId}
|
||||||
*/
|
*/
|
||||||
mangaDetail = (mangaId: string, params: RequestParams = {}) =>
|
mangaDetail = (mangaId: string, params: RequestParams = {}) =>
|
||||||
this.request<Manga, string>({
|
this.request<Manga, string>({ path: `/v2/Manga/${mangaId}`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/Manga/${mangaId}`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -308,11 +263,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @summary Merge two API.Controllers.DTOs.Manga into one. THIS IS NOT REVERSIBLE!
|
* @summary Merge two API.Controllers.DTOs.Manga into one. THIS IS NOT REVERSIBLE!
|
||||||
* @request PATCH:/v2/Manga/{MangaIdFrom}/MergeInto/{MangaIdInto}
|
* @request PATCH:/v2/Manga/{MangaIdFrom}/MergeInto/{MangaIdInto}
|
||||||
*/
|
*/
|
||||||
mangaMergeIntoPartialUpdate = (
|
mangaMergeIntoPartialUpdate = (mangaIdFrom: string, mangaIdInto: string, params: RequestParams = {}) =>
|
||||||
mangaIdFrom: string,
|
|
||||||
mangaIdInto: string,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<void, string>({
|
this.request<void, string>({
|
||||||
path: `/v2/Manga/${mangaIdFrom}/MergeInto/${mangaIdInto}`,
|
path: `/v2/Manga/${mangaIdFrom}/MergeInto/${mangaIdInto}`,
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
@@ -416,11 +367,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @summary Configure the API.Controllers.DTOs.Chapter cut-off for API.Controllers.DTOs.Manga
|
* @summary Configure the API.Controllers.DTOs.Chapter cut-off for API.Controllers.DTOs.Manga
|
||||||
* @request PATCH:/v2/Manga/{MangaId}/IgnoreChaptersBefore
|
* @request PATCH:/v2/Manga/{MangaId}/IgnoreChaptersBefore
|
||||||
*/
|
*/
|
||||||
mangaIgnoreChaptersBeforePartialUpdate = (
|
mangaIgnoreChaptersBeforePartialUpdate = (mangaId: string, data: number, params: RequestParams = {}) =>
|
||||||
mangaId: string,
|
|
||||||
data: number,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<void, string>({
|
this.request<void, string>({
|
||||||
path: `/v2/Manga/${mangaId}/IgnoreChaptersBefore`,
|
path: `/v2/Manga/${mangaId}/IgnoreChaptersBefore`,
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
@@ -469,11 +416,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @summary Initiate a search for API.Schema.MangaContext.Manga on a different API.MangaConnectors.MangaConnector
|
* @summary Initiate a search for API.Schema.MangaContext.Manga on a different API.MangaConnectors.MangaConnector
|
||||||
* @request POST:/v2/Manga/{MangaId}/SearchOn/{MangaConnectorName}
|
* @request POST:/v2/Manga/{MangaId}/SearchOn/{MangaConnectorName}
|
||||||
*/
|
*/
|
||||||
mangaSearchOnCreate = (
|
mangaSearchOnCreate = (mangaId: string, mangaConnectorName: string, params: RequestParams = {}) =>
|
||||||
mangaId: string,
|
|
||||||
mangaConnectorName: string,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<MinimalManga[], string | ProblemDetails | void>({
|
this.request<MinimalManga[], string | ProblemDetails | void>({
|
||||||
path: `/v2/Manga/${mangaId}/SearchOn/${mangaConnectorName}`,
|
path: `/v2/Manga/${mangaId}/SearchOn/${mangaConnectorName}`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -519,12 +462,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/MangaConnector
|
* @request GET:/v2/MangaConnector
|
||||||
*/
|
*/
|
||||||
mangaConnectorList = (params: RequestParams = {}) =>
|
mangaConnectorList = (params: RequestParams = {}) =>
|
||||||
this.request<MangaConnector[], any>({
|
this.request<MangaConnector[], any>({ path: `/v2/MangaConnector`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/MangaConnector`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -597,12 +535,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/MetadataFetcher
|
* @request GET:/v2/MetadataFetcher
|
||||||
*/
|
*/
|
||||||
metadataFetcherList = (params: RequestParams = {}) =>
|
metadataFetcherList = (params: RequestParams = {}) =>
|
||||||
this.request<string[], any>({
|
this.request<string[], any>({ path: `/v2/MetadataFetcher`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/MetadataFetcher`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -670,11 +603,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @summary Un-Links API.Schema.MangaContext.MetadataFetchers.MetadataFetcher (Metadata-Sites) from API.Schema.MangaContext.Manga
|
* @summary Un-Links API.Schema.MangaContext.MetadataFetchers.MetadataFetcher (Metadata-Sites) from API.Schema.MangaContext.Manga
|
||||||
* @request POST:/v2/MetadataFetcher/{MetadataFetcherName}/Unlink/{MangaId}
|
* @request POST:/v2/MetadataFetcher/{MetadataFetcherName}/Unlink/{MangaId}
|
||||||
*/
|
*/
|
||||||
metadataFetcherUnlinkCreate = (
|
metadataFetcherUnlinkCreate = (mangaId: string, metadataFetcherName: string, params: RequestParams = {}) =>
|
||||||
mangaId: string,
|
|
||||||
metadataFetcherName: string,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<void, ProblemDetails | string>({
|
this.request<void, ProblemDetails | string>({
|
||||||
path: `/v2/MetadataFetcher/${metadataFetcherName}/Unlink/${mangaId}`,
|
path: `/v2/MetadataFetcher/${metadataFetcherName}/Unlink/${mangaId}`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -703,10 +632,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @summary Creates a new API.Controllers.DTOs.NotificationConnector
|
* @summary Creates a new API.Controllers.DTOs.NotificationConnector
|
||||||
* @request PUT:/v2/NotificationConnector
|
* @request PUT:/v2/NotificationConnector
|
||||||
*/
|
*/
|
||||||
notificationConnectorUpdate = (
|
notificationConnectorUpdate = (data: CreateNotificationConnectorRecord, params: RequestParams = {}) =>
|
||||||
data: CreateNotificationConnectorRecord,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<void, string>({
|
this.request<void, string>({
|
||||||
path: `/v2/NotificationConnector`,
|
path: `/v2/NotificationConnector`,
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
@@ -738,11 +664,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request DELETE:/v2/NotificationConnector/{Name}
|
* @request DELETE:/v2/NotificationConnector/{Name}
|
||||||
*/
|
*/
|
||||||
notificationConnectorDelete = (name: string, params: RequestParams = {}) =>
|
notificationConnectorDelete = (name: string, params: RequestParams = {}) =>
|
||||||
this.request<void, string>({
|
this.request<void, string>({ path: `/v2/NotificationConnector/${name}`, method: 'DELETE', ...params });
|
||||||
path: `/v2/NotificationConnector/${name}`,
|
|
||||||
method: 'DELETE',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* @description Priority needs to be between 0 and 10
|
* @description Priority needs to be between 0 and 10
|
||||||
*
|
*
|
||||||
@@ -751,10 +673,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @summary Creates a new Gotify-API.Controllers.DTOs.NotificationConnector
|
* @summary Creates a new Gotify-API.Controllers.DTOs.NotificationConnector
|
||||||
* @request PUT:/v2/NotificationConnector/Gotify
|
* @request PUT:/v2/NotificationConnector/Gotify
|
||||||
*/
|
*/
|
||||||
notificationConnectorGotifyUpdate = (
|
notificationConnectorGotifyUpdate = (data: CreateGotifyConnectorRecord, params: RequestParams = {}) =>
|
||||||
data: CreateGotifyConnectorRecord,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<void, string>({
|
this.request<void, string>({
|
||||||
path: `/v2/NotificationConnector/Gotify`,
|
path: `/v2/NotificationConnector/Gotify`,
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
@@ -770,10 +689,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @summary Creates a new Ntfy-API.Controllers.DTOs.NotificationConnector
|
* @summary Creates a new Ntfy-API.Controllers.DTOs.NotificationConnector
|
||||||
* @request PUT:/v2/NotificationConnector/Ntfy
|
* @request PUT:/v2/NotificationConnector/Ntfy
|
||||||
*/
|
*/
|
||||||
notificationConnectorNtfyUpdate = (
|
notificationConnectorNtfyUpdate = (data: CreateNtfyConnectorRecord, params: RequestParams = {}) =>
|
||||||
data: CreateNtfyConnectorRecord,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<void, string>({
|
this.request<void, string>({
|
||||||
path: `/v2/NotificationConnector/Ntfy`,
|
path: `/v2/NotificationConnector/Ntfy`,
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
@@ -789,10 +705,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @summary Creates a new Pushover-API.Controllers.DTOs.NotificationConnector
|
* @summary Creates a new Pushover-API.Controllers.DTOs.NotificationConnector
|
||||||
* @request PUT:/v2/NotificationConnector/Pushover
|
* @request PUT:/v2/NotificationConnector/Pushover
|
||||||
*/
|
*/
|
||||||
notificationConnectorPushoverUpdate = (
|
notificationConnectorPushoverUpdate = (data: CreatePushoverConnectorRecord, params: RequestParams = {}) =>
|
||||||
data: CreatePushoverConnectorRecord,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<void, string>({
|
this.request<void, string>({
|
||||||
path: `/v2/NotificationConnector/Pushover`,
|
path: `/v2/NotificationConnector/Pushover`,
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
@@ -916,12 +829,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Settings
|
* @request GET:/v2/Settings
|
||||||
*/
|
*/
|
||||||
settingsList = (params: RequestParams = {}) =>
|
settingsList = (params: RequestParams = {}) =>
|
||||||
this.request<TrangaSettings, any>({
|
this.request<TrangaSettings, any>({ path: `/v2/Settings`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/Settings`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -1003,12 +911,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request DELETE:/v2/Settings/RequestLimits
|
* @request DELETE:/v2/Settings/RequestLimits
|
||||||
*/
|
*/
|
||||||
settingsRequestLimitsDelete = (params: RequestParams = {}) =>
|
settingsRequestLimitsDelete = (params: RequestParams = {}) =>
|
||||||
this.request<string, any>({
|
this.request<string, any>({ path: `/v2/Settings/RequestLimits`, method: 'DELETE', format: 'json', ...params });
|
||||||
path: `/v2/Settings/RequestLimits`,
|
|
||||||
method: 'DELETE',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -1019,11 +922,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @originalName settingsRequestLimitsPartialUpdate
|
* @originalName settingsRequestLimitsPartialUpdate
|
||||||
* @duplicate
|
* @duplicate
|
||||||
*/
|
*/
|
||||||
settingsRequestLimitsPartialUpdate2 = (
|
settingsRequestLimitsPartialUpdate2 = (requestType: RequestType, data: number, params: RequestParams = {}) =>
|
||||||
requestType: RequestType,
|
|
||||||
data: number,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<void, ProblemDetails>({
|
this.request<void, ProblemDetails>({
|
||||||
path: `/v2/Settings/RequestLimits/${requestType}`,
|
path: `/v2/Settings/RequestLimits/${requestType}`,
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
@@ -1057,11 +956,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Settings/ImageCompressionLevel
|
* @request GET:/v2/Settings/ImageCompressionLevel
|
||||||
*/
|
*/
|
||||||
settingsImageCompressionLevelList = (params: RequestParams = {}) =>
|
settingsImageCompressionLevelList = (params: RequestParams = {}) =>
|
||||||
this.request<number, any>({
|
this.request<number, any>({ path: `/v2/Settings/ImageCompressionLevel`, method: 'GET', ...params });
|
||||||
path: `/v2/Settings/ImageCompressionLevel`,
|
|
||||||
method: 'GET',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -1095,11 +990,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request PATCH:/v2/Settings/BWImages/{enabled}
|
* @request PATCH:/v2/Settings/BWImages/{enabled}
|
||||||
*/
|
*/
|
||||||
settingsBwImagesPartialUpdate = (enabled: boolean, params: RequestParams = {}) =>
|
settingsBwImagesPartialUpdate = (enabled: boolean, params: RequestParams = {}) =>
|
||||||
this.request<void, any>({
|
this.request<void, any>({ path: `/v2/Settings/BWImages/${enabled}`, method: 'PATCH', ...params });
|
||||||
path: `/v2/Settings/BWImages/${enabled}`,
|
|
||||||
method: 'PATCH',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* @description Placeholders: %M Obj Name %V Volume %C Chapter %T Title %A Author (first in list) %I Chapter Internal ID %i Obj Internal ID %Y Year (Obj) ?_(...) replace _ with a value from above: Everything inside the braces will only be added if the value of %_ is not null
|
* @description Placeholders: %M Obj Name %V Volume %C Chapter %T Title %A Author (first in list) %I Chapter Internal ID %i Obj Internal ID %Y Year (Obj) ?_(...) replace _ with a value from above: Everything inside the braces will only be added if the value of %_ is not null
|
||||||
*
|
*
|
||||||
@@ -1109,11 +1000,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Settings/ChapterNamingScheme
|
* @request GET:/v2/Settings/ChapterNamingScheme
|
||||||
*/
|
*/
|
||||||
settingsChapterNamingSchemeList = (params: RequestParams = {}) =>
|
settingsChapterNamingSchemeList = (params: RequestParams = {}) =>
|
||||||
this.request<string, any>({
|
this.request<string, any>({ path: `/v2/Settings/ChapterNamingScheme`, method: 'GET', ...params });
|
||||||
path: `/v2/Settings/ChapterNamingScheme`,
|
|
||||||
method: 'GET',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* @description Placeholders: %M Obj Name %V Volume %C Chapter %T Title %A Author (first in list) %Y Year (Obj) ?_(...) replace _ with a value from above: Everything inside the braces will only be added if the value of %_ is not null
|
* @description Placeholders: %M Obj Name %V Volume %C Chapter %T Title %A Author (first in list) %Y Year (Obj) ?_(...) replace _ with a value from above: Everything inside the braces will only be added if the value of %_ is not null
|
||||||
*
|
*
|
||||||
@@ -1155,11 +1042,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request DELETE:/v2/Settings/FlareSolverr/Url
|
* @request DELETE:/v2/Settings/FlareSolverr/Url
|
||||||
*/
|
*/
|
||||||
settingsFlareSolverrUrlDelete = (params: RequestParams = {}) =>
|
settingsFlareSolverrUrlDelete = (params: RequestParams = {}) =>
|
||||||
this.request<void, any>({
|
this.request<void, any>({ path: `/v2/Settings/FlareSolverr/Url`, method: 'DELETE', ...params });
|
||||||
path: `/v2/Settings/FlareSolverr/Url`,
|
|
||||||
method: 'DELETE',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -1169,11 +1052,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request POST:/v2/Settings/FlareSolverr/Test
|
* @request POST:/v2/Settings/FlareSolverr/Test
|
||||||
*/
|
*/
|
||||||
settingsFlareSolverrTestCreate = (params: RequestParams = {}) =>
|
settingsFlareSolverrTestCreate = (params: RequestParams = {}) =>
|
||||||
this.request<void, void>({
|
this.request<void, void>({ path: `/v2/Settings/FlareSolverr/Test`, method: 'POST', ...params });
|
||||||
path: `/v2/Settings/FlareSolverr/Test`,
|
|
||||||
method: 'POST',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -1183,11 +1062,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Settings/DownloadLanguage
|
* @request GET:/v2/Settings/DownloadLanguage
|
||||||
*/
|
*/
|
||||||
settingsDownloadLanguageList = (params: RequestParams = {}) =>
|
settingsDownloadLanguageList = (params: RequestParams = {}) =>
|
||||||
this.request<string, any>({
|
this.request<string, any>({ path: `/v2/Settings/DownloadLanguage`, method: 'GET', ...params });
|
||||||
path: `/v2/Settings/DownloadLanguage`,
|
|
||||||
method: 'GET',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -1197,11 +1072,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request PATCH:/v2/Settings/DownloadLanguage/{Language}
|
* @request PATCH:/v2/Settings/DownloadLanguage/{Language}
|
||||||
*/
|
*/
|
||||||
settingsDownloadLanguagePartialUpdate = (language: string, params: RequestParams = {}) =>
|
settingsDownloadLanguagePartialUpdate = (language: string, params: RequestParams = {}) =>
|
||||||
this.request<void, any>({
|
this.request<void, any>({ path: `/v2/Settings/DownloadLanguage/${language}`, method: 'PATCH', ...params });
|
||||||
path: `/v2/Settings/DownloadLanguage/${language}`,
|
|
||||||
method: 'PATCH',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -1210,10 +1081,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @summary Sets the time when Libraries are refreshed
|
* @summary Sets the time when Libraries are refreshed
|
||||||
* @request PATCH:/v2/Settings/LibraryRefresh
|
* @request PATCH:/v2/Settings/LibraryRefresh
|
||||||
*/
|
*/
|
||||||
settingsLibraryRefreshPartialUpdate = (
|
settingsLibraryRefreshPartialUpdate = (data: PatchLibraryRefreshRecord, params: RequestParams = {}) =>
|
||||||
data: PatchLibraryRefreshRecord,
|
|
||||||
params: RequestParams = {}
|
|
||||||
) =>
|
|
||||||
this.request<void, any>({
|
this.request<void, any>({
|
||||||
path: `/v2/Settings/LibraryRefresh`,
|
path: `/v2/Settings/LibraryRefresh`,
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
@@ -1230,12 +1098,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Worker
|
* @request GET:/v2/Worker
|
||||||
*/
|
*/
|
||||||
workerList = (params: RequestParams = {}) =>
|
workerList = (params: RequestParams = {}) =>
|
||||||
this.request<Worker[], any>({
|
this.request<Worker[], any>({ path: `/v2/Worker`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/Worker`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -1245,12 +1108,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Worker/Keys
|
* @request GET:/v2/Worker/Keys
|
||||||
*/
|
*/
|
||||||
workerKeysList = (params: RequestParams = {}) =>
|
workerKeysList = (params: RequestParams = {}) =>
|
||||||
this.request<string[], any>({
|
this.request<string[], any>({ path: `/v2/Worker/Keys`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/Worker/Keys`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -1260,12 +1118,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Worker/State/{State}
|
* @request GET:/v2/Worker/State/{State}
|
||||||
*/
|
*/
|
||||||
workerStateDetail = (state: WorkerExecutionState, params: RequestParams = {}) =>
|
workerStateDetail = (state: WorkerExecutionState, params: RequestParams = {}) =>
|
||||||
this.request<Worker[], any>({
|
this.request<Worker[], any>({ path: `/v2/Worker/State/${state}`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/Worker/State/${state}`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -1275,12 +1128,7 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request GET:/v2/Worker/{WorkerId}
|
* @request GET:/v2/Worker/{WorkerId}
|
||||||
*/
|
*/
|
||||||
workerDetail = (workerId: string, params: RequestParams = {}) =>
|
workerDetail = (workerId: string, params: RequestParams = {}) =>
|
||||||
this.request<Worker, string>({
|
this.request<Worker, string>({ path: `/v2/Worker/${workerId}`, method: 'GET', format: 'json', ...params });
|
||||||
path: `/v2/Worker/${workerId}`,
|
|
||||||
method: 'GET',
|
|
||||||
format: 'json',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* No description
|
* No description
|
||||||
*
|
*
|
||||||
@@ -1314,9 +1162,5 @@ export class V2<SecurityDataType = unknown> extends HttpClient<SecurityDataType>
|
|||||||
* @request POST:/v2/Worker/{WorkerId}/Stop
|
* @request POST:/v2/Worker/{WorkerId}/Stop
|
||||||
*/
|
*/
|
||||||
workerStopCreate = (workerId: string, params: RequestParams = {}) =>
|
workerStopCreate = (workerId: string, params: RequestParams = {}) =>
|
||||||
this.request<void, string | ProblemDetails>({
|
this.request<void, string | ProblemDetails>({ path: `/v2/Worker/${workerId}/Stop`, method: 'POST', ...params });
|
||||||
path: `/v2/Worker/${workerId}/Stop`,
|
|
||||||
method: 'POST',
|
|
||||||
...params,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
@@ -37,9 +37,7 @@ export type RequestParams = Omit<FullRequestParams, 'body' | 'method' | 'query'
|
|||||||
export interface ApiConfig<SecurityDataType = unknown> {
|
export interface ApiConfig<SecurityDataType = unknown> {
|
||||||
baseUrl?: string;
|
baseUrl?: string;
|
||||||
baseApiParams?: Omit<RequestParams, 'baseUrl' | 'cancelToken' | 'signal'>;
|
baseApiParams?: Omit<RequestParams, 'baseUrl' | 'cancelToken' | 'signal'>;
|
||||||
securityWorker?: (
|
securityWorker?: (securityData: SecurityDataType | null) => Promise<RequestParams | void> | RequestParams | void;
|
||||||
securityData: SecurityDataType | null
|
|
||||||
) => Promise<RequestParams | void> | RequestParams | void;
|
|
||||||
customFetch?: typeof fetch;
|
customFetch?: typeof fetch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,9 +97,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|||||||
const keys = Object.keys(query).filter((key) => 'undefined' !== typeof query[key]);
|
const keys = Object.keys(query).filter((key) => 'undefined' !== typeof query[key]);
|
||||||
return keys
|
return keys
|
||||||
.map((key) =>
|
.map((key) =>
|
||||||
Array.isArray(query[key])
|
Array.isArray(query[key]) ? this.addArrayQueryParam(query, key) : this.addQueryParam(query, key)
|
||||||
? this.addArrayQueryParam(query, key)
|
|
||||||
: this.addQueryParam(query, key)
|
|
||||||
)
|
)
|
||||||
.join('&');
|
.join('&');
|
||||||
}
|
}
|
||||||
@@ -113,13 +109,9 @@ export class HttpClient<SecurityDataType = unknown> {
|
|||||||
|
|
||||||
private contentFormatters: Record<ContentType, (input: any) => any> = {
|
private contentFormatters: Record<ContentType, (input: any) => any> = {
|
||||||
[ContentType.Json]: (input: any) =>
|
[ContentType.Json]: (input: any) =>
|
||||||
input !== null && (typeof input === 'object' || typeof input === 'string')
|
input !== null && (typeof input === 'object' || typeof input === 'string') ? JSON.stringify(input) : input,
|
||||||
? JSON.stringify(input)
|
|
||||||
: input,
|
|
||||||
[ContentType.JsonApi]: (input: any) =>
|
[ContentType.JsonApi]: (input: any) =>
|
||||||
input !== null && (typeof input === 'object' || typeof input === 'string')
|
input !== null && (typeof input === 'object' || typeof input === 'string') ? JSON.stringify(input) : input,
|
||||||
? JSON.stringify(input)
|
|
||||||
: input,
|
|
||||||
[ContentType.Text]: (input: any) =>
|
[ContentType.Text]: (input: any) =>
|
||||||
input !== null && typeof input !== 'string' ? JSON.stringify(input) : input,
|
input !== null && typeof input !== 'string' ? JSON.stringify(input) : input,
|
||||||
[ContentType.FormData]: (input: any) =>
|
[ContentType.FormData]: (input: any) =>
|
||||||
@@ -195,20 +187,15 @@ export class HttpClient<SecurityDataType = unknown> {
|
|||||||
const payloadFormatter = this.contentFormatters[type || ContentType.Json];
|
const payloadFormatter = this.contentFormatters[type || ContentType.Json];
|
||||||
const responseFormat = format || requestParams.format;
|
const responseFormat = format || requestParams.format;
|
||||||
|
|
||||||
return this.customFetch(
|
return this.customFetch(`${baseUrl || this.baseUrl || ''}${path}${queryString ? `?${queryString}` : ''}`, {
|
||||||
`${baseUrl || this.baseUrl || ''}${path}${queryString ? `?${queryString}` : ''}`,
|
|
||||||
{
|
|
||||||
...requestParams,
|
...requestParams,
|
||||||
headers: {
|
headers: {
|
||||||
...(requestParams.headers || {}),
|
...(requestParams.headers || {}),
|
||||||
...(type && type !== ContentType.FormData ? { 'Content-Type': type } : {}),
|
...(type && type !== ContentType.FormData ? { 'Content-Type': type } : {}),
|
||||||
},
|
},
|
||||||
signal:
|
signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null,
|
||||||
(cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) ||
|
|
||||||
null,
|
|
||||||
body: typeof body === 'undefined' || body === null ? null : payloadFormatter(body),
|
body: typeof body === 'undefined' || body === null ? null : payloadFormatter(body),
|
||||||
}
|
}).then(async (response) => {
|
||||||
).then(async (response) => {
|
|
||||||
const r = response.clone() as HttpResponse<T, E>;
|
const r = response.clone() as HttpResponse<T, E>;
|
||||||
r.data = null as unknown as T;
|
r.data = null as unknown as T;
|
||||||
r.error = null as unknown as E;
|
r.error = null as unknown as E;
|
||||||
|
@@ -4,13 +4,7 @@ import { ApiConfig } from '../api/http-client.ts';
|
|||||||
|
|
||||||
export const ApiContext = createContext<V2>(new V2());
|
export const ApiContext = createContext<V2>(new V2());
|
||||||
|
|
||||||
export default function ApiProvider({
|
export default function ApiProvider({ apiConfig, children }: { apiConfig: ApiConfig; children: ReactNode }) {
|
||||||
apiConfig,
|
|
||||||
children,
|
|
||||||
}: {
|
|
||||||
apiConfig: ApiConfig;
|
|
||||||
children: ReactNode;
|
|
||||||
}) {
|
|
||||||
const [api, setApi] = useState<V2>(new V2(apiConfig));
|
const [api, setApi] = useState<V2>(new V2(apiConfig));
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setApi(new V2(apiConfig));
|
setApi(new V2(apiConfig));
|
||||||
|
@@ -1,4 +1 @@
|
|||||||
{
|
{ "files": [], "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }] }
|
||||||
"files": [],
|
|
||||||
"references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user