diff options
Diffstat (limited to 'frontend/src/store')
| -rw-r--r-- | frontend/src/store/configure-store.js | 41 | ||||
| -rw-r--r-- | frontend/src/store/middlewares/dummy-middleware.js | 3 | ||||
| -rw-r--r-- | frontend/src/store/middlewares/viewport-adjustment.js | 90 |
3 files changed, 134 insertions, 0 deletions
diff --git a/frontend/src/store/configure-store.js b/frontend/src/store/configure-store.js new file mode 100644 index 00000000..29af25ab --- /dev/null +++ b/frontend/src/store/configure-store.js @@ -0,0 +1,41 @@ +import { applyMiddleware, compose, createStore } from "redux"; +import persistState from "redux-localstorage"; +import { createLogger } from "redux-logger"; +import createSagaMiddleware from "redux-saga"; +import thunk from "redux-thunk"; +import { authRedirectMiddleware } from "../auth/index"; +import rootReducer from "../reducers/index"; +import rootSaga from "../sagas/index"; +import { dummyMiddleware } from "./middlewares/dummy-middleware"; +import { viewportAdjustmentMiddleware } from "./middlewares/viewport-adjustment"; + +const sagaMiddleware = createSagaMiddleware(); + +let logger; +if (process.env.NODE_ENV !== "production") { + logger = createLogger(); +} + +const middlewares = [ + process.env.NODE_ENV === "production" ? dummyMiddleware : logger, + thunk, + sagaMiddleware, + authRedirectMiddleware, + viewportAdjustmentMiddleware +]; + +export let store = undefined; + +export default function configureStore() { + const configuredStore = createStore( + rootReducer, + compose( + persistState("auth"), + applyMiddleware(...middlewares) + ) + ); + sagaMiddleware.run(rootSaga); + store = configuredStore; + + return configuredStore; +} diff --git a/frontend/src/store/middlewares/dummy-middleware.js b/frontend/src/store/middlewares/dummy-middleware.js new file mode 100644 index 00000000..468b15d1 --- /dev/null +++ b/frontend/src/store/middlewares/dummy-middleware.js @@ -0,0 +1,3 @@ +export const dummyMiddleware = store => next => action => { + next(action); +}; diff --git a/frontend/src/store/middlewares/viewport-adjustment.js b/frontend/src/store/middlewares/viewport-adjustment.js new file mode 100644 index 00000000..132391f3 --- /dev/null +++ b/frontend/src/store/middlewares/viewport-adjustment.js @@ -0,0 +1,90 @@ +import { + SET_MAP_DIMENSIONS, + setMapPosition, + setMapScale +} from "../../actions/map"; +import { SET_CURRENT_DATACENTER } from "../../actions/topology/building"; +import { + MAP_MAX_SCALE, + MAP_MIN_SCALE, + SIDEBAR_WIDTH, + TILE_SIZE_IN_PIXELS, + VIEWPORT_PADDING +} from "../../components/app/map/MapConstants"; +import { calculateRoomListBounds } from "../../util/tile-calculations"; + +export const viewportAdjustmentMiddleware = store => next => action => { + const state = store.getState(); + + let datacenterId = -1; + let mapDimensions = {}; + if (action.type === SET_CURRENT_DATACENTER && action.datacenterId !== -1) { + datacenterId = action.datacenterId; + mapDimensions = state.map.dimensions; + } else if ( + action.type === SET_MAP_DIMENSIONS && + state.currentDatacenterId !== -1 + ) { + datacenterId = state.currentDatacenterId; + mapDimensions = { width: action.width, height: action.height }; + } + + if (datacenterId !== -1) { + const roomIds = state.objects.datacenter[datacenterId].roomIds; + const rooms = roomIds.map(id => Object.assign({}, state.objects.room[id])); + rooms.forEach( + room => + (room.tiles = room.tileIds.map(tileId => state.objects.tile[tileId])) + ); + + let hasNoTiles = true; + for (let i in rooms) { + if (rooms[i].tiles.length > 0) { + hasNoTiles = false; + break; + } + } + + if (!hasNoTiles) { + const viewportParams = calculateParametersToZoomInOnRooms( + rooms, + mapDimensions.width, + mapDimensions.height + ); + store.dispatch(setMapPosition(viewportParams.newX, viewportParams.newY)); + store.dispatch(setMapScale(viewportParams.newScale)); + } + } + + next(action); +}; + +function calculateParametersToZoomInOnRooms(rooms, mapWidth, mapHeight) { + const bounds = calculateRoomListBounds(rooms); + const newScale = calculateNewScale(bounds, mapWidth, mapHeight); + + // Coordinates of the center of the room, relative to the global origin of the map + const roomCenterCoordinates = { + x: bounds.center.x * TILE_SIZE_IN_PIXELS * newScale, + y: bounds.center.y * TILE_SIZE_IN_PIXELS * newScale + }; + + const newX = -roomCenterCoordinates.x + mapWidth / 2; + const newY = -roomCenterCoordinates.y + mapHeight / 2; + + return { newScale, newX, newY }; +} + +function calculateNewScale(bounds, mapWidth, mapHeight) { + const width = bounds.max.x - bounds.min.x; + const height = bounds.max.y - bounds.min.y; + + const scaleX = + (mapWidth - 2 * SIDEBAR_WIDTH) / + (width * TILE_SIZE_IN_PIXELS + 2 * VIEWPORT_PADDING); + const scaleY = + mapHeight / (height * TILE_SIZE_IN_PIXELS + 2 * VIEWPORT_PADDING); + const newScale = Math.min(scaleX, scaleY); + + return Math.min(Math.max(MAP_MIN_SCALE, newScale), MAP_MAX_SCALE); +} |
