Merge pull request #915 from chme/web_pl_folders

Show playlist folders in player web interface
This commit is contained in:
ejurgensen 2020-03-08 22:58:23 +01:00 committed by GitHub
commit 9452d3d8d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 61 additions and 17 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -531,7 +531,7 @@ fetch_playlists(struct query_params *query_params, json_object *items, int *tota
}
static json_object *
fetch_playlist(const char *playlist_id)
fetch_playlist(uint32_t playlist_id)
{
struct query_params query_params;
json_object *playlist;
@ -543,7 +543,7 @@ fetch_playlist(const char *playlist_id)
query_params.type = Q_PL;
query_params.sort = S_PLAYLIST;
query_params.filter = db_mprintf("(f.id = %s)", playlist_id);
query_params.filter = db_mprintf("(f.id = %d)", playlist_id);
ret = db_query_start(&query_params);
if (ret < 0)
@ -3185,16 +3185,34 @@ jsonapi_reply_library_playlists(struct httpd_request *hreq)
static int
jsonapi_reply_library_playlist(struct httpd_request *hreq)
{
const char *playlist_id;
json_object *reply;
uint32_t playlist_id;
json_object *reply = NULL;
int ret = 0;
if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE))
return HTTP_NOTMODIFIED;
playlist_id = hreq->uri_parsed->path_parts[3];
ret = safe_atou32(hreq->uri_parsed->path_parts[3], &playlist_id);
if (ret < 0)
{
DPRINTF(E_LOG, L_WEB, "Could not parse playlist id to integer\n");
goto error;
}
if (playlist_id == 0)
{
reply = json_object_new_object();
json_object_object_add(reply, "id", json_object_new_int(0));
json_object_object_add(reply, "name", json_object_new_string("Playlists"));
json_object_object_add(reply, "type", json_object_new_string(db_pl_type_label(PL_FOLDER)));
json_object_object_add(reply, "smart_playlist", json_object_new_boolean(false));
json_object_object_add(reply, "folder", json_object_new_boolean(true));
}
else
{
reply = fetch_playlist(playlist_id);
}
reply = fetch_playlist(playlist_id);
if (!reply)
{
ret = -1;

View File

@ -14,9 +14,13 @@
<span class="heading">Path</span>
<span class="title is-6">{{ playlist.path }}</span>
</p>
<p>
<span class="heading">Type</span>
<span class="title is-6">{{ playlist.type }}</span>
</p>
</div>
</div>
<footer class="card-footer">
<footer class="card-footer" v-if="!playlist.folder">
<a class="card-footer-item has-text-dark" @click="queue_add">
<span class="icon"><i class="mdi mdi-playlist-plus"></i></span> <span class="is-size-7">Add</span>
</a>
@ -60,7 +64,7 @@ export default {
open_playlist: function () {
this.$emit('close')
this.$router.push({ path: '/playlists/' + this.playlist.id })
this.$router.push({ path: '/playlists/' + this.playlist.id + '/tracks' })
}
}
}

View File

@ -166,7 +166,7 @@ export default {
},
open_playlist: function (playlist) {
this.$router.push({ path: '/playlists/' + playlist.id })
this.$router.push({ path: '/playlists/' + playlist.id + '/tracks' })
},
open_playlist_dialog: function (playlist) {

View File

@ -1,11 +1,16 @@
<template>
<content-with-heading>
<template slot="heading-left">
<p class="title is-4">Playlists</p>
<p class="title is-4">{{ playlist.name }}</p>
<p class="heading">{{ playlists.total }} playlists</p>
</template>
<template slot="content">
<list-item-playlist v-for="playlist in playlists.items" :key="playlist.id" :playlist="playlist" @click="open_playlist(playlist)">
<template slot="icon">
<span class="icon">
<i class="mdi" :class="{ 'mdi-library-music': playlist.type !== 'folder', 'mdi-folder': playlist.type === 'folder' }"></i>
</span>
</template>
<template slot="actions">
<a @click="open_dialog(playlist)">
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
@ -27,11 +32,15 @@ import webapi from '@/webapi'
const playlistsData = {
load: function (to) {
return webapi.library_playlists()
return Promise.all([
webapi.library_playlist(to.params.playlist_id),
webapi.library_playlist_folder(to.params.playlist_id)
])
},
set: function (vm, response) {
vm.playlists = response.data
vm.playlist = response[0].data
vm.playlists = response[1].data
}
}
@ -42,6 +51,7 @@ export default {
data () {
return {
playlist: {},
playlists: {},
show_details_modal: false,
@ -51,7 +61,11 @@ export default {
methods: {
open_playlist: function (playlist) {
this.$router.push({ path: '/playlists/' + playlist.id })
if (playlist.type !== 'folder') {
this.$router.push({ path: '/playlists/' + playlist.id + '/tracks' })
} else {
this.$router.push({ path: '/playlists/' + playlist.id })
}
},
open_dialog: function (playlist) {

View File

@ -295,7 +295,7 @@ export default {
},
open_playlist: function (playlist) {
this.$router.push({ path: '/playlists/' + playlist.id })
this.$router.push({ path: '/playlists/' + playlist.id + '/tracks' })
},
open_recent_search: function (query) {

View File

@ -156,12 +156,16 @@ export const router = new VueRouter({
},
{
path: '/playlists',
redirect: '/playlists/0'
},
{
path: '/playlists/:playlist_id',
name: 'Playlists',
component: PagePlaylists,
meta: { show_progress: true }
},
{
path: '/playlists/:playlist_id',
path: '/playlists/:playlist_id/tracks',
name: 'Playlist',
component: PagePlaylist,
meta: { show_progress: true }

View File

@ -287,6 +287,10 @@ export default {
return axios.get('/api/library/playlists')
},
library_playlist_folder (playlistId = 0) {
return axios.get('/api/library/playlists/' + playlistId + '/playlists')
},
library_playlist (playlistId) {
return axios.get('/api/library/playlists/' + playlistId)
},