import { Dispatch, Store } from 'redux'; import { Region } from 'react-native-maps'; import { getTilesToLoad, loadTiles, getPortalDetails } from '../Api/api'; import { Portal, Link, Field } from '../Api/types'; import { LoadedResult } from '../Api/interfaces'; import { decodePortal } from '../Api/entityDecoder'; const entity = { 'update': (region: Region, width: number, refresh: boolean) => async (dispatch, getStore) => { const store = getStore() let tiles = getTilesToLoad(region, width) if (!refresh) { const loadedAlready = Object.keys(store.entities.portals) tiles = tiles.filter(t => loadedAlready.indexOf(t) == -1) } const display = store.entities.display dispatch(entity.loadTiles(tiles, display)) }, 'loadTiles': (tiles: string[], display: any) => async (dispatch, getStore) => { const store = getStore() const { v, csrf } = store.auth const params = { v, csrf } dispatch(entity.entitiesLoad(tiles.length)) setImmediate(() => loadTiles(tiles, params) .then((loadedData: LoadedResult) => dispatch(entity.receiveTiles(loadedData, display)))) }, 'receiveTiles': (loadedData: LoadedResult, display: any) => async (dispatch) => { dispatch(entity.portalsSet(loadedData.portals)) dispatch(entity.linksSet(loadedData.links)) dispatch(entity.fieldsSet(loadedData.fields)) Object.keys(loadedData.portalsByTile).forEach(tile => { loadedData.portalsByTile[tile].forEach(p => { if (display.portals.indexOf(p) == -1) { display.portals.push(p) } }) }) Object.keys(loadedData.linksByTile).forEach(tile => { loadedData.linksByTile[tile].forEach(p => { if (display.links.indexOf(p) == -1) { display.links.push(p) } }) }) Object.keys(loadedData.fieldsByTile).forEach(tile => { loadedData.fieldsByTile[tile].forEach(p => { if (display.fields.indexOf(p) == -1) { display.fields.push(p) } }) }) dispatch(entity.entitiesDisplay(display)) if (loadedData.failedTiles.length > 0) { setImmediate(() => { dispatch(entity.loadTiles(loadedData.failedTiles, display)) }) } else { dispatch(entity.entitiesLoad(0)) } }, 'getPortalDetails': (guid: string) => async (dispatch, getStore) => { const store = getStore() const { v, csrf } = store.auth const params = { v, csrf } getPortalDetails(guid, params).then(j => { const portal = decodePortal(j.result) portal.fullLoad = true dispatch(entity.portalSet(guid, portal)) }) }, 'entitiesDisplay': (display: any) => ({ type: 'entitiesDisplay', display }), 'entitiesLoad': (loading: number) => ({ type: 'entitiesLoad', loading }), 'portalsSet': (portals: { [guid: string]: Portal }) => ({ type: 'portalsSet', portals, }), 'linksSet': (links: { [guid: string]: Link }) => ({ type: 'linksSet', links, }), 'fieldsSet': (fields: { [guid: string]: Field }) => ({ type: 'fieldsSet', fields, }), 'portalSet': (guid: string, portal: Portal) => ({ type: 'portalSet', guid, portal, }), 'linkSet': (guid: string, link: Link) => ({ type: 'linksSet', guid, link, }), 'fieldSet': (guid: string, field: Field) => ({ type: 'fieldsSet', guid, field, }) } export default entity