mirror of
				https://github.com/karl0ss/homepage.git
				synced 2025-11-04 08:20:58 +00:00 
			
		
		
		
	Fix: show recurring and multi-day events (#2451)
This commit is contained in:
		
							parent
							
								
									0a3d552114
								
							
						
					
					
						commit
						a72ccb6d27
					
				
							
								
								
									
										7
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -32,6 +32,7 @@
 | 
				
			|||||||
        "react-i18next": "^11.18.6",
 | 
					        "react-i18next": "^11.18.6",
 | 
				
			||||||
        "react-icons": "^4.4.0",
 | 
					        "react-icons": "^4.4.0",
 | 
				
			||||||
        "recharts": "^2.7.2",
 | 
					        "recharts": "^2.7.2",
 | 
				
			||||||
 | 
					        "rrule": "^2.8.1",
 | 
				
			||||||
        "swr": "^1.3.0",
 | 
					        "swr": "^1.3.0",
 | 
				
			||||||
        "systeminformation": "^5.17.12",
 | 
					        "systeminformation": "^5.17.12",
 | 
				
			||||||
        "tough-cookie": "^4.1.2",
 | 
					        "tough-cookie": "^4.1.2",
 | 
				
			||||||
@ -5501,9 +5502,9 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/rrule": {
 | 
					    "node_modules/rrule": {
 | 
				
			||||||
      "version": "2.7.2",
 | 
					      "version": "2.8.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.7.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.8.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-NkBsEEB6FIZOZ3T8frvEBOB243dm46SPufpDckY/Ap/YH24V1zLeMmDY8OA10lk452NdrF621+ynDThE7FQU2A==",
 | 
					      "integrity": "sha512-hM3dHSBMeaJ0Ktp7W38BJZ7O1zOgaFEsn41PDk+yHoEtfLV+PoJt9E9xAlZiWgf/iqEqionN0ebHFZIDAp+iGw==",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "tslib": "^2.4.0"
 | 
					        "tslib": "^2.4.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
				
			|||||||
@ -34,6 +34,7 @@
 | 
				
			|||||||
    "react-i18next": "^11.18.6",
 | 
					    "react-i18next": "^11.18.6",
 | 
				
			||||||
    "react-icons": "^4.4.0",
 | 
					    "react-icons": "^4.4.0",
 | 
				
			||||||
    "recharts": "^2.7.2",
 | 
					    "recharts": "^2.7.2",
 | 
				
			||||||
 | 
					    "rrule": "^2.8.1",
 | 
				
			||||||
    "swr": "^1.3.0",
 | 
					    "swr": "^1.3.0",
 | 
				
			||||||
    "systeminformation": "^5.17.12",
 | 
					    "systeminformation": "^5.17.12",
 | 
				
			||||||
    "tough-cookie": "^4.1.2",
 | 
					    "tough-cookie": "^4.1.2",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										9
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										9
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							@ -77,6 +77,9 @@ dependencies:
 | 
				
			|||||||
  recharts:
 | 
					  recharts:
 | 
				
			||||||
    specifier: ^2.7.2
 | 
					    specifier: ^2.7.2
 | 
				
			||||||
    version: 2.7.2(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0)
 | 
					    version: 2.7.2(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0)
 | 
				
			||||||
 | 
					  rrule:
 | 
				
			||||||
 | 
					    specifier: ^2.8.1
 | 
				
			||||||
 | 
					    version: 2.8.1
 | 
				
			||||||
  swr:
 | 
					  swr:
 | 
				
			||||||
    specifier: ^1.3.0
 | 
					    specifier: ^1.3.0
 | 
				
			||||||
    version: 1.3.0(react@18.2.0)
 | 
					    version: 1.3.0(react@18.2.0)
 | 
				
			||||||
@ -871,7 +874,7 @@ packages:
 | 
				
			|||||||
    resolution: {integrity: sha512-wlQwcF0fl4eLclyGdncF9rcNNq0ipRYZGagG6h3LVgRXvCWE1fdMUaCLXwfC9YWoz9jKKbjQAq7TpO2Y3yrvmA==}
 | 
					    resolution: {integrity: sha512-wlQwcF0fl4eLclyGdncF9rcNNq0ipRYZGagG6h3LVgRXvCWE1fdMUaCLXwfC9YWoz9jKKbjQAq7TpO2Y3yrvmA==}
 | 
				
			||||||
    dependencies:
 | 
					    dependencies:
 | 
				
			||||||
      ical-date-parser: 4.0.0
 | 
					      ical-date-parser: 4.0.0
 | 
				
			||||||
      rrule: 2.7.2
 | 
					      rrule: 2.8.1
 | 
				
			||||||
    dev: false
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /call-bind@1.0.2:
 | 
					  /call-bind@1.0.2:
 | 
				
			||||||
@ -3552,8 +3555,8 @@ packages:
 | 
				
			|||||||
    dependencies:
 | 
					    dependencies:
 | 
				
			||||||
      glob: 7.2.3
 | 
					      glob: 7.2.3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /rrule@2.7.2:
 | 
					  /rrule@2.8.1:
 | 
				
			||||||
    resolution: {integrity: sha512-NkBsEEB6FIZOZ3T8frvEBOB243dm46SPufpDckY/Ap/YH24V1zLeMmDY8OA10lk452NdrF621+ynDThE7FQU2A==}
 | 
					    resolution: {integrity: sha512-hM3dHSBMeaJ0Ktp7W38BJZ7O1zOgaFEsn41PDk+yHoEtfLV+PoJt9E9xAlZiWgf/iqEqionN0ebHFZIDAp+iGw==}
 | 
				
			||||||
    dependencies:
 | 
					    dependencies:
 | 
				
			||||||
      tslib: 2.5.0
 | 
					      tslib: 2.5.0
 | 
				
			||||||
    dev: false
 | 
					    dev: false
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ import { DateTime } from "luxon";
 | 
				
			|||||||
import { parseString } from "cal-parser";
 | 
					import { parseString } from "cal-parser";
 | 
				
			||||||
import { useEffect } from "react";
 | 
					import { useEffect } from "react";
 | 
				
			||||||
import { useTranslation } from "next-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					import { RRule } from "rrule";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import useWidgetAPI from "../../../utils/proxy/use-widget-api";
 | 
					import useWidgetAPI from "../../../utils/proxy/use-widget-api";
 | 
				
			||||||
import Error from "../../../components/services/widget/error";
 | 
					import Error from "../../../components/services/widget/error";
 | 
				
			||||||
@ -22,15 +23,15 @@ 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;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const eventsToAdd = {};
 | 
					    const eventsToAdd = {};
 | 
				
			||||||
    const events = parsedIcal?.getEventsBetweenDates(
 | 
					    const events = parsedIcal?.getEventsBetweenDates(startDate.toJSDate(), endDate.toJSDate());
 | 
				
			||||||
      DateTime.fromISO(params.start).toJSDate(),
 | 
					 | 
				
			||||||
      DateTime.fromISO(params.end).toJSDate(),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    events?.forEach((event) => {
 | 
					    events?.forEach((event) => {
 | 
				
			||||||
      let title = `${event?.summary?.value}`;
 | 
					      let title = `${event?.summary?.value}`;
 | 
				
			||||||
@ -38,16 +39,31 @@ export default function Integration({ config, params, setEvents, hideErrors }) {
 | 
				
			|||||||
        title = `${config.name}: ${title}`;
 | 
					        title = `${config.name}: ${title}`;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      event.matchingDates.forEach((date) => {
 | 
					      const eventToAdd = (date, i, type) => {
 | 
				
			||||||
        eventsToAdd[event?.uid?.value] = {
 | 
					        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,
 | 
					            title,
 | 
				
			||||||
          date: DateTime.fromJSDate(date),
 | 
					            date: DateTime.fromJSDate(date).plus({ days: j }),
 | 
				
			||||||
            color: config?.color ?? "zinc",
 | 
					            color: config?.color ?? "zinc",
 | 
				
			||||||
            isCompleted: DateTime.fromJSDate(date) < DateTime.now(),
 | 
					            isCompleted: DateTime.fromJSDate(date) < DateTime.now(),
 | 
				
			||||||
            additional: event.location?.value,
 | 
					            additional: event.location?.value,
 | 
				
			||||||
            type: "ical",
 | 
					            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 }));
 | 
					    setEvents((prevEvents) => ({ ...prevEvents, ...eventsToAdd }));
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user