mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-23 02:15:01 +00:00
Finish migration to inline action types
This commit is contained in:
parent
c6d0c2717c
commit
274abd9090
19 changed files with 247 additions and 425 deletions
|
|
@ -7,13 +7,6 @@ import { getWebampConfig } from "./webampConfig";
|
|||
import * as SoundCloud from "./SoundCloud";
|
||||
|
||||
import WebampLazy from "../../js/webampLazy";
|
||||
import {
|
||||
DISABLE_MARQUEE,
|
||||
SET_DUMMY_VIZ_DATA,
|
||||
SET_EQ_AUTO,
|
||||
TOGGLE_REPEAT,
|
||||
TOGGLE_SHUFFLE,
|
||||
} from "../../js/actionTypes";
|
||||
|
||||
import { disableMarquee, skinUrl as configSkinUrl } from "./config";
|
||||
import DemoDesktop from "./DemoDesktop";
|
||||
|
|
@ -95,15 +88,15 @@ async function main() {
|
|||
const webamp = new WebampLazy(config);
|
||||
|
||||
if (disableMarquee || screenshot) {
|
||||
webamp.store.dispatch({ type: DISABLE_MARQUEE });
|
||||
webamp.store.dispatch({ type: "DISABLE_MARQUEE" });
|
||||
}
|
||||
if (screenshot) {
|
||||
window.document.body.style.backgroundColor = "#000";
|
||||
webamp.store.dispatch({ type: TOGGLE_REPEAT });
|
||||
webamp.store.dispatch({ type: TOGGLE_SHUFFLE });
|
||||
webamp.store.dispatch({ type: SET_EQ_AUTO, value: true });
|
||||
webamp.store.dispatch({ type: "TOGGLE_REPEAT" });
|
||||
webamp.store.dispatch({ type: "TOGGLE_SHUFFLE" });
|
||||
webamp.store.dispatch({ type: "SET_EQ_AUTO", value: true });
|
||||
webamp.store.dispatch({
|
||||
type: SET_DUMMY_VIZ_DATA,
|
||||
type: "SET_DUMMY_VIZ_DATA",
|
||||
data: {
|
||||
0: 11.75,
|
||||
8: 11.0625,
|
||||
|
|
|
|||
|
|
@ -8,15 +8,6 @@ import * as SoundCloud from "./SoundCloud";
|
|||
|
||||
import { Action, Options, AppState, WindowLayout } from "../../js/types";
|
||||
|
||||
import {
|
||||
STEP_MARQUEE,
|
||||
UPDATE_TIME_ELAPSED,
|
||||
UPDATE_WINDOW_POSITIONS,
|
||||
SET_VOLUME,
|
||||
SET_BALANCE,
|
||||
SET_BAND_VALUE,
|
||||
} from "../../js/actionTypes";
|
||||
|
||||
import { getButterchurnOptions } from "./butterchurnOptions";
|
||||
import dropboxFilePicker from "./dropboxFilePicker";
|
||||
import availableSkins from "./availableSkins";
|
||||
|
|
@ -26,12 +17,12 @@ import screenshotInitialState from "./screenshotInitialState";
|
|||
import { InjectableDependencies, PrivateOptions } from "../../js/webampLazy";
|
||||
|
||||
const NOISY_ACTION_TYPES = new Set([
|
||||
STEP_MARQUEE,
|
||||
UPDATE_TIME_ELAPSED,
|
||||
UPDATE_WINDOW_POSITIONS,
|
||||
SET_VOLUME,
|
||||
SET_BALANCE,
|
||||
SET_BAND_VALUE,
|
||||
"STEP_MARQUEE",
|
||||
"UPDATE_TIME_ELAPSED",
|
||||
"UPDATE_WINDOW_POSITIONS",
|
||||
"SET_VOLUME",
|
||||
"SET_BALANCE",
|
||||
"SET_BAND_VALUE",
|
||||
]);
|
||||
|
||||
const MIN_MILKDROP_WIDTH = 725;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,5 @@
|
|||
// TODO: Split these out into individual files.
|
||||
import { BANDS } from "../constants";
|
||||
import {
|
||||
STOP,
|
||||
SET_VOLUME,
|
||||
SET_BALANCE,
|
||||
TOGGLE_REPEAT,
|
||||
TOGGLE_SHUFFLE,
|
||||
SET_BAND_VALUE,
|
||||
} from "../actionTypes";
|
||||
|
||||
import {
|
||||
stop,
|
||||
|
|
@ -23,21 +15,21 @@ import {
|
|||
} from "./";
|
||||
|
||||
test("stop", () => {
|
||||
const expectedAction = { type: STOP };
|
||||
const expectedAction = { type: "STOP" };
|
||||
expect(stop()).toEqual(expectedAction);
|
||||
});
|
||||
|
||||
describe("setVolume", () => {
|
||||
it("enforces a mimimum value", () => {
|
||||
const expectedAction = {
|
||||
type: SET_VOLUME,
|
||||
type: "SET_VOLUME",
|
||||
volume: 0,
|
||||
};
|
||||
expect(setVolume(-10)).toEqual(expectedAction);
|
||||
});
|
||||
it("enforces a maximum value", () => {
|
||||
const expectedAction = {
|
||||
type: SET_VOLUME,
|
||||
type: "SET_VOLUME",
|
||||
volume: 100,
|
||||
};
|
||||
expect(setVolume(110)).toEqual(expectedAction);
|
||||
|
|
@ -47,28 +39,28 @@ describe("setVolume", () => {
|
|||
describe("setBalance", () => {
|
||||
it("enforces a mimimum value", () => {
|
||||
const expectedAction = {
|
||||
type: SET_BALANCE,
|
||||
type: "SET_BALANCE",
|
||||
balance: -100,
|
||||
};
|
||||
expect(setBalance(-110)).toEqual(expectedAction);
|
||||
});
|
||||
it("enforces a maximum value", () => {
|
||||
const expectedAction = {
|
||||
type: SET_BALANCE,
|
||||
type: "SET_BALANCE",
|
||||
balance: 100,
|
||||
};
|
||||
expect(setBalance(110)).toEqual(expectedAction);
|
||||
});
|
||||
it("snaps to zero for positive values close to zero", () => {
|
||||
const expectedAction = {
|
||||
type: SET_BALANCE,
|
||||
type: "SET_BALANCE",
|
||||
balance: 0,
|
||||
};
|
||||
expect(setBalance(24)).toEqual(expectedAction);
|
||||
});
|
||||
it("snaps to zero for negative values close to zero", () => {
|
||||
const expectedAction = {
|
||||
type: SET_BALANCE,
|
||||
type: "SET_BALANCE",
|
||||
balance: 0,
|
||||
};
|
||||
expect(setBalance(-24)).toEqual(expectedAction);
|
||||
|
|
@ -76,22 +68,22 @@ describe("setBalance", () => {
|
|||
});
|
||||
|
||||
test("toggleRepeat", () => {
|
||||
const expectedAction = { type: TOGGLE_REPEAT };
|
||||
const expectedAction = { type: "TOGGLE_REPEAT" };
|
||||
expect(toggleRepeat()).toEqual(expectedAction);
|
||||
});
|
||||
|
||||
test("toggleShuffle", () => {
|
||||
const expectedAction = { type: TOGGLE_SHUFFLE };
|
||||
const expectedAction = { type: "TOGGLE_SHUFFLE" };
|
||||
expect(toggleShuffle()).toEqual(expectedAction);
|
||||
});
|
||||
|
||||
test("setPreamp", () => {
|
||||
const expectedAction = { type: SET_BAND_VALUE, band: "preamp", value: 100 };
|
||||
const expectedAction = { type: "SET_BAND_VALUE", band: "preamp", value: 100 };
|
||||
expect(setPreamp(100)).toEqual(expectedAction);
|
||||
});
|
||||
|
||||
test("setEqBand", () => {
|
||||
const expectedAction = { type: SET_BAND_VALUE, band: 3, value: 100 };
|
||||
const expectedAction = { type: "SET_BAND_VALUE", band: 3, value: 100 };
|
||||
expect(setEqBand(3, 100)).toEqual(expectedAction);
|
||||
});
|
||||
|
||||
|
|
@ -100,7 +92,7 @@ test("setEqToMax", () => {
|
|||
const dispatcher = setEqToMax();
|
||||
dispatcher(mockDispatch);
|
||||
const expectedCalls = BANDS.map((band) => [
|
||||
{ type: SET_BAND_VALUE, band, value: 100 },
|
||||
{ type: "SET_BAND_VALUE", band, value: 100 },
|
||||
]);
|
||||
expect(mockDispatch.mock.calls).toEqual(expectedCalls);
|
||||
});
|
||||
|
|
@ -110,7 +102,7 @@ test("setEqToMin", () => {
|
|||
const dispatcher = setEqToMin();
|
||||
dispatcher(mockDispatch);
|
||||
const expectedCalls = BANDS.map((band) => [
|
||||
{ type: SET_BAND_VALUE, band, value: 0 },
|
||||
{ type: "SET_BAND_VALUE", band, value: 0 },
|
||||
]);
|
||||
expect(mockDispatch.mock.calls).toEqual(expectedCalls);
|
||||
});
|
||||
|
|
@ -120,7 +112,7 @@ test("setEqToMid", () => {
|
|||
const dispatcher = setEqToMid();
|
||||
dispatcher(mockDispatch);
|
||||
const expectedCalls = BANDS.map((band) => [
|
||||
{ type: SET_BAND_VALUE, band, value: 50 },
|
||||
{ type: "SET_BAND_VALUE", band, value: 50 },
|
||||
]);
|
||||
expect(mockDispatch.mock.calls).toEqual(expectedCalls);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,4 @@
|
|||
import { FormEvent, memo, useCallback } from "react";
|
||||
|
||||
import {
|
||||
SEEK_TO_PERCENT_COMPLETE,
|
||||
SET_FOCUS,
|
||||
UNSET_FOCUS,
|
||||
SET_SCRUB_POSITION,
|
||||
} from "../../actionTypes";
|
||||
import * as Selectors from "../../selectors";
|
||||
import { useTypedSelector, useTypedDispatch } from "../../hooks";
|
||||
|
||||
|
|
@ -29,19 +22,19 @@ const Position = memo(() => {
|
|||
const seekToPercentComplete = useCallback(
|
||||
(e: FormEvent) => {
|
||||
dispatch({
|
||||
type: SEEK_TO_PERCENT_COMPLETE,
|
||||
type: "SEEK_TO_PERCENT_COMPLETE",
|
||||
percent: Number((e.target as HTMLInputElement).value),
|
||||
});
|
||||
dispatch({ type: UNSET_FOCUS });
|
||||
dispatch({ type: "UNSET_FOCUS" });
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
const setPosition = useCallback(
|
||||
(e: FormEvent) => {
|
||||
dispatch({ type: SET_FOCUS, input: "position" });
|
||||
dispatch({ type: "SET_FOCUS", input: "position" });
|
||||
dispatch({
|
||||
type: SET_SCRUB_POSITION,
|
||||
type: "SET_SCRUB_POSITION",
|
||||
position: Number((e.target as HTMLInputElement).value),
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
import { useCallback, ReactNode, TouchEvent } from "react";
|
||||
import classnames from "classnames";
|
||||
import {
|
||||
CLICKED_TRACK,
|
||||
CTRL_CLICKED_TRACK,
|
||||
SHIFT_CLICKED_TRACK,
|
||||
} from "../../actionTypes";
|
||||
import * as Selectors from "../../selectors";
|
||||
import * as Actions from "../../actionCreators";
|
||||
import {
|
||||
|
|
@ -36,16 +31,16 @@ function TrackCell({ children, handleMoveClick, index, id }: Props) {
|
|||
(e: React.MouseEvent<HTMLDivElement>) => {
|
||||
if (e.shiftKey) {
|
||||
e.preventDefault();
|
||||
dispatch({ type: SHIFT_CLICKED_TRACK, index });
|
||||
dispatch({ type: "SHIFT_CLICKED_TRACK", index });
|
||||
return;
|
||||
} else if (e.metaKey || e.ctrlKey) {
|
||||
e.preventDefault();
|
||||
dispatch({ type: CTRL_CLICKED_TRACK, index });
|
||||
dispatch({ type: "CTRL_CLICKED_TRACK", index });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!selected) {
|
||||
dispatch({ type: CLICKED_TRACK, index });
|
||||
dispatch({ type: "CLICKED_TRACK", index });
|
||||
}
|
||||
|
||||
handleMoveClick(e);
|
||||
|
|
@ -56,7 +51,7 @@ function TrackCell({ children, handleMoveClick, index, id }: Props) {
|
|||
const handleTouchStart = useCallback(
|
||||
(e: TouchEvent<HTMLDivElement>) => {
|
||||
if (!selected) {
|
||||
dispatch({ type: CLICKED_TRACK, index });
|
||||
dispatch({ type: "CLICKED_TRACK", index });
|
||||
}
|
||||
handleMoveClick(e);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,4 @@
|
|||
import { IMedia } from "./media";
|
||||
import {
|
||||
IS_PLAYING,
|
||||
PAUSE,
|
||||
PLAY,
|
||||
SEEK_TO_PERCENT_COMPLETE,
|
||||
SET_BAND_VALUE,
|
||||
SET_BALANCE,
|
||||
SET_MEDIA,
|
||||
SET_VOLUME,
|
||||
START_WORKING,
|
||||
STOP,
|
||||
STOP_WORKING,
|
||||
UPDATE_TIME_ELAPSED,
|
||||
SET_EQ_OFF,
|
||||
SET_EQ_ON,
|
||||
PLAY_TRACK,
|
||||
BUFFER_TRACK,
|
||||
LOAD_SERIALIZED_STATE,
|
||||
} from "./actionTypes";
|
||||
import { next as nextTrack } from "./actionCreators";
|
||||
import * as Selectors from "./selectors";
|
||||
import { MiddlewareStore, Action, Dispatch } from "./types";
|
||||
|
|
@ -37,7 +18,7 @@ export default (media: IMedia) => (store: MiddlewareStore) => {
|
|||
|
||||
media.on("timeupdate", () => {
|
||||
store.dispatch({
|
||||
type: UPDATE_TIME_ELAPSED,
|
||||
type: "UPDATE_TIME_ELAPSED",
|
||||
elapsed: media.timeElapsed(),
|
||||
});
|
||||
});
|
||||
|
|
@ -47,15 +28,15 @@ export default (media: IMedia) => (store: MiddlewareStore) => {
|
|||
});
|
||||
|
||||
media.on("playing", () => {
|
||||
store.dispatch({ type: IS_PLAYING });
|
||||
store.dispatch({ type: "IS_PLAYING" });
|
||||
});
|
||||
|
||||
media.on("waiting", () => {
|
||||
store.dispatch({ type: START_WORKING });
|
||||
store.dispatch({ type: "START_WORKING" });
|
||||
});
|
||||
|
||||
media.on("stopWaiting", () => {
|
||||
store.dispatch({ type: STOP_WORKING });
|
||||
store.dispatch({ type: "STOP_WORKING" });
|
||||
});
|
||||
|
||||
media.on("fileLoaded", () => {
|
||||
|
|
@ -67,7 +48,7 @@ export default (media: IMedia) => (store: MiddlewareStore) => {
|
|||
}
|
||||
store.dispatch({
|
||||
id,
|
||||
type: SET_MEDIA,
|
||||
type: "SET_MEDIA",
|
||||
kbps: "128",
|
||||
khz: "44",
|
||||
channels: 2,
|
||||
|
|
@ -79,52 +60,52 @@ export default (media: IMedia) => (store: MiddlewareStore) => {
|
|||
const returnValue = next(action);
|
||||
const state = store.getState();
|
||||
switch (action.type) {
|
||||
case PLAY:
|
||||
case "PLAY":
|
||||
media.play();
|
||||
break;
|
||||
case PAUSE:
|
||||
case "PAUSE":
|
||||
media.pause();
|
||||
break;
|
||||
case STOP:
|
||||
case "STOP":
|
||||
media.stop();
|
||||
break;
|
||||
case SET_VOLUME:
|
||||
case "SET_VOLUME":
|
||||
media.setVolume(Selectors.getVolume(state));
|
||||
break;
|
||||
case SET_BALANCE:
|
||||
case "SET_BALANCE":
|
||||
media.setBalance(Selectors.getBalance(state));
|
||||
break;
|
||||
case SEEK_TO_PERCENT_COMPLETE:
|
||||
media.seekToPercentComplete(action.percent);
|
||||
case "SEEK_TO_PERCENT_COMPLETE":
|
||||
media.seekToPercentComplete((action as any).percent);
|
||||
break;
|
||||
case PLAY_TRACK: {
|
||||
const url = Selectors.getTrackUrl(store.getState())(action.id);
|
||||
case "PLAY_TRACK": {
|
||||
const url = Selectors.getTrackUrl(store.getState())((action as any).id);
|
||||
if (url != null) {
|
||||
media.loadFromUrl(url, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BUFFER_TRACK: {
|
||||
const url = Selectors.getTrackUrl(store.getState())(action.id);
|
||||
case "BUFFER_TRACK": {
|
||||
const url = Selectors.getTrackUrl(store.getState())((action as any).id);
|
||||
if (url != null) {
|
||||
media.loadFromUrl(url, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SET_BAND_VALUE:
|
||||
if (action.band === "preamp") {
|
||||
media.setPreamp(action.value);
|
||||
case "SET_BAND_VALUE":
|
||||
if ((action as any).band === "preamp") {
|
||||
media.setPreamp((action as any).value);
|
||||
} else {
|
||||
media.setEqBand(action.band, action.value);
|
||||
media.setEqBand((action as any).band, (action as any).value);
|
||||
}
|
||||
break;
|
||||
case SET_EQ_OFF:
|
||||
case "SET_EQ_OFF":
|
||||
media.disableEq();
|
||||
break;
|
||||
case SET_EQ_ON:
|
||||
case "SET_EQ_ON":
|
||||
media.enableEq();
|
||||
break;
|
||||
case LOAD_SERIALIZED_STATE: {
|
||||
case "LOAD_SERIALIZED_STATE": {
|
||||
// Set ALL THE THINGS!
|
||||
if (Selectors.getEqualizerEnabled(state)) {
|
||||
media.enableEq();
|
||||
|
|
|
|||
|
|
@ -10,26 +10,6 @@ import {
|
|||
} from "../types";
|
||||
import * as Utils from "../utils";
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
import {
|
||||
CLOSE_WINAMP,
|
||||
OPEN_WINAMP,
|
||||
SET_SKIN_DATA,
|
||||
START_WORKING,
|
||||
STEP_MARQUEE,
|
||||
STOP_WORKING,
|
||||
TOGGLE_DOUBLESIZE_MODE,
|
||||
TOGGLE_LLAMA_MODE,
|
||||
TOGGLE_VISUALIZER_STYLE,
|
||||
SET_PLAYLIST_SCROLL_POSITION,
|
||||
LOADED,
|
||||
SET_Z_INDEX,
|
||||
DISABLE_MARQUEE,
|
||||
SET_DUMMY_VIZ_DATA,
|
||||
LOADING,
|
||||
LOAD_SERIALIZED_STATE,
|
||||
LOAD_DEFAULT_SKIN,
|
||||
} from "../actionTypes";
|
||||
import { DEFAULT_SKIN, VISUALIZER_ORDER } from "../constants";
|
||||
import { DisplaySerializedStateV1 } from "../serializedStates/v1Types";
|
||||
|
||||
|
|
@ -106,7 +86,7 @@ const display = (
|
|||
action: Action
|
||||
): DisplayState => {
|
||||
switch (action.type) {
|
||||
case LOAD_DEFAULT_SKIN: {
|
||||
case "LOAD_DEFAULT_SKIN": {
|
||||
const {
|
||||
skinImages,
|
||||
skinColors,
|
||||
|
|
@ -127,30 +107,30 @@ const display = (
|
|||
skinGenExColors,
|
||||
};
|
||||
}
|
||||
case TOGGLE_DOUBLESIZE_MODE:
|
||||
case "TOGGLE_DOUBLESIZE_MODE":
|
||||
return { ...state, doubled: !state.doubled };
|
||||
case TOGGLE_LLAMA_MODE:
|
||||
case "TOGGLE_LLAMA_MODE":
|
||||
return { ...state, llama: !state.llama };
|
||||
case STEP_MARQUEE:
|
||||
case "STEP_MARQUEE":
|
||||
return state.disableMarquee
|
||||
? state
|
||||
: { ...state, marqueeStep: state.marqueeStep + 1 };
|
||||
case DISABLE_MARQUEE:
|
||||
case "DISABLE_MARQUEE":
|
||||
return { ...state, disableMarquee: true };
|
||||
case STOP_WORKING:
|
||||
case "STOP_WORKING":
|
||||
return { ...state, working: false };
|
||||
case START_WORKING:
|
||||
case "START_WORKING":
|
||||
return { ...state, working: true };
|
||||
case CLOSE_WINAMP:
|
||||
case "CLOSE_WINAMP":
|
||||
return { ...state, closed: true };
|
||||
case OPEN_WINAMP:
|
||||
case "OPEN_WINAMP":
|
||||
return { ...state, closed: false };
|
||||
case LOADING:
|
||||
case "LOADING":
|
||||
return { ...state, loading: true };
|
||||
case LOADED:
|
||||
case "LOADED":
|
||||
return { ...state, loading: false };
|
||||
case SET_SKIN_DATA:
|
||||
const { data } = action;
|
||||
case "SET_SKIN_DATA":
|
||||
const { data } = action as any;
|
||||
return {
|
||||
...state,
|
||||
loading: false,
|
||||
|
|
@ -162,19 +142,19 @@ const display = (
|
|||
skinGenLetterWidths: data.skinGenLetterWidths,
|
||||
skinGenExColors: data.skinGenExColors || defaultSkinGenExColors,
|
||||
};
|
||||
case TOGGLE_VISUALIZER_STYLE:
|
||||
case "TOGGLE_VISUALIZER_STYLE":
|
||||
return {
|
||||
...state,
|
||||
visualizerStyle: (state.visualizerStyle + 1) % VISUALIZER_ORDER.length,
|
||||
};
|
||||
case SET_PLAYLIST_SCROLL_POSITION:
|
||||
return { ...state, playlistScrollPosition: action.position };
|
||||
case SET_Z_INDEX:
|
||||
return { ...state, zIndex: action.zIndex };
|
||||
case SET_DUMMY_VIZ_DATA:
|
||||
return { ...state, dummyVizData: action.data };
|
||||
case LOAD_SERIALIZED_STATE: {
|
||||
const { skinCursors, ...rest } = action.serializedState.display;
|
||||
case "SET_PLAYLIST_SCROLL_POSITION":
|
||||
return { ...state, playlistScrollPosition: (action as any).position };
|
||||
case "SET_Z_INDEX":
|
||||
return { ...state, zIndex: (action as any).zIndex };
|
||||
case "SET_DUMMY_VIZ_DATA":
|
||||
return { ...state, dummyVizData: (action as any).data };
|
||||
case "LOAD_SERIALIZED_STATE": {
|
||||
const { skinCursors, ...rest } = (action as any).serializedState.display;
|
||||
const upgrade = (url: string) => ({ type: "cur", url } as const);
|
||||
const newSkinCursors =
|
||||
skinCursors == null ? null : Utils.objectMap(skinCursors, upgrade);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,4 @@
|
|||
import { Slider, Action } from "./../types";
|
||||
|
||||
import {
|
||||
SET_BAND_VALUE,
|
||||
SET_EQ_AUTO,
|
||||
SET_EQ_ON,
|
||||
SET_EQ_OFF,
|
||||
LOAD_SERIALIZED_STATE,
|
||||
} from "../actionTypes";
|
||||
import { EqualizerSerializedStateV1 } from "../serializedStates/v1Types";
|
||||
|
||||
export interface EqualizerState {
|
||||
|
|
@ -38,17 +30,17 @@ const equalizer = (
|
|||
action: Action
|
||||
): EqualizerState => {
|
||||
switch (action.type) {
|
||||
case SET_BAND_VALUE:
|
||||
const newSliders = { ...state.sliders, [action.band]: action.value };
|
||||
case "SET_BAND_VALUE":
|
||||
const newSliders = { ...state.sliders, [(action as any).band]: (action as any).value };
|
||||
return { ...state, sliders: newSliders };
|
||||
case SET_EQ_ON:
|
||||
case "SET_EQ_ON":
|
||||
return { ...state, on: true };
|
||||
case SET_EQ_OFF:
|
||||
case "SET_EQ_OFF":
|
||||
return { ...state, on: false };
|
||||
case SET_EQ_AUTO:
|
||||
return { ...state, auto: action.value };
|
||||
case LOAD_SERIALIZED_STATE:
|
||||
return action.serializedState.equalizer || state;
|
||||
case "SET_EQ_AUTO":
|
||||
return { ...state, auto: (action as any).value };
|
||||
case "LOAD_SERIALIZED_STATE":
|
||||
return (action as any).serializedState.equalizer || state;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,4 @@
|
|||
import { Action, PlayerMediaStatus, TimeMode } 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,
|
||||
LOAD_SERIALIZED_STATE,
|
||||
CLOSE_WINAMP,
|
||||
OPEN_WINAMP,
|
||||
} from "../actionTypes";
|
||||
import { TIME_MODE, PLAYER_MEDIA_STATUS } from "../constants";
|
||||
import { MediaSerializedStateV1 } from "../serializedStates/v1Types";
|
||||
|
||||
|
|
@ -50,41 +33,41 @@ const media = (
|
|||
): MediaState => {
|
||||
switch (action.type) {
|
||||
// TODO: Make these constants
|
||||
case PLAY:
|
||||
case IS_PLAYING:
|
||||
case "PLAY":
|
||||
case "IS_PLAYING":
|
||||
return { ...state, status: PLAYER_MEDIA_STATUS.PLAYING };
|
||||
case PAUSE:
|
||||
case "PAUSE":
|
||||
return { ...state, status: PLAYER_MEDIA_STATUS.PAUSED };
|
||||
case STOP:
|
||||
case "STOP":
|
||||
return { ...state, status: PLAYER_MEDIA_STATUS.STOPPED };
|
||||
case IS_STOPPED:
|
||||
case "IS_STOPPED":
|
||||
return { ...state, status: PLAYER_MEDIA_STATUS.ENDED };
|
||||
case OPEN_WINAMP:
|
||||
case "OPEN_WINAMP":
|
||||
return { ...state, status: PLAYER_MEDIA_STATUS.STOPPED };
|
||||
case CLOSE_WINAMP:
|
||||
case "CLOSE_WINAMP":
|
||||
return { ...state, status: PLAYER_MEDIA_STATUS.CLOSED };
|
||||
case TOGGLE_TIME_MODE:
|
||||
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 SET_MEDIA:
|
||||
case "UPDATE_TIME_ELAPSED":
|
||||
return { ...state, timeElapsed: (action as any).elapsed };
|
||||
case "SET_MEDIA":
|
||||
return {
|
||||
...state,
|
||||
};
|
||||
case SET_VOLUME:
|
||||
return { ...state, volume: action.volume };
|
||||
case SET_BALANCE:
|
||||
return { ...state, balance: action.balance };
|
||||
case TOGGLE_REPEAT:
|
||||
case "SET_VOLUME":
|
||||
return { ...state, volume: (action as any).volume };
|
||||
case "SET_BALANCE":
|
||||
return { ...state, balance: (action as any).balance };
|
||||
case "TOGGLE_REPEAT":
|
||||
return { ...state, repeat: !state.repeat };
|
||||
case TOGGLE_SHUFFLE:
|
||||
case "TOGGLE_SHUFFLE":
|
||||
return { ...state, shuffle: !state.shuffle };
|
||||
case LOAD_SERIALIZED_STATE:
|
||||
return { ...state, ...action.serializedState.media };
|
||||
case "LOAD_SERIALIZED_STATE":
|
||||
return { ...state, ...(action as any).serializedState.media };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,4 @@
|
|||
import { Action, StatePreset, TransitionType, MilkdropMessage } from "../types";
|
||||
import {
|
||||
SET_MILKDROP_DESKTOP,
|
||||
SET_MILKDROP_FULLSCREEN,
|
||||
GOT_BUTTERCHURN_PRESETS,
|
||||
GOT_BUTTERCHURN,
|
||||
RESOLVE_PRESET_AT_INDEX,
|
||||
SELECT_PRESET_AT_INDEX,
|
||||
TOGGLE_PRESET_OVERLAY,
|
||||
PRESET_REQUESTED,
|
||||
TOGGLE_RANDOMIZE_PRESETS,
|
||||
TOGGLE_PRESET_CYCLING,
|
||||
SCHEDULE_MILKDROP_MESSAGE,
|
||||
} from "../actionTypes";
|
||||
import * as Utils from "../utils";
|
||||
|
||||
export interface MilkdropState {
|
||||
|
|
@ -47,55 +34,55 @@ export const milkdrop = (
|
|||
action: Action
|
||||
): MilkdropState => {
|
||||
switch (action.type) {
|
||||
case SET_MILKDROP_DESKTOP:
|
||||
return { ...state, display: action.enabled ? "DESKTOP" : "WINDOW" };
|
||||
case SET_MILKDROP_FULLSCREEN:
|
||||
return { ...state, display: action.enabled ? "FULLSCREEN" : "WINDOW" };
|
||||
case GOT_BUTTERCHURN:
|
||||
return { ...state, butterchurn: action.butterchurn };
|
||||
case GOT_BUTTERCHURN_PRESETS:
|
||||
case "SET_MILKDROP_DESKTOP":
|
||||
return { ...state, display: (action as any).enabled ? "DESKTOP" : "WINDOW" };
|
||||
case "SET_MILKDROP_FULLSCREEN":
|
||||
return { ...state, display: (action as any).enabled ? "FULLSCREEN" : "WINDOW" };
|
||||
case "GOT_BUTTERCHURN":
|
||||
return { ...state, butterchurn: (action as any).butterchurn };
|
||||
case "GOT_BUTTERCHURN_PRESETS":
|
||||
return {
|
||||
...state,
|
||||
presets: state.presets.concat(action.presets),
|
||||
presets: state.presets.concat((action as any).presets),
|
||||
};
|
||||
case PRESET_REQUESTED:
|
||||
if (action.addToHistory) {
|
||||
case "PRESET_REQUESTED":
|
||||
if ((action as any).addToHistory) {
|
||||
return {
|
||||
...state,
|
||||
presetHistory: [...state.presetHistory, action.index],
|
||||
presetHistory: [...state.presetHistory, (action as any).index],
|
||||
};
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
presetHistory: state.presetHistory.slice(0, -1),
|
||||
};
|
||||
case RESOLVE_PRESET_AT_INDEX:
|
||||
const preset = state.presets[action.index];
|
||||
case "RESOLVE_PRESET_AT_INDEX":
|
||||
const preset = state.presets[(action as any).index];
|
||||
return {
|
||||
...state,
|
||||
presets: Utils.replaceAtIndex(state.presets, action.index, {
|
||||
presets: Utils.replaceAtIndex(state.presets, (action as any).index, {
|
||||
type: "RESOLVED",
|
||||
name: preset.name,
|
||||
preset: action.json,
|
||||
preset: (action as any).json,
|
||||
}),
|
||||
};
|
||||
case SELECT_PRESET_AT_INDEX:
|
||||
case "SELECT_PRESET_AT_INDEX":
|
||||
return {
|
||||
...state,
|
||||
currentPresetIndex: action.index,
|
||||
transitionType: action.transitionType,
|
||||
currentPresetIndex: (action as any).index,
|
||||
transitionType: (action as any).transitionType,
|
||||
};
|
||||
case TOGGLE_PRESET_OVERLAY:
|
||||
case "TOGGLE_PRESET_OVERLAY":
|
||||
return { ...state, overlay: !state.overlay };
|
||||
case TOGGLE_RANDOMIZE_PRESETS:
|
||||
case "TOGGLE_RANDOMIZE_PRESETS":
|
||||
return { ...state, randomize: !state.randomize };
|
||||
case TOGGLE_PRESET_CYCLING:
|
||||
case "TOGGLE_PRESET_CYCLING":
|
||||
return { ...state, cycling: !state.cycling };
|
||||
case SCHEDULE_MILKDROP_MESSAGE:
|
||||
case "SCHEDULE_MILKDROP_MESSAGE":
|
||||
return {
|
||||
...state,
|
||||
message: {
|
||||
text: action.message,
|
||||
text: (action as any).message,
|
||||
time: Date.now(),
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { Action } from "../types";
|
||||
import { NETWORK_CONNECTED, NETWORK_DISCONNECTED } from "../actionTypes";
|
||||
|
||||
export interface NetworkState {
|
||||
connected: boolean;
|
||||
|
|
@ -10,9 +9,9 @@ const network = (
|
|||
action: Action
|
||||
): NetworkState => {
|
||||
switch (action.type) {
|
||||
case NETWORK_CONNECTED:
|
||||
case "NETWORK_CONNECTED":
|
||||
return { ...state, connected: true };
|
||||
case NETWORK_DISCONNECTED:
|
||||
case "NETWORK_DISCONNECTED":
|
||||
return { ...state, connected: false };
|
||||
default:
|
||||
return state;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
import {
|
||||
SHIFT_CLICKED_TRACK,
|
||||
CLICKED_TRACK,
|
||||
CTRL_CLICKED_TRACK,
|
||||
ADD_TRACK_FROM_URL,
|
||||
} from "../actionTypes";
|
||||
import reducer from "./playlist";
|
||||
|
||||
describe("playlist reducer", () => {
|
||||
|
|
@ -14,7 +8,7 @@ describe("playlist reducer", () => {
|
|||
lastSelectedIndex: null,
|
||||
};
|
||||
const nextState = reducer(initialState, {
|
||||
type: ADD_TRACK_FROM_URL,
|
||||
type: "ADD_TRACK_FROM_URL",
|
||||
id: 100,
|
||||
defaultName: "My Track Name",
|
||||
url: "url://some-url",
|
||||
|
|
@ -32,7 +26,7 @@ describe("playlist reducer", () => {
|
|||
lastSelectedIndex: 0,
|
||||
};
|
||||
const nextState = reducer(initialState, {
|
||||
type: ADD_TRACK_FROM_URL,
|
||||
type: "ADD_TRACK_FROM_URL",
|
||||
id: 100,
|
||||
defaultName: "My Track Name",
|
||||
url: "url://some-url",
|
||||
|
|
@ -50,7 +44,7 @@ describe("playlist reducer", () => {
|
|||
lastSelectedIndex: 0,
|
||||
};
|
||||
const nextState = reducer(initialState, {
|
||||
type: ADD_TRACK_FROM_URL,
|
||||
type: "ADD_TRACK_FROM_URL",
|
||||
id: 100,
|
||||
defaultName: "My Track Name",
|
||||
url: "url://some-url",
|
||||
|
|
@ -70,7 +64,7 @@ describe("playlist reducer", () => {
|
|||
};
|
||||
|
||||
const nextState = reducer(initialState, {
|
||||
type: CLICKED_TRACK,
|
||||
type: "CLICKED_TRACK",
|
||||
index: 1,
|
||||
});
|
||||
expect(nextState).toEqual({
|
||||
|
|
@ -87,7 +81,7 @@ describe("playlist reducer", () => {
|
|||
};
|
||||
|
||||
const nextState = reducer(initialState, {
|
||||
type: CTRL_CLICKED_TRACK,
|
||||
type: "CTRL_CLICKED_TRACK",
|
||||
index: 0,
|
||||
});
|
||||
expect(nextState).toEqual({
|
||||
|
|
@ -104,7 +98,7 @@ describe("playlist reducer", () => {
|
|||
};
|
||||
|
||||
const nextState = reducer(initialState, {
|
||||
type: SHIFT_CLICKED_TRACK,
|
||||
type: "SHIFT_CLICKED_TRACK",
|
||||
index: 3,
|
||||
});
|
||||
expect(nextState).toEqual({
|
||||
|
|
|
|||
|
|
@ -1,21 +1,4 @@
|
|||
import { Action } from "../types";
|
||||
import {
|
||||
CLICKED_TRACK,
|
||||
CTRL_CLICKED_TRACK,
|
||||
SHIFT_CLICKED_TRACK,
|
||||
SELECT_ALL,
|
||||
SELECT_ZERO,
|
||||
INVERT_SELECTION,
|
||||
REMOVE_ALL_TRACKS,
|
||||
REMOVE_TRACKS,
|
||||
ADD_TRACK_FROM_URL,
|
||||
REVERSE_LIST,
|
||||
RANDOMIZE_LIST,
|
||||
SET_TRACK_ORDER,
|
||||
PLAY_TRACK,
|
||||
BUFFER_TRACK,
|
||||
DRAG_SELECTED,
|
||||
} from "../actionTypes";
|
||||
import { shuffle, moveSelected } from "../utils";
|
||||
|
||||
export interface PlaylistState {
|
||||
|
|
@ -45,14 +28,14 @@ const playlist = (
|
|||
action: Action
|
||||
): PlaylistState => {
|
||||
switch (action.type) {
|
||||
case CLICKED_TRACK:
|
||||
case "CLICKED_TRACK":
|
||||
return {
|
||||
...state,
|
||||
selectedTracks: new Set([state.trackOrder[action.index]]),
|
||||
lastSelectedIndex: action.index,
|
||||
selectedTracks: new Set([state.trackOrder[(action as any).index]]),
|
||||
lastSelectedIndex: (action as any).index,
|
||||
};
|
||||
case CTRL_CLICKED_TRACK: {
|
||||
const id = state.trackOrder[action.index];
|
||||
case "CTRL_CLICKED_TRACK": {
|
||||
const id = state.trackOrder[(action as any).index];
|
||||
const newSelectedTracks = new Set(state.selectedTracks);
|
||||
toggleSetMembership(newSelectedTracks, id);
|
||||
return {
|
||||
|
|
@ -61,14 +44,14 @@ const playlist = (
|
|||
// Using this as the lastClickedIndex is kinda funny, since you
|
||||
// may have just _un_selected the track. However, this is what
|
||||
// Winamp 2 does, so we'll copy it.
|
||||
lastSelectedIndex: action.index,
|
||||
lastSelectedIndex: (action as any).index,
|
||||
};
|
||||
}
|
||||
case SHIFT_CLICKED_TRACK:
|
||||
case "SHIFT_CLICKED_TRACK":
|
||||
if (state.lastSelectedIndex == null) {
|
||||
return state;
|
||||
}
|
||||
const clickedIndex = action.index;
|
||||
const clickedIndex = (action as any).index;
|
||||
const start = Math.min(clickedIndex, state.lastSelectedIndex);
|
||||
const end = Math.max(clickedIndex, state.lastSelectedIndex);
|
||||
const selectedTracks = new Set(state.trackOrder.slice(start, end + 1));
|
||||
|
|
@ -76,24 +59,24 @@ const playlist = (
|
|||
...state,
|
||||
selectedTracks,
|
||||
};
|
||||
case SELECT_ALL:
|
||||
case "SELECT_ALL":
|
||||
return {
|
||||
...state,
|
||||
selectedTracks: new Set(state.trackOrder),
|
||||
};
|
||||
case SELECT_ZERO:
|
||||
case "SELECT_ZERO":
|
||||
return {
|
||||
...state,
|
||||
selectedTracks: new Set(),
|
||||
};
|
||||
case INVERT_SELECTION:
|
||||
case "INVERT_SELECTION":
|
||||
return {
|
||||
...state,
|
||||
selectedTracks: new Set(
|
||||
state.trackOrder.filter((id) => !state.selectedTracks.has(id))
|
||||
),
|
||||
};
|
||||
case REMOVE_ALL_TRACKS:
|
||||
case "REMOVE_ALL_TRACKS":
|
||||
// TODO: Consider disposing of ObjectUrls
|
||||
return {
|
||||
...state,
|
||||
|
|
@ -102,9 +85,9 @@ const playlist = (
|
|||
selectedTracks: new Set(),
|
||||
lastSelectedIndex: null,
|
||||
};
|
||||
case REMOVE_TRACKS:
|
||||
case "REMOVE_TRACKS":
|
||||
// TODO: Consider disposing of ObjectUrls
|
||||
const actionIds = new Set(action.ids.map(Number));
|
||||
const actionIds = new Set((action as any).ids.map(Number));
|
||||
const { currentTrack } = state;
|
||||
return {
|
||||
...state,
|
||||
|
|
@ -118,47 +101,47 @@ const playlist = (
|
|||
// TODO: This could probably be made to work, but we clear it just to be safe.
|
||||
lastSelectedIndex: null,
|
||||
};
|
||||
case REVERSE_LIST:
|
||||
case "REVERSE_LIST":
|
||||
return {
|
||||
...state,
|
||||
trackOrder: [...state.trackOrder].reverse(),
|
||||
// TODO: This could probably be made to work, but we clear it just to be safe.
|
||||
lastSelectedIndex: null,
|
||||
};
|
||||
case RANDOMIZE_LIST:
|
||||
case "RANDOMIZE_LIST":
|
||||
return {
|
||||
...state,
|
||||
trackOrder: shuffle(state.trackOrder),
|
||||
};
|
||||
case SET_TRACK_ORDER:
|
||||
const { trackOrder } = action;
|
||||
case "SET_TRACK_ORDER":
|
||||
const { trackOrder } = action as any;
|
||||
return { ...state, trackOrder };
|
||||
case ADD_TRACK_FROM_URL:
|
||||
case "ADD_TRACK_FROM_URL":
|
||||
const atIndex =
|
||||
action.atIndex == null ? state.trackOrder.length : action.atIndex;
|
||||
(action as any).atIndex == null ? state.trackOrder.length : (action as any).atIndex;
|
||||
return {
|
||||
...state,
|
||||
trackOrder: [
|
||||
...state.trackOrder.slice(0, atIndex),
|
||||
Number(action.id),
|
||||
Number((action as any).id),
|
||||
...state.trackOrder.slice(atIndex),
|
||||
],
|
||||
// TODO: This could probably be made to work, but we clear it just to be safe.
|
||||
lastSelectedIndex: null,
|
||||
};
|
||||
case PLAY_TRACK:
|
||||
case BUFFER_TRACK:
|
||||
case "PLAY_TRACK":
|
||||
case "BUFFER_TRACK":
|
||||
return {
|
||||
...state,
|
||||
currentTrack: action.id,
|
||||
currentTrack: (action as any).id,
|
||||
};
|
||||
case DRAG_SELECTED:
|
||||
case "DRAG_SELECTED":
|
||||
return {
|
||||
...state,
|
||||
trackOrder: moveSelected(
|
||||
state.trackOrder,
|
||||
(i) => state.selectedTracks.has(state.trackOrder[i]),
|
||||
action.offset
|
||||
(action as any).offset
|
||||
),
|
||||
// TODO: This could probably be made to work, but we clear it just to be safe.
|
||||
lastSelectedIndex: null,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { Action, Skin } from "../types";
|
||||
import { SET_AVAILABLE_SKINS } from "../actionTypes";
|
||||
|
||||
export interface SettingsState {
|
||||
availableSkins: Array<Skin>;
|
||||
|
|
@ -14,8 +13,8 @@ const settings = (
|
|||
action: Action
|
||||
): SettingsState => {
|
||||
switch (action.type) {
|
||||
case SET_AVAILABLE_SKINS:
|
||||
return { ...state, availableSkins: action.skins };
|
||||
case "SET_AVAILABLE_SKINS":
|
||||
return { ...state, availableSkins: (action as any).skins };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,4 @@
|
|||
import { PlaylistTrack, Action } from "../types";
|
||||
import {
|
||||
SET_MEDIA,
|
||||
SET_MEDIA_TAGS,
|
||||
SET_MEDIA_DURATION,
|
||||
MEDIA_TAG_REQUEST_INITIALIZED,
|
||||
MEDIA_TAG_REQUEST_FAILED,
|
||||
ADD_TRACK_FROM_URL,
|
||||
} from "../actionTypes";
|
||||
import { MEDIA_TAG_REQUEST_STATUS } from "../constants";
|
||||
import * as TrackUtils from "../trackUtils";
|
||||
|
||||
|
|
@ -21,54 +13,54 @@ const tracks = (
|
|||
action: Action
|
||||
): TracksState => {
|
||||
switch (action.type) {
|
||||
case ADD_TRACK_FROM_URL:
|
||||
case "ADD_TRACK_FROM_URL":
|
||||
return {
|
||||
...state,
|
||||
[action.id]: {
|
||||
id: action.id,
|
||||
defaultName: action.defaultName || null,
|
||||
duration: action.duration ?? null,
|
||||
url: action.url,
|
||||
[(action as any).id]: {
|
||||
id: (action as any).id,
|
||||
defaultName: (action as any).defaultName || null,
|
||||
duration: (action as any).duration ?? null,
|
||||
url: (action as any).url,
|
||||
mediaTagsRequestStatus: MEDIA_TAG_REQUEST_STATUS.INITIALIZED,
|
||||
},
|
||||
};
|
||||
case SET_MEDIA: {
|
||||
case "SET_MEDIA": {
|
||||
const newTrack = {
|
||||
...state[action.id],
|
||||
duration: action.length,
|
||||
...state[(action as any).id],
|
||||
duration: (action as any).length,
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
[action.id]: newTrack,
|
||||
[(action as any).id]: newTrack,
|
||||
};
|
||||
}
|
||||
case MEDIA_TAG_REQUEST_INITIALIZED:
|
||||
case "MEDIA_TAG_REQUEST_INITIALIZED":
|
||||
return {
|
||||
...state,
|
||||
[action.id]: {
|
||||
...state[action.id],
|
||||
[(action as any).id]: {
|
||||
...state[(action as any).id],
|
||||
mediaTagsRequestStatus: MEDIA_TAG_REQUEST_STATUS.INITIALIZED,
|
||||
},
|
||||
};
|
||||
case MEDIA_TAG_REQUEST_FAILED:
|
||||
case "MEDIA_TAG_REQUEST_FAILED":
|
||||
return {
|
||||
...state,
|
||||
[action.id]: {
|
||||
...state[action.id],
|
||||
[(action as any).id]: {
|
||||
...state[(action as any).id],
|
||||
mediaTagsRequestStatus: MEDIA_TAG_REQUEST_STATUS.FAILED,
|
||||
},
|
||||
};
|
||||
case SET_MEDIA_DURATION: {
|
||||
case "SET_MEDIA_DURATION": {
|
||||
return {
|
||||
...state,
|
||||
[action.id]: {
|
||||
...state[action.id],
|
||||
duration: action.duration,
|
||||
[(action as any).id]: {
|
||||
...state[(action as any).id],
|
||||
duration: (action as any).duration,
|
||||
},
|
||||
};
|
||||
}
|
||||
case SET_MEDIA_TAGS:
|
||||
const track = state[action.id];
|
||||
case "SET_MEDIA_TAGS":
|
||||
const track = state[(action as any).id];
|
||||
const {
|
||||
sampleRate,
|
||||
bitrate,
|
||||
|
|
@ -77,11 +69,11 @@ const tracks = (
|
|||
artist,
|
||||
album,
|
||||
albumArtUrl,
|
||||
} = action;
|
||||
} = action as any;
|
||||
const { kbps, khz, channels } = track;
|
||||
return {
|
||||
...state,
|
||||
[action.id]: {
|
||||
[(action as any).id]: {
|
||||
...track,
|
||||
mediaTagsRequestStatus: MEDIA_TAG_REQUEST_STATUS.COMPLETE,
|
||||
title,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { SET_FOCUS, SET_SCRUB_POSITION, UNSET_FOCUS } from "../actionTypes";
|
||||
import userInput from "./userInput";
|
||||
|
||||
describe("userInput reducer", () => {
|
||||
|
|
@ -13,7 +12,7 @@ describe("userInput reducer", () => {
|
|||
});
|
||||
it("can set focus", () => {
|
||||
const newState = userInput(state, {
|
||||
type: SET_FOCUS,
|
||||
type: "SET_FOCUS",
|
||||
input: "foo",
|
||||
bandFocused: null,
|
||||
userMessage: null,
|
||||
|
|
@ -28,7 +27,7 @@ describe("userInput reducer", () => {
|
|||
it("can unset focus", () => {
|
||||
const newState = userInput(
|
||||
{ ...state, focus: "foo", bandFocused: null },
|
||||
{ type: UNSET_FOCUS }
|
||||
{ type: "UNSET_FOCUS" }
|
||||
);
|
||||
expect(newState).toEqual({
|
||||
focus: null,
|
||||
|
|
@ -39,7 +38,7 @@ describe("userInput reducer", () => {
|
|||
});
|
||||
it("can set scrub position", () => {
|
||||
const newState = userInput(state, {
|
||||
type: SET_SCRUB_POSITION,
|
||||
type: "SET_SCRUB_POSITION",
|
||||
position: 5,
|
||||
bandFocused: null,
|
||||
userMessage: null,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,4 @@
|
|||
import { Action, Slider } from "../types";
|
||||
import {
|
||||
SET_FOCUS,
|
||||
SET_BAND_FOCUS,
|
||||
SET_SCRUB_POSITION,
|
||||
UNSET_FOCUS,
|
||||
SET_USER_MESSAGE,
|
||||
UNSET_USER_MESSAGE,
|
||||
} from "../actionTypes";
|
||||
|
||||
export interface UserInputState {
|
||||
focus: string | null; // TODO: Convert this to an enum?
|
||||
|
|
@ -27,17 +19,17 @@ export const userInput = (
|
|||
action: Action
|
||||
): UserInputState => {
|
||||
switch (action.type) {
|
||||
case SET_FOCUS:
|
||||
return { ...state, focus: action.input, bandFocused: null };
|
||||
case SET_BAND_FOCUS:
|
||||
return { ...state, focus: action.input, bandFocused: action.bandFocused };
|
||||
case UNSET_FOCUS:
|
||||
case "SET_FOCUS":
|
||||
return { ...state, focus: (action as any).input, bandFocused: null };
|
||||
case "SET_BAND_FOCUS":
|
||||
return { ...state, focus: (action as any).input, bandFocused: (action as any).bandFocused };
|
||||
case "UNSET_FOCUS":
|
||||
return { ...state, focus: null, bandFocused: null };
|
||||
case SET_SCRUB_POSITION:
|
||||
return { ...state, scrubPosition: action.position };
|
||||
case SET_USER_MESSAGE:
|
||||
return { ...state, userMessage: action.message };
|
||||
case UNSET_USER_MESSAGE:
|
||||
case "SET_SCRUB_POSITION":
|
||||
return { ...state, scrubPosition: (action as any).position };
|
||||
case "SET_USER_MESSAGE":
|
||||
return { ...state, userMessage: (action as any).message };
|
||||
case "UNSET_USER_MESSAGE":
|
||||
return { ...state, userMessage: null };
|
||||
default:
|
||||
return state;
|
||||
|
|
|
|||
|
|
@ -1,17 +1,5 @@
|
|||
import { Action, WindowId, Box, Point } from "../types";
|
||||
import { WINDOWS } from "../constants";
|
||||
import {
|
||||
SET_FOCUSED_WINDOW,
|
||||
TOGGLE_WINDOW,
|
||||
CLOSE_WINDOW,
|
||||
UPDATE_WINDOW_POSITIONS,
|
||||
WINDOW_SIZE_CHANGED,
|
||||
TOGGLE_WINDOW_SHADE_MODE,
|
||||
LOAD_SERIALIZED_STATE,
|
||||
BROWSER_WINDOW_SIZE_CHANGED,
|
||||
RESET_WINDOW_SIZES,
|
||||
ENABLE_MILKDROP,
|
||||
} from "../actionTypes";
|
||||
import * as Utils from "../utils";
|
||||
import { WindowsSerializedStateV1 } from "../serializedStates/v1Types";
|
||||
|
||||
|
|
@ -107,7 +95,7 @@ const windows = (
|
|||
action: Action
|
||||
): WindowsState => {
|
||||
switch (action.type) {
|
||||
case ENABLE_MILKDROP:
|
||||
case "ENABLE_MILKDROP":
|
||||
return {
|
||||
...state,
|
||||
milkdropEnabled: true,
|
||||
|
|
@ -115,90 +103,90 @@ const windows = (
|
|||
...state.genWindows,
|
||||
[WINDOWS.MILKDROP]: {
|
||||
...state.genWindows[WINDOWS.MILKDROP],
|
||||
open: action.open,
|
||||
open: (action as any).open,
|
||||
},
|
||||
},
|
||||
};
|
||||
case SET_FOCUSED_WINDOW:
|
||||
case "SET_FOCUSED_WINDOW":
|
||||
let windowOrder = state.windowOrder;
|
||||
if (action.window != null) {
|
||||
if ((action as any).window != null) {
|
||||
windowOrder = [
|
||||
...state.windowOrder.filter((windowId) => windowId !== action.window),
|
||||
action.window,
|
||||
...state.windowOrder.filter((windowId) => windowId !== (action as any).window),
|
||||
(action as any).window,
|
||||
];
|
||||
}
|
||||
return { ...state, focused: action.window, windowOrder };
|
||||
case TOGGLE_WINDOW_SHADE_MODE:
|
||||
const { canShade } = state.genWindows[action.windowId];
|
||||
return { ...state, focused: (action as any).window, windowOrder };
|
||||
case "TOGGLE_WINDOW_SHADE_MODE":
|
||||
const { canShade } = state.genWindows[(action as any).windowId];
|
||||
if (!canShade) {
|
||||
throw new Error(
|
||||
`Tried to shade/unshade a window that cannot be shaded: ${action.windowId}`
|
||||
`Tried to shade/unshade a window that cannot be shaded: ${(action as any).windowId}`
|
||||
);
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
genWindows: {
|
||||
...state.genWindows,
|
||||
[action.windowId]: {
|
||||
...state.genWindows[action.windowId],
|
||||
shade: !state.genWindows[action.windowId].shade,
|
||||
[(action as any).windowId]: {
|
||||
...state.genWindows[(action as any).windowId],
|
||||
shade: !state.genWindows[(action as any).windowId].shade,
|
||||
},
|
||||
},
|
||||
};
|
||||
case TOGGLE_WINDOW:
|
||||
const windowState = state.genWindows[action.windowId];
|
||||
case "TOGGLE_WINDOW":
|
||||
const windowState = state.genWindows[(action as any).windowId];
|
||||
return {
|
||||
...state,
|
||||
genWindows: {
|
||||
...state.genWindows,
|
||||
[action.windowId]: {
|
||||
[(action as any).windowId]: {
|
||||
...windowState,
|
||||
open: !windowState.open,
|
||||
},
|
||||
},
|
||||
};
|
||||
case CLOSE_WINDOW:
|
||||
case "CLOSE_WINDOW":
|
||||
return {
|
||||
...state,
|
||||
genWindows: {
|
||||
...state.genWindows,
|
||||
[action.windowId]: {
|
||||
...state.genWindows[action.windowId],
|
||||
[(action as any).windowId]: {
|
||||
...state.genWindows[(action as any).windowId],
|
||||
open: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
case WINDOW_SIZE_CHANGED:
|
||||
const { canResize } = state.genWindows[action.windowId];
|
||||
case "WINDOW_SIZE_CHANGED":
|
||||
const { canResize } = state.genWindows[(action as any).windowId];
|
||||
if (!canResize) {
|
||||
throw new Error(
|
||||
`Tried to resize a window that cannot be resized: ${action.windowId}`
|
||||
`Tried to resize a window that cannot be resized: ${(action as any).windowId}`
|
||||
);
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
genWindows: {
|
||||
...state.genWindows,
|
||||
[action.windowId]: {
|
||||
...state.genWindows[action.windowId],
|
||||
size: action.size,
|
||||
[(action as any).windowId]: {
|
||||
...state.genWindows[(action as any).windowId],
|
||||
size: (action as any).size,
|
||||
},
|
||||
},
|
||||
};
|
||||
case UPDATE_WINDOW_POSITIONS:
|
||||
case "UPDATE_WINDOW_POSITIONS":
|
||||
return {
|
||||
...state,
|
||||
positionsAreRelative:
|
||||
action.absolute === true ? false : state.positionsAreRelative,
|
||||
(action as any).absolute === true ? false : state.positionsAreRelative,
|
||||
genWindows: Utils.objectMap(state.genWindows, (w, windowId) => {
|
||||
const newPosition = action.positions[windowId];
|
||||
const newPosition = (action as any).positions[windowId];
|
||||
if (newPosition == null) {
|
||||
return w;
|
||||
}
|
||||
return { ...w, position: newPosition };
|
||||
}),
|
||||
};
|
||||
case RESET_WINDOW_SIZES:
|
||||
case "RESET_WINDOW_SIZES":
|
||||
return {
|
||||
...state,
|
||||
genWindows: Utils.objectMap(state.genWindows, (w) => ({
|
||||
|
|
@ -207,9 +195,9 @@ const windows = (
|
|||
size: [0, 0] as [number, number],
|
||||
})),
|
||||
};
|
||||
case LOAD_SERIALIZED_STATE: {
|
||||
case "LOAD_SERIALIZED_STATE": {
|
||||
const { genWindows, focused, positionsAreRelative } =
|
||||
action.serializedState.windows;
|
||||
(action as any).serializedState.windows;
|
||||
return {
|
||||
...state,
|
||||
positionsAreRelative,
|
||||
|
|
@ -225,10 +213,10 @@ const windows = (
|
|||
focused,
|
||||
};
|
||||
}
|
||||
case BROWSER_WINDOW_SIZE_CHANGED:
|
||||
case "BROWSER_WINDOW_SIZE_CHANGED":
|
||||
return {
|
||||
...state,
|
||||
browserWindowSize: { height: action.height, width: action.width },
|
||||
browserWindowSize: { height: (action as any).height, width: (action as any).width },
|
||||
};
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -27,17 +27,6 @@ import * as Actions from "./actionCreators";
|
|||
import { LOAD_STYLE } from "./constants";
|
||||
import * as FileUtils from "./fileUtils";
|
||||
|
||||
import {
|
||||
SET_AVAILABLE_SKINS,
|
||||
NETWORK_CONNECTED,
|
||||
NETWORK_DISCONNECTED,
|
||||
CLOSE_WINAMP,
|
||||
MINIMIZE_WINAMP,
|
||||
LOADED,
|
||||
SET_Z_INDEX,
|
||||
CLOSE_REQUESTED,
|
||||
ENABLE_MILKDROP,
|
||||
} from "./actionTypes";
|
||||
import Emitter from "./emitter";
|
||||
|
||||
import { SerializedStateV1 } from "./serializedStates/v1Types";
|
||||
|
|
@ -150,18 +139,18 @@ class Webamp {
|
|||
}
|
||||
|
||||
if (navigator.onLine) {
|
||||
this.store.dispatch({ type: NETWORK_CONNECTED });
|
||||
this.store.dispatch({ type: "NETWORK_CONNECTED" });
|
||||
} else {
|
||||
this.store.dispatch({ type: NETWORK_DISCONNECTED });
|
||||
this.store.dispatch({ type: "NETWORK_DISCONNECTED" });
|
||||
}
|
||||
|
||||
if (zIndex != null) {
|
||||
this.store.dispatch({ type: SET_Z_INDEX, zIndex });
|
||||
this.store.dispatch({ type: "SET_Z_INDEX", zIndex });
|
||||
}
|
||||
|
||||
if (options.__butterchurnOptions) {
|
||||
this.store.dispatch({
|
||||
type: ENABLE_MILKDROP,
|
||||
type: "ENABLE_MILKDROP",
|
||||
open: options.__butterchurnOptions.butterchurnOpen,
|
||||
});
|
||||
this.store.dispatch(
|
||||
|
|
@ -169,9 +158,9 @@ class Webamp {
|
|||
);
|
||||
}
|
||||
|
||||
const handleOnline = () => this.store.dispatch({ type: NETWORK_CONNECTED });
|
||||
const handleOnline = () => this.store.dispatch({ type: "NETWORK_CONNECTED" });
|
||||
const handleOffline = () =>
|
||||
this.store.dispatch({ type: NETWORK_DISCONNECTED });
|
||||
this.store.dispatch({ type: "NETWORK_DISCONNECTED" });
|
||||
|
||||
window.addEventListener("online", handleOnline);
|
||||
window.addEventListener("offline", handleOffline);
|
||||
|
|
@ -185,7 +174,7 @@ class Webamp {
|
|||
this.store.dispatch(Actions.setSkinFromUrl(initialSkin.url));
|
||||
} else {
|
||||
// We are using the default skin.
|
||||
this.store.dispatch({ type: LOADED });
|
||||
this.store.dispatch({ type: "LOADED" });
|
||||
}
|
||||
|
||||
if (initialTracks) {
|
||||
|
|
@ -198,9 +187,9 @@ class Webamp {
|
|||
"The misspelled option `avaliableSkins` is deprecated. Please use `availableSkins` instead."
|
||||
);
|
||||
// @ts-ignore
|
||||
this.store.dispatch({ type: SET_AVAILABLE_SKINS, skins: avaliableSkins });
|
||||
this.store.dispatch({ type: "SET_AVAILABLE_SKINS", skins: avaliableSkins });
|
||||
} else if (availableSkins != null) {
|
||||
this.store.dispatch({ type: SET_AVAILABLE_SKINS, skins: availableSkins });
|
||||
this.store.dispatch({ type: "SET_AVAILABLE_SKINS", skins: availableSkins });
|
||||
}
|
||||
|
||||
this.store.dispatch(Actions.setWindowLayout(options.windowLayout));
|
||||
|
|
@ -362,8 +351,8 @@ class Webamp {
|
|||
* @returns An "unsubscribe" function. Useful if at some point in the future you want to stop listening to these events.
|
||||
*/
|
||||
onWillClose(cb: (cancel: () => void) => void): () => void {
|
||||
return this._actionEmitter.on(CLOSE_REQUESTED, (action) => {
|
||||
cb(action.cancel);
|
||||
return this._actionEmitter.on("CLOSE_REQUESTED", (action) => {
|
||||
cb((action as any).cancel);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -373,7 +362,7 @@ class Webamp {
|
|||
* @returns An "unsubscribe" function. Useful if at some point in the future you want to stop listening to these events.
|
||||
*/
|
||||
onClose(cb: () => void): () => void {
|
||||
return this._actionEmitter.on(CLOSE_WINAMP, cb);
|
||||
return this._actionEmitter.on("CLOSE_WINAMP", cb);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -428,7 +417,7 @@ class Webamp {
|
|||
* @returns An "unsubscribe" function. Useful if at some point in the future you want to stop listening to these events.
|
||||
*/
|
||||
onMinimize(cb: () => void): () => void {
|
||||
return this._actionEmitter.on(MINIMIZE_WINAMP, cb);
|
||||
return this._actionEmitter.on("MINIMIZE_WINAMP", cb);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue