-
Notifications
You must be signed in to change notification settings - Fork 3
Always add DTEND to VEVENT for iCloud compatibility #154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Always add DTEND to VEVENT for iCloud compatibility #154
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR addresses an iCloud compatibility issue by ensuring DTEND is always added to VEVENT when DTSTART is present. iCloud rejects calendar events with DTSTART but no DTEND, even though this is valid according to the iCalendar specification. The workaround sets DTEND equal to DTSTART when DTEND is missing or invalid, except when DURATION is set (since DURATION and DTEND are mutually exclusive).
Key changes:
- Modified EndTimeHandler to always set DTEND when DTSTART is present and DURATION is not set
- DTEND defaults to DTSTART value when missing or not after DTSTART
- Updated tests to verify the new behavior instead of expecting null DTEND
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| EndTimeHandler.kt | Core logic change to always set DTEND equal to DTSTART when DURATION is not present, addressing iCloud rejection issue |
| EndTimeHandlerTest.kt | Updated test expectations to verify DTEND is now set equal to DTSTART in edge cases, plus added test for DURATION skip condition |
| DurationHandler.kt | Updated comments to reference the iCloud workaround context |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
lib/src/main/kotlin/at/bitfire/synctools/mapping/calendar/handler/EndTimeHandler.kt
Show resolved
Hide resolved
lib/src/main/kotlin/at/bitfire/synctools/mapping/calendar/handler/EndTimeHandler.kt
Outdated
Show resolved
Hide resolved
lib/src/main/kotlin/at/bitfire/synctools/mapping/calendar/handler/EndTimeHandler.kt
Outdated
Show resolved
Hide resolved
lib/src/main/kotlin/at/bitfire/synctools/mapping/calendar/handler/EndTimeHandler.kt
Outdated
Show resolved
Hide resolved
ArnyminerZ
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good
rfc2822
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a local event with an invalid (for instance negative) DURATION won't generate a DTEND even with this PR.
See the comment about the responsibility. This should be clarified first.
lib/src/main/kotlin/at/bitfire/synctools/mapping/calendar/handler/DurationHandler.kt
Outdated
Show resolved
Hide resolved
This comment was marked as resolved.
This comment was marked as resolved.
|
@rfc2822 It's ready for review. I think the code could be prettier with early returns, but I have used the |
Well if its better with other methods of flow control, these should be used. I just meant that it should be clear and easy to understand where the value for dtend comes from. I'll have a look |
|
I was not happy about a few details and thought that they may really come because we have merged the handlers. I tried out with different handlers in #157 and it I think it was easier to understand / test so I have merged it. @sunkup Please have a look at #157 nevertheless and if you see something suspicious, comment and/or create a new issue. |
iCloud rejects VEVENT uploads when DTSTART is set and DTEND is missing - even though it's valid - so as workaround we always add it with the value of DTSTART.
This PR uses the value of DTSTART to set DTEND if:
and either:
Otherwise (DTSTART missing or DURATION present) DTEND will not be set.