Context menu on mobile
This commit is contained in:
@ -3827,6 +3827,11 @@ input[type="submit"] {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
padding-top: 4px; }
|
||||
.context-menu__divider {
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: #454440; }
|
||||
.context-menu__submenu {
|
||||
-webkit-transition: all 0.2s ease-in-out;
|
||||
-moz-transition: all 0.2s ease-in-out;
|
||||
@ -3835,8 +3840,7 @@ input[type="submit"] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 100%;
|
||||
height: 100%;
|
||||
bottom: 0;
|
||||
min-height: 300px;
|
||||
max-height: 90vh;
|
||||
width: 0;
|
||||
@ -3844,10 +3848,8 @@ input[type="submit"] {
|
||||
overflow-y: scroll;
|
||||
background: #52514d;
|
||||
z-index: 3;
|
||||
border-radius: 3px; }
|
||||
.context-menu__submenu--expanded {
|
||||
width: 100%;
|
||||
left: 0; }
|
||||
border-radius: 3px;
|
||||
transform: translateX(100%); }
|
||||
.context-menu__submenu .context-menu__item {
|
||||
width: 100%; }
|
||||
.context-menu__submenu .context-menu__item.close-submenu {
|
||||
@ -3855,11 +3857,6 @@ input[type="submit"] {
|
||||
.context-menu__submenu .context-menu__item__label .icon {
|
||||
margin-bottom: 0.4em;
|
||||
padding-right: 6px; }
|
||||
.context-menu__divider {
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: #454440; }
|
||||
@media (max-width: 800px) {
|
||||
.context-menu {
|
||||
top: 0 !important;
|
||||
@ -3867,7 +3864,18 @@ input[type="submit"] {
|
||||
bottom: 0 !important;
|
||||
left: 0 !important;
|
||||
margin: 0 !important;
|
||||
overflow-y: scroll; }
|
||||
overflow-y: scroll;
|
||||
animation-name: fadein;
|
||||
animation-duration: 0.2s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: 1; }
|
||||
@keyframes fadein {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(20px); }
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0px); } }
|
||||
.context-menu__background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@ -3877,6 +3885,10 @@ input[type="submit"] {
|
||||
background: rgba(0, 0, 0, 0.88);
|
||||
z-index: 1; }
|
||||
.context-menu__inner {
|
||||
-webkit-transition: all 0.2s ease-in-out;
|
||||
-moz-transition: all 0.2s ease-in-out;
|
||||
-o-transition: all 0.2s ease-in-out;
|
||||
transition: all 0.2s ease-in-out;
|
||||
width: 250px;
|
||||
margin: 30px auto;
|
||||
max-width: 90vw;
|
||||
@ -3900,18 +3912,39 @@ input[type="submit"] {
|
||||
.context-menu__inner > span .dropdown-field {
|
||||
color: #FFFFFF; }
|
||||
.context-menu__title {
|
||||
display: block;
|
||||
display: none;
|
||||
padding: 14px 18px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 3px 3px 0 0; }
|
||||
.context-menu__divider {
|
||||
display: none; }
|
||||
.context-menu__items {
|
||||
-webkit-transition: all 0.2s ease-in-out;
|
||||
-moz-transition: all 0.2s ease-in-out;
|
||||
-o-transition: all 0.2s ease-in-out;
|
||||
transition: all 0.2s ease-in-out;
|
||||
opacity: 1; }
|
||||
.context-menu__item {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 800; }
|
||||
.context-menu__item__link {
|
||||
padding: 16px 22px;
|
||||
box-sizing: border-box; } }
|
||||
box-sizing: border-box; }
|
||||
.context-menu__item__link:before {
|
||||
display: none !important; }
|
||||
.context-menu__item__link:focus, .context-menu__item__link:active {
|
||||
background: #08d58f !important; }
|
||||
.context-menu__submenu {
|
||||
width: 100%;
|
||||
background: none;
|
||||
border-radius: 0;
|
||||
opacity: 0; }
|
||||
.context-menu--submenu-expanded .context-menu__items {
|
||||
transform: translateX(-100%);
|
||||
opacity: 0; }
|
||||
.context-menu--submenu-expanded .context-menu__submenu {
|
||||
transform: translateX(0%);
|
||||
opacity: 1; } }
|
||||
|
||||
.context-menu-trigger {
|
||||
display: inline-block;
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -98,7 +98,7 @@
|
||||
|
||||
// Release details
|
||||
// These are automatically injected to built HTML
|
||||
var build = "1541974041";
|
||||
var build = "1542004237";
|
||||
var version = "3.30.0";
|
||||
|
||||
// Construct the script tag
|
||||
|
||||
@ -354,13 +354,13 @@ class ContextMenu extends React.Component{
|
||||
|
||||
return (
|
||||
<div className={'context-menu__submenu' + (this.state.submenu_expanded ? ' context-menu__submenu--expanded' : '')}>
|
||||
<span className="context-menu__item">
|
||||
<a className="context-menu__item close-submenu" onClick={e => this.setState({submenu_expanded: false})}>
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link context-menu__item__link--close-submenu" onClick={e => this.setState({submenu_expanded: false})}>
|
||||
<span className="context-menu__item__label">
|
||||
<Icon name="arrow_back" />Back
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
{list}
|
||||
{loader}
|
||||
</div>
|
||||
@ -372,12 +372,12 @@ class ContextMenu extends React.Component{
|
||||
|
||||
if (context.name == 'custom'){
|
||||
return (
|
||||
<span className="context-menu__title">
|
||||
<div className="context-menu__title">
|
||||
<div className="context-menu__title__background context-menu__title__background--generic"></div>
|
||||
<div className="context-menu__title__text">
|
||||
{this.props.menu.title}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -389,7 +389,7 @@ class ContextMenu extends React.Component{
|
||||
var style = null;
|
||||
|
||||
return (
|
||||
<Link className="context-menu__title" to={global.baseURL+context.type+'/'+context.item.uri}>
|
||||
<div className="context-menu__title">
|
||||
{style ? <div className="context-menu__title__background" style={style}></div> : null}
|
||||
<div className="context-menu__title__type">
|
||||
{context.source}
|
||||
@ -397,13 +397,13 @@ class ContextMenu extends React.Component{
|
||||
{context.nice_name}
|
||||
</div>
|
||||
<div className="context-menu__title__text">{context.item.name}</div>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
break
|
||||
|
||||
default:
|
||||
return (
|
||||
<span className="context-menu__title">
|
||||
<div className="context-menu__title">
|
||||
<div className="context-menu__title__type">
|
||||
{context.source}
|
||||
|
||||
@ -413,7 +413,7 @@ class ContextMenu extends React.Component{
|
||||
{context.items_count} items
|
||||
</div>
|
||||
<div className="context-menu__title__background context-menu__title__background--generic"></div>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
break
|
||||
|
||||
@ -437,190 +437,190 @@ class ContextMenu extends React.Component{
|
||||
var context = this.getContext()
|
||||
|
||||
var play_uris = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.playURIs(e)}>
|
||||
<span className="context-menu__item__label">Play</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var play_playlist = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.playPlaylist(e)}>
|
||||
<span className="context-menu__item__label">Play</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var shuffle_play_playlist = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.shufflePlayPlaylist(e)}>
|
||||
<span className="context-menu__item__label">Shuffle play</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var play_queue_item = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.playQueueItem(e)}>
|
||||
<span className="context-menu__item__label">Play</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var play_uris_next = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.addToQueue(e, true)}>
|
||||
<span className="context-menu__item__label">Play next</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var play_artist_top_tracks = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.playArtistTopTracks(e)}>
|
||||
<span className="context-menu__item__label">Play top tracks</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var add_to_queue = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.addToQueue(e)}>
|
||||
<span className="context-menu__item__label">Add to queue</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var add_to_playlist = (
|
||||
<span className="context-menu__item context-menu__item--has-submenu">
|
||||
<div className="context-menu__item context-menu__item--has-submenu">
|
||||
<a className="context-menu__item__link" onClick={e => this.setPlaylistSubmenu()}>
|
||||
<span className="context-menu__item__label">Add to playlist</span>
|
||||
<Icon className="submenu-icon" name="arrow_forward" />
|
||||
</a>
|
||||
{this.renderPlaylistSubmenu()}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var toggle_in_library = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.toggleInLibrary(e, context.in_library)}>
|
||||
<span className="context-menu__item__label">
|
||||
{context.in_library ? 'Remove from library' : 'Add to library'}
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
if (!this.props.lastfm_authorized){
|
||||
var toggle_loved = null;
|
||||
} else if (helpers.isLoading(this.props.load_queue,['lastfm_track.getInfo'])){
|
||||
var toggle_loved = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link">
|
||||
<span className="context-menu__item__label mid_grey-text">
|
||||
Love track
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
var toggle_loved = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.toggleLoved(e, context.is_loved)}>
|
||||
<span className="context-menu__item__label">
|
||||
{context.is_loved ? 'Unlove' : 'Love'} track
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
var go_to_artist = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.goToArtist(e)}>
|
||||
<span className="context-menu__item__label">Go to artist</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var go_to_album = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.goToAlbum(e)}>
|
||||
<span className="context-menu__item__label">Go to album</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var go_to_user = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.goToUser(e)}>
|
||||
<span className="context-menu__item__label">Go to user</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var go_to_track = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.goToTrack(e)}>
|
||||
<span className="context-menu__item__label">Track info</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var go_to_recommendations = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.goToRecommendations(e)}>
|
||||
<span className="context-menu__item__label">Discover similar</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var start_radio = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.startRadio(e)}>
|
||||
<span className="context-menu__item__label">Start radio</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var remove_from_queue = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.removeFromQueue(e)}>
|
||||
<span className="context-menu__item__label">Remove</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var remove_from_playlist = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.removeFromPlaylist(e)}>
|
||||
<span className="context-menu__item__label">Remove</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var delete_playlist = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.deletePlaylist(e)}>
|
||||
<span className="context-menu__item__label">Delete</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
var copy_uris = (
|
||||
<span className="context-menu__item">
|
||||
<div className="context-menu__item">
|
||||
<a className="context-menu__item__link" onClick={e => this.copyURIs(e)}>
|
||||
<span className="context-menu__item__label">Copy URI{context.items_count > 1 ? 's' : ''}</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
switch (context.name){
|
||||
|
||||
case 'album':
|
||||
return (
|
||||
<div>
|
||||
<div className="context-menu__items">
|
||||
{play_uris}
|
||||
{play_uris_next}
|
||||
{add_to_queue}
|
||||
@ -635,7 +635,7 @@ class ContextMenu extends React.Component{
|
||||
|
||||
case 'artist':
|
||||
return (
|
||||
<div>
|
||||
<div className="context-menu__items">
|
||||
{context.source == 'spotify' ? play_artist_top_tracks : null}
|
||||
{context.source == 'spotify' ? start_radio : null}
|
||||
{this.canBeInLibrary() ? <div className="context-menu__divider" /> : null}
|
||||
@ -649,7 +649,7 @@ class ContextMenu extends React.Component{
|
||||
|
||||
case 'playlist':
|
||||
return (
|
||||
<div>
|
||||
<div className="context-menu__items">
|
||||
{play_playlist}
|
||||
{shuffle_play_playlist}
|
||||
{this.canBeInLibrary() ? <div className="context-menu__divider" /> : null}
|
||||
@ -663,7 +663,7 @@ class ContextMenu extends React.Component{
|
||||
|
||||
case 'editable-playlist':
|
||||
return (
|
||||
<div>
|
||||
<div className="context-menu__items">
|
||||
{play_playlist}
|
||||
{shuffle_play_playlist}
|
||||
{this.canBeInLibrary() ? <div className="context-menu__divider" /> : null}
|
||||
@ -679,7 +679,7 @@ class ContextMenu extends React.Component{
|
||||
|
||||
case 'queue-track':
|
||||
return (
|
||||
<div>
|
||||
<div className="context-menu__items">
|
||||
{context.items_count == 1 ? play_queue_item : null}
|
||||
<div className="context-menu__divider" />
|
||||
{add_to_playlist}
|
||||
@ -696,7 +696,7 @@ class ContextMenu extends React.Component{
|
||||
|
||||
case 'editable-playlist-track':
|
||||
return (
|
||||
<div>
|
||||
<div className="context-menu__items">
|
||||
{play_uris}
|
||||
{play_uris_next}
|
||||
{add_to_queue}
|
||||
@ -716,7 +716,7 @@ class ContextMenu extends React.Component{
|
||||
|
||||
default:
|
||||
return (
|
||||
<div>
|
||||
<div className="context-menu__items">
|
||||
{play_uris}
|
||||
{play_uris_next}
|
||||
{add_to_queue}
|
||||
|
||||
@ -206,13 +206,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__divider {
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: lighten(colour(grey), 5%);
|
||||
}
|
||||
|
||||
&__submenu {
|
||||
@include animate();
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 100%;
|
||||
height: 100%;
|
||||
bottom: 0;
|
||||
min-height: 300px;
|
||||
max-height: 90vh;
|
||||
width: 0;
|
||||
@ -221,11 +227,7 @@
|
||||
background: lighten(colour(grey), 10%);
|
||||
z-index: 3;
|
||||
border-radius: 3px;
|
||||
|
||||
&--expanded {
|
||||
width: 100%;
|
||||
left: 0;
|
||||
}
|
||||
transform: translateX(100%);
|
||||
|
||||
.context-menu {
|
||||
&__item {
|
||||
@ -245,13 +247,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__divider {
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: lighten(colour(grey), 5%);
|
||||
}
|
||||
|
||||
|
||||
@include responsive($bp_medium){
|
||||
top: 0 !important;
|
||||
@ -260,6 +255,7 @@
|
||||
left: 0 !important;
|
||||
margin: 0 !important;
|
||||
overflow-y: scroll;
|
||||
@include fadein(0.2s, 20px);
|
||||
|
||||
&__background {
|
||||
position: fixed;
|
||||
@ -272,6 +268,7 @@
|
||||
}
|
||||
|
||||
&__inner {
|
||||
@include animate(0.2s);
|
||||
width: 250px;
|
||||
margin: 30px auto;
|
||||
max-width: 90vw;
|
||||
@ -282,6 +279,7 @@
|
||||
box-shadow: none;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* These are the rules for automatically collated page headers
|
||||
* as context menus
|
||||
@ -304,7 +302,7 @@
|
||||
}
|
||||
|
||||
&__title {
|
||||
display: block;
|
||||
display: none;
|
||||
padding: 14px 18px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 3px 3px 0 0;
|
||||
@ -314,6 +312,11 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
&__items {
|
||||
@include animate();
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&__item {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 800;
|
||||
@ -321,6 +324,36 @@
|
||||
&__link {
|
||||
padding: 16px 22px;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:active {
|
||||
background: colour(turquoise) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__submenu {
|
||||
width: 100%;
|
||||
background: none;
|
||||
border-radius: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&--submenu-expanded {
|
||||
.context-menu {
|
||||
&__items {
|
||||
transform: translateX(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&__submenu {
|
||||
transform: translateX(0%);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,11 +84,11 @@ $bp_shallow: 650px;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@mixin fadein($duration: 0.2s){
|
||||
@mixin fadein($duration: 0.2s, $distance: 5px, $opacity: 0){
|
||||
@keyframes fadein {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(5px);
|
||||
opacity: $opacity;
|
||||
transform: translateY($distance);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
|
||||
Reference in New Issue
Block a user