mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-07 22:15:49 +01:00
Add basic Sonarr interaction
This is going to be a pain.
This commit is contained in:
@@ -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,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,80 +1,73 @@
|
|||||||
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,
|
|
||||||
|
// Get the medias from each service
|
||||||
|
// With no cors
|
||||||
|
// const promises = serviceUrls.map((service) =>
|
||||||
|
// fetch('/api/getCalendar', {
|
||||||
|
// method: 'POST',
|
||||||
|
// body: JSON.stringify({
|
||||||
// apiKey: service.apiKey,
|
// apiKey: service.apiKey,
|
||||||
// };
|
// remoteUrl: service.url,
|
||||||
// });
|
// }),
|
||||||
// // Get the medias from each service
|
// }).then((response) => console.log(response.json()))
|
||||||
// const promises = serviceUrls.map((service: serviceItem) => {
|
|
||||||
// return fetch(`${service.url}/api/v3/calendar`, {
|
|
||||||
// method: 'GET',
|
|
||||||
// headers: {
|
|
||||||
// 'Content-Type': 'application/json',
|
|
||||||
// 'X-Api-Key': service.apiKey,
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// // Wait for all the promises to resolve
|
|
||||||
// Promise.all(promises).then((responses) => {
|
|
||||||
// // Get the medias from each service
|
|
||||||
// const medias = responses.map((response) => {
|
|
||||||
// return response.json();
|
|
||||||
// });
|
|
||||||
// // Set the medias
|
|
||||||
// setMedias(medias);
|
|
||||||
// }
|
|
||||||
// );
|
// );
|
||||||
// }, []);
|
fetch('http://server:8989/api/calendar?apikey=ea736455118146fea297e6c7465205ce').then(
|
||||||
|
(response) => {
|
||||||
|
response.json().then((data) => setMedias(data));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, [config.services]);
|
||||||
|
|
||||||
|
if (medias === undefined) {
|
||||||
|
return <div>ok</div>;
|
||||||
|
}
|
||||||
|
|
||||||
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) => {
|
||||||
|
const date = new Date(media.airDate);
|
||||||
|
return date.getDate() === day;
|
||||||
|
});
|
||||||
|
if (filtered.length === 0) {
|
||||||
|
return <div>{day}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
if (match > -1) {
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -91,12 +84,10 @@ function DayComponent(props: any) {
|
|||||||
opened={opened}
|
opened={opened}
|
||||||
target={day}
|
target={day}
|
||||||
>
|
>
|
||||||
<MediaDisplay media={medias[match]} />
|
<MediaDisplay media={filtered[0]} />
|
||||||
</Popover>
|
</Popover>
|
||||||
</Indicator>
|
</Indicator>
|
||||||
</Center>
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
return <div>{day}</div>;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -145,9 +145,11 @@ export function Header({ links }: HeaderResponsiveProps) {
|
|||||||
onClose={() => toggleOpened()}
|
onClose={() => toggleOpened()}
|
||||||
position="right"
|
position="right"
|
||||||
>
|
>
|
||||||
|
{opened ?? (
|
||||||
<Center>
|
<Center>
|
||||||
<CalendarComponent />
|
<CalendarComponent />
|
||||||
</Center>
|
</Center>
|
||||||
|
)}
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</Container>
|
</Container>
|
||||||
</Head>
|
</Head>
|
||||||
|
|||||||
Reference in New Issue
Block a user