2022-05-06 17:50:03 +02:00
|
|
|
/* eslint-disable react/no-children-prop */
|
2022-05-25 10:50:57 +02:00
|
|
|
import { Box, Divider, Indicator, Popover, ScrollArea, useMantineTheme } from '@mantine/core';
|
2022-05-10 19:03:41 +02:00
|
|
|
import React, { useEffect, useState } from 'react';
|
2022-04-30 21:36:46 +02:00
|
|
|
import { Calendar } from '@mantine/dates';
|
2022-05-10 20:57:04 +02:00
|
|
|
import { showNotification } from '@mantine/notifications';
|
2022-05-14 01:14:56 +02:00
|
|
|
import { Calendar as CalendarIcon, Check } from 'tabler-icons-react';
|
2022-05-08 20:54:40 +02:00
|
|
|
import { useConfig } from '../../../tools/state';
|
2022-05-10 18:56:50 +02:00
|
|
|
import { IModule } from '../modules';
|
2022-05-25 10:50:57 +02:00
|
|
|
import {
|
|
|
|
|
SonarrMediaDisplay,
|
|
|
|
|
RadarrMediaDisplay,
|
|
|
|
|
LidarrMediaDisplay,
|
|
|
|
|
ReadarrMediaDisplay,
|
|
|
|
|
} from './MediaDisplay';
|
2022-05-08 20:54:40 +02:00
|
|
|
|
2022-05-10 18:56:50 +02:00
|
|
|
export const CalendarModule: IModule = {
|
2022-05-08 20:54:40 +02:00
|
|
|
title: 'Calendar',
|
2022-05-09 02:07:07 +02:00
|
|
|
description:
|
|
|
|
|
'A calendar module for displaying upcoming releases. It interacts with the Sonarr and Radarr API.',
|
2022-05-08 20:54:40 +02:00
|
|
|
icon: CalendarIcon,
|
|
|
|
|
component: CalendarComponent,
|
|
|
|
|
};
|
2022-04-30 21:36:46 +02:00
|
|
|
|
|
|
|
|
export default function CalendarComponent(props: any) {
|
2022-05-04 09:30:28 +02:00
|
|
|
const { config } = useConfig();
|
2022-05-05 09:22:44 +02:00
|
|
|
const [sonarrMedias, setSonarrMedias] = useState([] as any);
|
2022-05-25 10:50:57 +02:00
|
|
|
const [lidarrMedias, setLidarrMedias] = useState([] as any);
|
2022-05-05 09:22:44 +02:00
|
|
|
const [radarrMedias, setRadarrMedias] = useState([] as any);
|
2022-05-25 10:50:57 +02:00
|
|
|
const [readarrMedias, setReadarrMedias] = useState([] as any);
|
2022-05-05 09:22:44 +02:00
|
|
|
|
2022-05-04 09:30:28 +02:00
|
|
|
useEffect(() => {
|
|
|
|
|
// Filter only sonarr and radarr services
|
|
|
|
|
const filtered = config.services.filter(
|
2022-05-25 10:50:57 +02:00
|
|
|
(service) =>
|
|
|
|
|
service.type === 'Sonarr' ||
|
|
|
|
|
service.type === 'Radarr' ||
|
|
|
|
|
service.type === 'Lidarr' ||
|
|
|
|
|
service.type === 'Readarr'
|
2022-05-04 09:30:28 +02:00
|
|
|
);
|
|
|
|
|
|
2022-05-05 09:22:44 +02:00
|
|
|
// Get the url and apiKey for all Sonarr and Radarr services
|
|
|
|
|
const sonarrService = filtered.filter((service) => service.type === 'Sonarr').at(0);
|
|
|
|
|
const radarrService = filtered.filter((service) => service.type === 'Radarr').at(0);
|
2022-05-25 10:50:57 +02:00
|
|
|
const lidarrService = filtered.filter((service) => service.type === 'Lidarr').at(0);
|
|
|
|
|
const readarrService = filtered.filter((service) => service.type === 'Readarr').at(0);
|
2022-05-05 09:22:44 +02:00
|
|
|
const nextMonth = new Date(new Date().setMonth(new Date().getMonth() + 2)).toISOString();
|
2022-05-06 22:45:51 +02:00
|
|
|
if (sonarrService && sonarrService.apiKey) {
|
2022-05-21 00:55:11 +02:00
|
|
|
const baseUrl = new URL(sonarrService.url).origin;
|
2022-05-23 10:24:54 +02:00
|
|
|
fetch(`${baseUrl}/api/calendar?apikey=${sonarrService?.apiKey}&end=${nextMonth}`).then(
|
|
|
|
|
(response) => {
|
|
|
|
|
response.ok &&
|
|
|
|
|
response.json().then((data) => {
|
|
|
|
|
setSonarrMedias(data);
|
|
|
|
|
showNotification({
|
|
|
|
|
title: 'Sonarr',
|
|
|
|
|
icon: <Check />,
|
|
|
|
|
color: 'green',
|
|
|
|
|
autoClose: 1500,
|
|
|
|
|
radius: 'md',
|
|
|
|
|
message: `Loaded ${data.length} releases`,
|
|
|
|
|
});
|
2022-05-10 20:57:04 +02:00
|
|
|
});
|
2022-05-23 10:24:54 +02:00
|
|
|
}
|
|
|
|
|
);
|
2022-05-05 09:22:44 +02:00
|
|
|
}
|
2022-05-06 22:45:51 +02:00
|
|
|
if (radarrService && radarrService.apiKey) {
|
2022-05-21 00:55:11 +02:00
|
|
|
const baseUrl = new URL(radarrService.url).origin;
|
2022-05-21 01:26:55 +02:00
|
|
|
fetch(`${baseUrl}/api/v3/calendar?apikey=${radarrService?.apiKey}&end=${nextMonth}`).then(
|
2022-05-21 00:55:11 +02:00
|
|
|
(response) => {
|
|
|
|
|
response.ok &&
|
|
|
|
|
response.json().then((data) => {
|
|
|
|
|
setRadarrMedias(data);
|
|
|
|
|
showNotification({
|
|
|
|
|
title: 'Radarr',
|
|
|
|
|
icon: <Check />,
|
|
|
|
|
color: 'green',
|
|
|
|
|
autoClose: 1500,
|
|
|
|
|
radius: 'md',
|
|
|
|
|
message: `Loaded ${data.length} releases`,
|
|
|
|
|
});
|
2022-05-10 20:57:04 +02:00
|
|
|
});
|
2022-05-21 00:55:11 +02:00
|
|
|
}
|
|
|
|
|
);
|
2022-05-05 09:22:44 +02:00
|
|
|
}
|
2022-05-25 10:50:57 +02:00
|
|
|
if (lidarrService && lidarrService.apiKey) {
|
|
|
|
|
const baseUrl = new URL(lidarrService.url).origin;
|
|
|
|
|
fetch(`${baseUrl}/api/v1/calendar?apikey=${lidarrService?.apiKey}&end=${nextMonth}`).then(
|
|
|
|
|
(response) => {
|
|
|
|
|
response.ok &&
|
|
|
|
|
response.json().then((data) => {
|
|
|
|
|
setLidarrMedias(data);
|
|
|
|
|
showNotification({
|
|
|
|
|
title: 'Lidarr',
|
|
|
|
|
icon: <Check />,
|
|
|
|
|
color: 'green',
|
|
|
|
|
autoClose: 1500,
|
|
|
|
|
radius: 'md',
|
|
|
|
|
message: `Loaded ${data.length} releases`,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (readarrService && readarrService.apiKey) {
|
|
|
|
|
const baseUrl = new URL(readarrService.url).origin;
|
|
|
|
|
fetch(`${baseUrl}/api/v1/calendar?apikey=${readarrService?.apiKey}&end=${nextMonth}`).then(
|
|
|
|
|
(response) => {
|
|
|
|
|
response.ok &&
|
|
|
|
|
response.json().then((data) => {
|
|
|
|
|
setReadarrMedias(data);
|
|
|
|
|
showNotification({
|
|
|
|
|
title: 'Readarr',
|
|
|
|
|
icon: <Check />,
|
|
|
|
|
color: 'green',
|
|
|
|
|
autoClose: 1500,
|
|
|
|
|
radius: 'md',
|
|
|
|
|
message: `Loaded ${data.length} releases`,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
2022-05-04 09:30:28 +02:00
|
|
|
}, [config.services]);
|
2022-04-30 21:36:46 +02:00
|
|
|
|
2022-05-05 09:22:44 +02:00
|
|
|
if (sonarrMedias === undefined && radarrMedias === undefined) {
|
|
|
|
|
return <Calendar />;
|
2022-05-04 09:30:28 +02:00
|
|
|
}
|
2022-04-30 21:36:46 +02:00
|
|
|
return (
|
|
|
|
|
<Calendar
|
2022-05-02 18:10:56 +02:00
|
|
|
onChange={(day: any) => {}}
|
2022-05-05 09:22:44 +02:00
|
|
|
renderDay={(renderdate) => (
|
|
|
|
|
<DayComponent
|
|
|
|
|
renderdate={renderdate}
|
|
|
|
|
sonarrmedias={sonarrMedias}
|
|
|
|
|
radarrmedias={radarrMedias}
|
2022-05-25 10:50:57 +02:00
|
|
|
lidarrmedias={lidarrMedias}
|
|
|
|
|
readarrmedias={readarrMedias}
|
2022-05-05 09:22:44 +02:00
|
|
|
/>
|
|
|
|
|
)}
|
2022-04-30 21:36:46 +02:00
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function DayComponent(props: any) {
|
2022-05-05 09:22:44 +02:00
|
|
|
const {
|
|
|
|
|
renderdate,
|
|
|
|
|
sonarrmedias,
|
|
|
|
|
radarrmedias,
|
2022-05-25 10:50:57 +02:00
|
|
|
lidarrmedias,
|
|
|
|
|
readarrmedias,
|
|
|
|
|
}: { renderdate: Date; sonarrmedias: []; radarrmedias: []; lidarrmedias: []; readarrmedias: [] } =
|
|
|
|
|
props;
|
2022-04-30 21:36:46 +02:00
|
|
|
const [opened, setOpened] = useState(false);
|
2022-05-17 00:19:24 +02:00
|
|
|
const theme = useMantineTheme();
|
2022-04-30 21:36:46 +02:00
|
|
|
|
|
|
|
|
const day = renderdate.getDate();
|
2022-05-25 10:50:57 +02:00
|
|
|
|
|
|
|
|
const readarrFiltered = readarrmedias.filter((media: any) => {
|
2022-05-25 13:13:17 +02:00
|
|
|
const date = new Date(media.releaseDate);
|
|
|
|
|
return date.getDate() === day && date.getMonth() === renderdate.getMonth();
|
2022-05-25 10:50:57 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const lidarrFiltered = lidarrmedias.filter((media: any) => {
|
|
|
|
|
const date = new Date(media.releaseDate);
|
|
|
|
|
// Return true if the date is renerdate without counting hours and minutes
|
|
|
|
|
return date.getDate() === day && date.getMonth() === renderdate.getMonth();
|
|
|
|
|
});
|
2022-05-05 09:22:44 +02:00
|
|
|
const sonarrFiltered = sonarrmedias.filter((media: any) => {
|
|
|
|
|
const date = new Date(media.airDate);
|
|
|
|
|
// Return true if the date is renerdate without counting hours and minutes
|
|
|
|
|
return date.getDate() === day && date.getMonth() === renderdate.getMonth();
|
|
|
|
|
});
|
|
|
|
|
const radarrFiltered = radarrmedias.filter((media: any) => {
|
2022-05-06 17:50:03 +02:00
|
|
|
const date = new Date(media.inCinemas);
|
2022-05-05 09:22:44 +02:00
|
|
|
// Return true if the date is renerdate without counting hours and minutes
|
|
|
|
|
return date.getDate() === day && date.getMonth() === renderdate.getMonth();
|
2022-05-04 09:30:28 +02:00
|
|
|
});
|
2022-05-25 10:50:57 +02:00
|
|
|
if (
|
|
|
|
|
sonarrFiltered.length === 0 &&
|
|
|
|
|
radarrFiltered.length === 0 &&
|
|
|
|
|
lidarrFiltered.length === 0 &&
|
|
|
|
|
readarrFiltered.length === 0
|
|
|
|
|
) {
|
2022-05-04 09:30:28 +02:00
|
|
|
return <div>{day}</div>;
|
2022-04-30 21:36:46 +02:00
|
|
|
}
|
2022-05-04 09:30:28 +02:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Box
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setOpened(true);
|
|
|
|
|
}}
|
|
|
|
|
>
|
2022-05-25 10:50:57 +02:00
|
|
|
{readarrFiltered.length > 0 && (
|
|
|
|
|
<Indicator
|
|
|
|
|
size={10}
|
|
|
|
|
withBorder
|
|
|
|
|
style={{
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
bottom: 8,
|
|
|
|
|
left: 8,
|
|
|
|
|
}}
|
|
|
|
|
color="red"
|
|
|
|
|
children={null}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{radarrFiltered.length > 0 && (
|
|
|
|
|
<Indicator
|
|
|
|
|
size={10}
|
|
|
|
|
withBorder
|
|
|
|
|
style={{
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
top: 8,
|
|
|
|
|
left: 8,
|
|
|
|
|
}}
|
|
|
|
|
color="yellow"
|
|
|
|
|
children={null}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{sonarrFiltered.length > 0 && (
|
|
|
|
|
<Indicator
|
|
|
|
|
size={10}
|
|
|
|
|
withBorder
|
|
|
|
|
style={{
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
top: 8,
|
|
|
|
|
right: 8,
|
|
|
|
|
}}
|
|
|
|
|
color="blue"
|
|
|
|
|
children={null}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{lidarrFiltered.length > 0 && (
|
|
|
|
|
<Indicator
|
|
|
|
|
size={10}
|
|
|
|
|
withBorder
|
|
|
|
|
style={{
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
bottom: 8,
|
|
|
|
|
right: 8,
|
|
|
|
|
}}
|
|
|
|
|
color="green"
|
|
|
|
|
children={undefined}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2022-05-06 21:40:21 +02:00
|
|
|
<Popover
|
|
|
|
|
position="left"
|
2022-05-12 23:04:59 +02:00
|
|
|
radius="lg"
|
|
|
|
|
shadow="xl"
|
|
|
|
|
transition="pop"
|
2022-05-29 09:11:46 +02:00
|
|
|
styles={{
|
|
|
|
|
body: {
|
|
|
|
|
boxShadow: '0 0 14px 14px rgba(0, 0, 0, 0.1), 0 14px 11px rgba(0, 0, 0, 0.1)',
|
|
|
|
|
},
|
|
|
|
|
}}
|
2022-05-06 21:40:21 +02:00
|
|
|
width={700}
|
|
|
|
|
onClose={() => setOpened(false)}
|
|
|
|
|
opened={opened}
|
2022-05-17 00:19:24 +02:00
|
|
|
target={day}
|
2022-05-06 21:40:21 +02:00
|
|
|
>
|
|
|
|
|
<ScrollArea style={{ height: 400 }}>
|
2022-05-10 19:03:41 +02:00
|
|
|
{sonarrFiltered.map((media: any, index: number) => (
|
|
|
|
|
<React.Fragment key={index}>
|
|
|
|
|
<SonarrMediaDisplay media={media} />
|
|
|
|
|
{index < sonarrFiltered.length - 1 && <Divider variant="dashed" my="xl" />}
|
|
|
|
|
</React.Fragment>
|
|
|
|
|
))}
|
2022-05-06 21:40:21 +02:00
|
|
|
{radarrFiltered.length > 0 && sonarrFiltered.length > 0 && (
|
|
|
|
|
<Divider variant="dashed" my="xl" />
|
2022-05-06 17:50:03 +02:00
|
|
|
)}
|
2022-05-10 19:03:41 +02:00
|
|
|
{radarrFiltered.map((media: any, index: number) => (
|
|
|
|
|
<React.Fragment key={index}>
|
|
|
|
|
<RadarrMediaDisplay media={media} />
|
|
|
|
|
{index < radarrFiltered.length - 1 && <Divider variant="dashed" my="xl" />}
|
|
|
|
|
</React.Fragment>
|
|
|
|
|
))}
|
2022-05-25 10:50:57 +02:00
|
|
|
{lidarrFiltered.map((media: any, index: number) => (
|
|
|
|
|
<React.Fragment key={index}>
|
|
|
|
|
<LidarrMediaDisplay media={media} />
|
|
|
|
|
{index < lidarrFiltered.length - 1 && <Divider variant="dashed" my="xl" />}
|
|
|
|
|
</React.Fragment>
|
|
|
|
|
))}
|
|
|
|
|
{readarrFiltered.map((media: any, index: number) => (
|
|
|
|
|
<React.Fragment key={index}>
|
|
|
|
|
<ReadarrMediaDisplay media={media} />
|
|
|
|
|
{index < readarrFiltered.length - 1 && <Divider variant="dashed" my="xl" />}
|
|
|
|
|
</React.Fragment>
|
|
|
|
|
))}
|
2022-05-06 21:40:21 +02:00
|
|
|
</ScrollArea>
|
|
|
|
|
</Popover>
|
2022-05-04 09:30:28 +02:00
|
|
|
</Box>
|
|
|
|
|
);
|
2022-04-30 21:36:46 +02:00
|
|
|
}
|