Use source loader for email sprite icons
[ProtonMail-WebClient.git] / packages / wallet / store / slices / priceGraphData.ts
blob04ed5691d0850392c9c7d6aba5ce8ffb86163e92
1 import { createSlice } from '@reduxjs/toolkit';
3 import type { ModelState } from '@proton/account';
4 import { getInitialModelState } from '@proton/account';
5 import type { WasmFiatCurrencySymbol, WasmPriceGraph, WasmTimeframe } from '@proton/andromeda';
6 import { createAsyncModelThunk, handleAsyncModel } from '@proton/redux-utilities';
7 import { type SimpleMap } from '@proton/shared/lib/interfaces';
9 import type { WalletThunkArguments } from '../thunk';
11 const name = 'price_graph' as const;
13 type WasmPriceGraphByFiatAndTimeframe = SimpleMap<WasmPriceGraph>;
15 export interface PriceGraphDataState {
16     [name]: ModelState<WasmPriceGraphByFiatAndTimeframe>;
19 type SliceState = PriceGraphDataState[typeof name];
20 type Model = NonNullable<SliceState['value']>;
22 export const selectPriceGraphData = (state: PriceGraphDataState) => {
23     return state[name];
26 export const getKey = (fiat: WasmFiatCurrencySymbol, timeframe: WasmTimeframe) => `${fiat}-${timeframe}`;
28 const modelThunk = createAsyncModelThunk<
29     Model,
30     PriceGraphDataState,
31     WalletThunkArguments,
32     [WasmFiatCurrencySymbol, WasmTimeframe?]
33 >(`${name}/fetch`, {
34     miss: async ({ extraArgument, options, getState }) => {
35         const stateValue = getState()[name].value;
36         if (!options?.thunkArg) {
37             return stateValue ?? {};
38         }
40         const fiat = options?.thunkArg?.[0] ?? 'USD';
41         const timeframe = options?.thunkArg?.[1] ?? 'OneDay';
43         const key = getKey(fiat, timeframe);
45         try {
46             const priceGraph = await extraArgument.walletApi
47                 .clients()
48                 .price_graph.getGraphData(fiat, timeframe)
49                 .then(({ data }) => {
50                     return data;
51                 });
53             return {
54                 [key]: priceGraph,
55                 ...stateValue,
56             };
57         } catch (error) {
58             return stateValue ?? {};
59         }
60     },
61     previous: ({ getState, options }) => {
62         const state = getState()[name];
64         if (!state.value) {
65             return undefined;
66         }
68         const fiat = options?.thunkArg?.[0] ?? 'USD';
69         const timeframe = options?.thunkArg?.[1] ?? 'OneDay';
71         const key = getKey(fiat, timeframe);
73         if (state.value[key]) {
74             return state;
75         }
77         return undefined;
78     },
79 });
81 const initialState = getInitialModelState<Model>();
83 const slice = createSlice({
84     name,
85     initialState,
86     reducers: {},
87     extraReducers: (builder) => {
88         handleAsyncModel(builder, modelThunk);
89     },
90 });
92 export const priceGraphDataReducer = { [name]: slice.reducer };
93 export const priceGraphDataThunk = modelThunk.thunk;