1 import type { MutableRefObject } from 'react';
2 import { useEffect, useMemo, useState } from 'react';
4 import { useApi } from '@proton/components';
5 import { DAY, MINUTE } from '@proton/shared/lib/constants';
6 import { addMilliseconds } from '@proton/shared/lib/date-fns-utc';
7 import type { Calendar as tsCalendar } from '@proton/shared/lib/interfaces/calendar';
8 import noop from '@proton/utils/noop';
10 import type { CalendarsAlarmsCache } from './CacheInterface';
11 import getCalendarsAlarmsCached from './getCalendarsAlarmsCached';
13 const PADDING = 2 * MINUTE;
15 export const getCalendarsAlarmsCache = ({
16 start = new Date(2000, 1, 1),
17 end = new Date(2000, 1, 1),
18 } = {}): CalendarsAlarmsCache => ({
24 const useCalendarsAlarms = (
25 calendars: tsCalendar[],
26 cacheRef: MutableRefObject<CalendarsAlarmsCache>,
30 const [forceRefresh, setForceRefresh] = useState<any>();
32 const calendarIDs = useMemo(() => calendars.map(({ ID }) => ID), [calendars]);
35 let timeoutHandle = 0;
36 let unmounted = false;
38 const update = async () => {
39 const now = new Date();
42 if (+cacheRef.current.end - PADDING <= +now) {
43 cacheRef.current = getCalendarsAlarmsCache({
45 end: addMilliseconds(now, lookAhead),
47 cacheRef.current.rerender = () => setForceRefresh({});
50 const promise = getCalendarsAlarmsCached(api, cacheRef.current.calendarsCache, calendarIDs, [
51 cacheRef.current.start,
54 cacheRef.current.promise = promise;
57 clearTimeout(timeoutHandle);
62 // If it's not the latest, ignore
63 if (unmounted || promise !== cacheRef.current.promise) {
67 const delay = Math.max(0, +cacheRef.current.end - PADDING - Date.now());
69 timeoutHandle = window.setTimeout(() => {
78 cacheRef.current.rerender = () => setForceRefresh({});
80 cacheRef.current.rerender = undefined;
82 clearTimeout(timeoutHandle);
86 return useMemo(() => {
87 const { calendarsCache } = cacheRef.current;
89 .map((calendarID) => {
90 return calendarsCache[calendarID]?.result ?? [];
94 return a.Occurrence - b.Occurrence;
96 }, [forceRefresh, calendarIDs]);
99 export default useCalendarsAlarms;