Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / shared / lib / calendar / icsSurgery / valarm.ts
blob4e787835a3cef3a2dbf2c77a2aa7c7a43977a9db
1 import { DAY_IN_SECONDS } from '@proton/shared/lib/constants';
2 import isTruthy from '@proton/utils/isTruthy';
4 import { normalize } from '../../helpers/string';
5 import type {
6     DateTimeValue,
7     VcalDateOrDateTimeProperty,
8     VcalStringProperty,
9     VcalValarmComponent,
10     VcalValarmRelativeComponent,
11 } from '../../interfaces/calendar';
12 import { getIsAbsoluteTrigger, normalizeDurationToUnit, normalizeTrigger } from '../alarms/trigger';
13 import { ICAL_ALARM_ACTION, MAX_NOTIFICATIONS, NOTIFICATION_UNITS, NOTIFICATION_UNITS_MAX } from '../constants';
14 import { getIsDateTimeValue, getIsPropertyAllDay } from '../vcalHelper';
16 const { DISPLAY, EMAIL, AUDIO } = ICAL_ALARM_ACTION;
18 export const getSupportedAlarmAction = (action: VcalStringProperty) => {
19     if (normalize(action.value) === 'email') {
20         return { value: EMAIL };
21     }
23     return { value: DISPLAY };
26 /**
27  * Determine if a VALARM component is correct according to the RFC
28  */
29 export const getIsValidAlarm = (alarm: VcalValarmComponent) => {
30     const { action, trigger, duration, repeat } = alarm;
31     const supportedActions: string[] = [DISPLAY, EMAIL, AUDIO];
33     if (!supportedActions.includes(action?.value)) {
34         return false;
35     }
36     if (!trigger) {
37         return false;
38     }
39     // absolute triggers should have the right format
40     if (getIsAbsoluteTrigger(trigger) && !getIsDateTimeValue(trigger.value as DateTimeValue)) {
41         return false;
42     }
43     // duration and repeat must be both present or absent
44     if (+!duration ^ +!repeat) {
45         return false;
46     }
47     return true;
50 /**
51  * Given a VALARM component, try to transform it into something that we support.
52  * Return undefined otherwise
53  */
54 export const getSupportedAlarm = (
55     alarm: VcalValarmComponent,
56     dtstart: VcalDateOrDateTimeProperty
57 ): VcalValarmRelativeComponent | undefined => {
58     if (!getIsValidAlarm(alarm)) {
59         return;
60     }
62     const supportedAction = getSupportedAlarmAction(alarm.action);
64     const { trigger } = alarm;
66     if (!getIsAbsoluteTrigger(trigger) && trigger.parameters?.related?.toLocaleLowerCase() === 'end') {
67         return;
68     }
70     const normalizedTrigger = normalizeTrigger(trigger, dtstart);
71     const triggerDurationInSeconds = normalizeDurationToUnit(normalizedTrigger, 1);
73     const inFuture = getIsPropertyAllDay(dtstart)
74         ? !normalizedTrigger.isNegative && triggerDurationInSeconds >= DAY_IN_SECONDS
75         : !normalizedTrigger.isNegative && triggerDurationInSeconds !== 0;
76     const nonSupportedTrigger =
77         normalizedTrigger.seconds !== 0 ||
78         normalizedTrigger.minutes > NOTIFICATION_UNITS_MAX[NOTIFICATION_UNITS.MINUTE] ||
79         normalizedTrigger.hours > NOTIFICATION_UNITS_MAX[NOTIFICATION_UNITS.HOUR] ||
80         normalizedTrigger.days > NOTIFICATION_UNITS_MAX[NOTIFICATION_UNITS.DAY] ||
81         normalizedTrigger.weeks > NOTIFICATION_UNITS_MAX[NOTIFICATION_UNITS.WEEK];
83     if (inFuture || nonSupportedTrigger) {
84         return;
85     }
87     return {
88         component: 'valarm',
89         action: supportedAction,
90         trigger: { value: normalizedTrigger },
91     };
94 export const getSupportedAlarms = (valarms: VcalValarmComponent[], dtstart: VcalDateOrDateTimeProperty) => {
95     return valarms
96         .map((alarm) => getSupportedAlarm(alarm, dtstart))
97         .filter(isTruthy)
98         .slice(0, MAX_NOTIFICATIONS);