1 import { createSlice } from '@reduxjs/toolkit';
3 import { type ModelState, getInitialModelState, serverEvent } from '@proton/account';
4 import type { ProtonThunkArguments } from '@proton/redux-shared-store-types';
5 import { createAsyncModelThunk, handleAsyncModel, previousSelector } from '@proton/redux-utilities';
6 import { queryContactEmails } from '@proton/shared/lib/api/contacts';
7 import queryPages from '@proton/shared/lib/api/helpers/queryPages';
8 import { CONTACTS_REQUESTS_PER_SECOND, CONTACT_EMAILS_LIMIT } from '@proton/shared/lib/constants';
9 import { EVENT_ERRORS } from '@proton/shared/lib/errors';
10 import { hasBit } from '@proton/shared/lib/helpers/bitset';
11 import updateCollection, { sortCollection } from '@proton/shared/lib/helpers/updateCollection';
12 import type { Api } from '@proton/shared/lib/interfaces';
13 import type { ContactEmail } from '@proton/shared/lib/interfaces/contacts';
15 const name = 'contactEmails' as const;
17 export const getContactEmailsModel = (api: Api) => {
28 pageSize: CONTACT_EMAILS_LIMIT,
29 pagesPerChunk: CONTACTS_REQUESTS_PER_SECOND,
33 return sortCollection(
35 pages.flatMap(({ ContactEmails }) => ContactEmails)
41 [name]: ModelState<ContactEmail[]>;
44 type SliceState = State[typeof name];
45 type Model = NonNullable<SliceState['value']>;
47 export const selectContactEmails = (state: State) => state[name];
49 const modelThunk = createAsyncModelThunk<Model, State, ProtonThunkArguments>(`${name}/fetch`, {
50 miss: async ({ extraArgument }) => {
51 return getContactEmailsModel(extraArgument.api);
53 previous: previousSelector(selectContactEmails),
56 const initialState = getInitialModelState<Model>();
57 const slice = createSlice({
61 extraReducers: (builder) => {
62 handleAsyncModel(builder, modelThunk);
63 builder.addCase(serverEvent, (state, action) => {
64 if (state.value && action.payload.ContactEmails) {
65 state.value = sortCollection(
69 events: action.payload.ContactEmails,
70 itemKey: 'ContactEmail',
74 if (state.value && hasBit(action.payload.Refresh, EVENT_ERRORS.CONTACTS)) {
82 export const contactEmailsReducer = { [name]: slice.reducer };
83 export const contactEmailsThunk = modelThunk.thunk;