2023-04-24 21:39:04 +02:00
|
|
|
import { useMantineTheme } from '@mantine/core';
|
2022-12-11 14:11:25 +01:00
|
|
|
import { Calendar } from '@mantine/dates';
|
2023-05-15 17:40:59 +09:00
|
|
|
import { IconCalendarTime } from '@tabler/icons-react';
|
2023-01-31 12:53:32 +09:00
|
|
|
import { i18n } from 'next-i18next';
|
2022-12-11 14:11:25 +01:00
|
|
|
import { useState } from 'react';
|
2023-06-10 18:00:24 +02:00
|
|
|
import { api } from '~/utils/api';
|
|
|
|
|
import { useEditModeStore } from '../../components/Dashboard/Views/useEditModeStore';
|
2022-12-16 21:01:06 +01:00
|
|
|
import { useConfigContext } from '../../config/provider';
|
2022-12-18 21:21:23 +01:00
|
|
|
import { defineWidget } from '../helper';
|
|
|
|
|
import { IWidget } from '../widgets';
|
2022-12-11 14:11:25 +01:00
|
|
|
import { CalendarDay } from './CalendarDay';
|
2023-04-24 21:39:04 +02:00
|
|
|
import { getBgColorByDateAndTheme } from './bg-calculator';
|
2022-12-11 14:11:25 +01:00
|
|
|
import { MediasType } from './type';
|
|
|
|
|
|
2022-12-18 21:21:23 +01:00
|
|
|
const definition = defineWidget({
|
|
|
|
|
id: 'calendar',
|
|
|
|
|
icon: IconCalendarTime,
|
|
|
|
|
options: {
|
2023-06-28 19:59:25 +09:00
|
|
|
hideWeekDays: {
|
|
|
|
|
type: 'switch',
|
|
|
|
|
defaultValue: true,
|
|
|
|
|
},
|
2023-02-06 01:09:11 +09:00
|
|
|
useSonarrv4: {
|
|
|
|
|
type: 'switch',
|
|
|
|
|
defaultValue: false,
|
|
|
|
|
},
|
2022-12-18 21:21:23 +01:00
|
|
|
sundayStart: {
|
|
|
|
|
type: 'switch',
|
|
|
|
|
defaultValue: false,
|
|
|
|
|
},
|
2023-01-11 08:44:14 +09:00
|
|
|
radarrReleaseType: {
|
|
|
|
|
type: 'select',
|
|
|
|
|
defaultValue: 'inCinemas',
|
|
|
|
|
data: [
|
|
|
|
|
{ label: 'In Cinemas', value: 'inCinemas' },
|
|
|
|
|
{ label: 'Physical', value: 'physicalRelease' },
|
|
|
|
|
{ label: 'Digital', value: 'digitalRelease' },
|
|
|
|
|
],
|
|
|
|
|
},
|
2023-07-11 23:29:14 +02:00
|
|
|
fontSize:{
|
|
|
|
|
type: 'select',
|
|
|
|
|
defaultValue: 'xs',
|
|
|
|
|
data: [
|
|
|
|
|
{ label: 'Extra Small', value: 'xs' },
|
|
|
|
|
{ label: 'Small', value: 'sm' },
|
|
|
|
|
{ label: 'Medium', value: 'md' },
|
|
|
|
|
{ label: 'Large', value: 'lg' },
|
|
|
|
|
{ label: 'Extra Large', value: 'xl' },
|
|
|
|
|
]
|
|
|
|
|
},
|
2022-12-18 21:21:23 +01:00
|
|
|
},
|
2022-12-18 21:50:08 +01:00
|
|
|
gridstack: {
|
2023-01-08 12:41:55 +09:00
|
|
|
minWidth: 2,
|
|
|
|
|
minHeight: 2,
|
2022-12-18 21:50:08 +01:00
|
|
|
maxWidth: 12,
|
|
|
|
|
maxHeight: 12,
|
|
|
|
|
},
|
2022-12-18 21:21:23 +01:00
|
|
|
component: CalendarTile,
|
|
|
|
|
});
|
|
|
|
|
|
2023-02-22 22:04:09 +01:00
|
|
|
export type ICalendarWidget = IWidget<(typeof definition)['id'], typeof definition>;
|
2022-12-18 21:21:23 +01:00
|
|
|
|
2022-12-19 18:26:04 +01:00
|
|
|
interface CalendarTileProps {
|
2022-12-19 17:03:39 +01:00
|
|
|
widget: ICalendarWidget;
|
2022-12-11 14:11:25 +01:00
|
|
|
}
|
|
|
|
|
|
2022-12-19 18:26:04 +01:00
|
|
|
function CalendarTile({ widget }: CalendarTileProps) {
|
2023-07-11 23:29:14 +02:00
|
|
|
const { colorScheme, radius } = useMantineTheme();
|
2022-12-11 14:11:25 +01:00
|
|
|
const { name: configName } = useConfigContext();
|
|
|
|
|
const [month, setMonth] = useState(new Date());
|
2023-05-15 16:20:48 +09:00
|
|
|
const isEditMode = useEditModeStore((x) => x.enabled);
|
2022-12-11 14:11:25 +01:00
|
|
|
|
2023-06-10 18:00:24 +02:00
|
|
|
const { data: medias } = api.calendar.medias.useQuery(
|
|
|
|
|
{
|
|
|
|
|
configName: configName!,
|
|
|
|
|
month: month.getMonth() + 1,
|
|
|
|
|
year: month.getFullYear(),
|
|
|
|
|
options: { useSonarrv4: widget.properties.useSonarrv4 },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
staleTime: 1000 * 60 * 60 * 5,
|
|
|
|
|
enabled: isEditMode === false,
|
|
|
|
|
}
|
|
|
|
|
);
|
2022-12-11 14:11:25 +01:00
|
|
|
|
|
|
|
|
return (
|
2023-04-17 14:48:04 +09:00
|
|
|
<Calendar
|
|
|
|
|
defaultDate={new Date()}
|
|
|
|
|
onPreviousMonth={setMonth}
|
|
|
|
|
onNextMonth={setMonth}
|
2023-07-11 23:29:14 +02:00
|
|
|
size={widget.properties.fontSize}
|
2023-04-17 14:48:04 +09:00
|
|
|
locale={i18n?.resolvedLanguage ?? 'en'}
|
|
|
|
|
firstDayOfWeek={widget.properties.sundayStart ? 0 : 1}
|
2023-07-17 00:26:10 +02:00
|
|
|
hideWeekdays={widget.properties.hideWeekDays}
|
2023-07-11 23:29:14 +02:00
|
|
|
style={{ position: 'relative' }}
|
2023-04-17 14:48:04 +09:00
|
|
|
date={month}
|
|
|
|
|
maxLevel="month"
|
|
|
|
|
hasNextLevel={false}
|
|
|
|
|
styles={{
|
|
|
|
|
calendarHeader: {
|
|
|
|
|
maxWidth: 'inherit',
|
2023-07-11 23:29:14 +02:00
|
|
|
marginBottom: '0.35rem !important',
|
|
|
|
|
},
|
|
|
|
|
calendarHeaderLevel: {
|
|
|
|
|
height:"100%",
|
|
|
|
|
},
|
|
|
|
|
calendarHeaderControl:{
|
|
|
|
|
height:"100%",
|
2023-04-17 14:48:04 +09:00
|
|
|
},
|
|
|
|
|
calendar: {
|
|
|
|
|
height: '100%',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
width: '100%',
|
|
|
|
|
},
|
|
|
|
|
monthLevelGroup: {
|
|
|
|
|
height: '100%',
|
|
|
|
|
},
|
|
|
|
|
monthLevel: {
|
|
|
|
|
height: '100%',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
width: '100%',
|
|
|
|
|
},
|
2023-07-11 23:29:14 +02:00
|
|
|
monthCell:{
|
|
|
|
|
textAlign:'center',
|
|
|
|
|
},
|
2023-04-17 14:48:04 +09:00
|
|
|
month: {
|
|
|
|
|
flex: 1,
|
|
|
|
|
},
|
2023-07-11 23:29:14 +02:00
|
|
|
day:{
|
2023-07-17 00:26:10 +02:00
|
|
|
borderRadius: ['xs','sm'].includes(widget.properties.fontSize) ? radius.md : radius.lg,
|
2023-07-11 23:29:14 +02:00
|
|
|
},
|
2023-04-17 14:48:04 +09:00
|
|
|
}}
|
2023-04-24 21:39:04 +02:00
|
|
|
getDayProps={(date) => ({
|
|
|
|
|
bg: getBgColorByDateAndTheme(colorScheme, date),
|
|
|
|
|
})}
|
2023-04-17 14:48:04 +09:00
|
|
|
renderDay={(date) => (
|
2023-07-11 23:29:14 +02:00
|
|
|
<CalendarDay date={date} medias={getReleasedMediasForDate(medias, date, widget)} size={widget.properties.fontSize} />
|
2023-04-17 14:48:04 +09:00
|
|
|
)}
|
|
|
|
|
/>
|
2022-12-11 14:11:25 +01:00
|
|
|
);
|
2022-12-18 21:21:23 +01:00
|
|
|
}
|
2022-12-11 14:11:25 +01:00
|
|
|
|
2023-01-11 08:44:14 +09:00
|
|
|
const getReleasedMediasForDate = (
|
|
|
|
|
medias: MediasType | undefined,
|
|
|
|
|
date: Date,
|
|
|
|
|
widget: ICalendarWidget
|
|
|
|
|
): MediasType => {
|
2023-02-22 22:04:09 +01:00
|
|
|
const { radarrReleaseType } = widget.properties;
|
2023-01-11 08:44:14 +09:00
|
|
|
|
2022-12-11 14:11:25 +01:00
|
|
|
const books =
|
|
|
|
|
medias?.books.filter((b) => new Date(b.releaseDate).toDateString() === date.toDateString()) ??
|
|
|
|
|
[];
|
|
|
|
|
const movies =
|
2023-01-11 08:44:14 +09:00
|
|
|
medias?.movies.filter(
|
|
|
|
|
(m) => new Date(m[radarrReleaseType]).toDateString() === date.toDateString()
|
|
|
|
|
) ?? [];
|
2022-12-11 14:11:25 +01:00
|
|
|
const musics =
|
|
|
|
|
medias?.musics.filter((m) => new Date(m.releaseDate).toDateString() === date.toDateString()) ??
|
|
|
|
|
[];
|
|
|
|
|
const tvShows =
|
|
|
|
|
medias?.tvShows.filter(
|
|
|
|
|
(tv) => new Date(tv.airDateUtc).toDateString() === date.toDateString()
|
|
|
|
|
) ?? [];
|
|
|
|
|
const totalCount = medias ? books.length + movies.length + musics.length + tvShows.length : 0;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
books,
|
|
|
|
|
movies,
|
|
|
|
|
musics,
|
|
|
|
|
tvShows,
|
|
|
|
|
totalCount,
|
|
|
|
|
};
|
|
|
|
|
};
|
2022-12-18 21:21:23 +01:00
|
|
|
|
|
|
|
|
export default definition;
|