Add basic Sonarr interaction

This is going to be a pain.
This commit is contained in:
Aj - Thomas
2022-05-04 09:30:28 +02:00
parent 6769ca701c
commit f0fcb7f083
4 changed files with 81 additions and 87 deletions

View File

@@ -20,6 +20,7 @@ import { serviceItem } from '../../tools/types';
const useStyles = createStyles((theme) => ({ const useStyles = createStyles((theme) => ({
main: { main: {
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[1], backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[1],
//TODO: #3 Fix this temporary fix and make the width and height dynamic / responsive
width: 200, width: 200,
height: 180, height: 180,
}, },

View File

@@ -1,102 +1,93 @@
import { Indicator, Popover, Box, Center } from '@mantine/core'; import { Indicator, Popover, Box, Center } from '@mantine/core';
import { useState } from 'react'; import { useEffect, useState } from 'react';
import { Calendar } from '@mantine/dates'; import { Calendar } from '@mantine/dates';
import dayjs from 'dayjs';
import MediaDisplay from './MediaDisplay'; import MediaDisplay from './MediaDisplay';
import { medias } from './mediaExample';
import { useConfig } from '../../tools/state'; import { useConfig } from '../../tools/state';
import { serviceItem } from '../../tools/types';
async function GetCalendars(endDate: Date) {
// Load context
const { config, addService, removeService, setConfig } = useConfig();
// Load services that have the type to "Sonarr" or "Radarr"
const sonarrServices = config.services.filter((service) => service.type === 'Sonarr');
const radarrServices = config.services.filter((service) => service.type === 'Radarr');
// Merge the two arrays
const allServices = [...sonarrServices, ...radarrServices];
// Load the calendars for each service
const Calendars = await Promise.all(
allServices.map((service) =>
fetch(`${service.url}/api/v3/calendar?end=${endDate}?apikey=${service.apiKey}`)
)
);
}
export default function CalendarComponent(props: any) { export default function CalendarComponent(props: any) {
const { config } = useConfig();
const [opened, setOpened] = useState(false); const [opened, setOpened] = useState(false);
// const [medias, setMedias] = useState(); const [medias, setMedias] = useState([] as any);
const dates = medias.map((media) => media.inCinemas); if (medias === undefined) {
const parsedDates = dates.map((date) => dayjs(date)); return <div>ok</div>;
}
useEffect(() => {
// Filter only sonarr and radarr services
const filtered = config.services.filter(
(service) => service.type === 'Sonarr' || service.type === 'Radarr'
);
// useEffect(() => { // Get the url and API key for each service
// const { services } = props; const serviceUrls = filtered.map((service: serviceItem) => ({
// // Get the url and API key for each service url: service.url,
// const serviceUrls = services.map((service: serviceItem) => { apiKey: service.apiKey,
// return { }));
// url: service.url,
// apiKey: service.apiKey, // Get the medias from each service
// }; // With no cors
// }); // const promises = serviceUrls.map((service) =>
// // Get the medias from each service // fetch('/api/getCalendar', {
// const promises = serviceUrls.map((service: serviceItem) => { // method: 'POST',
// return fetch(`${service.url}/api/v3/calendar`, { // body: JSON.stringify({
// method: 'GET', // apiKey: service.apiKey,
// headers: { // remoteUrl: service.url,
// 'Content-Type': 'application/json', // }),
// 'X-Api-Key': service.apiKey, // }).then((response) => console.log(response.json()))
// }, // );
// }); fetch('http://server:8989/api/calendar?apikey=ea736455118146fea297e6c7465205ce').then(
// }); (response) => {
// // Wait for all the promises to resolve response.json().then((data) => setMedias(data));
// Promise.all(promises).then((responses) => { }
// // Get the medias from each service );
// const medias = responses.map((response) => { }, [config.services]);
// return response.json();
// }); if (medias === undefined) {
// // Set the medias return <div>ok</div>;
// setMedias(medias); }
// }
// );
// }, []);
return ( return (
<Calendar <Calendar
onChange={(day: any) => {}} onChange={(day: any) => {}}
renderDay={(renderdate) => <DayComponent renderdate={renderdate} parsedDates={parsedDates} />} renderDay={(renderdate) => <DayComponent renderdate={renderdate} medias={medias} />}
/> />
); );
} }
function DayComponent(props: any) { function DayComponent(props: any) {
const { renderdate, parsedDates }: { renderdate: Date; parsedDates: dayjs.Dayjs[] } = props; const { renderdate, medias }: { renderdate: Date; medias: [] } = props;
const [opened, setOpened] = useState(false); const [opened, setOpened] = useState(false);
const day = renderdate.getDate(); const day = renderdate.getDate();
const match = parsedDates.findIndex((date) => date.isSame(dayjs(renderdate), 'day')); // Itterate over the medias and filter the ones that are on the same day
const filtered = medias.filter((media: any) => {
if (match > -1) { const date = new Date(media.airDate);
return ( return date.getDate() === day;
<Box });
onClick={() => { if (filtered.length === 0) {
setOpened(true); return <div>{day}</div>;
}}
style={{ height: '100%', width: '100%' }}
>
<Center>
<Indicator size={10} color="red">
<Popover
position="left"
width={700}
onClose={() => setOpened(false)}
opened={opened}
target={day}
>
<MediaDisplay media={medias[match]} />
</Popover>
</Indicator>
</Center>
</Box>
);
} }
return <div>{day}</div>;
return (
<Box
onClick={() => {
setOpened(true);
}}
style={{ height: '100%', width: '100%' }}
>
<Center>
<Indicator size={10} color="red">
<Popover
position="left"
width={700}
onClose={() => setOpened(false)}
opened={opened}
target={day}
>
<MediaDisplay media={filtered[0]} />
</Popover>
</Indicator>
</Center>
</Box>
);
} }

View File

@@ -15,8 +15,8 @@ export default function MediaDisplay(props: any) {
return ( return (
<Group noWrap align="self-start"> <Group noWrap align="self-start">
<Image <Image
src={media.images[0].url} src={media.series.images[0].url}
alt={media.title} alt={media.series.title}
style={{ style={{
maxWidth: 300, maxWidth: 300,
}} }}
@@ -28,12 +28,12 @@ export default function MediaDisplay(props: any) {
})} })}
> >
<Group direction="column"> <Group direction="column">
<Title order={3}>{media.title}</Title> <Title order={3}>{media.series.title}</Title>
<Text>{media.overview}</Text> <Text>{media.overview}</Text>
</Group> </Group>
{/*Add the genres at the bottom of the poster*/} {/*Add the genres at the bottom of the poster*/}
<Group> <Group>
{media.genres.map((genre: string, i: number) => ( {media.series.genres.map((genre: string, i: number) => (
<Badge key={i}>{genre}</Badge> <Badge key={i}>{genre}</Badge>
))} ))}
</Group> </Group>

View File

@@ -145,9 +145,11 @@ export function Header({ links }: HeaderResponsiveProps) {
onClose={() => toggleOpened()} onClose={() => toggleOpened()}
position="right" position="right"
> >
<Center> {opened ?? (
<CalendarComponent /> <Center>
</Center> <CalendarComponent />
</Center>
)}
</Drawer> </Drawer>
</Container> </Container>
</Head> </Head>