import { createStore , createHook , SetState , GetState } from 'react-sweet-state' ; import RNNetworkExtension from 'react-native-network-extension' ; import logger from '../logger' ; import Keychain from '../keychain' ; import { Token } from 'providers/types/Token' ; import { Server } from 'providers/types/Server' ; import { Provider } from 'providers/types/Provider' ; interface State { privacyAccepted : boolean ; providerTokens : Token [ ] ; currentServer : Server | null ; vpnStatus : string ; notifications : { type : string ; notification : string ; } [ ] ; } const initialState = { privacyAccepted : false , providerTokens : [ ] , currentServer : null , vpnStatus : 'Disconnected' , notifications : [ ] , } ; interface StoreActions { setState : SetState < State > ; getState : GetState < State > ; dispatch : any ; } const actions = { acceptPrivacy : ( ) => ( { setState , dispatch } ) => { setState ( { privacyAccepted : true } ) ; dispatch ( actions . persistState ( ) ) ; } , addProviderToken : ( token ) => ( { setState , getState , dispatch } ) => { setState ( { providerTokens : [ ... getState ( ) . providerTokens , token ] } ) ; dispatch ( actions . persistState ( ) ) ; } , setCurrentVPNServer : ( server ) => ( { setState , dispatch } ) => { setState ( { currentServer : server } ) ; dispatch ( actions . persistState ( ) ) ; } , setVPNStatus : ( status ) => ( { setState } ) => { setState ( { vpnStatus : status } ) ; } , toggleVPN : ( ) => async ( { setState , getState , dispatch } ) => { if ( getState ( ) . vpnStatus === 'Connected' ) { RNNetworkExtension . disconnect ( ) ; } else { setState ( { vpnStatus : 'Connecting' } ) ; try { await RNNetworkExtension . connect ( ) ; } catch ( e ) { dispatch ( actions . notify ( 'error' , `Failed to start VPN connection: ${ e . message || JSON . stringify ( e ) }` ) ) ; } } } , triggerSignOut : ( provider ) => ( { setState , getState , dispatch } ) => { setState ( { providerTokens : getState ( ) . providerTokens . filter ( ( token ) => token . provider !== provider . id ) , } ) ; dispatch ( actions . persistState ( ) ) ; } , resetNotification : ( ) => ( { setState } ) => { setState ( { notifications : [ ] } ) ; } , notify : ( type , notification ) => ( { setState , getState } ) => { setState ( { notifications : [ { type , notification } , ... getState ( ) . notifications ] } ) ; logger . log ( type , notification ) ; } , initState : ( state ) => ( { setState } ) => setState ( state ) , persistState : ( ) => ( { getState } ) => { const state = { privacyAccepted : getState ( ) . privacyAccepted , providerTokens : getState ( ) . providerTokens , currentServer : getState ( ) . currentServer , } ; Keychain . setInitialState ( state ) ; } , } ; const Store = createStore ( { name : 'main_store' , initialState , actions , } ) ; export const useStore = createHook ( Store ) ;