Last Updated: 6/9/2026
Editing Events
Modify existing calendar events from ZCal Buddy, including updating event details, converting between event types, and managing Zoom meetings. You can add a Zoom meeting to an offline event, remove a meeting from an event, or change meeting settings.
Prerequisites
- Zoom account connected to ZCal Buddy
- Write access to the event’s calendar (
canWrite == true) - Internet connection for API calls
- Valid event ID and calendar ID
Opening the Event Editor
From Event Details
- Tap an event card in the widget to open event details
- Tap the Edit button in the top-right corner
- The app opens
EditEventScreenwith the event data pre-filled
The screen receives event data via intent extras or from the selected event object:
val selectedEvent = events.value.firstOrNull { event ->
event.eventId == eventId &&
(eventCalendarId.isNullOrBlank() || event.calendarId == eventCalendarId)
}From the App
- Open ZCal Buddy
- Navigate to an event’s details screen
- Tap Edit
Edit Form Fields
The edit form displays all event properties with current values pre-filled:
Event Name
The Event Name field shows the current event title. Edit this to change the event summary. This updates both the calendar event and, if it’s a Zoom Meeting, the meeting topic.
Event Type Conversion
The Event Type dropdown allows you to convert between “Offline” and “Zoom Meeting” types. The initial value is determined by:
val eventType = remember {
mutableStateOf(
event?.eventType
?: if (zoomUrl.isNullOrBlank()) "Offline" else "Zoom Meeting"
)
}Converting to Offline: When you change from “Zoom Meeting” to “Offline”, the app deletes the associated Zoom meeting and removes the join URL from the calendar event.
Converting to Zoom Meeting: When you change from “Offline” to “Zoom Meeting”, the app creates a new Zoom meeting and adds the join URL to the calendar event.
Date and Time
All date and time fields are editable:
- Start Date: Tap to open date picker
- Start Time: Tap to open time picker (hidden for all-day events)
- End Date: Tap to open date picker
- End Time: Tap to open time picker (hidden for all-day events)
- All Day: Toggle to switch between timed and all-day events
- Time Zone: Text field showing the event’s time zone
When you change the start date, the end date automatically updates to match:
onStartDateChange = { newDate ->
startDate.value = newDate
endDate.value = newDate
}Invitees
The invitees editor shows current attendees from event?.attendees. You can:
- Add new invitees by entering an email and tapping Add
- Remove invitees by tapping Remove next to their email
- The list prevents duplicate emails using case-insensitive comparison
The invitees list is initialized with existing attendees:
val invitees = remember { mutableStateOf(event?.attendees ?: emptyList()) }Location and Description
Location: Text field for event location. Pre-filled with event?.location.
Description: Text field for event notes. Pre-filled with event?.description.
For Zoom Meeting events, these fields are included in the calendar event. When converting to Offline, the app clears these fields:
if (selected == "Offline") {
eventLocation.value = ""
eventDescription.value = ""
}Handling Event Type Conversion
The app performs different operations based on whether you’re adding, removing, or keeping a Zoom meeting:
Removing a Zoom Meeting
When the original event had a Zoom URL (originalWasZoom == true) but the new type is “Offline” (newIsZoom == false):
val meetingId = event?.meetingId ?: extractMeetingIdFromZoomUrl(zoomUrl)
if (!meetingId.isNullOrBlank()) {
authRepository.deleteZoomMeeting(
accessToken = accessToken,
meetingId = meetingId
)
}The app extracts the meeting ID from the event’s meetingId property or parses it from the Zoom URL using the regex /j/(\d+). It then calls the Zoom API to delete the meeting: DELETE https://api.zoom.us/v2/meetings/{meetingId}.
The final Zoom URL is set to null, removing the meeting link from the calendar event.
Adding a Zoom Meeting
When the original event didn’t have a Zoom URL (originalWasZoom == false) but the new type is “Zoom Meeting” (newIsZoom == true):
val meetingResponse = authRepository.createZoomMeeting(
accessToken = accessToken,
title = eventTitle.value,
startDate = mmDdYyyyToIso(startDate.value),
startTime24 = startTime.value.to24Hour(),
endTime24 = endTime.value.to24Hour(),
timeZone = timeZone.value,
usePmi = false,
requirePasscode = true,
passcode = "123456",
waitingRoom = false,
authenticatedUsersOnly = false,
aiCompanion = false
)The app creates a new Zoom meeting with default settings:
usePmi:false(generate new meeting ID)requirePasscode:truepasscode:"123456"waitingRoom:falseauthenticatedUsersOnly:falseaiCompanion:false
The API returns a join_url which becomes the event’s Zoom URL.
Keeping Existing Meeting
When both the original and new event types match (both Zoom Meeting or both Offline), the Zoom URL remains unchanged. The app doesn’t create or delete meetings—it only updates the calendar event details.
Saving Changes
Tap Save Changes to update the event. The app performs these steps:
Step 1: Validate Inputs
The app checks for required data:
if (eventId.isBlank() || calendarId.isBlank()) {
return@withContext "Missing event ID or calendar ID."
}It also retrieves a valid access token, refreshing if necessary.
Step 2: Handle Meeting Changes
Based on the event type conversion logic above, the app:
- Deletes the old Zoom meeting if converting to Offline
- Creates a new Zoom meeting if converting to Zoom Meeting
- Keeps the existing URL if the type hasn’t changed
Step 3: Update Calendar Event
The app calls updateCalendarEvent with all event details:
authRepository.updateCalendarEvent(
accessToken = accessToken,
calendarId = calendarId,
eventId = eventId,
title = eventTitle.value,
allDay = allDay.value,
startDate = startDate.value,
startTime24 = startTime.value.to24Hour(),
endDate = endDate.value,
endTime24 = endTime.value.to24Hour(),
timeZone = timeZone.value,
description = if (newIsZoom) eventDescription.value else "",
location = if (newIsZoom) eventLocation.value else "",
zoomJoinUrl = finalZoomUrl,
attendees = invitees.value,
eventType = eventType.value
)This sends a PATCH request to https://api.zoom.us/v2/calendars/{calendarId}/events/{eventId}?sendUpdates=all. The sendUpdates=all parameter ensures all attendees receive update notifications.
Note that description and location are only included when newIsZoom == true. For Offline events, these fields are cleared.
Step 4: Sync and Refresh
After a successful update:
- The app refreshes the calendar from Zoom’s API
- Local storage is updated with the refreshed events
- The widget refreshes via
forceWidgetRefresh(context) - The screen returns to the home screen
The status message changes from “Saving event…” to “Event saved.”
Edit Permissions
The app checks write permissions before allowing edits. The canWrite property on CalendarAccount determines if you can modify events:
val canWrite: Boolean
get() = accessRole.equals("owner", true) ||
accessRole.equals("writer", true)If you don’t have write access to the event’s calendar, the edit operation will fail with an API error. The app doesn’t pre-check permissions in the UI—it relies on the API to enforce access control.
Verify Changes
After saving changes:
- Check event details: Tap the event in the widget to view updated details
- Verify meeting changes: If you added or removed a Zoom meeting, check that the “Join Zoom” button appears or disappears accordingly
- Check Zoom app: For meeting changes, open the Zoom app and verify the meeting list reflects your changes
- Verify attendee updates: If you added or removed invitees, they should receive calendar notifications (controlled by
sendUpdates=all)
Troubleshooting Edit Issues
“Missing event ID or calendar ID.”
The app couldn’t identify which event to update. This happens if:
- The event was deleted before you opened the editor
- The event data wasn’t passed correctly to the edit screen
Return to the home screen and try opening the event again.
“No saved Zoom access token. Connect Zoom again.”
Your Zoom connection expired. Tap Connect Zoom on the home screen to re-authenticate, then try editing again.
Changes saved but widget doesn’t update
The calendar event was updated successfully but the widget hasn’t refreshed. Try:
- Wait 15 seconds for the automatic refresh
- Tap the refresh button (↻) in the widget header
- Open the app to trigger a manual sync
Meeting deletion failed but event updated
The calendar event was updated but the Zoom meeting wasn’t deleted. This can happen if:
- The meeting ID couldn’t be extracted from the URL
- The meeting was already deleted
- You don’t have permission to delete the meeting
The calendar event will show as “Offline” but the old meeting may still exist in Zoom. Manually delete it from the Zoom app if needed.
Meeting creation failed but event updated
The calendar event was updated but the new Zoom meeting wasn’t created. Common causes:
- Network issues during meeting creation
- Zoom API rate limiting
- Invalid meeting settings
Edit the event again and try converting to Zoom Meeting again. The app will attempt to create a new meeting.
Attendees not receiving updates
The app sends sendUpdates=all with every update, which should notify all attendees. If they’re not receiving notifications:
- Check that their email addresses are correct
- Verify they haven’t disabled calendar notifications in their Zoom settings
- Confirm the Zoom API accepted the attendee list (check for API errors)
Time zone changes not reflected
If you changed the time zone but the event shows at the wrong time:
- The widget displays events in your device’s local time zone
- The event is stored with the time zone you specified
- Other attendees see the event in their local time zones
- Verify the time zone field shows the correct value
Meeting Settings Limitations
When converting an event to a Zoom Meeting via the edit screen, the app uses default meeting settings:
- Passcode required: Yes (default: “123456”)
- Waiting room: Disabled
- PMI: Not used (generates new meeting ID)
- Authenticated users only: Disabled
- AI Companion: Disabled
These defaults are hardcoded in the edit flow. To create a meeting with custom settings, delete the event and recreate it using the event creation screen, which provides full meeting configuration options.
What’s Next
After editing events, you may want to view full event details including attendee lists and RSVP status. See Viewing Event Details to learn how to access comprehensive event information and join Zoom meetings directly from the details screen.