webamp/js/reducers/windows.ts
Jordan Eldredge d24b86e189
Rm media library (#957)
* Remove CSS

* Remove LibraryButton

* Remove Sidebar

* Remove LibraryTable

* Remove MediaLibrary components

* Clean up skin stuff and some odds and ends

* Clean up constants

* Remove Media Library from compiled CSS
2019-12-06 06:24:21 -08:00

272 lines
6.8 KiB
TypeScript

import { Action, WindowId, Box, Point } from "../types";
import { WINDOWS } from "../constants";
import {
SET_FOCUSED_WINDOW,
TOGGLE_WINDOW,
CLOSE_WINDOW,
SET_WINDOW_VISIBILITY,
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";
export type WindowPosition = Point;
export type WindowPositions = {
[windowId: string]: WindowPosition;
};
export interface WebampWindow {
title: string;
size: [number, number];
open: boolean;
hidden: boolean;
shade?: boolean;
canResize: boolean;
canShade: boolean;
canDouble: boolean;
hotkey?: string;
position: WindowPosition;
}
export interface WindowInfo extends Box {
key: WindowId;
}
export interface WindowsState {
focused: WindowId | null;
genWindows: { [name: string]: WebampWindow };
browserWindowSize: { height: number; width: number };
positionsAreRelative: boolean;
windowOrder: WindowId[];
}
const defaultWindowsState: WindowsState = {
focused: WINDOWS.MAIN,
positionsAreRelative: true,
genWindows: {
// TODO: Remove static capabilites and derive them from ids/generic
[WINDOWS.MAIN]: {
title: "Main Window",
size: [0, 0],
open: true,
hidden: false,
shade: false,
canResize: false,
canShade: true,
canDouble: true,
hotkey: "Alt+W",
position: { x: 0, y: 0 },
},
[WINDOWS.EQUALIZER]: {
title: "Equalizer",
size: [0, 0],
open: true,
hidden: false,
shade: false,
canResize: false,
canShade: true,
canDouble: true,
hotkey: "Alt+G",
position: { x: 0, y: 0 },
},
[WINDOWS.PLAYLIST]: {
title: "Playlist Editor",
size: [0, 0],
open: true,
hidden: false,
shade: false,
canResize: true,
canShade: true,
canDouble: false,
hotkey: "Alt+E",
position: { x: 0, y: 0 },
},
},
browserWindowSize: { width: 0, height: 0 },
windowOrder: [
WINDOWS.PLAYLIST,
WINDOWS.EQUALIZER,
WINDOWS.MILKDROP,
WINDOWS.MAIN,
],
};
const windows = (
state: WindowsState = defaultWindowsState,
action: Action
): WindowsState => {
switch (action.type) {
case ENABLE_MILKDROP:
return {
...state,
genWindows: {
...state.genWindows,
[WINDOWS.MILKDROP]: {
title: "Milkdrop",
size: [0, 0],
open: action.open,
hidden: false,
shade: false,
canResize: true,
canShade: false,
canDouble: false,
position: { x: 0, y: 0 },
},
},
};
case SET_FOCUSED_WINDOW:
let windowOrder = state.windowOrder;
if (action.window != null) {
windowOrder = [
...state.windowOrder.filter(windowId => windowId !== action.window),
action.window,
];
}
return { ...state, focused: action.window, windowOrder };
case TOGGLE_WINDOW_SHADE_MODE:
const { canShade } = state.genWindows[action.windowId];
if (!canShade) {
throw new Error(
`Tried to shade/unshade a window that cannot be shaded: ${action.windowId}`
);
}
return {
...state,
genWindows: {
...state.genWindows,
[action.windowId]: {
...state.genWindows[action.windowId],
shade: !state.genWindows[action.windowId].shade,
},
},
};
case TOGGLE_WINDOW:
const windowState = state.genWindows[action.windowId];
return {
...state,
genWindows: {
...state.genWindows,
[action.windowId]: {
...windowState,
open: !windowState.open,
// Reset hidden state when opening window
hidden: windowState.open ? windowState.hidden : false,
},
},
};
case CLOSE_WINDOW:
return {
...state,
genWindows: {
...state.genWindows,
[action.windowId]: {
...state.genWindows[action.windowId],
open: false,
},
},
};
case SET_WINDOW_VISIBILITY:
return {
...state,
genWindows: {
...state.genWindows,
[action.windowId]: {
...state.genWindows[action.windowId],
hidden: action.hidden,
},
},
};
case WINDOW_SIZE_CHANGED:
const { canResize } = state.genWindows[action.windowId];
if (!canResize) {
throw new Error(
`Tried to resize a window that cannot be resized: ${action.windowId}`
);
}
return {
...state,
genWindows: {
...state.genWindows,
[action.windowId]: {
...state.genWindows[action.windowId],
size: action.size,
},
},
};
case UPDATE_WINDOW_POSITIONS:
return {
...state,
positionsAreRelative:
action.absolute === true ? false : state.positionsAreRelative,
genWindows: Utils.objectMap(state.genWindows, (w, windowId) => {
const newPosition = action.positions[windowId];
if (newPosition == null) {
return w;
}
return { ...w, position: newPosition };
}),
};
case RESET_WINDOW_SIZES:
return {
...state,
genWindows: Utils.objectMap(state.genWindows, w => ({
...w,
// Not sure why TypeScript can't figure this out for itself.
size: [0, 0] as [number, number],
})),
};
case LOAD_SERIALIZED_STATE: {
const {
genWindows,
focused,
positionsAreRelative,
} = action.serializedState.windows;
return {
...state,
positionsAreRelative,
genWindows: Utils.objectMap(state.genWindows, (w, windowId) => {
const serializedW = genWindows[windowId];
if (serializedW == null) {
return w;
}
return { ...w, ...serializedW };
}),
focused,
};
}
case BROWSER_WINDOW_SIZE_CHANGED:
return {
...state,
browserWindowSize: { height: action.height, width: action.width },
};
default:
return state;
}
};
export function getSerializedState(
state: WindowsState
): WindowsSerializedStateV1 {
return {
positionsAreRelative: state.positionsAreRelative,
genWindows: Utils.objectMap(state.genWindows, w => {
return {
size: w.size,
open: w.open,
hidden: w.hidden,
shade: w.shade || false,
position: w.position,
};
}),
focused: state.focused,
};
}
export default windows;