Merge branch 'fix-typo-drive' into 'main'
[ProtonMail-WebClient.git] / packages / pass / hooks / useValidateInviteAddress.ts
blobea6bc6fc87be023b58d6c411a14bd43d5938bad1
1 import { type MutableRefObject, useMemo, useRef } from 'react';
3 import type { inviteAddressesValidateFailure, inviteAddressesValidateSuccess } from '@proton/pass/store/actions';
4 import { inviteAddressesValidateIntent } from '@proton/pass/store/actions';
5 import { type Awaiter, awaiter } from '@proton/pass/utils/fp/promises';
7 import { uniqueId } from '../utils/string/unique-id';
8 import { useActionRequest } from './useActionRequest';
10 type InviteAddressesCache = Map<string, boolean>;
11 export interface InviteAddressValidator {
12     validate: (addresses: string[]) => Promise<void>;
13     emails: MutableRefObject<InviteAddressesCache>;
14     loading: boolean;
17 export const useValidateInviteAddresses = (shareId: string): InviteAddressValidator => {
18     /** keeps track of valid/invalid email addresses in a map
19      * in order to only request new emails to validate*/
20     const cache = useRef<InviteAddressesCache>(new Map());
21     const pending = useRef<Awaiter<void>>();
23     const validateAddresses = useActionRequest<
24         typeof inviteAddressesValidateIntent,
25         typeof inviteAddressesValidateSuccess,
26         typeof inviteAddressesValidateFailure
27     >(inviteAddressesValidateIntent, {
28         onSuccess: ({ data }) => {
29             Object.entries(data).forEach(([email, valid]) => cache.current.set(email, valid));
30             pending.current?.resolve();
31         },
32     });
34     return useMemo(
35         () => ({
36             validate: async (addresses: string[]) => {
37                 pending.current?.reject('aborted');
38                 pending.current = awaiter();
40                 const emails = addresses.filter((email) => cache.current.get(email) === undefined);
42                 if (emails.length > 0) validateAddresses.revalidate({ shareId, emails }, uniqueId());
43                 else pending.current.resolve();
45                 await pending.current;
46             },
47             emails: cache,
48             loading: validateAddresses.loading,
49         }),
50         [validateAddresses]
51     );