UNPKG

expo-calendar

Version:

Provides an API for interacting with the device's system calendars, events, reminders, and associated records.

264 lines 12.5 kB
import { createPermissionHook } from 'expo'; import { UnavailabilityError } from 'expo-modules-core'; import { Platform, processColor } from 'react-native'; import InternalExpoCalendar from './ExpoCalendar'; import { stringifyDateValues, stringifyIfDate, getNullableDetailsFields } from './utils'; /** * Represents a calendar attendee object. */ export class ExpoCalendarAttendee extends InternalExpoCalendar.ExpoCalendarAttendee { async update(details) { if (!super.update) { throw new UnavailabilityError('ExpoCalendarAttendee', 'update'); } const nullableDetailsFields = getNullableDetailsFields(details); return super.update(stringifyDateValues(details), nullableDetailsFields); } async delete() { if (!super.delete) { throw new UnavailabilityError('ExpoCalendarAttendee', 'delete'); } await super.delete(); } } /** * Represents a calendar event object that can be accessed and modified using the Expo Calendar Next API. */ export class ExpoCalendarEvent extends InternalExpoCalendar.ExpoCalendarEvent { getOccurrenceSync(recurringEventOptions = {}) { const result = super.getOccurrenceSync(stringifyDateValues(recurringEventOptions)); Object.setPrototypeOf(result, ExpoCalendarEvent.prototype); return result; } async getAttendees() { const attendees = await super.getAttendees(); return attendees.map((attendee) => { Object.setPrototypeOf(attendee, ExpoCalendarAttendee.prototype); return attendee; }); } async createAttendee(attendee) { if (!super.createAttendee) { throw new UnavailabilityError('ExpoCalendarEvent', 'createAttendee'); } const newAttendee = await super.createAttendee(attendee); Object.setPrototypeOf(newAttendee, ExpoCalendarAttendee.prototype); return newAttendee; } async update(details) { const nullableDetailsFields = getNullableDetailsFields(details); return await super.update(stringifyDateValues(details), nullableDetailsFields); } async delete() { await super.delete(); } static async get(eventId) { const event = await InternalExpoCalendar.getEventById(eventId); Object.setPrototypeOf(event, ExpoCalendarEvent.prototype); return event; } } /** * Represents a calendar reminder object that can be accessed and modified using the Expo Calendar Next API. */ export class ExpoCalendarReminder extends InternalExpoCalendar.ExpoCalendarReminder { async update(details) { const nullableDetailsFields = getNullableDetailsFields(details); await super.update(stringifyDateValues(details), nullableDetailsFields); } static async get(reminderId) { const reminder = await InternalExpoCalendar.getReminderById(reminderId); Object.setPrototypeOf(reminder, ExpoCalendarReminder.prototype); return reminder; } } /** * Represents a calendar object that can be accessed and modified using the Expo Calendar Next API. * * This class provides properties and methods for interacting with a specific calendar on the device, * such as retrieving its events, updating its details, and accessing its metadata. */ export class ExpoCalendar extends InternalExpoCalendar.ExpoCalendar { async createEvent(details) { const newEvent = await super.createEvent(stringifyDateValues(details)); Object.setPrototypeOf(newEvent, ExpoCalendarEvent.prototype); return newEvent; } async createReminder(details) { const newReminder = await super.createReminder(stringifyDateValues(details)); Object.setPrototypeOf(newReminder, ExpoCalendarReminder.prototype); return newReminder; } async listEvents(startDate, endDate) { if (!startDate) { throw new Error('listEvents must be called with a startDate (date) to search for events'); } if (!endDate) { throw new Error('listEvents must be called with an endDate (date) to search for events'); } const events = await super.listEvents(stringifyIfDate(startDate), stringifyIfDate(endDate)); return events.map((event) => { Object.setPrototypeOf(event, ExpoCalendarEvent.prototype); return event; }); } async listReminders(startDate = null, endDate = null, status = null) { const reminders = await super.listReminders(startDate ? stringifyIfDate(startDate) : null, endDate ? stringifyIfDate(endDate) : null, status); return reminders.map((reminder) => { Object.setPrototypeOf(reminder, ExpoCalendarReminder.prototype); return reminder; }); } async update(details) { const color = details.color ? processColor(details.color) : undefined; const newDetails = { ...details, color: color || undefined }; return await super.update(newDetails); } async addEventWithForm(options) { if (!super.addEventWithForm) { throw new UnavailabilityError('ExpoCalendar', 'addEventWithForm'); } return super.addEventWithForm(options && stringifyDateValues(options)); } static async get(calendarId) { const calendar = await InternalExpoCalendar.getCalendarById(calendarId); Object.setPrototypeOf(calendar, ExpoCalendar.prototype); return calendar; } } /** * Gets an instance of the default calendar object. * @return An [`ExpoCalendar`](#expocalendar) object that is the user's default calendar. */ export function getDefaultCalendarSync() { if (Platform.OS === 'android' || !InternalExpoCalendar.getDefaultCalendarSync) { throw new UnavailabilityError('Calendar', 'getDefaultCalendar'); } const defaultCalendar = InternalExpoCalendar.getDefaultCalendarSync(); Object.setPrototypeOf(defaultCalendar, ExpoCalendar.prototype); return defaultCalendar; } /** * Gets an array of [`ExpoCalendar`](#expocalendar) shared objects with details about the different calendars stored on the device. * @param entityType __iOS Only.__ Not required, but if defined, filters the returned calendars to * a specific [entity type](#entitytypes). Possible values are `Calendar.EntityTypes.EVENT` (for calendars shown in * the Calendar app) and `Calendar.EntityTypes.REMINDER` (for the Reminders app). * > **Note:** If not defined, you will need both permissions: **CALENDAR** and **REMINDERS**. * @return An array of [`ExpoCalendar`](#expocalendar) shared objects matching the provided entity type (if provided). */ export async function getCalendars(entityType) { if (!InternalExpoCalendar.getCalendars) { throw new UnavailabilityError('Calendar', 'getCalendars'); } const calendars = await InternalExpoCalendar.getCalendars(entityType); return calendars.map((calendar) => { Object.setPrototypeOf(calendar, ExpoCalendar.prototype); return calendar; }); } /** * Creates a new calendar on the device, allowing events to be added later and displayed in the OS Calendar app. * @param details A map of details for the calendar to be created. * @returns An [`ExpoCalendar`](#expocalendar) object representing the newly created calendar. */ export async function createCalendar(details = {}) { const color = details.color ? processColor(details.color) : undefined; const newDetails = { ...details, id: undefined, color: color || undefined }; const createdCalendar = await InternalExpoCalendar.createCalendar(newDetails); Object.setPrototypeOf(createdCalendar, ExpoCalendar.prototype); return createdCalendar; } /** * Presents the OS calendar picker and returns the selected calendar. * @return An [`ExpoCalendar`](#expocalendar) object or `null` when the picker is cancelled. * @platform ios */ export async function presentPicker() { if (!InternalExpoCalendar.presentPicker) { throw new UnavailabilityError('Calendar', 'presentPicker'); } const calendar = await InternalExpoCalendar.presentPicker(); if (calendar) { Object.setPrototypeOf(calendar, ExpoCalendar.prototype); } return calendar; } /** * Lists events from the device's calendar. It can be used to search events in multiple calendars. * > **Note:** If you want to search events in a single calendar, you can use [`ExpoCalendar.listEvents`](#listeventsstartdate-enddate) instead. * @param calendars An array of calendar IDs (`string[]`) or [`ExpoCalendar`](#expocalendar) objects to search for events. * @param startDate The start date of the time range to search for events. * @param endDate The end date of the time range to search for events. * @returns An array of [`ExpoCalendarEvent`](#expocalendarevent) objects representing the events found. */ export async function listEvents(calendars, startDate, endDate) { if (!InternalExpoCalendar.listEvents) { throw new UnavailabilityError('Calendar', 'listEvents'); } const calendarIds = Array.isArray(calendars) ? calendars.map((c) => (typeof c === 'string' ? c : c.id)) : []; return InternalExpoCalendar.listEvents(calendarIds, stringifyIfDate(startDate), stringifyIfDate(endDate)); } /** * Asks the user to grant permissions for accessing user's calendars. * @param writeOnly - On iOS, whether to request write-only access, which allows creating calendar events * without reading existing calendars or events. This does not grant permission to create, update, or delete calendars. * @return A promise that resolves to an object of type [`PermissionResponse`](#permissionresponse). */ export const requestCalendarPermissions = InternalExpoCalendar.requestCalendarPermissions; /** * Checks user's permissions for accessing user's calendars. * @param writeOnly - On iOS, whether to check write-only access, which allows creating calendar events * without reading existing calendars or events. This does not grant permission to create, update, or delete calendars. * @return A promise that resolves to an object of type [`PermissionResponse`](#permissionresponse). */ export const getCalendarPermissions = InternalExpoCalendar.getCalendarPermissions; /** * Asks the user to grant permissions for accessing user's reminders. * @return A promise that resolves to an object of type [`PermissionResponse`](#permissionresponse). */ export const requestRemindersPermissions = InternalExpoCalendar.requestRemindersPermissions; /** * Checks user's permissions for accessing user's reminders. * @return A promise that resolves to an object of type [`PermissionResponse`](#permissionresponse). */ export const getRemindersPermissions = InternalExpoCalendar.getRemindersPermissions; /** * Gets an array of Source objects with details about the different sources stored on the device. * @returns An array of Source objects representing the sources found. */ export const getSourcesSync = InternalExpoCalendar.getSourcesSync; export { AlarmMethod, AttendeeRole, AttendeeStatus, AttendeeType, Availability, CalendarAccessLevel, CalendarDialogResultActions, CalendarType, DayOfTheWeek, EntityTypes, EventAccessLevel, EventStatus, Frequency, MonthOfTheYear, ReminderStatus, SourceType, } from './legacy/Calendar'; /** * Check or request permissions to access the user's calendars. * This uses both `getCalendarPermissions` and `requestCalendarPermissions` to interact * with the permissions. * On iOS, `writeOnly` requests permission to create calendar events without reading * existing calendars or events. It does not grant permission to create, update, or delete calendars. * * @example * ```ts * const [status, requestPermission] = Calendar.useCalendarPermissions(); * ``` */ export const useCalendarPermissions = createPermissionHook({ getMethod: (options) => getCalendarPermissions(options?.writeOnly), requestMethod: (options) => requestCalendarPermissions(options?.writeOnly), }); /** * Check or request permissions to access the user's reminders. * This uses both `getRemindersPermissions` and `requestRemindersPermissions` to interact * with the permissions. * * @example * ```ts * const [status, requestPermission] = Calendar.useRemindersPermissions(); * ``` */ export const useRemindersPermissions = createPermissionHook({ getMethod: getRemindersPermissions, requestMethod: requestRemindersPermissions, }); export * from './legacyWarnings'; //# sourceMappingURL=Calendar.js.map