1 import { useCallback } from 'react';
3 import { getVtimezones } from '@proton/shared/lib/api/calendars';
4 import { parse } from '@proton/shared/lib/calendar/vcal';
5 import { GET_VTIMEZONES_API_LIMIT } from '@proton/shared/lib/constants';
6 import type { VcalVtimezoneComponent } from '@proton/shared/lib/interfaces/calendar';
7 import type { GetVTimezonesMap, VTimezoneObject } from '@proton/shared/lib/interfaces/hooks/GetVTimezonesMap';
8 import type { SimpleMap } from '@proton/shared/lib/interfaces/utils';
9 import chunk from '@proton/utils/chunk';
10 import unique from '@proton/utils/unique';
12 import useApi from './useApi';
13 import useCache from './useCache';
14 import { getIsRecordInvalid, getPromiseValue } from './useCachedModelResult';
16 const CACHE_KEY = 'VTIMEZONES';
18 export const useGetVtimezonesMap = () => {
20 const cache = useCache();
22 const getVTimezonesMap = useCallback(
23 async (tzids: string[]): Promise<SimpleMap<VTimezoneObject>> => {
24 const uniqueTzids = unique(tzids.filter((tzid) => tzid.toLowerCase() !== 'utc'));
25 const encodedTzids = uniqueTzids.map((tzid) => encodeURIComponent(tzid));
27 if (!uniqueTzids.length) {
28 return Promise.resolve({});
31 const batchedTimezones = chunk(encodedTzids, GET_VTIMEZONES_API_LIMIT);
35 batchedTimezones.map(async (batch) => {
36 const { Timezones = {} } = await api<{ Timezones: SimpleMap<string> }>(getVtimezones(batch));
38 return tzids.reduce<SimpleMap<VTimezoneObject>>((acc, tzid) => {
39 const vtimezoneString = Timezones[tzid];
41 if (vtimezoneString) {
44 vtimezone: parse(vtimezoneString) as VcalVtimezoneComponent,
52 ).reduce<SimpleMap<VTimezoneObject>>((acc, curr) => ({ ...acc, ...curr }), {});
57 return useCallback<GetVTimezonesMap>(
58 (tzids: string[]) => {
59 if (!cache.has(CACHE_KEY)) {
60 cache.set(CACHE_KEY, new Map());
62 const subCache = cache.get(CACHE_KEY);
63 const missing = tzids.filter((tzid) => {
64 return getIsRecordInvalid(subCache.get(tzid));
66 const promise = getVTimezonesMap(missing);
67 const miss = async (tzid: string) => {
68 const map = await promise;
72 tzids.map(async (tzid) => {
73 const result = await getPromiseValue(subCache, tzid, miss);
76 result: result as VTimezoneObject,
80 return result.reduce<SimpleMap<VTimezoneObject>>((acc, { tzid, result }) => {
86 [cache, getVTimezonesMap]