UNPKG

@elemental-design/expo-notifications

Version:
93 lines (85 loc) 3.32 kB
import uuidv4 from 'uuid/v4'; import NotificationScheduler from './NotificationScheduler'; import { NotificationTriggerInput as NativeNotificationTriggerInput } from './NotificationScheduler.types'; import { NotificationRequestInput, NotificationTriggerInput, DailyTriggerInput, CalendarTriggerInput, TimeIntervalTriggerInput, } from './Notifications.types'; export default async function scheduleNotificationAsync( request: NotificationRequestInput ): Promise<string> { return await NotificationScheduler.scheduleNotificationAsync( request.identifier ?? uuidv4(), request.content, parseTrigger(request.trigger) ); } function parseTrigger(userFacingTrigger: NotificationTriggerInput): NativeNotificationTriggerInput { if (userFacingTrigger === null) { return null; } if (userFacingTrigger === undefined) { throw new TypeError( 'Encountered an `undefined` notification trigger. If you want to trigger the notification immediately, pass in an explicit `null` value.' ); } if (userFacingTrigger instanceof Date) { return { type: 'date', timestamp: userFacingTrigger.getTime() }; } else if (typeof userFacingTrigger === 'number') { return { type: 'date', timestamp: userFacingTrigger }; } else if (isDailyTriggerInput(userFacingTrigger)) { const hour = userFacingTrigger.hour; const minute = userFacingTrigger.minute; if (hour === undefined || hour == null || minute === undefined || minute == null) { throw new TypeError('Both hour and minute need to have valid values. Found undefined'); } if (hour < 0 || hour > 23) { throw new RangeError(`The hour parameter needs to be between 0 and 23. Found: ${hour}`); } if (minute < 0 || minute > 59) { throw new RangeError(`The minute parameter needs to be between 0 and 59. Found: ${minute}`); } return { type: 'daily', hour, minute, }; } else if (isSecondsPropertyMisusedInCalendarTriggerInput(userFacingTrigger)) { throw new TypeError( 'Could not have inferred the notification trigger type: if you want to use a time interval trigger, pass in only `seconds` with or without `repeats` property; if you want to use calendar-based trigger, pass in `second`.' ); } else if ('seconds' in userFacingTrigger) { return { type: 'timeInterval', seconds: userFacingTrigger.seconds, repeats: userFacingTrigger.repeats ?? false, }; } else { const { repeats, ...calendarTrigger } = userFacingTrigger; return { type: 'calendar', value: calendarTrigger, repeats }; } } function isDailyTriggerInput( trigger: DailyTriggerInput | CalendarTriggerInput | TimeIntervalTriggerInput ): trigger is DailyTriggerInput { return ( Object.keys(trigger).length === 3 && 'hour' in trigger && 'minute' in trigger && 'repeats' in trigger && trigger.repeats === true ); } function isSecondsPropertyMisusedInCalendarTriggerInput( trigger: TimeIntervalTriggerInput | CalendarTriggerInput ) { return ( // eg. { seconds: ..., repeats: ..., hour: ... } ('seconds' in trigger && 'repeats' in trigger && Object.keys(trigger).length > 2) || // eg. { seconds: ..., hour: ... } ('seconds' in trigger && !('repeats' in trigger) && Object.keys(trigger).length > 1) ); }