Touch-device context menu; AddToPlaylist fix
This commit is contained in:
@ -5,6 +5,7 @@ import { bindActionCreators } from 'redux'
|
||||
import FontAwesome from 'react-fontawesome'
|
||||
|
||||
import TrackList from './TrackList'
|
||||
import * as helpers from '../helpers'
|
||||
import * as uiActions from '../services/ui/actions'
|
||||
import * as mopidyActions from '../services/mopidy/actions'
|
||||
import * as spotifyActions from '../services/spotify/actions'
|
||||
@ -13,9 +14,9 @@ class ContextMenu extends React.Component{
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleScroll = this.handleScroll.bind(this);
|
||||
//this.handleScroll = this.handleScroll.bind(this);
|
||||
}
|
||||
|
||||
/*
|
||||
componentDidMount(){
|
||||
window.addEventListener("scroll", this.handleScroll, false);
|
||||
}
|
||||
@ -28,7 +29,7 @@ class ContextMenu extends React.Component{
|
||||
if( this.props.context_menu.show ){
|
||||
this.props.uiActions.hideContextMenu();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
playQueueItem(){
|
||||
var selectedTracks = this.props.context_menu.data.selected_tracks;
|
||||
@ -47,21 +48,13 @@ class ContextMenu extends React.Component{
|
||||
}
|
||||
|
||||
playItems(){
|
||||
var selected_tracks = this.props.context_menu.data.selected_tracks;
|
||||
var selected_tracks_uris = [];
|
||||
for( var i = 0; i < selected_tracks.length; i++ ){
|
||||
selected_tracks_uris.push( selected_tracks[i].uri );
|
||||
}
|
||||
var selected_tracks_uris = helpers.asURIs(this.props.context_menu.data.selected_tracks)
|
||||
this.props.mopidyActions.playURIs(selected_tracks_uris);
|
||||
this.props.uiActions.hideContextMenu();
|
||||
}
|
||||
|
||||
playItemsNext(){
|
||||
var selected_tracks = this.props.context_menu.data.selected_tracks;
|
||||
var selected_tracks_uris = [];
|
||||
for( var i = 0; i < selected_tracks.length; i++ ){
|
||||
selected_tracks_uris.push( selected_tracks[i].uri );
|
||||
}
|
||||
var selected_tracks_uris = helpers.asURIs(this.props.context_menu.data.selected_tracks)
|
||||
|
||||
var current_track = this.props.current_track
|
||||
var current_track_index = -1
|
||||
@ -79,16 +72,24 @@ class ContextMenu extends React.Component{
|
||||
this.props.uiActions.hideContextMenu();
|
||||
}
|
||||
|
||||
addToPlaylist(){
|
||||
var selected_tracks_uris = helpers.asURIs(this.props.context_menu.data.selected_tracks)
|
||||
this.props.uiActions.openModal( 'add_to_playlist', { tracks_uris: selected_tracks_uris } )
|
||||
this.props.uiActions.hideContextMenu();
|
||||
}
|
||||
|
||||
addToQueue(){
|
||||
var selected_tracks = this.props.context_menu.data.selected_tracks;
|
||||
var selected_tracks_uris = [];
|
||||
for( var i = 0; i < selected_tracks.length; i++ ){
|
||||
selected_tracks_uris.push( selected_tracks[i].uri );
|
||||
}
|
||||
var selected_tracks_uris = helpers.asURIs(this.props.context_menu.data.selected_tracks)
|
||||
this.props.mopidyActions.enqueueTracks(selected_tracks_uris);
|
||||
this.props.uiActions.hideContextMenu();
|
||||
}
|
||||
|
||||
addTracksToPlaylist( playlist_uri ){
|
||||
var selected_tracks_uris = helpers.asURIs(this.props.context_menu.data.selected_tracks)
|
||||
this.props.uiActions.addTracksToPlaylist( playlist_uri, selected_tracks_uris )
|
||||
this.props.uiActions.hideContextMenu();
|
||||
}
|
||||
|
||||
removeFromPlaylist(){
|
||||
this.props.uiActions.removeTracksFromPlaylist( this.props.playlist.uri, this.props.context_menu.data.selected_tracks_indexes )
|
||||
this.props.uiActions.hideContextMenu();
|
||||
@ -115,15 +116,11 @@ class ContextMenu extends React.Component{
|
||||
{
|
||||
playlists.map( playlist => {
|
||||
return (
|
||||
<a
|
||||
className="menu-item"
|
||||
key={playlist.uri}
|
||||
onClick={ () => {
|
||||
this.props.uiActions.addTracksToPlaylist( playlist.uri, this.props.context_menu.data.selected_tracks )
|
||||
this.props.uiActions.hideContextMenu() }
|
||||
}>
|
||||
{ playlist.name }
|
||||
</a>
|
||||
<span className="menu-item-wrapper" key={playlist.uri} >
|
||||
<a className="menu-item" onClick={ () => this.addTracksToPlaylist(playlist.uri) }>
|
||||
<span className="label">{ playlist.name }</span>
|
||||
</a>
|
||||
</span>
|
||||
)
|
||||
})
|
||||
}
|
||||
@ -138,31 +135,31 @@ class ContextMenu extends React.Component{
|
||||
|
||||
case 'queue':
|
||||
items = [
|
||||
{ handleClick: 'playQueueItem', label: 'Play' },
|
||||
{ handleClick: 'addToPlaylist', label: 'Add to playlist', playlists: true },
|
||||
{ handleClick: 'copyURIs', label: 'Copy URIs' },
|
||||
{ handleClick: 'removeFromQueue', label: 'Remove' }
|
||||
{ handleClick: 'playQueueItem', label: 'Play', icon: 'play' },
|
||||
{ handleClick: 'addToPlaylist', label: 'Add to playlist', icon: 'plus', playlists: true },
|
||||
{ handleClick: 'copyURIs', label: 'Copy URIs', icon: 'copy' },
|
||||
{ handleClick: 'removeFromQueue', label: 'Remove', icon: 'trash' }
|
||||
];
|
||||
break;
|
||||
|
||||
case 'editable-playlist':
|
||||
items = [
|
||||
{ handleClick: 'playItems', label: 'Play' },
|
||||
{ handleClick: 'playItemsNext', label: 'Play next' },
|
||||
{ handleClick: 'addToQueue', label: 'Add to queue' },
|
||||
{ handleClick: 'addToPlaylist', label: 'Add to playlist', playlists: true },
|
||||
{ handleClick: 'copyURIs', label: 'Copy URIs' },
|
||||
{ handleClick: 'removeFromPlaylist', label: 'Remove' }
|
||||
{ handleClick: 'playItems', label: 'Play', icon: 'play' },
|
||||
{ handleClick: 'playItemsNext', label: 'Play next', icon: 'play' },
|
||||
{ handleClick: 'addToQueue', label: 'Add to queue', icon: 'plus' },
|
||||
{ handleClick: 'addToPlaylist', label: 'Add to playlist', icon: 'plus', playlists: true },
|
||||
{ handleClick: 'copyURIs', label: 'Copy URIs', icon: 'copy' },
|
||||
{ handleClick: 'removeFromPlaylist', label: 'Remove', icon: 'trash' }
|
||||
];
|
||||
break;
|
||||
|
||||
default:
|
||||
items = [
|
||||
{ handleClick: 'playItems', label: 'Play' },
|
||||
{ handleClick: 'playItemsNext', label: 'Play next' },
|
||||
{ handleClick: 'addToQueue', label: 'Add to queue' },
|
||||
{ handleClick: 'addToPlaylist', label: 'Add to playlist', playlists: true },
|
||||
{ handleClick: 'copyURIs', label: 'Copy URIs' }
|
||||
{ handleClick: 'playItems', label: 'Play', icon: 'play' },
|
||||
{ handleClick: 'playItemsNext', label: 'Play next', icon: 'play' },
|
||||
{ handleClick: 'addToQueue', label: 'Add to queue', icon: 'plus' },
|
||||
{ handleClick: 'addToPlaylist', label: 'Add to playlist', icon: 'plus', playlists: true },
|
||||
{ handleClick: 'copyURIs', label: 'Copy URIs', icon: 'copy' }
|
||||
];
|
||||
break;
|
||||
}
|
||||
@ -173,14 +170,24 @@ class ContextMenu extends React.Component{
|
||||
items.map((item, index) => {
|
||||
if( item.playlists ){
|
||||
return (
|
||||
<span key={item.handleClick} className="menu-item has-submenu">
|
||||
{ item.label }
|
||||
<FontAwesome name="caret-right" />
|
||||
<span key={item.handleClick} className="menu-item-wrapper has-submenu">
|
||||
<a className="menu-item" onClick={ (e) => this[item.handleClick](e) }>
|
||||
<FontAwesome className="icon" fixedWidth name={item.icon} />
|
||||
<span className="label">{ item.label }</span>
|
||||
<FontAwesome className="submenu-icon" name="caret-right" />
|
||||
</a>
|
||||
{ this.renderPlaylistSubmenu() }
|
||||
</span>
|
||||
)
|
||||
}else{
|
||||
return <a className="menu-item" key={item.handleClick} onClick={ (e) => this[item.handleClick](e) }>{ item.label }</a>
|
||||
return (
|
||||
<span className="menu-item-wrapper" key={item.handleClick}>
|
||||
<a className="menu-item" onClick={ (e) => this[item.handleClick](e) }>
|
||||
<FontAwesome className="icon" fixedWidth name={item.icon} />
|
||||
<span className="label">{ item.label }</span>
|
||||
</a>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ const localstorageMiddleware = (function(){
|
||||
|
||||
// append our state to a global variable. This gives us access to debug the store at any point
|
||||
window._store = store
|
||||
//console.log(action)
|
||||
console.log(action)
|
||||
|
||||
switch( action.type ){
|
||||
|
||||
|
||||
@ -164,8 +164,7 @@ export function removeTracksFromPlaylist( playlist_uri, tracks_indexes ){
|
||||
}
|
||||
}
|
||||
|
||||
export function addTracksToPlaylist( playlist_uri, tracks ){
|
||||
var tracks_uris = helpers.asURIs(tracks)
|
||||
export function addTracksToPlaylist( playlist_uri, tracks_uris ){
|
||||
switch( helpers.uriSource( playlist_uri ) ){
|
||||
|
||||
case 'spotify':
|
||||
|
||||
@ -117,6 +117,8 @@ class App extends React.Component{
|
||||
var className = '';
|
||||
if( this.props.dragger && this.props.dragger.active ) className += ' dragging'
|
||||
if( this.props.sidebar_open ) className += ' sidebar-open'
|
||||
if( this.props.modal ) className += ' modal-open'
|
||||
if( 'ontouchstart' in document.documentElement ) className += ' has-touch-events'
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
||||
@ -3,31 +3,40 @@
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 98;
|
||||
z-index: 99;
|
||||
background: $dark_grey;
|
||||
color: #FFFFFF;
|
||||
|
||||
.menu-item {
|
||||
.menu-item-wrapper {
|
||||
display: block;
|
||||
padding: 8px 12px;
|
||||
width: 120px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
&:not(:first-child){
|
||||
border-top: 1px solid lighten($dark_grey, 8%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background: lighten($dark_grey, 5%);
|
||||
|
||||
.menu-item {
|
||||
background: lighten($dark_grey, 5%);
|
||||
}
|
||||
.submenu {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.fa {
|
||||
.menu-item {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
padding: 8px 12px;
|
||||
width: 120px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
&:not(:first-child) .menu-item {
|
||||
border-top: 1px solid lighten($dark_grey, 8%);
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.submenu-icon {
|
||||
font-size: 10px;
|
||||
float: right;
|
||||
padding-top: 4px;
|
||||
@ -42,7 +51,7 @@
|
||||
overflow-y: scroll;
|
||||
background: lighten($dark_grey, 5%);
|
||||
|
||||
.menu-item {
|
||||
.menu-item-wrapper {
|
||||
width: 150px;
|
||||
&:hover {
|
||||
background: lighten($dark_grey, 10%);
|
||||
@ -58,16 +67,48 @@
|
||||
top: auto !important;
|
||||
background: $blue;
|
||||
|
||||
.menu-item {
|
||||
.menu-item-wrapper {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
height: auto;
|
||||
border: 0 !important;
|
||||
|
||||
.fa,
|
||||
.menu-item {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border: 0 !important;
|
||||
vertical-align: top;
|
||||
|
||||
&:hover {
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&:focus {
|
||||
background: rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
.icon {
|
||||
padding: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.submenu-icon {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&:not(:first-child) .menu-item {
|
||||
border-left: 1px solid rgba(255,255,255,0.2) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -100,4 +100,21 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include responsive( $bp_medium ){
|
||||
|
||||
.content {
|
||||
|
||||
padding: 50px;
|
||||
width: 80%;
|
||||
|
||||
.playlists {
|
||||
.playlist {
|
||||
float: none !important;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,10 +127,10 @@
|
||||
.slider-wrapper {
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
bottom: -6px;
|
||||
left: -4px;
|
||||
height: 80px;
|
||||
padding: 5px 5px 35px 5px;
|
||||
padding: 10px 5px 35px 5px;
|
||||
background: rgba(0,0,0,0.8);
|
||||
z-index: 98;
|
||||
}
|
||||
|
||||
@ -34,7 +34,6 @@
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
margin: 10px 0;
|
||||
width: 20px;
|
||||
height: 100%;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user