Skip to content

Commit

Permalink
Fix: show recurring and multi-day events (#2451)
Browse files Browse the repository at this point in the history
  • Loading branch information
denispapec authored Dec 10, 2023
1 parent 0a3d552 commit a72ccb6
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 21 deletions.
7 changes: 4 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"react-i18next": "^11.18.6",
"react-icons": "^4.4.0",
"recharts": "^2.7.2",
"rrule": "^2.8.1",
"swr": "^1.3.0",
"systeminformation": "^5.17.12",
"tough-cookie": "^4.1.2",
Expand Down
9 changes: 6 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 31 additions & 15 deletions src/widgets/calendar/integrations/ical.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { DateTime } from "luxon";
import { parseString } from "cal-parser";
import { useEffect } from "react";
import { useTranslation } from "next-i18next";
import { RRule } from "rrule";

import useWidgetAPI from "../../../utils/proxy/use-widget-api";
import Error from "../../../components/services/widget/error";
Expand All @@ -22,32 +23,47 @@ export default function Integration({ config, params, setEvents, hideErrors }) {
}
}

if (icalError || !parsedIcal) {
const startDate = DateTime.fromISO(params.start);
const endDate = DateTime.fromISO(params.end);

if (icalError || !parsedIcal || !startDate.isValid || !endDate.isValid) {
return;
}

const eventsToAdd = {};
const events = parsedIcal?.getEventsBetweenDates(
DateTime.fromISO(params.start).toJSDate(),
DateTime.fromISO(params.end).toJSDate(),
);
const events = parsedIcal?.getEventsBetweenDates(startDate.toJSDate(), endDate.toJSDate());

events?.forEach((event) => {
let title = `${event?.summary?.value}`;
if (config?.params?.showName) {
title = `${config.name}: ${title}`;
}

event.matchingDates.forEach((date) => {
eventsToAdd[event?.uid?.value] = {
title,
date: DateTime.fromJSDate(date),
color: config?.color ?? "zinc",
isCompleted: DateTime.fromJSDate(date) < DateTime.now(),
additional: event.location?.value,
type: "ical",
};
});
const eventToAdd = (date, i, type) => {
const duration = event.dtend.value - event.dtstart.value;
const days = duration / (1000 * 60 * 60 * 24);

for (let j = 0; j < days; j += 1) {
eventsToAdd[`${event?.uid?.value}${i}${j}${type}`] = {
title,
date: DateTime.fromJSDate(date).plus({ days: j }),
color: config?.color ?? "zinc",
isCompleted: DateTime.fromJSDate(date) < DateTime.now(),
additional: event.location?.value,
type: "ical",
};
}
};

if (event?.recurrenceRule?.options) {
const rule = new RRule(event.recurrenceRule.options);
const recurringEvents = rule.between(startDate.toJSDate(), endDate.toJSDate());

recurringEvents.forEach((date, i) => eventToAdd(date, i, "recurring"));
return;
}

event.matchingDates.forEach((date, i) => eventToAdd(date, i, "single"));
});

setEvents((prevEvents) => ({ ...prevEvents, ...eventsToAdd }));
Expand Down

0 comments on commit a72ccb6

Please sign in to comment.