music.mpd vue.js refactoring WIP: Implemented playlist track move feature
This commit is contained in:
parent
d3ecb7b871
commit
611a137ff6
7 changed files with 74 additions and 24 deletions
|
@ -132,6 +132,13 @@
|
|||
height: 4rem;
|
||||
@include animation(active-track 5s infinite);
|
||||
}
|
||||
|
||||
&.move:hover {
|
||||
background: $move-mode-track-bg !important;
|
||||
border-top: $move-mode-track-border;
|
||||
border-bottom: $move-mode-track-border;
|
||||
cursor: move;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,3 +23,6 @@ $playlist-controls-border: $default-border-2;
|
|||
$active-track-bg-1: #d4ffe3;
|
||||
$active-track-bg-2: #9cdfb0;
|
||||
|
||||
$move-mode-track-border: 3px dotted rgb(216,156,136);
|
||||
$move-mode-track-bg: rgba(216,156,136,0.3);
|
||||
|
||||
|
|
|
@ -17,6 +17,11 @@ Vue.component('music-mpd', {
|
|||
browser: false,
|
||||
},
|
||||
|
||||
moveMode: {
|
||||
playlist: false,
|
||||
editor: false,
|
||||
},
|
||||
|
||||
selectedPlaylistItems: {},
|
||||
selectedBrowserItems: {},
|
||||
|
||||
|
@ -45,24 +50,29 @@ Vue.component('music-mpd', {
|
|||
});
|
||||
}
|
||||
|
||||
items.push(
|
||||
{
|
||||
text: 'Add to playlist',
|
||||
icon: 'list',
|
||||
},
|
||||
{
|
||||
items.push({
|
||||
text: 'Add to playlist',
|
||||
icon: 'list',
|
||||
});
|
||||
|
||||
if (Object.keys(this.selectedPlaylistItems).length < this.playlist.length) {
|
||||
items.push({
|
||||
text: 'Move',
|
||||
icon: 'retweet',
|
||||
},
|
||||
{
|
||||
text: 'Remove from queue',
|
||||
icon: 'trash',
|
||||
click: async function() {
|
||||
await self.del();
|
||||
self.selectedPlaylistItems = {};
|
||||
click: function() {
|
||||
self.moveMode.playlist = true;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
items.push({
|
||||
text: 'Remove from queue',
|
||||
icon: 'trash',
|
||||
click: async function() {
|
||||
await self.del();
|
||||
self.selectedPlaylistItems = {};
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
if (Object.keys(this.selectedPlaylistItems).length === 1) {
|
||||
items.push({
|
||||
|
@ -473,10 +483,8 @@ Vue.component('music-mpd', {
|
|||
this._parsePlaylist(playlist);
|
||||
},
|
||||
|
||||
load: async function(item) {
|
||||
let status = await request('music.mpd.load', {playlist:item});
|
||||
this._parseStatus(status);
|
||||
|
||||
load: async function(item, play=false) {
|
||||
await request('music.mpd.load', {playlist:item, play:play});
|
||||
let playlist = await request('music.mpd.playlistinfo');
|
||||
this._parsePlaylist(playlist);
|
||||
},
|
||||
|
@ -511,6 +519,16 @@ Vue.component('music-mpd', {
|
|||
this._parseBrowserItems(items);
|
||||
},
|
||||
|
||||
move: async function(fromPos, toPos, updateChanges=true) {
|
||||
let status = await request('music.mpd.move', {from_pos: fromPos, to_pos: toPos});
|
||||
|
||||
if (updateChanges) {
|
||||
this._parseStatus(status);
|
||||
const playlist = await request('music.mpd.playlistinfo');
|
||||
this._parsePlaylist(playlist);
|
||||
}
|
||||
},
|
||||
|
||||
swap: async function() {
|
||||
if (Object.keys(this.selectedPlaylistItems).length !== 2) {
|
||||
return;
|
||||
|
@ -693,13 +711,24 @@ Vue.component('music-mpd', {
|
|||
this.browserFilter.toLocaleLowerCase().split(' ').filter(_ => _.length > 0).join(' ')) >= 0;
|
||||
},
|
||||
|
||||
onPlaylistItemClick: function(track) {
|
||||
onPlaylistItemClick: async function(track) {
|
||||
if (this.selectionMode.playlist) {
|
||||
if (track.pos in this.selectedPlaylistItems) {
|
||||
Vue.delete(this.selectedPlaylistItems, track.pos);
|
||||
} else {
|
||||
Vue.set(this.selectedPlaylistItems, track.pos, track);
|
||||
}
|
||||
} else if (this.moveMode.playlist) {
|
||||
var fromPos = Object.values(this.selectedPlaylistItems).map(_ => _.pos);
|
||||
var toPos = track.pos;
|
||||
this.moveMode.playlist = false;
|
||||
|
||||
const promises = fromPos.map((pos,i) => this.move(pos, toPos+i, false));
|
||||
await Promise.all(promises);
|
||||
this.selectedPlaylistItems = {};
|
||||
|
||||
const playlist = await request('music.mpd.playlistinfo');
|
||||
this._parsePlaylist(playlist);
|
||||
} else if (track.pos in this.selectedPlaylistItems) {
|
||||
Vue.delete(this.selectedPlaylistItems, track.pos);
|
||||
} else {
|
||||
|
|
|
@ -15,6 +15,11 @@ Vue.component('music-mpd-playlist-item', {
|
|||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
|
||||
move: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@
|
|||
:track="item"
|
||||
:active="track.file && status.state !== 'stop' && item.file === track.file"
|
||||
:selected="item.pos in selectedPlaylistItems"
|
||||
:move="moveMode.playlist"
|
||||
:ref="track.file && status.state !== 'stop' && item.file === track.file ? 'activePlaylistTrack' : undefined"
|
||||
@input="onPlaylistItemClick">
|
||||
</music-mpd-playlist-item>
|
||||
|
@ -167,7 +168,7 @@
|
|||
<div class="col-3 pull-right">
|
||||
<div class="row">
|
||||
<button @click="single" :class="{enabled: status.single}" title="Toggle single mode">
|
||||
<i class="fa fa-chess-pawn"></i>
|
||||
<i class="fa fa-bullseye"></i>
|
||||
</button>
|
||||
<button @click="consume" :class="{enabled: status.consume}" title="Toggle consume mode">
|
||||
<i class="fa fa-utensils"></i>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<script type="text/x-template" id="tmpl-music-mpd-playlist-item">
|
||||
<div class="row item playlist-item"
|
||||
:class="{selected: selected, active: active}"
|
||||
:class="{selected: selected, active: active, move: move}"
|
||||
@click="$emit('input', track)">
|
||||
<div class="col-5 artist" v-text="track.artist"></div>
|
||||
<div class="col-5 title" v-text="track.title"></div>
|
||||
|
|
|
@ -379,16 +379,21 @@ class MusicMpdPlugin(MusicPlugin):
|
|||
return resource
|
||||
|
||||
@action
|
||||
def load(self, playlist):
|
||||
def load(self, playlist, play=True):
|
||||
"""
|
||||
Load and play a playlist by name
|
||||
|
||||
:param playlist: Playlist name
|
||||
:type playlist: str
|
||||
|
||||
:param play: Start playback after loading the playlist (default: True)
|
||||
:type play: bool
|
||||
"""
|
||||
|
||||
self._exec('load', playlist)
|
||||
return self.play()
|
||||
ret = self._exec('load', playlist)
|
||||
if play:
|
||||
self.play()
|
||||
return ret
|
||||
|
||||
@action
|
||||
def clear(self):
|
||||
|
|
Loading…
Reference in a new issue