import React from "react"; import { connect } from "react-redux"; import classnames from "classnames"; import { WINDOWS, TRACK_HEIGHT, LOAD_STYLE } from "../../constants"; import { scrollUpFourTracks, scrollDownFourTracks, togglePlaylistShadeMode, scrollVolume, closeWindow, loadMedia, } from "../../actionCreators"; import * as Selectors from "../../selectors"; import { clamp } from "../../utils"; import DropTarget from "../DropTarget"; import Visualizer from "../Visualizer"; import PlaylistShade from "./PlaylistShade"; import AddMenu from "./AddMenu"; import RemoveMenu from "./RemoveMenu"; import SelectionMenu from "./SelectionMenu"; import MiscMenu from "./MiscMenu"; import ListMenu from "./ListMenu"; import PlaylistResizeTarget from "./PlaylistResizeTarget"; import PlaylistActionArea from "./PlaylistActionArea"; import TrackList from "./TrackList"; import ScrollBar from "./ScrollBar"; import "../../../css/playlist-window.css"; import { AppState, PlaylistStyle, Dispatch } from "../../types"; import FocusTarget from "../FocusTarget"; interface StateProps { offset: number; maxTrackIndex: number; playlistWindowPixelSize: { width: number; height: number }; showVisualizer: boolean; activateVisualizer: boolean; selected: boolean; skinPlaylistStyle: PlaylistStyle; playlistSize: [number, number]; playlistShade: boolean; duration: number | null; } interface DispatchProps { close(): void; toggleShade(): void; scrollUpFourTracks(): void; scrollDownFourTracks(): void; loadMedia(e: React.DragEvent, startIndex: number): void; scrollVolume(e: React.WheelEvent): void; } interface OwnProps { analyser: AnalyserNode; } type Props = StateProps & DispatchProps & OwnProps; class PlaylistWindow extends React.Component { _handleDrop = ( e: React.DragEvent, targetCoords: { x: number; y: number } ) => { const top = e.clientY - targetCoords.y; const atIndex = clamp( this.props.offset + Math.round((top - 23) / TRACK_HEIGHT), 0, this.props.maxTrackIndex + 1 ); this.props.loadMedia(e, atIndex); }; render() { const { skinPlaylistStyle, selected, playlistSize, playlistWindowPixelSize, playlistShade, close, toggleShade, analyser, showVisualizer, activateVisualizer, } = this.props; if (playlistShade) { return ; } const style = { color: skinPlaylistStyle.normal, backgroundColor: skinPlaylistStyle.normalbg, fontFamily: `${skinPlaylistStyle.font}, Arial, sans-serif`, height: `${playlistWindowPixelSize.height}px`, width: `${playlistWindowPixelSize.width}px`, }; const classes = classnames("window", "draggable", { selected }); const showSpacers = playlistSize[0] % 2 === 0; return (
{showSpacers && (
)}
{showSpacers && (
)}
{showVisualizer && (
{activateVisualizer && (
)}
)}
); } } const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => { return { close: () => dispatch(closeWindow(WINDOWS.PLAYLIST)), toggleShade: () => dispatch(togglePlaylistShadeMode()), scrollUpFourTracks: () => dispatch(scrollUpFourTracks()), scrollDownFourTracks: () => dispatch(scrollDownFourTracks()), loadMedia: (e, startIndex) => dispatch(loadMedia(e, LOAD_STYLE.NONE, startIndex)), scrollVolume: e => dispatch(scrollVolume(e)), }; }; const mapStateToProps = (state: AppState): StateProps => { const { playlist: { trackOrder }, } = state; const playlistSize = Selectors.getWindowSize(state)(WINDOWS.PLAYLIST); return { offset: Selectors.getScrollOffset(state), maxTrackIndex: trackOrder.length - 1, playlistWindowPixelSize: Selectors.getWindowPixelSize(state)( WINDOWS.PLAYLIST ), showVisualizer: playlistSize[0] > 2, activateVisualizer: !Selectors.getWindowOpen(state)(WINDOWS.MAIN), playlistSize, selected: Selectors.getFocusedWindow(state) === WINDOWS.PLAYLIST, skinPlaylistStyle: Selectors.getSkinPlaylistStyle(state), playlistShade: Boolean(Selectors.getWindowShade(state)(WINDOWS.PLAYLIST)), duration: Selectors.getDuration(state), }; }; export default connect( mapStateToProps, mapDispatchToProps )(PlaylistWindow);