import React from "react"; import { connect } from "react-redux"; import { getTimeStr } from "../../utils"; import { getVisibleTrackIds, getScrollOffset, getNumberOfTracks } from "../../selectors"; import { TRACK_HEIGHT } from "../../constants"; import { SELECT_ZERO } from "../../actionTypes"; import { dragSelected, scrollPlaylistByDelta } from "../../actionCreators"; import TrackCell from "./TrackCell"; import TrackTitle from "./TrackTitle"; function getNumberLength(number) { return number.toString().length; } class TrackList extends React.Component { constructor(props) { super(props); this._handleMoveClick = this._handleMoveClick.bind(this); } _renderTracks(format) { return this.props.trackIds.map((id, i) => ( {format(id, i)} )); } _handleMoveClick(e) { if (!this._node) { return; } const { top, bottom, left, right } = this._node.getBoundingClientRect(); const mouseStart = e.clientY; let lastDiff = 0; const handleMouseMove = ee => { const { clientY: y, clientX: x } = ee; if (y < top || y > bottom || x < left || x > right) { // Mouse is outside the track list return; } const proposedDiff = Math.floor((y - mouseStart) / TRACK_HEIGHT); if (proposedDiff !== lastDiff) { const diffDiff = proposedDiff - lastDiff; this.props.dragSelected(diffDiff); lastDiff = proposedDiff; } }; window.addEventListener("mouseup", () => { window.removeEventListener("mousemove", handleMouseMove); }); window.addEventListener("mousemove", handleMouseMove); } render() { const { tracks, offset } = this.props; const maxTrackNumberLength = getNumberLength(this.props.numberOfTracks); const paddedTrackNumForIndex = i => (i + 1 + offset).toString().padStart(maxTrackNumberLength, "\u00A0"); return (
{ this._node = node; }} className="playlist-tracks" style={{ height: "100%" }} onClick={this.props.selectZero} onWheel={this.props.scrollPlaylistByDelta} >
{this._renderTracks((id, i) => ( ))}
{this._renderTracks(id => getTimeStr(tracks[id].duration))}
); } } const mapDispatchToProps = { selectZero: () => ({ type: SELECT_ZERO }), dragSelected, scrollPlaylistByDelta }; const mapStateToProps = state => ({ offset: getScrollOffset(state), trackIds: getVisibleTrackIds(state), tracks: state.playlist.tracks, numberOfTracks: getNumberOfTracks(state) }); export default connect( mapStateToProps, mapDispatchToProps )(TrackList);