Type some more stuff

This commit is contained in:
Jordan Eldredge 2019-02-09 23:22:44 -05:00
parent 02bd19e75f
commit c05099fd8f
8 changed files with 140 additions and 105 deletions

View file

@ -143,7 +143,7 @@ export function loadSerializedState(
};
}
export function loadDefaultSkin() {
export function loadDefaultSkin(): Dispatchable {
return { type: LOAD_DEFAULT_SKIN };
}

View file

@ -1,21 +0,0 @@
import React from "react";
import GenWindow from "../GenWindow";
import "../../../css/gen-window.css";
const AvsWindow = () => (
<GenWindow title="Avs" close={() => {}} windowId="AVS_WINDOW">
<canvas
style={{
position: "absolute",
top: 0,
bottom: 0,
left: 0,
right: 0,
height: "100%",
width: "100%"
}}
/>
</GenWindow>
);
export default AvsWindow;

View file

@ -1,9 +1,18 @@
import React from "react";
import PropTypes from "prop-types";
import React, { ReactNode } from "react";
import ContextMenu from "./ContextMenu";
export default class ContextMenuWraper extends React.Component {
constructor(props) {
interface Props {
renderContents(): ReactNode;
}
interface State {
selected: boolean;
offsetTop: number | null;
offsetLeft: number | null;
}
export default class ContextMenuWraper extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
selected: false,
@ -29,14 +38,14 @@ export default class ContextMenuWraper extends React.Component {
this._closeMenu();
};
_handleGlobalClick = e => {
_handleGlobalClick = (e: MouseEvent) => {
if (e.button === 2) {
return;
}
this._closeMenu();
};
_handleRightClick = e => {
_handleRightClick = (e: React.MouseEvent<HTMLDivElement>) => {
const { pageX, pageY } = e;
this.setState({
selected: true,
@ -63,8 +72,8 @@ export default class ContextMenuWraper extends React.Component {
>
<ContextMenu
selected={this.state.selected}
offsetTop={this.state.offsetTop}
offsetLeft={this.state.offsetLeft}
offsetTop={this.state.offsetTop || 0}
offsetLeft={this.state.offsetLeft || 0}
>
{renderContents()}
</ContextMenu>
@ -73,8 +82,3 @@ export default class ContextMenuWraper extends React.Component {
);
}
}
ContextMenuWraper.propTypes = {
children: PropTypes.any.isRequired,
renderContents: PropTypes.func.isRequired
};

View file

@ -1,17 +1,34 @@
import React from "react";
import { connect } from "react-redux";
import Slider from "rc-slider/lib/Slider";
import Slider from "rc-slider";
import { SET_BAND_FOCUS, UNSET_FOCUS } from "../../actionTypes";
import { AppState, Dispatch, Band as BandType } from "../../types";
interface StateProps {
value: number;
backgroundPosition: string;
}
interface DispatchProps {
handleMouseDown(): void;
handleMouseUp(): void;
}
interface OwnProps {
id: string;
band: BandType;
onChange(value: number): void;
}
type Props = StateProps & DispatchProps & OwnProps;
const MAX_VALUE = 100;
// Given a value between 1-100, return the sprite number (0-27)
export const spriteNumber = value => {
export const spriteNumber = (value: number): number => {
const percent = value / 100;
return Math.round(percent * 27);
};
// Given a sprite number, return the x,y
export const spriteOffsets = number => {
export const spriteOffsets = (number: number): { x: number; y: number } => {
const x = number % 14;
const y = Math.floor(number / 14);
return { x, y };
@ -26,10 +43,9 @@ const Band = ({
onChange,
handleMouseDown,
handleMouseUp
}) => (
}: Props) => (
<div id={id} className="band" style={{ backgroundPosition }}>
<Slider
type="range"
min={1}
max={MAX_VALUE}
step={1}
@ -43,20 +59,19 @@ const Band = ({
</div>
);
const mapStateToProps = (state, ownProps) => {
const mapStateToProps = (state: AppState, ownProps: OwnProps): StateProps => {
const value = state.equalizer.sliders[ownProps.band];
const { x, y } = spriteOffsets(spriteNumber(value));
const xOffset = x * 15; // Each sprite is 15px wide
const yOffset = y * 65; // Each sprite is 15px tall
const backgroundPosition = `-${xOffset}px -${yOffset}px`;
return {
id: ownProps.id,
value,
backgroundPosition
};
return { value, backgroundPosition };
};
const mapDispatchToProps = (dispatch, ownProps) => ({
const mapDispatchToProps = (
dispatch: Dispatch,
ownProps: OwnProps
): DispatchProps => ({
handleMouseDown: () =>
dispatch({ type: SET_BAND_FOCUS, input: "eq", bandFocused: ownProps.band }),
handleMouseUp: () => dispatch({ type: UNSET_FOCUS })

View file

@ -4,18 +4,29 @@ import classnames from "classnames";
import { getWindowOpen } from "../../selectors";
import { toggleWindow } from "../../actionCreators";
import { AppState } from "../../types";
const EqToggleButton = props => (
interface StateProps {
windowOpen: boolean;
}
interface DispatchProps {
handleClick(e: React.MouseEvent<HTMLDivElement>): void;
}
type Props = StateProps & DispatchProps;
const EqToggleButton = (props: Props) => (
<div
id="equalizer-button"
className={classnames({ selected: props.getWindowOpen("equalizer") })}
className={classnames({ selected: props.windowOpen })}
onClick={props.handleClick}
title="Toggle Graphical Equalizer"
/>
);
const mapStateToProps = state => ({
getWindowOpen: getWindowOpen(state)
const mapStateToProps = (state: AppState): StateProps => ({
windowOpen: getWindowOpen(state)("equalizer")
});
const mapDispatchToProps = {

View file

@ -1,18 +1,21 @@
import React from "react";
import { connect } from "react-redux";
import {
previous,
play,
pause,
stop,
next,
seekForward,
seekBackward,
nextN
} from "../actionCreators";
import * as Actions from "../actionCreators";
import { Hr, Node } from "./ContextMenu";
import { Dispatch } from "../types";
const PlaybackContextMenu = props => (
interface Props {
previous(): void;
play(): void;
pause(): void;
stop(): void;
next(): void;
seekBackward(steps: number): void;
seekForward(steps: number): void;
nextN(steps: number): void;
}
const PlaybackContextMenu = (props: Props) => (
<React.Fragment>
<Node label="Previous" hotkey="Z" onClick={props.previous} />
<Node label="Play" hotkey="X" onClick={props.play} />
@ -55,15 +58,17 @@ const PlaybackContextMenu = props => (
</React.Fragment>
);
const mapDispatchToProps = {
previous,
play,
pause,
stop,
next,
seekForward,
seekBackward,
nextN
const mapDispatchToProps = (dispatch: Dispatch): Props => {
return {
previous: () => dispatch(Actions.previous()),
play: () => dispatch(Actions.play()),
pause: () => dispatch(Actions.pause()),
stop: () => dispatch(Actions.stop()),
next: () => dispatch(Actions.next()),
seekForward: steps => dispatch(Actions.seekForward(steps)),
seekBackward: steps => dispatch(Actions.seekBackward(steps)),
nextN: steps => dispatch(Actions.nextN(steps))
};
};
export default connect(

View file

@ -1,34 +0,0 @@
import React from "react";
import { connect } from "react-redux";
import * as Actions from "../actionCreators";
import { Hr, Node, Parent } from "./ContextMenu";
const SkinContextMenu = props => (
<Parent label="Skins">
<Node onClick={props.openSkinFileDialog} label="Load Skin..." />
<Hr />
<Node onClick={props.loadDefaultSkin} label={"<Base Skin>"} />
{props.availableSkins.map(skin => (
<Node
key={skin.url}
onClick={() => props.setSkin(skin.url)}
label={skin.name}
/>
))}
</Parent>
);
const mapStateToProps = state => ({
availableSkins: state.settings.availableSkins
});
const mapDispatchToProps = {
loadDefaultSkin: Actions.loadDefaultSkin,
openSkinFileDialog: Actions.openSkinFileDialog,
setSkin: Actions.setSkinFromUrl
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(SkinContextMenu);

View file

@ -0,0 +1,55 @@
import React from "react";
import { connect } from "react-redux";
import * as Actions from "../actionCreators";
import { Hr, Node, Parent } from "./ContextMenu";
import { AppState, Skin, Dispatch } from "../types";
interface StateProps {
availableSkins: Skin[];
}
interface DispatchProps {
loadDefaultSkin(): void;
setSkin(url: string): void;
openSkinFileDialog(): void;
}
type Props = StateProps & DispatchProps;
const SkinContextMenu = (props: Props) => (
<Parent label="Skins">
<Node onClick={props.openSkinFileDialog} label="Load Skin..." />
<Hr />
<Node onClick={props.loadDefaultSkin} label={"<Base Skin>"} />
{props.availableSkins.map(skin => (
<Node
key={skin.url}
onClick={() => props.setSkin(skin.url)}
label={skin.name}
/>
))}
</Parent>
);
const mapStateToProps = (state: AppState): StateProps => ({
availableSkins: state.settings.availableSkins
});
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => {
return {
loadDefaultSkin() {
dispatch(Actions.loadDefaultSkin());
},
openSkinFileDialog() {
dispatch(Actions.openSkinFileDialog());
},
setSkin(url: string) {
dispatch(Actions.setSkinFromUrl(url));
}
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(SkinContextMenu);