/** * Created by jimsugg on 9/17/16. */ import { combineReducers } from 'redux'; import { createSelector } from 'reselect'; import { BaDmId, BaDmIdNone, ZoneType } from '../baDmDataTypes'; import { DmZoneState, DmZone } from '../baDmInterfaces'; import { DmInternal } from "../baDmClasses"; import { ZoneEntityAction, ZoneParams, MediaStateParams } from '../baDmActions' import { NEW_SIGN, ADD_ZONE, UPDATE_ZONE, DELETE_ZONE, ADD_MEDIA_STATE } from "../baDmActions"; var _ = require('lodash/omit'); type DmState = DmInternal.DmState; type DmZoneMap = DmInternal.DmMap; // Return a simple object conforming to DmZoneState const createZoneState = (id: BaDmId, name: string, type: ZoneType, nonInteractive: boolean) => ({ id: id, name: name, type: type, nonInteractive: nonInteractive, initialMediaStateId: BaDmIdNone }); const zonesById = (state : DmZoneMap = {}, {type, id, payload} : ZoneEntityAction) => { switch (type) { case NEW_SIGN : return {}; case ADD_ZONE : let {name: zoneName, type: zoneType, nonInteractive} = payload; return Object.assign({}, state, {[id]: createZoneState(id, zoneName, zoneType, nonInteractive)}); case UPDATE_ZONE : let updatedZone = Object.assign({}, state[id], payload); return Object.assign({}, state, {[id]: updatedZone}); case DELETE_ZONE : return _.omit(state, id); case ADD_MEDIA_STATE : // First media state added to a zone always becomes the initial state // For this action, action.id == mediaStateId, mediaState.container.id == ZoneId let {container} = payload; let zone = state[container.id]; if (zone && zone.initialMediaStateId === BaDmIdNone) { let updatedZone = Object.assign({}, state[container.id], {initialMediaStateId: id}); return Object.assign({}, state, {[container.id]: updatedZone}); } break; } return state; }; const allZones = (state: Array = [], {type, id} : ZoneEntityAction) => { switch (type) { case NEW_SIGN : return []; case ADD_ZONE : return [...state, id]; case DELETE_ZONE : let index = state.indexOf(id); if (index >= 0) { return [...state.slice(0,index), ...state.slice(index+1)]; } } return state; }; const zoneReducer = combineReducers( {zonesById, allZones} ); export default zoneReducer; // Selectors export const getZoneById = (state: DmState, props: any) => { let zoneState = state.zones.zonesById[props.id]; return zoneState ? new DmInternal.Zone(zoneState) : undefined; } const getZonesById = (state: DmState) => state.zones.zonesById; const getZoneNameProp = (state: DmState, props : any) : string => (props.name); export const getZoneByName = createSelector ( getZonesById, getZoneNameProp, (zones, name) => { let zoneState : DmZoneState = undefined; Object.keys(zones).some((id, index, idArray): boolean => { if (zones[id].name === name) { zoneState = zones[id]; return true; } }); return zoneState ? new DmInternal.Zone(zoneState) : undefined; } ); export const getZonesForSign = (state: DmState) => state.zones.allZones; export const getZoneCount = (state: DmState) => state.zones.allZones.length;