import { createAction, createReducer, createSelector } from '@reduxjs/toolkit' import { addressToDisplayNameSelector, addressToE164NumberSelector } from 'src/identity/selectors' import { AddressToRecipient, NumberToRecipient } from 'src/recipients/recipient' import { REHYDRATE, RehydrateAction, getRehydratePayload } from 'src/redux/persist-helper' import { RootState } from 'src/redux/reducers' interface State { // phoneRecipientCache contains the processed contact data imported from the // phone for a single app session. // Think of contacts as raw data and recipients as filtered data // No relation to recent recipients, which is in /send/reducer.ts phoneRecipientCache: NumberToRecipient // appRecipientCache contains accounts that the user has sent/recieved transactions from, // and includes CIP8 profile data if available appRecipientCache: AddressToRecipient rewardsSenders: string[] inviteRewardsSenders: string[] coinbasePaySenders: string[] } const initialState: State = { phoneRecipientCache: {}, appRecipientCache: {}, rewardsSenders: [], inviteRewardsSenders: [], coinbasePaySenders: [], } const rehydrate = createAction(REHYDRATE) export const setPhoneRecipientCache = createAction( 'RECIPIENTS/SET_PHONE_RECIPIENT_CACHE' ) export const updateAppRecipientCache = createAction( 'RECIPIENTS/SET_APP_RECIPIENT_CACHE' ) export const rewardsSendersFetched = createAction('RECIPIENTS/REWARDS_SENDERS_FETCHED') export const inviteRewardsSendersFetched = createAction( 'RECIPIENTS/INVITE_REWARDS_SENDERS_FETCHED' ) export const coinbasePaySendersFetched = createAction( 'RECIPIENTS/COINBASE_PAY_SENDERS_FETCHED' ) export const recipientsReducer = createReducer(initialState, (builder) => { builder .addCase(rehydrate, (state, action) => { // hack to allow rehydrate actions here const hydrated = getRehydratePayload(action as unknown as RehydrateAction, 'recipients') return { ...initialState, ...state, ...hydrated, } }) .addCase(setPhoneRecipientCache, (state, action) => ({ ...state, phoneRecipientCache: action.payload, })) .addCase(updateAppRecipientCache, (state, action) => ({ ...state, appRecipientCache: { ...state.appRecipientCache, ...action.payload }, })) .addCase(rewardsSendersFetched, (state, action) => ({ ...state, rewardsSenders: action.payload, })) .addCase(inviteRewardsSendersFetched, (state, action) => ({ ...state, inviteRewardsSenders: action.payload, })) .addCase(coinbasePaySendersFetched, (state, action) => ({ ...state, coinbasePaySenders: action.payload, })) }) export const phoneRecipientCacheSelector = (state: RootState) => state.recipients.phoneRecipientCache export const appRecipientCacheSelector = (state: RootState) => state.recipients.appRecipientCache export const rewardsSendersSelector = (state: RootState) => state.recipients.rewardsSenders export const inviteRewardsSendersSelector = (state: RootState) => state.recipients.inviteRewardsSenders export const allRewardsSendersSelector = createSelector( [rewardsSendersSelector, inviteRewardsSendersSelector], (rewardsSenders, inviteRewardsSenders) => { return [...rewardsSenders, ...inviteRewardsSenders] } ) export const coinbasePaySendersSelector = (state: RootState) => state.recipients.coinbasePaySenders export const recipientInfoSelector = createSelector( [ addressToE164NumberSelector, phoneRecipientCacheSelector, appRecipientCacheSelector, addressToDisplayNameSelector, ], (addressToE164Number, phoneRecipientCache, appRecipientCache, addressToDisplayName) => { return { addressToE164Number, phoneRecipientCache, appRecipientCache, addressToDisplayName, } } )