Skip to content

feat: add support for apple travel time#10660

Merged
zomars merged 6 commits intocalcom:mainfrom
nicktrn:feat/apple-travel-time
Aug 16, 2023
Merged

feat: add support for apple travel time#10660
zomars merged 6 commits intocalcom:mainfrom
nicktrn:feat/apple-travel-time

Conversation

@nicktrn
Copy link
Copy Markdown
Contributor

@nicktrn nicktrn commented Aug 9, 2023

What does this PR do?

Adds support for Apple's Travel Time feature

See JSFiddle for example payload and parsing.

Fixes #10474
/claim #10474

Requirement/Documentation

Type of change

  • New feature (non-breaking change which adds functionality)

How should this be tested?

  1. Add travel time via Apple Calendar
  2. Check if it's now unavailable to book via Cal

Mandatory Tasks

  • Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected.

Checklist

  • I haven't added tests that prove my fix is effective or that my feature works

@vercel
Copy link
Copy Markdown

vercel bot commented Aug 9, 2023

@nicktrn is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Aug 9, 2023

Thank you for following the naming conventions! 🙏

@github-actions github-actions bot added calendar-apps area: calendar, google calendar, outlook, lark, microsoft 365, apple calendar Low priority Created by Linear-GitHub Sync ✨ feature New feature or request 💎 Bounty A bounty on Algora.io labels Aug 9, 2023
@vercel
Copy link
Copy Markdown

vercel bot commented Aug 9, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
ui ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 14, 2023 9:37am

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Aug 9, 2023

📦 Next.js Bundle Analysis for @calcom/web

This analysis was generated by the Next.js Bundle Analysis action. 🤖

This PR introduced no changes to the JavaScript bundle! 🙌

@alishaz-polymath
Copy link
Copy Markdown
Member

Hey @nicktrn Thank you for the PR.
Please make sure to ready it for review once you're happy with the changes. Please ensure you've gone through Contributor's Guide to PR and ensure self-review is done when you push it to be reviewed 🙏

@nicktrn
Copy link
Copy Markdown
Contributor Author

nicktrn commented Aug 9, 2023

Hi @alishaz-polymath Thanks for having a look this quickly, but this is only a draft for now. As you know there are still things to discuss. By the way, ical.js is a pain to work with.

@alishaz-polymath
Copy link
Copy Markdown
Member

Hi @alishaz-polymath Thanks for having a look this quickly, but this is only a draft for now. As you know there are still things to discuss. By the way, ical.js is a pain to work with.

Oh for sure. And yes, iCal.js is painful 😅

Copy link
Copy Markdown
Contributor Author

@nicktrn nicktrn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready for review by a Certified iCal.js Expert ™️

};

const applyTravelDuration = (event: ICAL.Event, seconds: number) => {
if (seconds <= 0) return event;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Negative travel times should be impossible, but better to be safe than sorry


// 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");
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did consider checking if this is indeed an ICAL.Duration, but their helpers are incredibly useless here. Will let any string with P as first or second character pass. See:

https://github.com/kewisch/ical.js/blob/35533497954b2c6e20a902789fe11e95740c3cf6/lib/ical/duration.js#L36-L38

Comment on lines +70 to +72
const travelSeconds = travelDuration.toSeconds();
// integer validation as we can never be sure with ical.js
if (!Number.isInteger(travelSeconds)) return 0;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also rather incredible. There are no type checks in the function and we could be getting a very long random string back instead. I think isInteger() is the best bet here.

return travelSeconds;
} catch (e) {
log.error("[ERROR] invalid travelDuration?", e);
return 0;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in case anything fails. Will actually change the error message quickly, only just realised I replaced it with the proper logger in the end.

public isNegative: boolean;
public icalclass: string;
public icaltype: string;
public toSeconds(): number;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did consider using number | string or even any type here to be accurate, but the rest of the ambient def doesn't do this so I chose not to.

@nicktrn nicktrn marked this pull request as ready for review August 9, 2023 10:59
@alishaz-polymath
Copy link
Copy Markdown
Member

alishaz-polymath commented Aug 9, 2023

I'm wondering if it would be better to have travel time as separate events attached to the primary event, or extend the duration of the event instead (as done in this case) 🤔
My thoughts:

  1. If we extend the duration of the same event, it obviously looks cleaner on the calendar, however, we lose vital information about when an event is supposed to start versus when it shows as blocked. Is there a way we can emphasise/identify right off the first look what the actual event start time is (excluding the adjusted time, that is)?
  2. We could think about linking pre and post meeting travel time as separate events, keeping them linked to the main event, such that if and when the primary event is removed/rescheduled, the necessary changes take place in the travel time events as well. Would this be a better approach? Are there any pitfalls here?

How does Apple Calendar handle this exactly?

cc: @joeauyeung @PeerRich @nicktrn

@nicktrn
Copy link
Copy Markdown
Contributor Author

nicktrn commented Aug 9, 2023

@alishaz-polymath Thanks for reviewing!

I think mutating the ICAL.Event startDate directly is safe and the simplest solution in this case, as we are just checking availability and returning EventBusyDate[], i.e. an array of start/end dates without additional info.

The data is only used for those availability checks and discarded when the function returns, so this should not have any unintended side-effects.

In summary, this will only affect availability of users with linked Apple Calendars who set travel times for specific events.

Apologies if my comments in the related issue confused matters.

This is what it looks like in Calendar on Mac, and this is exactly what we will be blocking:

787430E6-59F1-4263-B4D9-3F95B7ABDD90
(borrowed from the linked Nextcloud Calendar issue)

Copy link
Copy Markdown
Contributor

@zomars zomars left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simple. Non intrusive. And it seems to work. Will test before merging. Thank you for your contribution 🙏 @nicktrn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💎 Bounty A bounty on Algora.io calendar-apps area: calendar, google calendar, outlook, lark, microsoft 365, apple calendar ✨ feature New feature or request Low priority Created by Linear-GitHub Sync

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Apple's Travel Time

3 participants