All events handled by targets, fixes #210

This commit is contained in:
James Barnsley
2017-12-07 16:54:28 +13:00
parent ef99935e0a
commit bbfb785c3a
11 changed files with 118 additions and 74 deletions

View File

@ -3406,7 +3406,8 @@ input[type="submit"] {
border-radius: 5px; border-radius: 5px;
background: #FFFFFF; background: #FFFFFF;
display: inline-block; display: inline-block;
margin: 1px; } margin: 1px;
pointer-events: none; }
.context-menu-trigger:active { .context-menu-trigger:active {
margin-top: 0px; margin-top: 0px;
margin-bottom: -1px; } margin-bottom: -1px; }

View File

@ -1115,8 +1115,15 @@ function setSelectedTracks() {
} }
function showContextMenu(data) { function showContextMenu(data) {
data.position_x = data.e.clientX;
data.position_y = data.e.clientY; if (data.e.touches) {
data.position_x = data.e.touches[0].clientX;
data.position_y = data.e.touches[0].clientY;
} else {
data.position_x = data.e.clientX;
data.position_y = data.e.clientY;
}
return { return {
type: 'SHOW_CONTEXT_MENU', type: 'SHOW_CONTEXT_MENU',
data: data data: data
@ -16006,8 +16013,6 @@ var TrackList = function (_React$Component) {
var siblings = over.parent().children('.track'); var siblings = over.parent().children('.track');
var dropped_at = siblings.index(over) - 1; var dropped_at = siblings.index(over) - 1;
console.log('touchend', helpers.arrayOf('index', this.digestTracksKeys()), 'to', dropped_at);
if (this.props.reorderTracks !== undefined) { if (this.props.reorderTracks !== undefined) {
this.props.reorderTracks(helpers.arrayOf('index', this.digestTracksKeys()), dropped_at); this.props.reorderTracks(helpers.arrayOf('index', this.digestTracksKeys()), dropped_at);
this.props.uiActions.setSelectedTracks([]); this.props.uiActions.setSelectedTracks([]);
@ -16023,7 +16028,9 @@ var TrackList = function (_React$Component) {
}, { }, {
key: 'handleDoubleClick', key: 'handleDoubleClick',
value: function handleDoubleClick(e, track_key) { value: function handleDoubleClick(e, track_key) {
if (this.props.context_menu) this.props.uiActions.hideContextMenu(); if (this.props.context_menu) {
this.props.uiActions.hideContextMenu();
}
this.playTracks(); this.playTracks();
} }
}, { }, {
@ -16051,14 +16058,17 @@ var TrackList = function (_React$Component) {
uris: selected_tracks_uris, uris: selected_tracks_uris,
indexes: selected_tracks_indexes indexes: selected_tracks_indexes
}; };
this.props.uiActions.showContextMenu(data); this.props.uiActions.showContextMenu(data);
} }
}, { }, {
key: 'handleSelection', key: 'handleSelection',
value: function handleSelection(e, track_key) { value: function handleSelection(e, track_key) {
var touched = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var selected_tracks = this.props.selected_tracks; var selected_tracks = this.props.selected_tracks;
if (e.ctrlKey || e.metaKey || this.props.slim_mode || helpers.isTouchDevice()) { if (e.ctrlKey || e.metaKey || touched) {
// Already selected, so unselect it // Already selected, so unselect it
if (selected_tracks.includes(track_key)) { if (selected_tracks.includes(track_key)) {
@ -16115,6 +16125,10 @@ var TrackList = function (_React$Component) {
var selected_tracks = this.digestTracksKeys(); var selected_tracks = this.digestTracksKeys();
var selected_tracks_indexes = helpers.arrayOf('index', selected_tracks); var selected_tracks_indexes = helpers.arrayOf('index', selected_tracks);
if (selected_tracks.length <= 0) {
return this.props.uiActions.createNotification('No tracks selected', 'bad');
}
// Our parent handles playing // Our parent handles playing
if (this.props.playTracks !== undefined) { if (this.props.playTracks !== undefined) {
return this.props.playTracks(selected_tracks); return this.props.playTracks(selected_tracks);
@ -16343,7 +16357,8 @@ var TrackList = function (_React$Component) {
selected: _this2.props.selected_tracks.includes(track_key), selected: _this2.props.selected_tracks.includes(track_key),
dragger: _this2.props.dragger, dragger: _this2.props.dragger,
handleSelection: function handleSelection(e) { handleSelection: function handleSelection(e) {
return _this2.handleSelection(e, track_key); var touched = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
return _this2.handleSelection(e, track_key, touched);
}, },
handleDoubleClick: function handleDoubleClick(e) { handleDoubleClick: function handleDoubleClick(e) {
return _this2.handleDoubleClick(e, track_key); return _this2.handleDoubleClick(e, track_key);
@ -33084,6 +33099,7 @@ var Track = function (_React$Component) {
hover: false hover: false
}; };
_this.last_touchstart = 0;
_this.start_position = false; _this.start_position = false;
return _this; return _this;
} }
@ -33091,19 +33107,16 @@ var Track = function (_React$Component) {
_createClass(Track, [{ _createClass(Track, [{
key: 'handleMouseEnter', key: 'handleMouseEnter',
value: function handleMouseEnter(e) { value: function handleMouseEnter(e) {
console.log("handleMouseEnter");
this.setState({ hover: true }); this.setState({ hover: true });
} }
}, { }, {
key: 'handleMouseLeave', key: 'handleMouseLeave',
value: function handleMouseLeave(e) { value: function handleMouseLeave(e) {
console.log("handleMouseLeave");
this.setState({ hover: false }); this.setState({ hover: false });
} }
}, { }, {
key: 'handleMouseDown', key: 'handleMouseDown',
value: function handleMouseDown(e) { value: function handleMouseDown(e) {
console.log("handleMouseDown");
var target = $(e.target); var target = $(e.target);
console.log(e.type); console.log(e.type);
@ -33128,7 +33141,6 @@ var Track = function (_React$Component) {
}, { }, {
key: 'handleMouseMove', key: 'handleMouseMove',
value: function handleMouseMove(e) { value: function handleMouseMove(e) {
console.log("handleMouseMove");
var target = $(e.target); var target = $(e.target);
// No drag handling means NO // No drag handling means NO
@ -33153,7 +33165,6 @@ var Track = function (_React$Component) {
}, { }, {
key: 'handleMouseUp', key: 'handleMouseUp',
value: function handleMouseUp(e) { value: function handleMouseUp(e) {
console.log("handleMouseUp");
var target = $(e.target); var target = $(e.target);
// Only listen for left clicks // Only listen for left clicks
@ -33180,45 +33191,69 @@ var Track = function (_React$Component) {
}, { }, {
key: 'handleDoubleClick', key: 'handleDoubleClick',
value: function handleDoubleClick(e) { value: function handleDoubleClick(e) {
console.log("handleDoubleClick"); this.props.handleDoubleClick(e);
var target = $(e.target);
} }
}, { }, {
key: 'handleTouchStart', key: 'handleTouchStart',
value: function handleTouchStart(e) { value: function handleTouchStart(e) {
console.log("handleTouchStart"); var _this2 = this;
e.preventDefault();
var target = $(e.target);
// Touch-drag zone var target = $(e.target);
if (target.hasClass('drag-zone')) { var timestamp = Math.floor(Date.now());
// Clicked a nested link (ie Artist name), so no touch intervention required
if (target.is('a')) {
return false;
// We started a touchstart within 300ms ago, so handle as double-tap
} else if (timestamp - this.last_touchstart > 0 && timestamp - this.last_touchstart <= 300) {
// Update our selection. By not passing touch = true selection will work like a regular click
this.props.handleSelection(e);
// Wait a moment to give Redux time to update our selected tracks
// TODO: Use proper callback, rather than assuming a fixed period of time for store change
setTimeout(function () {
_this2.props.handleDoubleClick(e);
}, 100);
e.preventDefault();
// Touch-drag zone
} else if (target.hasClass('drag-zone')) {
this.props.handleTouchDrag(e); this.props.handleTouchDrag(e);
e.preventDefault();
// Select zone // Select zone
} else if (target.hasClass('select-zone')) { } else if (target.hasClass('select-zone')) {
this.props.handleSelection(e); this.props.handleSelection(e, true);
e.preventDefault();
// Clicked a nested link (ie Artist name), so no dragging required
} else if (target.is('a')) {
return false;
// Touch contextable // Touch contextable
} else if (target.hasClass('touch-contextable')) { } else if (target.hasClass('touch-contextable')) {
this.props.handleContextMenu(e); this.props.handleSelection(e);
this.handleContextMenu(e);
e.preventDefault();
} }
// Save our last tap
this.last_touchstart = timestamp;
return false; return false;
} }
}, { }, {
key: 'handleTouchEnd', key: 'handleTouchEnd',
value: function handleTouchEnd(e) { value: function handleTouchEnd(e) {
console.log("handleTouchEnd"); var target = $(e.target);
e.preventDefault(); var timestamp = Math.floor(Date.now());
// Clicked a nested link (ie Artist name), so no dragging required
if (!target.is('a')) {
e.preventDefault();
}
} }
}, { }, {
key: 'handleContextMenu', key: 'handleContextMenu',
value: function handleContextMenu(e) { value: function handleContextMenu(e) {
console.log("handleContextMenu");
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
e.cancelBubble = true; e.cancelBubble = true;
@ -33227,7 +33262,7 @@ var Track = function (_React$Component) {
}, { }, {
key: 'render', key: 'render',
value: function render() { value: function render() {
var _this2 = this; var _this3 = this;
if (!this.props.track) { if (!this.props.track) {
return null; return null;
@ -33397,7 +33432,7 @@ var Track = function (_React$Component) {
} }
track_actions.push(_react2.default.createElement(_ContextMenuTrigger2.default, { key: 'context', onTrigger: function onTrigger(e) { track_actions.push(_react2.default.createElement(_ContextMenuTrigger2.default, { key: 'context', onTrigger: function onTrigger(e) {
return _this2.handleContextMenu(e); return _this3.handleContextMenu(e);
} })); } }));
if (this.props.mini_zones) { if (this.props.mini_zones) {
@ -33428,33 +33463,33 @@ var Track = function (_React$Component) {
{ {
className: className, className: className,
onMouseEnter: function onMouseEnter(e) { onMouseEnter: function onMouseEnter(e) {
return _this2.handleMouseEnter(e); return _this3.handleMouseEnter(e);
}, },
onMouseLeave: function onMouseLeave(e) { onMouseLeave: function onMouseLeave(e) {
return _this2.handleMouseLeave(e); return _this3.handleMouseLeave(e);
}, },
onMouseDown: function onMouseDown(e) { onMouseDown: function onMouseDown(e) {
return _this2.handleMouseDown(e); return _this3.handleMouseDown(e);
}, },
onMouseUp: function onMouseUp(e) { onMouseUp: function onMouseUp(e) {
return _this2.handleMouseUp(e); return _this3.handleMouseUp(e);
}, },
onMouseMove: function onMouseMove(e) { onMouseMove: function onMouseMove(e) {
return _this2.handleMouseMove(e); return _this3.handleMouseMove(e);
}, },
onDoubleClick: function onDoubleClick(e) { onDoubleClick: function onDoubleClick(e) {
return _this2.handleDoubleClick(e); return _this3.handleDoubleClick(e);
}, },
onContextMenu: function onContextMenu(e) { onContextMenu: function onContextMenu(e) {
return _this2.handleContextMenu(e); return _this3.handleContextMenu(e);
}, },
onTouchStart: function onTouchStart(e) { onTouchStart: function onTouchStart(e) {
return _this2.handleTouchStart(e); return _this3.handleTouchStart(e);
}, },
onTouchEnd: function onTouchEnd(e) { onTouchEnd: function onTouchEnd(e) {
return _this2.handleTouchEnd(e); return _this3.handleTouchEnd(e);
} }, } },
track_actions, track_actions,
track_columns track_columns

File diff suppressed because one or more lines are too long

View File

@ -3406,7 +3406,8 @@ input[type="submit"] {
border-radius: 5px; border-radius: 5px;
background: #FFFFFF; background: #FFFFFF;
display: inline-block; display: inline-block;
margin: 1px; } margin: 1px;
pointer-events: none; }
.context-menu-trigger:active { .context-menu-trigger:active {
margin-top: 0px; margin-top: 0px;
margin-bottom: -1px; } margin-bottom: -1px; }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -38,7 +38,7 @@
// Release details // Release details
// These are automatically injected to built HTML // These are automatically injected to built HTML
var build = "1512444391"; var build = "1512618796";
var version = "3.8.9"; var version = "3.8.9";
// Construct the script tag // Construct the script tag

View File

@ -24,17 +24,14 @@ export default class Track extends React.Component{
} }
handleMouseEnter(e){ handleMouseEnter(e){
console.log("handleMouseEnter");
this.setState({hover: true}); this.setState({hover: true});
} }
handleMouseLeave(e){ handleMouseLeave(e){
console.log("handleMouseLeave");
this.setState({hover: false}); this.setState({hover: false});
} }
handleMouseDown(e){ handleMouseDown(e){
console.log("handleMouseDown");
var target = $(e.target); var target = $(e.target);
console.log(e.type); console.log(e.type);
@ -58,7 +55,6 @@ export default class Track extends React.Component{
} }
handleMouseMove(e){ handleMouseMove(e){
console.log("handleMouseMove");
var target = $(e.target); var target = $(e.target);
// No drag handling means NO // No drag handling means NO
@ -82,7 +78,6 @@ export default class Track extends React.Component{
} }
handleMouseUp(e){ handleMouseUp(e){
console.log("handleMouseUp");
var target = $(e.target); var target = $(e.target);
// Only listen for left clicks // Only listen for left clicks
@ -108,40 +103,47 @@ export default class Track extends React.Component{
} }
handleDoubleClick(e){ handleDoubleClick(e){
console.log("handleDoubleClick");
this.props.handleDoubleClick(e); this.props.handleDoubleClick(e);
} }
handleTouchStart(e){ handleTouchStart(e){
console.log("handleTouchStart");
var target = $(e.target); var target = $(e.target);
var timestamp = Math.floor(Date.now()); var timestamp = Math.floor(Date.now());
// Clicked a nested link (ie Artist name), so no touch intervention required // Clicked a nested link (ie Artist name), so no touch intervention required
if (target.is('a')){ if (target.is('a')){
console.log('a');
return false; return false;
// We started a touchstart within 300ms ago, so handle as double-tap // We started a touchstart within 300ms ago, so handle as double-tap
} else if ((timestamp - this.last_touchstart) > 0 && (timestamp - this.last_touchstart) <= 300){ } else if ((timestamp - this.last_touchstart) > 0 && (timestamp - this.last_touchstart) <= 300){
e.preventDefault();
// Update our selection. By not passing touch = true selection will work like a regular click
this.props.handleSelection(e); this.props.handleSelection(e);
this.props.handleDoubleClick(e);
// Wait a moment to give Redux time to update our selected tracks
// TODO: Use proper callback, rather than assuming a fixed period of time for store change
setTimeout(() => {
this.props.handleDoubleClick(e);
},
100
);
e.preventDefault();
// Touch-drag zone // Touch-drag zone
} else if (target.hasClass('drag-zone')){ } else if (target.hasClass('drag-zone')){
e.preventDefault();
this.props.handleTouchDrag(e); this.props.handleTouchDrag(e);
e.preventDefault();
// Select zone // Select zone
} else if (target.hasClass('select-zone')){ } else if (target.hasClass('select-zone')){
this.props.handleSelection(e, true);
e.preventDefault(); e.preventDefault();
this.props.handleSelection(e);
// Touch contextable // Touch contextable
} else if (target.hasClass('touch-contextable')){ } else if (target.hasClass('touch-contextable')){
this.props.handleSelection(e);
this.handleContextMenu(e);
e.preventDefault(); e.preventDefault();
this.props.handleContextMenu(e);
} }
// Save our last tap // Save our last tap
@ -151,7 +153,6 @@ export default class Track extends React.Component{
} }
handleTouchEnd(e){ handleTouchEnd(e){
console.log("handleTouchEnd");
var target = $(e.target); var target = $(e.target);
var timestamp = Math.floor(Date.now()); var timestamp = Math.floor(Date.now());
@ -162,7 +163,6 @@ export default class Track extends React.Component{
} }
handleContextMenu(e){ handleContextMenu(e){
console.log("handleContextMenu");
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
e.cancelBubble = true; e.cancelBubble = true;

View File

@ -158,14 +158,12 @@ class TrackList extends React.Component{
over = over.closest('.track') over = over.closest('.track')
} }
if (over.length > 0){ if (over.length > 0){
let siblings = over.parent().children('.track') let siblings = over.parent().children('.track');
let dropped_at = siblings.index(over) - 1 let dropped_at = siblings.index(over) - 1;
console.log('touchend',helpers.arrayOf('index',this.digestTracksKeys()),'to',dropped_at)
if (this.props.reorderTracks !== undefined){ if (this.props.reorderTracks !== undefined){
this.props.reorderTracks(helpers.arrayOf('index',this.digestTracksKeys()),dropped_at) this.props.reorderTracks(helpers.arrayOf('index',this.digestTracksKeys()),dropped_at);
this.props.uiActions.setSelectedTracks([]) this.props.uiActions.setSelectedTracks([]);
} }
} }
@ -204,13 +202,14 @@ class TrackList extends React.Component{
uris: selected_tracks_uris, uris: selected_tracks_uris,
indexes: selected_tracks_indexes indexes: selected_tracks_indexes
} }
this.props.uiActions.showContextMenu(data); this.props.uiActions.showContextMenu(data);
} }
handleSelection(e,track_key){ handleSelection(e, track_key, touched = false){
let selected_tracks = this.props.selected_tracks let selected_tracks = this.props.selected_tracks
if ((e.ctrlKey || e.metaKey) || this.props.slim_mode || helpers.isTouchDevice()){ if ((e.ctrlKey || e.metaKey) || touched){
// Already selected, so unselect it // Already selected, so unselect it
if (selected_tracks.includes(track_key)){ if (selected_tracks.includes(track_key)){
@ -253,7 +252,7 @@ class TrackList extends React.Component{
selected_tracks = [track_key] selected_tracks = [track_key]
} }
this.props.uiActions.setSelectedTracks(selected_tracks) this.props.uiActions.setSelectedTracks(selected_tracks);
} }
isRightClick(e){ isRightClick(e){
@ -436,7 +435,7 @@ class TrackList extends React.Component{
can_sort={this.props.context == 'queue' || this.props.context == 'editable-playlist'} can_sort={this.props.context == 'queue' || this.props.context == 'editable-playlist'}
selected={this.props.selected_tracks.includes(track_key)} selected={this.props.selected_tracks.includes(track_key)}
dragger={this.props.dragger} dragger={this.props.dragger}
handleSelection={e => this.handleSelection(e, track_key)} handleSelection={(e, touched = false) => this.handleSelection(e, track_key, touched)}
handleDoubleClick={e => this.handleDoubleClick(e, track_key)} handleDoubleClick={e => this.handleDoubleClick(e, track_key)}
handleContextMenu={e => this.handleContextMenu(e, track_key)} handleContextMenu={e => this.handleContextMenu(e, track_key)}
handleDrag={e => this.handleDrag(e, track_key)} handleDrag={e => this.handleDrag(e, track_key)}

View File

@ -12,8 +12,15 @@ export function setSelectedTracks(keys = []){
} }
export function showContextMenu(data){ export function showContextMenu(data){
data.position_x = data.e.clientX;
data.position_y = data.e.clientY; if (data.e.touches){
data.position_x = data.e.touches[0].clientX;
data.position_y = data.e.touches[0].clientY;
} else {
data.position_x = data.e.clientX;
data.position_y = data.e.clientY;
}
return { return {
type: 'SHOW_CONTEXT_MENU', type: 'SHOW_CONTEXT_MENU',
data: data data: data

View File

@ -296,6 +296,7 @@
background: $white; background: $white;
display: inline-block; display: inline-block;
margin: 1px; margin: 1px;
pointer-events: none;
} }
&:active { &:active {