Skip to Content
📱 Using the Appediting-events

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

  1. Tap an event card in the widget to open event details
  2. Tap the Edit button in the top-right corner
  3. The app opens EditEventScreen with 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

  1. Open ZCal Buddy
  2. Navigate to an event’s details screen
  3. 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: true
  • passcode: "123456"
  • waitingRoom: false
  • authenticatedUsersOnly: false
  • aiCompanion: 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:

  1. The app refreshes the calendar from Zoom’s API
  2. Local storage is updated with the refreshed events
  3. The widget refreshes via forceWidgetRefresh(context)
  4. 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:

  1. Check event details: Tap the event in the widget to view updated details
  2. Verify meeting changes: If you added or removed a Zoom meeting, check that the “Join Zoom” button appears or disappears accordingly
  3. Check Zoom app: For meeting changes, open the Zoom app and verify the meeting list reflects your changes
  4. 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:

  1. Wait 15 seconds for the automatic refresh
  2. Tap the refresh button (↻) in the widget header
  3. 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.