mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-26 23:25:56 -05:00
Merge pull request #915 from chme/web_pl_folders
Show playlist folders in player web interface
This commit is contained in:
commit
9452d3d8d0
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -531,7 +531,7 @@ fetch_playlists(struct query_params *query_params, json_object *items, int *tota
|
|||||||
}
|
}
|
||||||
|
|
||||||
static json_object *
|
static json_object *
|
||||||
fetch_playlist(const char *playlist_id)
|
fetch_playlist(uint32_t playlist_id)
|
||||||
{
|
{
|
||||||
struct query_params query_params;
|
struct query_params query_params;
|
||||||
json_object *playlist;
|
json_object *playlist;
|
||||||
@ -543,7 +543,7 @@ fetch_playlist(const char *playlist_id)
|
|||||||
|
|
||||||
query_params.type = Q_PL;
|
query_params.type = Q_PL;
|
||||||
query_params.sort = S_PLAYLIST;
|
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);
|
ret = db_query_start(&query_params);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -3185,16 +3185,34 @@ jsonapi_reply_library_playlists(struct httpd_request *hreq)
|
|||||||
static int
|
static int
|
||||||
jsonapi_reply_library_playlist(struct httpd_request *hreq)
|
jsonapi_reply_library_playlist(struct httpd_request *hreq)
|
||||||
{
|
{
|
||||||
const char *playlist_id;
|
uint32_t playlist_id;
|
||||||
json_object *reply;
|
json_object *reply = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE))
|
if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE))
|
||||||
return HTTP_NOTMODIFIED;
|
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)
|
if (!reply)
|
||||||
{
|
{
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -14,9 +14,13 @@
|
|||||||
<span class="heading">Path</span>
|
<span class="heading">Path</span>
|
||||||
<span class="title is-6">{{ playlist.path }}</span>
|
<span class="title is-6">{{ playlist.path }}</span>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Type</span>
|
||||||
|
<span class="title is-6">{{ playlist.type }}</span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<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>
|
<span class="icon"><i class="mdi mdi-playlist-plus"></i></span> <span class="is-size-7">Add</span>
|
||||||
</a>
|
</a>
|
||||||
@ -60,7 +64,7 @@ export default {
|
|||||||
|
|
||||||
open_playlist: function () {
|
open_playlist: function () {
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
this.$router.push({ path: '/playlists/' + this.playlist.id })
|
this.$router.push({ path: '/playlists/' + this.playlist.id + '/tracks' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
open_playlist: function (playlist) {
|
open_playlist: function (playlist) {
|
||||||
this.$router.push({ path: '/playlists/' + playlist.id })
|
this.$router.push({ path: '/playlists/' + playlist.id + '/tracks' })
|
||||||
},
|
},
|
||||||
|
|
||||||
open_playlist_dialog: function (playlist) {
|
open_playlist_dialog: function (playlist) {
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<content-with-heading>
|
<content-with-heading>
|
||||||
<template slot="heading-left">
|
<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>
|
<p class="heading">{{ playlists.total }} playlists</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-playlist v-for="playlist in playlists.items" :key="playlist.id" :playlist="playlist" @click="open_playlist(playlist)">
|
<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">
|
<template slot="actions">
|
||||||
<a @click="open_dialog(playlist)">
|
<a @click="open_dialog(playlist)">
|
||||||
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
<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 = {
|
const playlistsData = {
|
||||||
load: function (to) {
|
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) {
|
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 () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
playlist: {},
|
||||||
playlists: {},
|
playlists: {},
|
||||||
|
|
||||||
show_details_modal: false,
|
show_details_modal: false,
|
||||||
@ -51,7 +61,11 @@ export default {
|
|||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
open_playlist: function (playlist) {
|
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) {
|
open_dialog: function (playlist) {
|
||||||
|
@ -295,7 +295,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
open_playlist: function (playlist) {
|
open_playlist: function (playlist) {
|
||||||
this.$router.push({ path: '/playlists/' + playlist.id })
|
this.$router.push({ path: '/playlists/' + playlist.id + '/tracks' })
|
||||||
},
|
},
|
||||||
|
|
||||||
open_recent_search: function (query) {
|
open_recent_search: function (query) {
|
||||||
|
@ -156,12 +156,16 @@ export const router = new VueRouter({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/playlists',
|
path: '/playlists',
|
||||||
|
redirect: '/playlists/0'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/playlists/:playlist_id',
|
||||||
name: 'Playlists',
|
name: 'Playlists',
|
||||||
component: PagePlaylists,
|
component: PagePlaylists,
|
||||||
meta: { show_progress: true }
|
meta: { show_progress: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/playlists/:playlist_id',
|
path: '/playlists/:playlist_id/tracks',
|
||||||
name: 'Playlist',
|
name: 'Playlist',
|
||||||
component: PagePlaylist,
|
component: PagePlaylist,
|
||||||
meta: { show_progress: true }
|
meta: { show_progress: true }
|
||||||
|
@ -287,6 +287,10 @@ export default {
|
|||||||
return axios.get('/api/library/playlists')
|
return axios.get('/api/library/playlists')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
library_playlist_folder (playlistId = 0) {
|
||||||
|
return axios.get('/api/library/playlists/' + playlistId + '/playlists')
|
||||||
|
},
|
||||||
|
|
||||||
library_playlist (playlistId) {
|
library_playlist (playlistId) {
|
||||||
return axios.get('/api/library/playlists/' + playlistId)
|
return axios.get('/api/library/playlists/' + playlistId)
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user