import { createStore, combineReducers, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import { createReducer } from 'redux-su'; import { AsyncStorage } from 'react-native'; import { persistStore, persistReducer } from 'redux-persist'; import { Portal, Link, Field } from '../Api/types'; import { Region } from '../Api/interfaces'; const reducers = { 'auth': createReducer({ 'authSet': (store: any, action: { v: string, csrf: string, user: any }) => ({ v: action.v, csrf: action.csrf, user: action.user, loading: false }), 'authLoad': (store: any, action: { loading: boolean }) => ({ ...store, loading: action.loading }) }, { v: "", csrf: "", user: null, loading: false }), 'entities': createReducer({ 'portalSet': (store: any, action: { guid: string, portal: Portal }) => ({ ...store, portals: { ...store.portals, [action.guid]: { ...action.portal } } }), 'linkSet': (store: any, action: { guid: string, link: Link }) => ({ ...store, links: { ...store.links, [action.guid]: action.link } }), 'fieldSet': (store: any, action: { guid: string, field: Field }) => ({ ...store, fields: { ...store.fields, [action.guid]: action.field } }), 'portalsSet': (store: any, action: { portals: Portal }) => { const portals = store.portals Object.keys(action.portals).forEach(guid => { if (portals[guid]) { portals[guid] = { ...portals[guid], fraction: action.portals[guid].fraction, level: action.portals[guid].level } } else { portals[guid] = action.portals[guid] } }) return { ...store, portals } }, 'linksSet': (store: any, action: { links: { [guid: string]: Link } }) => ({ ...store, links: { ...store.links, ...action.links } }), 'fieldsSet': (store: any, action: { fields: { [guid: string]: Field } }) => ({ ...store, fields: { ...store.fields, ...action.fields } }), 'setLoad': (store: any, action: { queue: string[] }) => ({ ...store, loadQueue: [...action.queue] }), 'portalsGC': (store: any, action: { portals: { [tile: string]: string[] } }) => { let portalsCache = store.portalsCache let portals = store.portals Object.keys(action.portals).forEach(tileId => { const oldPortals = portalsCache[tileId] if (oldPortals != undefined) { oldPortals.forEach((guid: string) => { delete portals[guid] }) } portalsCache[tileId] = action.portals[tileId] }) return ({ ...store, portals: { ...portals }, portalsCache }) }, 'linksGC': (store: any, action: { links: { [tile: string]: string[] } }) => { let linksCache = store.linksCache let links = store.links Object.keys(action.links).forEach(tileId => { const oldLinks = linksCache[tileId] if (oldLinks != undefined) { oldLinks.forEach((guid: string) => { delete links[guid] }) } linksCache[tileId] = action.links[tileId] }) return ({ ...store, links: { ...links }, linksCache }) }, 'fieldsGC': (store: any, action: { fields: { [tile: string]: string[] } }) => { let fieldsCache = store.fieldsCache let fields = store.fields Object.keys(action.fields).forEach(tileId => { const oldFields = fieldsCache[tileId] if (oldFields != undefined) { oldFields.forEach((guid: string) => { delete fields[guid] }) } fieldsCache[tileId] = action.fields[tileId] }) return ({ ...store, fields: { ...fields }, fieldsCache }) }, }, { portals: {}, fields: {}, links: {}, loadQueue: [], linksCache: {}, fieldsCache: {}, portalsCache: {} }), 'settings': createReducer({ 'setLevelFrom': (store: any, action: { level: number }) => ({ ...store, filterLevel: [action.level, store.filterLevel[1]] }), 'setLevelTo': (store: any, action: { level: number }) => ({ ...store, filterLevel: [store.filterLevel[0], action.level] }), 'setRegion': (store: any, action: { region: Region }) => ({ ...store, region: action.region }) }, { filterLevel: [0, 8], region: null }) } const rootReducer = combineReducers(reducers) const persistConfig = { key: 'root', storage: AsyncStorage, } const persistedReducer = persistReducer(persistConfig, rootReducer) export default () => { let store = createStore(persistedReducer, applyMiddleware(thunk)) let persistor = persistStore(store) return { store, persistor } }