Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / shared / lib / calendar / alarms / trigger.ts
blobd8c0b7b4efbd14c6815b9c9d66a60b08c3f1d0b6
1 import { differenceInMinutes } from 'date-fns';
3 import isTruthy from '@proton/utils/isTruthy';
5 import type {
6     VcalDateOrDateTimeProperty,
7     VcalDateTimeProperty,
8     VcalDurationValue,
9     VcalTriggerProperty,
10 } from '../../interfaces/calendar';
11 import { propertyToUTCDate } from '../vcalConverter';
12 import { getIsPropertyAllDay } from '../vcalHelper';
14 const MINUTE = 60;
15 const HOUR = 60 * MINUTE;
16 const DAY = 24 * HOUR;
17 const WEEK = 7 * DAY;
19 export const transformBeforeAt = (at: Date) => {
20     const minutes = 60 - (at.getMinutes() || 60);
21     const hours = 24 - (at.getHours() || 24) - (minutes > 0 ? 1 : 0);
22     return new Date(at.getFullYear(), at.getMonth(), at.getDate(), hours, minutes);
25 export const getIsAbsoluteTrigger = (trigger: VcalTriggerProperty): trigger is VcalDateTimeProperty => {
26     return (trigger as VcalDateTimeProperty).parameters?.type === 'date-time';
29 export const absoluteToRelativeTrigger = (trigger: VcalDateTimeProperty, dtstart: VcalDateOrDateTimeProperty) => {
30     const utcStartDate = propertyToUTCDate(dtstart);
31     const triggerDate = propertyToUTCDate(trigger);
32     const durationInMinutes = differenceInMinutes(utcStartDate, triggerDate);
33     const duration = Math.abs(durationInMinutes * MINUTE);
34     const weeks = Math.floor(duration / WEEK);
35     const days = Math.floor((duration % WEEK) / DAY);
36     const hours = Math.floor((duration % DAY) / HOUR);
37     const minutes = Math.floor((duration % HOUR) / MINUTE);
39     return { weeks, days, hours, minutes, seconds: 0, isNegative: durationInMinutes >= 0 };
42 /**
43  * If you import this function, notice unit has to be in seconds, not milliseconds
44  */
45 export const normalizeDurationToUnit = (duration: Partial<VcalDurationValue>, unit: number) => {
46     const normalizedUnits = [
47         Math.floor(((duration.weeks || 0) * WEEK) / unit),
48         Math.floor(((duration.days || 0) * DAY) / unit),
49         Math.floor(((duration.hours || 0) * HOUR) / unit),
50         Math.floor(((duration.minutes || 0) * MINUTE) / unit),
51         Math.floor((duration.seconds || 0) / unit),
52     ];
53     return normalizedUnits.reduce((acc, curr) => acc + curr, 0);
56 export const normalizeRelativeTrigger = (duration: VcalDurationValue, isAllDay: boolean) => {
57     const { minutes, hours, weeks, days, isNegative } = duration;
58     if (isAllDay) {
59         // the API admits all trigger components for all-day events,
60         // but we do not support arbitrary combinations of non-zero values for weeks and days
61         const isMidNightAlarm = hours === 0 && minutes === 0;
62         const mustKeepWeeks = !isNegative || isMidNightAlarm ? days === 0 : days === 6;
63         return mustKeepWeeks
64             ? { ...duration, seconds: 0 }
65             : { ...duration, weeks: 0, days: days + 7 * weeks, seconds: 0 };
66     }
67     // We only admit one trigger component for part-day events
68     // If that's the case already, no need to normalize
69     if ([minutes, hours, weeks, days].filter(isTruthy).length <= 1) {
70         return { ...duration, seconds: 0 };
71     }
72     // Otherwise, normalize to a single component
73     const result = { weeks: 0, days: 0, hours: 0, minutes: 0, seconds: 0, isNegative };
74     const totalMinutes = normalizeDurationToUnit(duration, MINUTE);
75     if (totalMinutes % 60 !== 0) {
76         return { ...result, minutes: totalMinutes };
77     }
78     const totalHours = Math.floor(totalMinutes / 60);
79     if (totalHours % 24 !== 0) {
80         return { ...result, hours: totalHours };
81     }
82     const totalDays = Math.floor(totalHours / 24);
83     if (totalDays % 7 !== 0) {
84         return { ...result, days: totalDays };
85     }
86     const totalWeeks = Math.floor(totalDays / 7);
87     return { ...result, weeks: totalWeeks };
90 export const normalizeTrigger = (trigger: VcalTriggerProperty, dtstart: VcalDateOrDateTimeProperty) => {
91     const duration = getIsAbsoluteTrigger(trigger) ? absoluteToRelativeTrigger(trigger, dtstart) : trigger.value;
92     return normalizeRelativeTrigger(duration, getIsPropertyAllDay(dtstart));