1 import { createSlice } from '@reduxjs/toolkit';
3 import type { ProtonThunkArguments } from '@proton/redux-shared-store-types';
10 } from '@proton/redux-utilities';
11 import { getUser } from '@proton/shared/lib/api/user';
12 import { DAY } from '@proton/shared/lib/constants';
13 import type { User, UserModel } from '@proton/shared/lib/interfaces';
14 import { formatUser } from '@proton/shared/lib/user/helpers';
16 import { serverEvent } from '../eventLoop';
17 import { initEvent } from '../init';
18 import { getInitialModelState } from '../initialModelState';
19 import type { ModelState } from '../interface';
21 const name = 'user' as const;
23 export interface UserState {
24 [name]: ModelState<UserModel>;
27 type SliceState = UserState[typeof name];
28 type Model = NonNullable<SliceState['value']>;
30 export const selectUser = (state: UserState) => state.user;
32 const modelThunk = createAsyncModelThunk<Model, UserState, ProtonThunkArguments>(`${name}/fetch`, {
34 miss: ({ extraArgument }) => {
35 return extraArgument.api<{ User: User }>(getUser()).then(({ User }) => {
36 return formatUser(User);
39 previous: previousSelector(selectUser),
42 const initialState = getInitialModelState<Model>();
43 const slice = createSlice({
47 extraReducers: (builder) => {
48 handleAsyncModel(builder, modelThunk);
50 .addCase(initEvent, (state, action) => {
51 if (action.payload.User) {
52 state.value = formatUser(action.payload.User);
53 state.meta.fetchedAt = getFetchedAt();
54 state.meta.fetchedEphemeral = getFetchedEphemeral();
57 .addCase(serverEvent, (state, action) => {
58 if (state.value && (action.payload.User || action.payload.UsedSpace)) {
59 const user = action.payload.User || state.value;
60 if (action.payload.UsedSpace !== undefined) {
61 user.UsedSpace = action.payload.UsedSpace;
63 if (action.payload.UsedBaseSpace !== undefined) {
64 user.UsedBaseSpace = action.payload.UsedBaseSpace;
66 if (action.payload.UsedDriveSpace !== undefined) {
67 user.UsedDriveSpace = action.payload.UsedDriveSpace;
69 if (action.payload.ProductUsedSpace !== undefined) {
70 user.ProductUsedSpace = action.payload.ProductUsedSpace;
72 state.value = formatUser(user);
78 export const userReducer = { [name]: slice.reducer };
79 export const userThunk = modelThunk.thunk;