Files
Iris/src/js/components/Track.js

266 lines
7.2 KiB
JavaScript
Raw Normal View History

2016-10-03 21:21:14 +13:00
import React, { PropTypes } from 'react'
import { Link } from 'react-router'
2016-10-06 16:38:06 +13:00
import FontAwesome from 'react-fontawesome'
2016-10-25 21:36:33 +13:00
import ArtistSentence from './ArtistSentence'
2016-10-31 16:49:42 +13:00
import Dater from './Dater'
import URILink from './URILink'
import * as helpers from '../helpers'
2016-10-03 21:21:14 +13:00
export default class Track extends React.Component{
2017-10-10 13:05:28 +13:00
constructor(props){
super(props)
this.state = {
hover: false
}
this.start_position = false
2016-10-03 21:21:14 +13:00
}
2016-11-15 17:08:21 +13:00
handleMouseDown(e){
// Only listen for left mouse clicks
if (e.button === 0){
this.start_position = {
x: e.pageX,
y: e.pageY
}
// Not left click, then ensure no dragging
} else {
this.start_position = false
}
2016-11-15 17:08:21 +13:00
}
2016-11-10 16:17:10 +13:00
handleMouseMove(e){
2017-07-25 09:22:15 +12:00
// No drag handling means NO
if (this.props.handleDrag === undefined){
return false
}
if (this.start_position){
let start_x = this.start_position.x
let start_y = this.start_position.y
let threshold = 5
// Have we dragged outside of our threshold zone?
if (e.pageX > start_x + threshold || e.pageX < start_x - threshold || e.pageY > start_y + threshold || e.pageY < start_y - threshold){
// Handover to parent for dragging. We can unset all our behaviour now.
this.props.handleDrag(e)
this.start_position = false
}
}
}
handleMouseUp(e){
2017-07-25 09:22:15 +12:00
// Only listen for left clicks
if (e.button === 0){
if (this.props.dragger){
e.preventDefault()
2017-07-25 09:22:15 +12:00
if (this.props.handleDrop !== undefined){
this.props.handleDrop(e)
}
} else {
var target = $(e.target);
if (!target.is('a') && target.closest('a').length <= 0){
this.props.handleSelection(e)
this.start_position = false
}
}
// Not left click, then ensure no dragging
} else {
this.start_position = false
return false
}
}
handleTouchStart(e){
this.props.handleTouchDrag(e)
2016-10-27 10:02:12 +13:00
}
handleContextMenu(e){
e.preventDefault()
e.stopPropagation()
e.cancelBubble = true
this.props.handleContextMenu(e)
}
2016-10-03 21:21:14 +13:00
render(){
2017-10-10 13:05:28 +13:00
if (!this.props.track ) return null
2016-10-06 16:38:06 +13:00
var track = this.props.track
var className = 'list-item track'
2017-07-21 22:56:28 +12:00
if (this.props.selected) className += ' selected'
if (this.props.selected) className += ' selected'
if (this.props.can_sort) className += ' can-sort'
2017-07-21 22:56:28 +12:00
if (track.type !== undefined) className += ' '+track.type
if (track.playing) className += ' playing'
if (this.state.hover) className += ' hover'
var album = '-'
2017-10-10 13:05:28 +13:00
if (track.album){
if (track.album.uri){
album = <URILink type="album" uri={track.album.uri}>{track.album.name}</URILink>
} else {
album = <span>{track.album.name}</span>
}
}
let track_columns = []
if (track.type == 'history'){
2017-02-10 09:06:41 +13:00
track_columns.push(
2017-08-03 16:40:34 +12:00
<span className="col name" key="name">
{track.name ? track.name : <span className="grey-text">{track.uri}</span>}
</span>
)
track_columns.push(
2017-08-03 16:40:34 +12:00
<span className="col source" key="source">
{helpers.uriSource(track.uri)}
</span>
)
track_columns.push(
2017-08-03 16:40:34 +12:00
<span className="col played_at" key="played_at">
{track.played_at ? <span><Dater type="ago" data={track.played_at} /> ago</span> : null}
</span>
)
} else if (this.props.context == 'queue'){
if (track.added_from && track.added_by){
var type = (track.added_from ? helpers.uriType(track.added_from) : null)
if (type == 'discover'){
var link = <URILink type="recommendations" uri={helpers.getFromUri('seeds',track.added_from)}>discover</URILink>
} else {
var link = <URILink type={type} uri={track.added_from}>{type}</URILink>
}
var added = <span>{track.added_by} <span className="grey-text"> (from {link})</span></span>
2017-02-10 09:06:41 +13:00
} else if (track.added_by){
var added = track.added_by
} else {
var added = '-'
}
track_columns.push(
<span className="col name" key="name">
{track.name ? track.name : <span className="grey-text">{track.uri}</span>}
{track.explicit ? <span className="flag dark">EXPLICIT</span> : null}
</span>
)
if (this.props.show_source_icon){
track_columns.push(
<FontAwesome name={helpers.sourceIcon(track.uri)} className="source" key="source" fixedWidth />
2017-02-10 09:06:41 +13:00
)
}
track_columns.push(
<span className="col artists" key="artists">
{track.artists ? <ArtistSentence artists={track.artists} /> : '-'}
</span>
)
track_columns.push(
<span className="col album" key="album">
{album}
</span>
)
track_columns.push(
<span className="col added" key="added">
{added}
</span>
)
track_columns.push(
<span className="col duration" key="duration">
2017-10-18 17:03:59 +13:00
{track.duration ? <Dater type="length" data={track.duration} /> : null}
</span>
)
} else {
track_columns.push(
<span className="col name" key="name">
{track.name ? track.name : <span className="grey-text">{track.uri}</span>}
{track.explicit ? <span className="flag dark">EXPLICIT</span> : null}
</span>
)
if (this.props.show_source_icon){
track_columns.push(
<FontAwesome name={helpers.sourceIcon(track.uri)} className="source" key="source" fixedWidth />
)
}
track_columns.push(
<span className="col artists" key="artists">
{track.artists ? <ArtistSentence artists={track.artists} /> : '-'}
</span>
)
track_columns.push(
<span className="col album" key="album">
{album}
</span>
)
track_columns.push(
<span className="col duration" key="duration">
{track.duration ? <Dater type="length" data={track.duration} /> : null}
</span>
)
2017-02-10 09:06:41 +13:00
}
if (this.props.mini_zones){
// Select zone handles selection events only
// We use onClick to capture touch as well as mouse events in one tidy parcel
track_columns.push(
<span
className="select-zone"
key="select-zone"
onClick={e => this.props.handleSelection(e)}>
{this.props.selected ? <FontAwesome name="check" className="selected" fixedWidth /> : null}
</span>
)
if (this.props.can_sort){
track_columns.push(
<span
className="drag-zone"
key="drag-zone"
onTouchStart={e => this.handleTouchStart(e)}>
<FontAwesome name="bars" fixedWidth />
</span>
)
}
// No events attached directly to the track. Instead events are attached to
// the appropriate select/drag zone sub-elements
return (
<div className={className}>
2017-02-10 09:06:41 +13:00
{ track_columns }
</div>
)
} else {
return (
<div
className={className}
onMouseEnter={e => this.setState({hover: true})}
onMouseLeave={e => this.setState({hover: false})}
//onTouchEnd={e => this.handleTouchEnd(e)} // When touch dragging is dropped on me
onMouseDown={e => this.handleMouseDown(e)} // Click (or potentially a mouse drag start)
onMouseMove={e => this.handleMouseMove(e)} // Any movement over me
onMouseUp={e => this.handleMouseUp(e)} // End of click, or potentially a dragging drop event
onDoubleClick={e => this.props.handleDoubleClick(e)}
onContextMenu={e => {this.handleContextMenu(e)}}>
{ track_columns }
</div>
)
}
2016-10-03 21:21:14 +13:00
}
}