From f0dcfc83c838f6dd114d596fd48e660c2d53078c Mon Sep 17 00:00:00 2001 From: nicktrn <55853254+nicktrn@users.noreply.github.com> Date: Wed, 16 Aug 2023 21:32:04 +0100 Subject: [PATCH] feat: add support for apple travel time (#10660) Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com> --- packages/lib/CalendarService.ts | 27 +++++++++++++++++++++++++++ packages/types/ical.d.ts | 1 + 2 files changed, 28 insertions(+) diff --git a/packages/lib/CalendarService.ts b/packages/lib/CalendarService.ts index 5a310cd72f..c18dec7332 100644 --- a/packages/lib/CalendarService.ts +++ b/packages/lib/CalendarService.ts @@ -60,6 +60,30 @@ function getFileExtension(url: string): string { return fileName.substring(fileName.lastIndexOf(".") + 1); } +// for Apple's Travel Time feature only (for now) +const getTravelDurationInSeconds = (vevent: ICAL.Component, log: typeof logger) => { + const travelDuration: ICAL.Duration = vevent.getFirstPropertyValue("x-apple-travel-duration"); + if (!travelDuration) return 0; + + // we can't rely on this being a valid duration and it's painful to check, so just try and catch if anything throws + try { + const travelSeconds = travelDuration.toSeconds(); + // integer validation as we can never be sure with ical.js + if (!Number.isInteger(travelSeconds)) return 0; + return travelSeconds; + } catch (e) { + log.error("invalid travelDuration?", e); + return 0; + } +}; + +const applyTravelDuration = (event: ICAL.Event, seconds: number) => { + if (seconds <= 0) return event; + // move event start date back by the specified travel time + event.startDate.second -= seconds; + return event; +}; + const convertDate = (date: string): DateArray => dayjs(date) .utc() @@ -387,6 +411,9 @@ export default abstract class BaseCalendarService implements Calendar { } const vtimezone = vcalendar.getFirstSubcomponent("vtimezone"); + // mutate event to consider travel time + applyTravelDuration(event, getTravelDurationInSeconds(vevent, this.log)); + if (event.isRecurring()) { let maxIterations = 365; if (["HOURLY", "SECONDLY", "MINUTELY"].includes(event.getRecurrenceTypes())) { diff --git a/packages/types/ical.d.ts b/packages/types/ical.d.ts index 775460f004..982a4b4552 100644 --- a/packages/types/ical.d.ts +++ b/packages/types/ical.d.ts @@ -168,6 +168,7 @@ declare module "ical.js" { public isNegative: boolean; public icalclass: string; public icaltype: string; + public toSeconds(): number; } export class RecurExpansion {