mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-10 15:35:55 +01:00
✏️ Fix request Modal
This commit is contained in:
@@ -1,8 +1,19 @@
|
|||||||
import { Alert, Checkbox, createStyles, Group, LoadingOverlay, Stack, Table } from '@mantine/core';
|
import {
|
||||||
|
Alert,
|
||||||
|
Button,
|
||||||
|
Checkbox,
|
||||||
|
createStyles,
|
||||||
|
Group,
|
||||||
|
LoadingOverlay,
|
||||||
|
Modal,
|
||||||
|
Stack,
|
||||||
|
Table,
|
||||||
|
} from '@mantine/core';
|
||||||
import { openConfirmModal } from '@mantine/modals';
|
import { openConfirmModal } from '@mantine/modals';
|
||||||
import { showNotification, updateNotification } from '@mantine/notifications';
|
import { showNotification, updateNotification } from '@mantine/notifications';
|
||||||
import { IconAlertCircle, IconCheck, IconDownload } from '@tabler/icons';
|
import { IconAlertCircle, IconCheck, IconDownload } from '@tabler/icons';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import Consola from 'consola';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useColorTheme } from '../../tools/color';
|
import { useColorTheme } from '../../tools/color';
|
||||||
import { MovieResult } from './Movie.d';
|
import { MovieResult } from './Movie.d';
|
||||||
@@ -11,6 +22,8 @@ import { TvShowResult, TvShowResultSeason } from './TvShow.d';
|
|||||||
|
|
||||||
interface RequestModalProps {
|
interface RequestModalProps {
|
||||||
base: Result;
|
base: Result;
|
||||||
|
opened: boolean;
|
||||||
|
setOpened: (opened: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = createStyles((theme) => ({
|
const useStyles = createStyles((theme) => ({
|
||||||
@@ -22,43 +35,53 @@ const useStyles = createStyles((theme) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default function RequestModal({ base }: RequestModalProps) {
|
export function RequestModal({ base, opened, setOpened }: RequestModalProps) {
|
||||||
const [result, setResult] = useState<MovieResult | TvShowResult>();
|
const [result, setResult] = useState<MovieResult | TvShowResult>();
|
||||||
|
const { secondaryColor } = useColorTheme();
|
||||||
useEffect(() => {
|
function getResults(base: Result) {
|
||||||
// Use the overseerr API get the media info.
|
|
||||||
axios.get(`/api/modules/overseerr/${base.id}?type=${base.mediaType}`).then((res) => {
|
axios.get(`/api/modules/overseerr/${base.id}?type=${base.mediaType}`).then((res) => {
|
||||||
setResult(res.data);
|
setResult(res.data);
|
||||||
});
|
});
|
||||||
}, [base]);
|
}
|
||||||
|
if (opened && !result) {
|
||||||
const { secondaryColor } = useColorTheme();
|
getResults(base);
|
||||||
if (!result) {
|
}
|
||||||
return <LoadingOverlay color={secondaryColor} visible />;
|
if (!result || !opened) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return base.mediaType === 'movie' ? (
|
return base.mediaType === 'movie' ? (
|
||||||
<MovieRequestModal result={result as MovieResult} />
|
<MovieRequestModal result={result as MovieResult} opened={opened} setOpened={setOpened} />
|
||||||
) : (
|
) : (
|
||||||
<TvRequestModal result={result as TvShowResult} />
|
<TvRequestModal result={result as TvShowResult} opened={opened} setOpened={setOpened} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function MovieRequestModal({ result }: { result: MovieResult }) {
|
export function MovieRequestModal({
|
||||||
|
result,
|
||||||
|
opened,
|
||||||
|
setOpened,
|
||||||
|
}: {
|
||||||
|
result: MovieResult;
|
||||||
|
opened: boolean;
|
||||||
|
setOpened: (opened: boolean) => void;
|
||||||
|
}) {
|
||||||
const { secondaryColor } = useColorTheme();
|
const { secondaryColor } = useColorTheme();
|
||||||
openConfirmModal({
|
return (
|
||||||
title: (
|
<Modal
|
||||||
<Group>
|
onClose={() => setOpened(false)}
|
||||||
<IconDownload />
|
radius="lg"
|
||||||
Ask for {result.title}
|
size="lg"
|
||||||
</Group>
|
trapFocus
|
||||||
),
|
zIndex={150}
|
||||||
radius: 'lg',
|
withinPortal
|
||||||
labels: { confirm: 'Request', cancel: 'Cancel' },
|
opened={opened}
|
||||||
onConfirm: () => {
|
title={
|
||||||
askForMedia(MediaType.Movie, result.id, result.title);
|
<Group>
|
||||||
},
|
<IconDownload />
|
||||||
size: 'lg',
|
Ask for {result.title}
|
||||||
children: (
|
</Group>
|
||||||
|
}
|
||||||
|
>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Alert
|
<Alert
|
||||||
icon={<IconAlertCircle size={16} />}
|
icon={<IconAlertCircle size={16} />}
|
||||||
@@ -69,13 +92,30 @@ function MovieRequestModal({ result }: { result: MovieResult }) {
|
|||||||
>
|
>
|
||||||
This request will be automatically approved
|
This request will be automatically approved
|
||||||
</Alert>
|
</Alert>
|
||||||
|
<Group>
|
||||||
|
<Button onClick={() => setOpened(false)}>Cancel</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
askForMedia(MediaType.Movie, result.id, result.title, []);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Request
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
),
|
</Modal>
|
||||||
});
|
);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function TvRequestModal({ result }: { result: TvShowResult }) {
|
export function TvRequestModal({
|
||||||
|
result,
|
||||||
|
opened,
|
||||||
|
setOpened,
|
||||||
|
}: {
|
||||||
|
result: TvShowResult;
|
||||||
|
opened: boolean;
|
||||||
|
setOpened: (opened: boolean) => void;
|
||||||
|
}) {
|
||||||
const [selection, setSelection] = useState<TvShowResultSeason[]>(result.seasons);
|
const [selection, setSelection] = useState<TvShowResultSeason[]>(result.seasons);
|
||||||
const { classes, cx } = useStyles();
|
const { classes, cx } = useStyles();
|
||||||
|
|
||||||
@@ -107,28 +147,8 @@ function TvRequestModal({ result }: { result: TvShowResult }) {
|
|||||||
});
|
});
|
||||||
const { secondaryColor } = useColorTheme();
|
const { secondaryColor } = useColorTheme();
|
||||||
|
|
||||||
openConfirmModal({
|
return (
|
||||||
title: (
|
<Modal onClose={() => setOpened(false)} radius="lg" size="lg" opened={opened}>
|
||||||
<Group>
|
|
||||||
<IconDownload />
|
|
||||||
Ask for {result.name}
|
|
||||||
</Group>
|
|
||||||
),
|
|
||||||
radius: 'lg',
|
|
||||||
labels: { confirm: 'Request', cancel: 'Cancel' },
|
|
||||||
confirmProps: {
|
|
||||||
disabled: selection.length === 0,
|
|
||||||
},
|
|
||||||
onConfirm: () => {
|
|
||||||
askForMedia(
|
|
||||||
MediaType.Tv,
|
|
||||||
result.id,
|
|
||||||
result.name,
|
|
||||||
selection.map((s) => s.seasonNumber)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
size: 'lg',
|
|
||||||
children: (
|
|
||||||
<Stack>
|
<Stack>
|
||||||
<Alert
|
<Alert
|
||||||
icon={<IconAlertCircle size={16} />}
|
icon={<IconAlertCircle size={16} />}
|
||||||
@@ -157,13 +177,29 @@ function TvRequestModal({ result }: { result: TvShowResult }) {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>{rows}</tbody>
|
<tbody>{rows}</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
<Group>
|
||||||
|
<Button onClick={() => setOpened(false)}>Cancel</Button>
|
||||||
|
<Button
|
||||||
|
disabled={selection.length === 0}
|
||||||
|
onClick={() => {
|
||||||
|
askForMedia(
|
||||||
|
MediaType.Tv,
|
||||||
|
result.id,
|
||||||
|
result.name,
|
||||||
|
selection.map((s) => s.seasonNumber)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Request
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
),
|
</Modal>
|
||||||
});
|
);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function askForMedia(type: MediaType, id: number, name: string, seasons?: number[]) {
|
function askForMedia(type: MediaType, id: number, name: string, seasons?: number[]) {
|
||||||
|
Consola.info(`Requesting ${type} ${id} ${name}`);
|
||||||
showNotification({
|
showNotification({
|
||||||
title: 'Request',
|
title: 'Request',
|
||||||
id: id.toString(),
|
id: id.toString(),
|
||||||
|
|||||||
Reference in New Issue
Block a user