aboutsummaryrefslogblamecommitdiffstats
path: root/packages/website/ts/redux/reducer.ts
blob: f54801639389e2910f89e2288fc7e200a70ab089 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                  
                                             
                            
                                 
        


                   
                

                 

                     
                   
                  
                                               
                                               
                                       









                                                                                     



                                    
                           





                                             
                                       
                        
                                      

                                       
                                           
                                                                                          
                                        





                                   
                                           

                                 
                         
 
 
                                     
             
                                          
                              


                                                                     
                       

                                              



                                           

                           

                       
                                                
                    
                                     
                                      

                                     
                                         


                                                 

                            
                                        
                             
                               

  
                                                                              

                          
                                    



                                           
 


                                           
                                       
              






                                                      

         


                                             
                                         
              

         


                                                 
                                             
              

         


                                                                 
                                                             
              

         


                                                  
                                                   
              

         


                                                        
                                                    
              

         
                                                    
                                                                  
                                                                 

                         
                                                  
              

         
                                                         
                                                                  
                                                          

                         
                                                  
              

         
                                                
                                                               

                                       



                                                     

                                                             

                         
                               
              

         
                                         
                                                                                                                      


                                                 
                            
                                                               
                                                           


              
                                                

                         
                                                            
              
 
                                                

                         
                                            
              

         


                                             
                                         
              

         


                                                    
                                                
              

         


                                                    
                                           
              

         


                                           
                                       
              

         


                                                  
                                                      


                         
                                                      
              

         
                                                         
                                                                                  
                                                        

                                          
                                                  


                         
                                                      
              

         

                                           

                                                                     


                         
                                                      
              

         


                                             
                                                  
              

         


                                                   
                                               
              

         
                                             
                                                                              

                         
                            
              

         












                                                          
                                                                                                                       

                                                             


              
               


                                                
                                         
              
         


                                                          
                                                  
              


                 


                                            
                                          
              

         


                                            
                                        
              

         


                                              
                                          
              

         


                                                      
                                                  
              





                         
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import * as moment from 'moment';
import {
    Action,
    ActionTypes,
    BlockchainErrs,
    PortalOrder,
    ProviderType,
    ScreenWidths,
    Side,
    SideToAssetToken,
    TokenByAddress,
} from 'ts/types';
import { constants } from 'ts/utils/constants';
import { Translate } from 'ts/utils/translate';
import { utils } from 'ts/utils/utils';

// Instead of defaulting the docs version to an empty string, we pre-populate it with
// a valid version value. This does not need to be updated however, since onLoad, it
// is always replaced with a value retrieved from our S3 bucket.
const DEFAULT_DOCS_VERSION = '0.0.0';

export interface State {
    // Portal
    blockchainErr: BlockchainErrs;
    blockchainIsLoaded: boolean;
    networkId: number;
    orderExpiryTimestamp: BigNumber;
    orderFillAmount: BigNumber;
    orderTakerAddress: string;
    orderSignature: string;
    orderSalt: BigNumber;
    nodeVersion: string;
    screenWidth: ScreenWidths;
    shouldBlockchainErrDialogBeOpen: boolean;
    sideToAssetToken: SideToAssetToken;
    tokenByAddress: TokenByAddress;
    lastForceTokenStateRefetch: number;
    userAddress: string;
    userEtherBalanceInWei?: BigNumber;
    portalOnboardingStep: number;
    isPortalOnboardingShowing: boolean;
    hasPortalOnboardingBeenClosed: boolean;
    // Note: cache of supplied orderJSON in fill order step. Do not use for anything else.
    userSuppliedOrderCache: PortalOrder;

    // Docs
    docsVersion: string;
    availableDocVersions: string[];

    // Shared
    flashMessage: string | React.ReactNode;
    providerType: ProviderType;
    injectedProviderName: string;
    translate: Translate;
}

export const INITIAL_STATE: State = {
    // Portal
    blockchainErr: BlockchainErrs.NoError,
    blockchainIsLoaded: false,
    networkId: undefined,
    orderExpiryTimestamp: utils.initialOrderExpiryUnixTimestampSec(),
    orderFillAmount: undefined,
    orderSignature: '',
    orderTakerAddress: constants.NULL_ADDRESS,
    orderSalt: generatePseudoRandomSalt(),
    nodeVersion: undefined,
    screenWidth: utils.getScreenWidth(),
    shouldBlockchainErrDialogBeOpen: false,
    sideToAssetToken: {
        [Side.Deposit]: {},
        [Side.Receive]: {},
    },
    tokenByAddress: {},
    lastForceTokenStateRefetch: moment().unix(),
    userAddress: '',
    userEtherBalanceInWei: undefined,
    userSuppliedOrderCache: undefined,
    portalOnboardingStep: 0,
    isPortalOnboardingShowing: false,
    hasPortalOnboardingBeenClosed: false,
    // Docs
    docsVersion: DEFAULT_DOCS_VERSION,
    availableDocVersions: [DEFAULT_DOCS_VERSION],
    // Shared
    flashMessage: undefined,
    providerType: ProviderType.Injected,
    injectedProviderName: '',
    translate: new Translate(),
};

export function reducer(state: State = INITIAL_STATE, action: Action): State {
    switch (action.type) {
        // Portal
        case ActionTypes.ResetState:
            return {
                ...INITIAL_STATE,
                translate: state.translate,
            };

        case ActionTypes.UpdateOrderSalt: {
            return {
                ...state,
                orderSalt: action.data,
            };
        }

        case ActionTypes.UpdateSelectedLanguage: {
            return {
                ...state,
                translate: new Translate(action.data),
            };
        }

        case ActionTypes.UpdateNodeVersion: {
            return {
                ...state,
                nodeVersion: action.data,
            };
        }

        case ActionTypes.UpdateOrderFillAmount: {
            return {
                ...state,
                orderFillAmount: action.data,
            };
        }

        case ActionTypes.UpdateShouldBlockchainErrDialogBeOpen: {
            return {
                ...state,
                shouldBlockchainErrDialogBeOpen: action.data,
            };
        }

        case ActionTypes.UpdateUserEtherBalance: {
            return {
                ...state,
                userEtherBalanceInWei: action.data,
            };
        }

        case ActionTypes.UpdateUserSuppliedOrderCache: {
            return {
                ...state,
                userSuppliedOrderCache: action.data,
            };
        }

        case ActionTypes.AddTokenToTokenByAddress: {
            const newTokenByAddress = { ...state.tokenByAddress };
            newTokenByAddress[action.data.address] = action.data;
            return {
                ...state,
                tokenByAddress: newTokenByAddress,
            };
        }

        case ActionTypes.RemoveTokenFromTokenByAddress: {
            const newTokenByAddress = { ...state.tokenByAddress };
            delete newTokenByAddress[action.data.address];
            return {
                ...state,
                tokenByAddress: newTokenByAddress,
            };
        }

        case ActionTypes.UpdateTokenByAddress: {
            const tokenByAddress = { ...state.tokenByAddress };
            const tokens = action.data;
            _.each(tokens, token => {
                const updatedToken = {
                    ...tokenByAddress[token.address],
                    ...token,
                };
                tokenByAddress[token.address] = updatedToken;
            });
            return {
                ...state,
                tokenByAddress,
            };
        }

        case ActionTypes.BatchDispatch: {
            const userAddress = _.isUndefined(action.data.userAddressIfExists) ? '' : action.data.userAddressIfExists;
            return {
                ...state,
                networkId: action.data.networkId,
                userAddress,
                sideToAssetToken: action.data.sideToAssetToken,
                tokenByAddress: action.data.tokenByAddress,
            };
        }

        case ActionTypes.ForceTokenStateRefetch:
            return {
                ...state,
                lastForceTokenStateRefetch: moment().unix(),
            };

        case ActionTypes.UpdateOrderSignature: {
            return {
                ...state,
                orderSignature: action.data,
            };
        }

        case ActionTypes.UpdateScreenWidth: {
            return {
                ...state,
                screenWidth: action.data,
            };
        }

        case ActionTypes.UpdateBlockchainIsLoaded: {
            return {
                ...state,
                blockchainIsLoaded: action.data,
            };
        }

        case ActionTypes.BlockchainErrEncountered: {
            return {
                ...state,
                blockchainErr: action.data,
            };
        }

        case ActionTypes.UpdateNetworkId: {
            return {
                ...state,
                networkId: action.data,
            };
        }

        case ActionTypes.UpdateChosenAssetToken: {
            const newSideToAssetToken = {
                ...state.sideToAssetToken,
                [action.data.side]: action.data.token,
            };
            return {
                ...state,
                sideToAssetToken: newSideToAssetToken,
            };
        }

        case ActionTypes.UpdateChosenAssetTokenAddress: {
            const newAssetToken = { ...state.sideToAssetToken[action.data.side] };
            newAssetToken.address = action.data.address;
            const newSideToAssetToken = {
                ...state.sideToAssetToken,
                [action.data.side]: newAssetToken,
            };
            return {
                ...state,
                sideToAssetToken: newSideToAssetToken,
            };
        }

        case ActionTypes.SwapAssetTokens: {
            const newSideToAssetToken = {
                [Side.Deposit]: state.sideToAssetToken[Side.Receive],
                [Side.Receive]: state.sideToAssetToken[Side.Deposit],
            };
            return {
                ...state,
                sideToAssetToken: newSideToAssetToken,
            };
        }

        case ActionTypes.UpdateOrderExpiry: {
            return {
                ...state,
                orderExpiryTimestamp: action.data,
            };
        }

        case ActionTypes.UpdateOrderTakerAddress: {
            return {
                ...state,
                orderTakerAddress: action.data,
            };
        }

        case ActionTypes.UpdateUserAddress: {
            const userAddress = _.isUndefined(action.data) ? '' : action.data;
            return {
                ...state,
                userAddress,
            };
        }

        case ActionTypes.UpdatePortalOnboardingStep: {
            const portalOnboardingStep = action.data;
            return {
                ...state,
                portalOnboardingStep,
            };
        }

        case ActionTypes.UpdatePortalOnboardingShowing: {
            const isPortalOnboardingShowing = action.data;
            return {
                ...state,
                isPortalOnboardingShowing,
                hasPortalOnboardingBeenClosed: !isPortalOnboardingShowing ? true : state.hasPortalOnboardingBeenClosed,
                // always start onboarding from the beginning
                portalOnboardingStep: 0,
            };
        }

        // Docs
        case ActionTypes.UpdateLibraryVersion: {
            return {
                ...state,
                docsVersion: action.data,
            };
        }
        case ActionTypes.UpdateAvailableLibraryVersions: {
            return {
                ...state,
                availableDocVersions: action.data,
            };
        }

        // Shared
        case ActionTypes.ShowFlashMessage: {
            return {
                ...state,
                flashMessage: action.data,
            };
        }

        case ActionTypes.HideFlashMessage: {
            return {
                ...state,
                flashMessage: undefined,
            };
        }

        case ActionTypes.UpdateProviderType: {
            return {
                ...state,
                providerType: action.data,
            };
        }

        case ActionTypes.UpdateInjectedProviderName: {
            return {
                ...state,
                injectedProviderName: action.data,
            };
        }

        default:
            return state;
    }
}