Context menu in action

This commit is contained in:
James Barnsley
2017-02-27 08:44:02 +13:00
parent f5fcaee5eb
commit 8d93a21c83
7 changed files with 240 additions and 153 deletions

View File

@ -1,6 +1,6 @@
import React, { PropTypes } from 'react'
import { Link } from 'react-router'
import { Link, hashHistory } from 'react-router'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import FontAwesome from 'react-fontawesome'
@ -30,12 +30,17 @@ class ContextMenu extends React.Component{
window.removeEventListener("click", this.handleClick, false)
}
handleScroll(){
if (this.props.menu) this.props.uiActions.hideContextMenu()
handleScroll(e){
if (this.props.menu){
this.props.uiActions.hideContextMenu()
}
}
handleClick(){
if (this.props.menu) this.props.uiActions.hideContextMenu()
handleClick(e){
var target = e.target
if (this.props.menu && !target.classList.contains('context-menu-trigger')){
this.props.uiActions.hideContextMenu()
}
}
playQueueItem(){
@ -89,6 +94,10 @@ class ContextMenu extends React.Component{
this.props.uiActions.hideContextMenu();
}
goToUser(){
hashHistory.push( global.baseURL +'user/'+ this.props.menu.item.owner.uri );
}
copyURIs(e){
var temp = $("<input>");
$("body").append(temp);
@ -100,6 +109,17 @@ class ContextMenu extends React.Component{
this.props.uiActions.hideContextMenu()
}
copyLinks(e){
var temp = $("<input>");
$("body").append(temp);
temp.val(this.props.menu.item.external_urls.spotify).select();
document.execCommand("copy");
temp.remove();
this.props.uiActions.createNotification( "Copied link" )
this.props.uiActions.hideContextMenu()
}
closeAndDeselectTracks(){
this.props.uiActions.hideContextMenu();
}
@ -137,8 +157,10 @@ class ContextMenu extends React.Component{
{ handleClick: 'playURIs', label: 'Play' },
{ handleClick: 'playURIsNext', label: 'Play next' },
{ handleClick: 'addToQueue', label: 'Add to queue' },
{ handleClick: 'goToArtist', label: 'Go to artist' },
// { handleClick: 'toggleFollow', label: 'Follow/unfollow' }, TODO
{ handleClick: 'copyURIs', label: 'Copy URI' }
{ handleClick: 'copyURIs', label: 'Copy URI' },
{ handleClick: 'copyLinks', label: 'Copy link' }
]
break
@ -146,15 +168,18 @@ class ContextMenu extends React.Component{
var items = [
//{ handleClick: 'toggleFollow', label: 'Follow/unfollow' }, TODO
{ handleClick: 'startRadio', label: 'Start radio' },
{ handleClick: 'copyURIs', label: 'Copy URI' }
{ handleClick: 'copyURIs', label: 'Copy URI' },
{ handleClick: 'copyLinks', label: 'Copy link' }
]
break
case 'playlist':
var items = [
{ handleClick: 'playURIs', label: 'Play' },
{ handleClick: 'goToUser', label: 'Go to user' },
// { handleClick: 'toggleFollow', label: 'Follow/unfollow' }, TODO
{ handleClick: 'copyURIs', label: 'Copy URI' }
{ handleClick: 'copyURIs', label: 'Copy URI' },
{ handleClick: 'copyLinks', label: 'Copy link' }
]
break
@ -205,6 +230,11 @@ class ContextMenu extends React.Component{
return (
<Link className="title" to={global.baseURL+helpers.uriType(item.uri)+'/'+item.uri}>
{style ? <div className="background" style={style}></div> : null}
<div className="type">
{helpers.uriSource(item.uri)}
&nbsp;
{this.props.menu.context}
</div>
<div className="text">{item.name}</div>
</Link>
)
@ -264,8 +294,10 @@ class ContextMenu extends React.Component{
return (
<div className={className} style={style}>
{this.props.menu.item ? this.renderTitle() : null}
{this.renderItems()}
<div className="liner">
{this.props.menu.item ? this.renderTitle() : null}
{this.renderItems()}
</div>
</div>
);
}

View File

@ -49,6 +49,16 @@ class Album extends React.Component{
}
}
handleContextMenu(e){
var data = {
e: e,
context: 'album',
item: this.props.album,
uris: [this.props.params.uri]
}
this.props.uiActions.showContextMenu(data)
}
loadAlbum( props = this.props ){
switch( helpers.uriSource( props.params.uri ) ){
@ -119,6 +129,7 @@ class Album extends React.Component{
<div className="actions">
<button className="primary" onClick={e => this.play()}>Play</button>
{ helpers.uriSource(this.props.params.uri) == 'spotify' ? <FollowButton className="secondary" uri={this.props.params.uri} addText="Add to library" removeText="Remove from library" is_following={this.props.album.is_following} /> : null }
<button className="context-menu-trigger" onClick={e => this.handleContextMenu(e)}><FontAwesome name="ellipsis-v" /></button>
</div>
<section className="list-wrapper">

View File

@ -122,7 +122,11 @@ class App extends React.Component{
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 (helpers.isTouchDevice() || this.props.emulate_touch) className += ' can-touch'
if (helpers.isTouchDevice() || this.props.emulate_touch){
className += ' touch'
} else {
className += ' notouch'
}
return (
<div className={className}>

View File

@ -54,6 +54,16 @@ class Artist extends React.Component{
}
}
handleContextMenu(e){
var data = {
e: e,
context: 'artist',
item: this.props.artist,
uris: [this.props.params.uri]
}
this.props.uiActions.showContextMenu(data)
}
loadArtist( props = this.props ){
switch( helpers.uriSource( props.params.uri ) ){
@ -204,7 +214,7 @@ class Artist extends React.Component{
<div className="actions">
{ can_play_radio ? <button className="primary" onClick={e => this.props.pusherActions.startRadio([this.props.artist.uri])}>Start radio</button> : null}
{ can_follow ? <FollowButton className="white" uri={this.props.params.uri} removeText="Unfollow" addText="Follow" is_following={this.props.artist.is_following} /> : null}
<button>...</button>
<button className="context-menu-trigger white" onClick={e => this.handleContextMenu(e)}><FontAwesome name="ellipsis-v" /></button>
</div>
{ this.renderSubViewMenu() }
</div>

View File

@ -39,6 +39,16 @@ class Playlist extends React.Component{
}
}
handleContextMenu(e){
var data = {
e: e,
context: (this.props.playlist.can_edit ? 'editable-playlist' : 'playlist'),
item: this.props.playlist,
uris: [this.props.params.uri]
}
this.props.uiActions.showContextMenu(data)
}
loadPlaylist( props = this.props ){
switch( helpers.uriSource( props.params.uri ) ){
@ -97,7 +107,7 @@ class Playlist extends React.Component{
<div className="actions">
<button className="primary" onClick={ e => this.play() }>Play</button>
<button className="secondary" onClick={ e => this.props.uiActions.openModal('edit_playlist', { uri: this.props.playlist.uri, name: this.props.playlist.name }) }>Edit</button>
<ConfirmationButton className="destructive" content="Delete" confirmingContent="Are you sure?" onConfirm={ e => this.delete() } />
<button className="context-menu-trigger" onClick={e => this.handleContextMenu(e)}><FontAwesome name="ellipsis-v" /></button>
</div>
)
@ -107,7 +117,7 @@ class Playlist extends React.Component{
<div className="actions">
<button className="primary" onClick={ e => this.play() }>Play</button>
<button className="secondary" onClick={ e => this.props.uiActions.openModal('edit_playlist', { uri: this.props.playlist.uri, name: this.props.playlist.name, is_public: this.props.playlist.public }) }>Edit</button>
<ConfirmationButton className="destructive" content="Delete" confirmingContent="Are you sure?" onConfirm={ e => this.unfollow() } />
<button className="context-menu-trigger" onClick={e => this.handleContextMenu(e)}><FontAwesome name="ellipsis-v" /></button>
</div>
)
}
@ -115,6 +125,7 @@ class Playlist extends React.Component{
<div className="actions">
<button className="primary" onClick={ e => this.play() }>Play</button>
<FollowButton className="secondary" uri={this.props.playlist.uri} addText="Add to library" removeText="Remove from library" is_following={this.props.playlist.is_following} />
<button className="context-menu-trigger" onClick={e => this.handleContextMenu(e)}><FontAwesome name="ellipsis-v" /></button>
</div>
)
@ -122,6 +133,7 @@ class Playlist extends React.Component{
return (
<div className="actions">
<button className="primary" onClick={ e => this.play() }>Play</button>
<button className="context-menu-trigger" onClick={e => this.handleContextMenu(e)}><FontAwesome name="ellipsis-v" /></button>
</div>
)
}