import { Alert, Button, Checkbox, createStyles, Group, Modal, Stack, Table } from '@mantine/core'; import { showNotification, updateNotification } from '@mantine/notifications'; import { IconAlertCircle, IconCheck, IconDownload } from '@tabler/icons-react'; import Consola from 'consola'; import { useTranslation } from 'next-i18next'; import { useState } from 'react'; import { useConfigContext } from '~/config/provider'; import { api } from '~/utils/api'; import { useColorTheme } from '../../tools/color'; import { MovieResult } from './Movie.d'; import { Result } from './SearchResult.d'; import { TvShowResult, TvShowResultSeason } from './TvShow.d'; interface RequestModalProps { base: Result; opened: boolean; setOpened: (opened: boolean) => void; } const useStyles = createStyles((theme) => ({ rowSelected: { backgroundColor: theme.colorScheme === 'dark' ? theme.fn.rgba(theme.colors[theme.primaryColor][7], 0.2) : theme.colors[theme.primaryColor][0], }, })); export function RequestModal({ base, opened, setOpened }: RequestModalProps) { const { name: configName } = useConfigContext(); const { data: result } = api.overseerr.byId.useQuery( { id: base.id, type: base.mediaType, configName: configName!, }, { enabled: opened, } ); if (!result || !opened) { return null; } return base.mediaType === 'movie' ? ( ) : ( ); } export function MovieRequestModal({ result, opened, setOpened, }: { result: MovieResult; opened: boolean; setOpened: (opened: boolean) => void; }) { const { secondaryColor } = useColorTheme(); const requestMediaAsync = useMediaRequestMutation(); const { t } = useTranslation('modules/overseerr'); return ( setOpened(false)} radius="lg" size="lg" trapFocus zIndex={150} withinPortal opened={opened} title={ {t('popup.item.buttons.askFor', { title: result.title })} } > } title={t('popup.item.alerts.automaticApproval.title')} color={secondaryColor} radius="md" variant="filled" > {t('popup.item.alerts.automaticApproval.text')} ); } export function TvRequestModal({ result, opened, setOpened, }: { result: TvShowResult; opened: boolean; setOpened: (opened: boolean) => void; }) { const [selection, setSelection] = useState(result.seasons); const { classes, cx } = useStyles(); const { t } = useTranslation('modules/overseerr'); const requestMediaAsync = useMediaRequestMutation(); const toggleRow = (container: TvShowResultSeason) => setSelection((current: TvShowResultSeason[]) => current.includes(container) ? current.filter((c) => c !== container) : [...current, container] ); const toggleAll = () => setSelection((current: any) => current.length === result.seasons.length ? [] : result.seasons.map((c) => c) ); const rows = result.seasons.map((element) => { const selected = selection.includes(element); return ( toggleRow(element)} transitionDuration={0} /> {element.name} {element.episodeCount} ); }); const { secondaryColor } = useColorTheme(); return ( setOpened(false)} radius="lg" size="lg" opened={opened} title={ {t('popup.item.buttons.askFor', { title: result.name ?? result.originalName ?? 'a TV show', })} } > } title={t('popup.item.alerts.automaticApproval.title')} color={secondaryColor} radius="md" variant="filled" > {t('popup.item.alerts.automaticApproval.text')} {rows}
{t('popup.seasonSelector.caption')}
0 && selection.length !== result.seasons.length} transitionDuration={0} /> {t('popup.seasonSelector.table.header.season')} {t('popup.seasonSelector.table.header.numberOfEpisodes')}
); } const useMediaRequestMutation = () => { const { name: configName } = useConfigContext(); const { mutateAsync } = api.overseerr.request.useMutation(); return async (type: 'tv' | 'movie', id: number, name: string, seasons?: number[]) => { Consola.info(`Requesting ${type} ${id} ${name}`); showNotification({ title: 'Request', id: id.toString(), message: `Requesting media ${name}`, color: 'orange', loading: true, autoClose: false, withCloseButton: false, icon: , }); await mutateAsync( { configName: configName!, id, type, seasons: seasons ?? [], }, { onSuccess: () => { updateNotification({ id: id.toString(), title: '', color: 'green', message: ` ${name} requested`, icon: , autoClose: 2000, }); }, onError: (err) => { updateNotification({ id: id.toString(), color: 'red', title: 'There was an error', message: err.message, autoClose: 2000, }); }, } ); }; };