Skip to content

Feat: Support recurrence exceptions#281

Merged
lukasdotcom merged 5 commits into
nextcloud:mainfrom
MarcelRobitaille:support_recurrence
Sep 24, 2025
Merged

Feat: Support recurrence exceptions#281
lukasdotcom merged 5 commits into
nextcloud:mainfrom
MarcelRobitaille:support_recurrence

Conversation

@MarcelRobitaille
Copy link
Copy Markdown
Contributor

@MarcelRobitaille MarcelRobitaille commented Sep 15, 2025

See MarcelRobitaille#38

The app currently does not properly support recurring events. If you create a daily event and then for a single instance add an exception like changing the time, the event will show up twice that day, instead of once with the modified time.

Some notes about recurring events:

  • The "parent" event and all "exceptions" (events that modify specific instances of the recurring event) should go in the same BEGIN:VCALENDAR (same database entry)
  • The exceptions should have the RECURRENCE-ID set to the original start time of the instance they are excepting (not the start time of the parent or the ID of the parent).

Comment thread lib/Service/GoogleCalendarAPIService.php Outdated
@lukasdotcom
Copy link
Copy Markdown
Member

Hi @MarcelRobitaille,

Thanks for the pr. I tried it out on one of my calendars and it seems to work great 🎉. You can run composer cs:fix to fix the failing test.

Copy link
Copy Markdown
Member

@lukasdotcom lukasdotcom left a comment

Choose a reason for hiding this comment

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

Looks good except some small nits.

Comment thread lib/Service/GoogleCalendarAPIService.php Outdated
Comment thread lib/Service/GoogleCalendarAPIService.php Outdated
Comment thread lib/Service/GoogleCalendarAPIService.php Outdated
@lukasdotcom lukasdotcom changed the title Support recurrence exceptions Feat: Support recurrence exceptions Sep 17, 2025
Signed-off-by: Marcel Robitaille <mail@marcelrobitaille.me>
Signed-off-by: Marcel Robitaille <mail@marcelrobitaille.me>
@MarcelRobitaille
Copy link
Copy Markdown
Contributor Author

$localEventUpdatedTimestamp = $existingEvent['lastmodified'] ?? 0;
if ($remoteEventUpdatedTimestamp <= $localEventUpdatedTimestamp) {
	continue;
}

Can we somehow store the version of the app the event was created with and update it if the app was upgraded? Otherwise this fix will not apply to existing events.

Signed-off-by: Marcel Robitaille <mail@marcelrobitaille.me>
@lukasdotcom

This comment was marked as outdated.

@MarcelRobitaille
Copy link
Copy Markdown
Contributor Author

Hi @lukasdotcom

Thanks for sharing. I'll look into that bug. Good idea to test it.

Could you please add nextcloud@marcelrobitaille.me instead?

@lukasdotcom
Copy link
Copy Markdown
Member

Hi @lukasdotcom

Thanks for sharing. I'll look into that bug. Good idea to test it.

Could you please add nextcloud@marcelrobitaille.me instead?

There should be an invite email to the company Nextcloud instance that will give you the steps to join. I used the new email you gave (nextcloud@marcelrobitaille.me).

@MarcelRobitaille
Copy link
Copy Markdown
Contributor Author

There should be an invite email to the company Nextcloud instance that will give you the steps to join. I used the new email you gave (nextcloud@marcelrobitaille.me).

I got it. Thanks.

@MarcelRobitaille
Copy link
Copy Markdown
Contributor Author

Hi @lukasdotcom

I also did just find a bug for when one event of a repeated event is cancelled. It currently shows both the cancelled and not cancelled event.

How did you provoke this? If I delete a single event, it shows as cancelled in the calendar.

image

I expect it to work like a normal exception but with STATUS: CANCELLED

@lukasdotcom
Copy link
Copy Markdown
Member

Hi @lukasdotcom

I also did just find a bug for when one event of a repeated event is cancelled. It currently shows both the cancelled and not cancelled event.

How did you provoke this? If I delete a single event, it shows as cancelled in the calendar.
image

I expect it to work like a normal exception but with STATUS: CANCELLED

Sorry for the mistake. It turns out that calendar was just broken in general. It shows the double events in google calendar too 😂

@MarcelRobitaille
Copy link
Copy Markdown
Contributor Author

It turns out that calendar was just broken in general. It shows the double events in google calendar too 😂

I hope dealing with that is out of scope for this addon 😂

@lukasdotcom
Copy link
Copy Markdown
Member

It turns out that calendar was just broken in general. It shows the double events in google calendar too 😂

I hope dealing with that is out of scope for this addon 😂

Yeah that would be out of scope.

Signed-off-by: Marcel Robitaille <mail@marcelrobitaille.me>
Copy link
Copy Markdown
Member

@lukasdotcom lukasdotcom left a comment

Choose a reason for hiding this comment

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

Thanks for the pr this looks good to merge 🚀. Just a small typo I noticed then it can be merged.

Comment on lines +202 to +204
foreach ($exceptions as $candiateException) {
if (($candiateException['recurringEventId'] == $e['id']) && ($candiateException['id'] != $e['id'])) {
$eventData .= $this->generateEventData($candiateException, $exceptions, $ncCalId, $eventColors);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Candidate is misspelled.

Suggested change
foreach ($exceptions as $candiateException) {
if (($candiateException['recurringEventId'] == $e['id']) && ($candiateException['id'] != $e['id'])) {
$eventData .= $this->generateEventData($candiateException, $exceptions, $ncCalId, $eventColors);
foreach ($exceptions as $candidateException) {
if (($candidateException['recurringEventId'] == $e['id']) && ($candidateException['id'] != $e['id'])) {
$eventData .= $this->generateEventData($candidateException, $exceptions, $ncCalId, $eventColors);

Signed-off-by: Marcel Robitaille <mail@marcelrobitaille.me>
@lukasdotcom lukasdotcom merged commit 1901a85 into nextcloud:main Sep 24, 2025
20 checks passed
@MarcelRobitaille MarcelRobitaille deleted the support_recurrence branch September 24, 2025 21:29
@lukasdotcom
Copy link
Copy Markdown
Member

Thank you for the pr. I've now merged it 🎉

@github-actions
Copy link
Copy Markdown

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants