import React from "react"; import { connect } from "react-redux"; import { AppState, Dispatch } from "../../types"; import { SEEK_TO_PERCENT_COMPLETE, SET_FOCUS, UNSET_FOCUS, SET_SCRUB_POSITION, } from "../../actionTypes"; import * as Selectors from "../../selectors"; interface StateProps { displayedPosition: number; position: number; } interface DispatchProps { seekToPercentComplete(e: React.MouseEvent): void; setPosition(e: React.MouseEvent): void; } type Props = StateProps & DispatchProps; const Position = ({ position, seekToPercentComplete, displayedPosition, setPosition, }: Props) => { // In shade mode, the position slider shows up differently depending on if // it's near the start, middle or end of its progress let className = ""; if (position <= 33) { className = "left"; } else if (position >= 66) { className = "right"; } return ( {} /* React complains without this, can probably rename onInput to onChange */ } onMouseUp={seekToPercentComplete} onMouseDown={setPosition} title="Seeking Bar" /> ); }; const mapStateToProps = (state: AppState): StateProps => { const duration = Selectors.getDuration(state); const timeElapsed = Selectors.getTimeElapsed(state); const userInputFocus = Selectors.getUserInputFocus(state); const scrubPosition = Selectors.getUserInputScrubPosition(state); const position = duration ? (Math.floor(timeElapsed) / duration) * 100 : 0; const displayedPosition = userInputFocus === "position" ? scrubPosition : position; return { displayedPosition, position, }; }; const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({ seekToPercentComplete: e => { dispatch({ type: SEEK_TO_PERCENT_COMPLETE, percent: Number((e.target as HTMLInputElement).value), }); dispatch({ type: UNSET_FOCUS }); }, setPosition: e => { dispatch({ type: SET_FOCUS, input: "position" }); dispatch({ type: SET_SCRUB_POSITION, position: Number((e.target as HTMLInputElement).value), }); }, }); export default connect( mapStateToProps, mapDispatchToProps )(Position);