/** * Created by jimsugg on 9/8/16. */ import { Action, ActionCreator, Dispatch } from 'redux'; import { ThunkAction } from 'redux-thunk'; import { BaDmId, BaDmIdNone, VideoMode, ZoneType, EventType, TransitionType } from './baDmDataTypes' import { DmMediaStateContainer, DmContentItem, DmEventData } from './baDmInterfaces'; import { DmInternal } from './baDmClasses'; import { getMediaStatesForZone } from './reducers/reducerMediaState'; import { newBaDmId } from './utils'; type DmState = DmInternal.DmState; // Dispatch type for baDm actions export type DmDispatch = Dispatch; // Actions export const NEW_SIGN = 'NEW_SIGN'; export const OPEN_SIGN = 'OPEN_SIGN'; export const ADD_ZONE = 'ADD_ZONE'; export const UPDATE_ZONE = 'UPDATE_ZONE'; export const DELETE_ZONE = 'DELETE_ZONE'; export const ADD_MEDIA_STATE = 'ADD_MEDIA_STATE'; export const UPDATE_MEDIA_STATE = 'UPDATE_MEDIA_STATE'; export const DELETE_MEDIA_STATE = 'DELETE_MEDIA_STATE'; export const ADD_EVENT = 'ADD_EVENT'; export const UPDATE_EVENT = 'UPDATE_EVENT'; export const DELETE_EVENT = 'DELETE_EVENT'; export const ADD_TRANSITION = 'ADD_TRANSITION'; export const UPDATE_TRANSITION = 'UPDATE_TRANSITION'; export const DELETE_TRANSITION = 'DELETE_TRANSITION'; interface BaDmSimpleAction extends Action { type: string, // override Any - must be a string id: BaDmId, } interface BaDmAction extends BaDmSimpleAction { payload: T } export interface SignParams { name?: string, videoMode?: VideoMode } export type SignAction = BaDmAction; export const baNewSign: ActionCreator = (name: string, mode: VideoMode) => ({ type: NEW_SIGN, id: newBaDmId(), payload: { name: name, videoMode: mode } }); // TODO - how will this be used?? export const baOpenSign: ActionCreator = (name: string, mode: VideoMode) => ({ type: OPEN_SIGN, id: newBaDmId(), payload: { name: name, videoMode: mode } }); export interface ZoneParams { name?: string, type?: ZoneType, nonInteractive?: boolean, initialMediaStateId?: BaDmId } export type ZoneAction = BaDmAction; // Zone can process several entity action payloads (this is a Typescript 2.0 discriminated union type) export type ZoneEntityAction = ZoneAction | MediaStateAction; export const baAddZone: ActionCreator = (name: string, type: ZoneType, nonInteractive = true) => ({ type: ADD_ZONE, id: newBaDmId(), payload: { name: name, type: type, nonInteractive: nonInteractive } }); // This fat arrow form, which should be roughly equivalent to the more traditional function def below, // doesn't work!!! Typescript complains. Lesson: Stick to old style functions for thunks in TypeScript. // export const baUpdateZone: ThunkAction = (id: BaDmId, params: ZoneParams) => // (dispatch, getState, ex) => // { // dispatch({type: UPDATE_ZONE, id: id, payload: params}); // }; export function baUpdateZone(id: BaDmId, params: ZoneParams) : ThunkAction { return (dispatch, getState, ex) => { // If the update parameters include an update initialMediaStateId, make sure that the ID // actually refers to a media state in the given zone. If not, do not proceed with the update. // TODO: if update fails, return an error (probably best achieved by returning a Promise.) let doUpdate = true; if (params.initialMediaStateId) { let mediaStates = getMediaStatesForZone(getState(), {id: id}); doUpdate = mediaStates.indexOf(params.initialMediaStateId) >= 0; } if (doUpdate) { dispatch({type: UPDATE_ZONE, id: id, payload: params}); } else { console.log("ERROR!! - invalid initial media state"); } }; } export const baDeleteZone: ActionCreator = (id: BaDmId) => ({ type: DELETE_ZONE, id: id }); export interface MediaStateParams { name?: string, container?: DmMediaStateContainer, contentItem?: DmContentItem, } export type MediaStateAction = BaDmAction; export const baAddMediaState: ActionCreator = ( name: string, container: DmMediaStateContainer, contentItem: DmContentItem, volume = 0 ) => ({ type: ADD_MEDIA_STATE, id: newBaDmId(), payload: { name: name, container: container, contentItem: contentItem, volume: volume } }); export const baUpdateMediaState: ActionCreator = (id: BaDmId, params: MediaStateParams) => ({ type: UPDATE_MEDIA_STATE, id: id, payload: params }); export const baDeleteMediaState: ActionCreator = (id: BaDmId) => ({ type: DELETE_MEDIA_STATE, id: id }); export interface EventParams { name?: string, type?: EventType; mediaStateId?: BaDmId; data?: DmEventData; } export type EventAction = BaDmAction; export const baAddEvent: ActionCreator = (name: string, type: EventType, mediaState: BaDmId, data?: DmEventData) => ({ type: ADD_EVENT, id: newBaDmId(), payload: { name: name, type: type, mediaStateId: mediaState, data: data } }); export const baUpdateEvent: ActionCreator = (id: BaDmId, params: EventParams) => ({ type: UPDATE_EVENT , id: id, payload: params }); export const baDeleteEvent: ActionCreator = (id: BaDmId) => ({ type: DELETE_EVENT, id: id }); export interface TransitionParams { name?: string, eventId?: BaDmId, targetMediaStateId?: BaDmId; type?: TransitionType; conditionId?: BaDmId; } export type TransitionAction = BaDmAction; export const baAddTransition: ActionCreator = ( name: string, eventId: BaDmId, targetMediaStateId: BaDmId, type : TransitionType = TransitionType.No_effect, conditionId? : BaDmId ) => ({ type: ADD_TRANSITION, id: newBaDmId(), payload: { name: name, eventId: eventId, targetMediaStateId: targetMediaStateId, type: type, conditionId: conditionId } }); export const baUpdateTransition: ActionCreator = (id: BaDmId, params: TransitionParams) => ({ type: UPDATE_TRANSITION , id: id, payload: params }); export const baDeleteTransition: ActionCreator = (id: BaDmId) => ({ type: DELETE_TRANSITION, id: id });