webamp/js/reducers/media.ts
2018-10-06 14:20:08 -07:00

115 lines
3 KiB
TypeScript

import { Action, MediaStatus } from "../types";
import {
PLAY,
STOP,
PAUSE,
IS_STOPPED,
IS_PLAYING,
SET_VOLUME,
SET_BALANCE,
SET_MEDIA,
TOGGLE_REPEAT,
TOGGLE_SHUFFLE,
TOGGLE_TIME_MODE,
UPDATE_TIME_ELAPSED,
ADD_TRACK_FROM_URL,
CHANNEL_COUNT_CHANGED,
LOAD_SERIALIZED_STATE
} from "../actionTypes";
import { TIME_MODE, MEDIA_STATUS } from "../constants";
import { MediaSerializedStateV1 } from "../serializedStates/v1Types";
export interface MediaState {
timeMode: string; // TODO: Convert this to an enum
timeElapsed: number;
length: number | null;
kbps: string | null;
khz: string | null;
volume: number;
balance: number;
channels: number | null; // TODO: Convert this to an enum
shuffle: boolean;
repeat: boolean;
status: MediaStatus | null; // TODO: Convert this to an enum
}
const defaultState = {
timeMode: TIME_MODE.ELAPSED,
timeElapsed: 0,
length: null, // Consider renaming to "duration"
kbps: null,
khz: null,
// The winamp ini file declares the default volume as "200".
// The UI seems to show a default volume near 78, which would
// math with the default value being 200 out of 255.
volume: Math.round((200 / 255) * 100),
balance: 0,
channels: null,
shuffle: false,
repeat: false,
// TODO: Enforce possible values
status: MEDIA_STATUS.STOPPED
};
const media = (
state: MediaState = defaultState,
action: Action
): MediaState => {
switch (action.type) {
// TODO: Make these constants
case PLAY:
case IS_PLAYING:
return { ...state, status: MEDIA_STATUS.PLAYING };
case PAUSE:
return { ...state, status: MEDIA_STATUS.PAUSED };
case STOP:
case IS_STOPPED:
return { ...state, status: MEDIA_STATUS.STOPPED };
case CHANNEL_COUNT_CHANGED:
return { ...state, channels: action.channels };
case TOGGLE_TIME_MODE:
const newMode =
state.timeMode === TIME_MODE.REMAINING
? TIME_MODE.ELAPSED
: TIME_MODE.REMAINING;
return { ...state, timeMode: newMode };
case UPDATE_TIME_ELAPSED:
return { ...state, timeElapsed: action.elapsed };
case ADD_TRACK_FROM_URL:
return {
...state,
timeElapsed: 0,
length: null,
kbps: null,
khz: null,
channels: null
};
case SET_MEDIA:
return {
...state,
length: action.length,
kbps: action.kbps,
khz: action.khz,
channels: action.channels
};
case SET_VOLUME:
return { ...state, volume: action.volume };
case SET_BALANCE:
return { ...state, balance: action.balance };
case TOGGLE_REPEAT:
return { ...state, repeat: !state.repeat };
case TOGGLE_SHUFFLE:
return { ...state, shuffle: !state.shuffle };
case LOAD_SERIALIZED_STATE:
return { ...state, ...action.serializedState.media };
default:
return state;
}
};
export function getSerializedState(state: MediaState): MediaSerializedStateV1 {
const { volume, balance, shuffle, repeat } = state;
return { volume, balance, shuffle, repeat };
}
export default media;