mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-01-15 02:18:27 +01:00
Update:Add libraries playlists API endpoint, add lazy playlists card
This commit is contained in:
parent
0979b3e03d
commit
7e171576e0
@ -165,6 +165,9 @@ export default {
|
|||||||
isCollectionsPage() {
|
isCollectionsPage() {
|
||||||
return this.page === 'collections'
|
return this.page === 'collections'
|
||||||
},
|
},
|
||||||
|
isPlaylistsPage() {
|
||||||
|
return this.page === 'playlists'
|
||||||
|
},
|
||||||
isHomePage() {
|
isHomePage() {
|
||||||
return this.$route.name === 'library-library'
|
return this.$route.name === 'library-library'
|
||||||
},
|
},
|
||||||
@ -185,6 +188,7 @@ export default {
|
|||||||
if (!this.page) return this.$strings.LabelBooks
|
if (!this.page) return this.$strings.LabelBooks
|
||||||
if (this.isSeriesPage) return this.$strings.LabelSeries
|
if (this.isSeriesPage) return this.$strings.LabelSeries
|
||||||
if (this.isCollectionsPage) return this.$strings.LabelCollections
|
if (this.isCollectionsPage) return this.$strings.LabelCollections
|
||||||
|
if (this.isPlaylistsPage) return this.$strings.LabelPlaylists
|
||||||
return ''
|
return ''
|
||||||
},
|
},
|
||||||
seriesId() {
|
seriesId() {
|
||||||
|
@ -87,11 +87,11 @@ export default {
|
|||||||
emptyMessage() {
|
emptyMessage() {
|
||||||
if (this.page === 'series') return this.$strings.MessageBookshelfNoSeries
|
if (this.page === 'series') return this.$strings.MessageBookshelfNoSeries
|
||||||
if (this.page === 'collections') return this.$strings.MessageBookshelfNoCollections
|
if (this.page === 'collections') return this.$strings.MessageBookshelfNoCollections
|
||||||
|
if (this.page === 'playlists') return this.$strings.MessageNoUserPlaylists
|
||||||
if (this.hasFilter) {
|
if (this.hasFilter) {
|
||||||
if (this.filterName === 'Issues') return this.$strings.MessageNoIssues
|
if (this.filterName === 'Issues') return this.$strings.MessageNoIssues
|
||||||
else if (this.filterName === 'Feed-open') return this.$strings.MessageBookshelfNoRSSFeeds
|
else if (this.filterName === 'Feed-open') return this.$strings.MessageBookshelfNoRSSFeeds
|
||||||
return this.$getString('MessageBookshelfNoResultsForFilter', [this.filterName, this.filterValue])
|
return this.$getString('MessageBookshelfNoResultsForFilter', [this.filterName, this.filterValue])
|
||||||
// return `No Results for filter "${this.filterName}: ${this.filterValue}"`
|
|
||||||
}
|
}
|
||||||
return this.$strings.MessageNoResults
|
return this.$strings.MessageNoResults
|
||||||
},
|
},
|
||||||
@ -178,7 +178,7 @@ export default {
|
|||||||
return this.shelfPadding * 2
|
return this.shelfPadding * 2
|
||||||
},
|
},
|
||||||
entityWidth() {
|
entityWidth() {
|
||||||
if (this.entityName === 'series' || this.entityName === 'collections') {
|
if (this.entityName === 'series' || this.entityName === 'collections' || this.entityName === 'playlists') {
|
||||||
if (this.bookWidth * 2 > this.bookshelfWidth - this.shelfPadding) return this.bookWidth * 1.6
|
if (this.bookWidth * 2 > this.bookshelfWidth - this.shelfPadding) return this.bookWidth * 1.6
|
||||||
return this.bookWidth * 2
|
return this.bookWidth * 2
|
||||||
}
|
}
|
||||||
@ -302,11 +302,11 @@ export default {
|
|||||||
this.currentSFQueryString = this.buildSearchParams()
|
this.currentSFQueryString = this.buildSearchParams()
|
||||||
}
|
}
|
||||||
|
|
||||||
var entityPath = this.entityName === 'books' || this.entityName === 'series-books' ? `items` : this.entityName
|
const entityPath = this.entityName === 'books' || this.entityName === 'series-books' ? 'items' : this.entityName
|
||||||
var sfQueryString = this.currentSFQueryString ? this.currentSFQueryString + '&' : ''
|
const sfQueryString = this.currentSFQueryString ? this.currentSFQueryString + '&' : ''
|
||||||
var fullQueryString = `?${sfQueryString}limit=${this.booksPerFetch}&page=${page}&minified=1`
|
const fullQueryString = `?${sfQueryString}limit=${this.booksPerFetch}&page=${page}&minified=1`
|
||||||
|
|
||||||
var payload = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/${entityPath}${fullQueryString}`).catch((error) => {
|
const payload = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/${entityPath}${fullQueryString}`).catch((error) => {
|
||||||
console.error('failed to fetch books', error)
|
console.error('failed to fetch books', error)
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
@ -71,6 +71,14 @@
|
|||||||
<div v-show="isPodcastSearchPage" class="h-full w-0.5 bg-yellow-400 absolute top-0 left-0" />
|
<div v-show="isPodcastSearchPage" class="h-full w-0.5 bg-yellow-400 absolute top-0 left-0" />
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
|
|
||||||
|
<nuxt-link v-if="showPlaylists" :to="`/library/${currentLibraryId}/bookshelf/playlists`" class="w-full h-20 flex flex-col items-center justify-center text-white text-opacity-80 border-b border-primary border-opacity-70 hover:bg-primary cursor-pointer relative" :class="isPlaylistsPage ? 'bg-primary bg-opacity-80' : 'bg-bg bg-opacity-60'">
|
||||||
|
<span class="material-icons text-2.5xl">playlist_play</span>
|
||||||
|
|
||||||
|
<p class="font-book pt-0.5 text-center leading-4" style="font-size: 0.9rem">{{ $strings.ButtonPlaylists }}</p>
|
||||||
|
|
||||||
|
<div v-show="isPlaylistsPage" class="h-full w-0.5 bg-yellow-400 absolute top-0 left-0" />
|
||||||
|
</nuxt-link>
|
||||||
|
|
||||||
<nuxt-link v-if="numIssues" :to="`/library/${currentLibraryId}/bookshelf?filter=issues`" class="w-full h-20 flex flex-col items-center justify-center text-white text-opacity-80 border-b border-primary border-opacity-70 hover:bg-opacity-40 cursor-pointer relative" :class="showingIssues ? 'bg-error bg-opacity-40' : ' bg-error bg-opacity-20'">
|
<nuxt-link v-if="numIssues" :to="`/library/${currentLibraryId}/bookshelf?filter=issues`" class="w-full h-20 flex flex-col items-center justify-center text-white text-opacity-80 border-b border-primary border-opacity-70 hover:bg-opacity-40 cursor-pointer relative" :class="showingIssues ? 'bg-error bg-opacity-40' : ' bg-error bg-opacity-20'">
|
||||||
<span class="material-icons text-2xl">warning</span>
|
<span class="material-icons text-2xl">warning</span>
|
||||||
|
|
||||||
@ -143,6 +151,9 @@ export default {
|
|||||||
isAuthorsPage() {
|
isAuthorsPage() {
|
||||||
return this.$route.name === 'library-library-authors'
|
return this.$route.name === 'library-library-authors'
|
||||||
},
|
},
|
||||||
|
isPlaylistsPage() {
|
||||||
|
return this.paramId === 'playlists'
|
||||||
|
},
|
||||||
libraryBookshelfPage() {
|
libraryBookshelfPage() {
|
||||||
return this.$route.name === 'library-library-bookshelf-id'
|
return this.$route.name === 'library-library-bookshelf-id'
|
||||||
},
|
},
|
||||||
@ -173,6 +184,9 @@ export default {
|
|||||||
},
|
},
|
||||||
streamLibraryItem() {
|
streamLibraryItem() {
|
||||||
return this.$store.state.streamLibraryItem
|
return this.$store.state.streamLibraryItem
|
||||||
|
},
|
||||||
|
showPlaylists() {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
115
client/components/cards/LazyPlaylistCard.vue
Normal file
115
client/components/cards/LazyPlaylistCard.vue
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
<template>
|
||||||
|
<div ref="card" :id="`playlist-card-${index}`" :style="{ width: width + 'px', height: height + 'px' }" class="absolute top-0 left-0 rounded-sm z-30 cursor-pointer" @mousedown.prevent @mouseup.prevent @mousemove.prevent @mouseover="mouseover" @mouseleave="mouseleave" @click="clickCard">
|
||||||
|
<div class="absolute top-0 left-0 w-full box-shadow-book shadow-height" />
|
||||||
|
<div class="w-full h-full bg-primary relative rounded overflow-hidden">
|
||||||
|
<covers-playlist-cover ref="cover" :items="items" :width="width" :height="height" :book-cover-aspect-ratio="bookCoverAspectRatio" />
|
||||||
|
</div>
|
||||||
|
<div v-show="isHovering && userCanUpdate" class="w-full h-full absolute top-0 left-0 z-10 bg-black bg-opacity-40 pointer-events-none">
|
||||||
|
<div class="absolute pointer-events-auto" :style="{ top: 0.5 * sizeMultiplier + 'rem', right: 0.5 * sizeMultiplier + 'rem' }" @click.stop.prevent="clickEdit">
|
||||||
|
<span class="material-icons text-xl text-white text-opacity-75 hover:text-opacity-100">edit</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="!isAlternativeBookshelfView" class="categoryPlacard absolute z-30 left-0 right-0 mx-auto -bottom-6 h-6 rounded-md font-book text-center" :style="{ width: Math.min(160, width) + 'px' }">
|
||||||
|
<div class="w-full h-full shinyBlack flex items-center justify-center rounded-sm border" :style="{ padding: `0rem ${0.5 * sizeMultiplier}rem` }">
|
||||||
|
<p class="truncate" :style="{ fontSize: labelFontSize + 'rem' }">{{ title }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="absolute z-30 left-0 right-0 mx-auto -bottom-8 h-8 py-1 rounded-md text-center">
|
||||||
|
<p class="truncate" :style="{ fontSize: labelFontSize + 'rem' }">{{ title }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
index: Number,
|
||||||
|
width: Number,
|
||||||
|
height: Number,
|
||||||
|
bookCoverAspectRatio: Number,
|
||||||
|
bookshelfView: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
playlistMount: {
|
||||||
|
type: Object,
|
||||||
|
default: () => null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
playlist: null,
|
||||||
|
isSelectionMode: false,
|
||||||
|
selected: false,
|
||||||
|
isHovering: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
labelFontSize() {
|
||||||
|
if (this.width < 160) return 0.75
|
||||||
|
return 0.875
|
||||||
|
},
|
||||||
|
sizeMultiplier() {
|
||||||
|
if (this.bookCoverAspectRatio === 1) return this.width / (120 * 1.6 * 2)
|
||||||
|
return this.width / 240
|
||||||
|
},
|
||||||
|
title() {
|
||||||
|
return this.playlist ? this.playlist.name : ''
|
||||||
|
},
|
||||||
|
items() {
|
||||||
|
return this.playlist ? this.playlist.items || [] : []
|
||||||
|
},
|
||||||
|
store() {
|
||||||
|
return this.$store || this.$nuxt.$store
|
||||||
|
},
|
||||||
|
currentLibraryId() {
|
||||||
|
return this.store.state.libraries.currentLibraryId
|
||||||
|
},
|
||||||
|
isAlternativeBookshelfView() {
|
||||||
|
const constants = this.$constants || this.$nuxt.$constants
|
||||||
|
return this.bookshelfView == constants.BookshelfView.DETAIL
|
||||||
|
},
|
||||||
|
userCanUpdate() {
|
||||||
|
return this.store.getters['user/getUserCanUpdate']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setEntity(playlist) {
|
||||||
|
this.playlist = playlist
|
||||||
|
},
|
||||||
|
setSelectionMode(val) {
|
||||||
|
this.isSelectionMode = val
|
||||||
|
},
|
||||||
|
mouseover() {
|
||||||
|
this.isHovering = true
|
||||||
|
},
|
||||||
|
mouseleave() {
|
||||||
|
this.isHovering = false
|
||||||
|
},
|
||||||
|
clickCard() {
|
||||||
|
if (!this.playlist) return
|
||||||
|
var router = this.$router || this.$nuxt.$router
|
||||||
|
router.push(`/playlist/${this.playlist.id}`)
|
||||||
|
},
|
||||||
|
clickEdit() {
|
||||||
|
this.$emit('edit', this.playlist)
|
||||||
|
},
|
||||||
|
destroy() {
|
||||||
|
// destroy the vue listeners, etc
|
||||||
|
this.$destroy()
|
||||||
|
|
||||||
|
// remove the element from the DOM
|
||||||
|
if (this.$el && this.$el.parentNode) {
|
||||||
|
this.$el.parentNode.removeChild(this.$el)
|
||||||
|
} else if (this.$el && this.$el.remove) {
|
||||||
|
this.$el.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.playlistMount) {
|
||||||
|
this.setEntity(this.playlistMount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -75,7 +75,7 @@ export default {
|
|||||||
return selectedPlaylistItem.libraryItem.media.metadata.title || ''
|
return selectedPlaylistItem.libraryItem.media.metadata.title || ''
|
||||||
},
|
},
|
||||||
playlists() {
|
playlists() {
|
||||||
return this.$store.state.user.playlists || []
|
return this.$store.state.libraries.userPlaylists || []
|
||||||
},
|
},
|
||||||
bookCoverAspectRatio() {
|
bookCoverAspectRatio() {
|
||||||
return this.$store.getters['libraries/getBookCoverAspectRatio']
|
return this.$store.getters['libraries/getBookCoverAspectRatio']
|
||||||
@ -113,9 +113,9 @@ export default {
|
|||||||
if (!this.playlists.length) {
|
if (!this.playlists.length) {
|
||||||
this.processing = true
|
this.processing = true
|
||||||
this.$axios
|
this.$axios
|
||||||
.$get(`/api/playlists`)
|
.$get(`/api/libraries/${this.currentLibraryId}/playlists`)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.$store.commit('user/setPlaylists', data.playlists || [])
|
this.$store.commit('libraries/setUserPlaylists', data.results || [])
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to get playlists', error)
|
console.error('Failed to get playlists', error)
|
||||||
|
@ -54,9 +54,12 @@ export default {
|
|||||||
isCasting() {
|
isCasting() {
|
||||||
return this.$store.state.globals.isCasting
|
return this.$store.state.globals.isCasting
|
||||||
},
|
},
|
||||||
|
currentLibraryId() {
|
||||||
|
return this.$store.state.libraries.currentLibraryId
|
||||||
|
},
|
||||||
isShowingSideRail() {
|
isShowingSideRail() {
|
||||||
if (!this.$route.name) return false
|
if (!this.$route.name) return false
|
||||||
return !this.$route.name.startsWith('config') && this.$store.state.libraries.currentLibraryId
|
return !this.$route.name.startsWith('config') && this.currentLibraryId
|
||||||
},
|
},
|
||||||
isShowingToolbar() {
|
isShowingToolbar() {
|
||||||
return this.isShowingSideRail && this.$route.name !== 'upload' && this.$route.name !== 'account'
|
return this.isShowingSideRail && this.$route.name !== 'upload' && this.$route.name !== 'account'
|
||||||
@ -169,7 +172,7 @@ export default {
|
|||||||
this.$store.commit('libraries/remove', library)
|
this.$store.commit('libraries/remove', library)
|
||||||
|
|
||||||
// When removed currently selected library then set next accessible library
|
// When removed currently selected library then set next accessible library
|
||||||
const currLibraryId = this.$store.state.libraries.currentLibraryId
|
const currLibraryId = this.currentLibraryId
|
||||||
if (currLibraryId === library.id) {
|
if (currLibraryId === library.id) {
|
||||||
var nextLibrary = this.$store.getters['libraries/getNextAccessibleLibrary']
|
var nextLibrary = this.$store.getters['libraries/getNextAccessibleLibrary']
|
||||||
if (nextLibrary) {
|
if (nextLibrary) {
|
||||||
@ -208,7 +211,7 @@ export default {
|
|||||||
libraryItemRemoved(item) {
|
libraryItemRemoved(item) {
|
||||||
if (this.$route.name.startsWith('item')) {
|
if (this.$route.name.startsWith('item')) {
|
||||||
if (this.$route.params.id === item.id) {
|
if (this.$route.params.id === item.id) {
|
||||||
this.$router.replace(`/library/${this.$store.state.libraries.currentLibraryId}`)
|
this.$router.replace(`/library/${this.currentLibraryId}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -293,35 +296,39 @@ export default {
|
|||||||
this.$store.commit('user/updateMediaProgress', payload)
|
this.$store.commit('user/updateMediaProgress', payload)
|
||||||
},
|
},
|
||||||
collectionAdded(collection) {
|
collectionAdded(collection) {
|
||||||
|
if (this.currentLibraryId !== collection.libraryId) return
|
||||||
this.$store.commit('libraries/addUpdateCollection', collection)
|
this.$store.commit('libraries/addUpdateCollection', collection)
|
||||||
},
|
},
|
||||||
collectionUpdated(collection) {
|
collectionUpdated(collection) {
|
||||||
|
if (this.currentLibraryId !== collection.libraryId) return
|
||||||
this.$store.commit('libraries/addUpdateCollection', collection)
|
this.$store.commit('libraries/addUpdateCollection', collection)
|
||||||
},
|
},
|
||||||
collectionRemoved(collection) {
|
collectionRemoved(collection) {
|
||||||
|
if (this.currentLibraryId !== collection.libraryId) return
|
||||||
if (this.$route.name.startsWith('collection')) {
|
if (this.$route.name.startsWith('collection')) {
|
||||||
if (this.$route.params.id === collection.id) {
|
if (this.$route.params.id === collection.id) {
|
||||||
this.$router.replace(`/library/${this.$store.state.libraries.currentLibraryId}/bookshelf/collections`)
|
this.$router.replace(`/library/${this.currentLibraryId}/bookshelf/collections`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.$store.commit('libraries/removeCollection', collection)
|
this.$store.commit('libraries/removeCollection', collection)
|
||||||
},
|
},
|
||||||
playlistAdded(playlist) {
|
playlistAdded(playlist) {
|
||||||
if (playlist.userId !== this.user.id) return
|
if (playlist.userId !== this.user.id || this.currentLibraryId !== playlist.libraryId) return
|
||||||
this.$store.commit('user/addUpdatePlaylist', playlist)
|
this.$store.commit('libraries/addUpdateUserPlaylist', playlist)
|
||||||
},
|
},
|
||||||
playlistUpdated(playlist) {
|
playlistUpdated(playlist) {
|
||||||
if (playlist.userId !== this.user.id) return
|
if (playlist.userId !== this.user.id || this.currentLibraryId !== playlist.libraryId) return
|
||||||
this.$store.commit('user/addUpdatePlaylist', playlist)
|
this.$store.commit('libraries/addUpdateUserPlaylist', playlist)
|
||||||
},
|
},
|
||||||
playlistRemoved(playlist) {
|
playlistRemoved(playlist) {
|
||||||
if (playlist.userId !== this.user.id) return
|
if (playlist.userId !== this.user.id || this.currentLibraryId !== playlist.libraryId) return
|
||||||
|
|
||||||
if (this.$route.name.startsWith('playlist')) {
|
if (this.$route.name.startsWith('playlist')) {
|
||||||
if (this.$route.params.id === playlist.id) {
|
if (this.$route.params.id === playlist.id) {
|
||||||
this.$router.replace(`/library/${this.$store.state.libraries.currentLibraryId}/bookshelf/playlists`)
|
this.$router.replace(`/library/${this.currentLibraryId}/bookshelf/playlists`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.$store.commit('user/removePlaylist', playlist)
|
this.$store.commit('libraries/removeUserPlaylist', playlist)
|
||||||
},
|
},
|
||||||
rssFeedOpen(data) {
|
rssFeedOpen(data) {
|
||||||
this.$store.commit('feeds/addFeed', data)
|
this.$store.commit('feeds/addFeed', data)
|
||||||
|
@ -2,6 +2,7 @@ import Vue from 'vue'
|
|||||||
import LazyBookCard from '@/components/cards/LazyBookCard'
|
import LazyBookCard from '@/components/cards/LazyBookCard'
|
||||||
import LazySeriesCard from '@/components/cards/LazySeriesCard'
|
import LazySeriesCard from '@/components/cards/LazySeriesCard'
|
||||||
import LazyCollectionCard from '@/components/cards/LazyCollectionCard'
|
import LazyCollectionCard from '@/components/cards/LazyCollectionCard'
|
||||||
|
import LazyPlaylistCard from '@/components/cards/LazyPlaylistCard'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@ -15,6 +16,7 @@ export default {
|
|||||||
getComponentClass() {
|
getComponentClass() {
|
||||||
if (this.entityName === 'series') return Vue.extend(LazySeriesCard)
|
if (this.entityName === 'series') return Vue.extend(LazySeriesCard)
|
||||||
if (this.entityName === 'collections') return Vue.extend(LazyCollectionCard)
|
if (this.entityName === 'collections') return Vue.extend(LazyCollectionCard)
|
||||||
|
if (this.entityName === 'playlists') return Vue.extend(LazyPlaylistCard)
|
||||||
return Vue.extend(LazyBookCard)
|
return Vue.extend(LazyBookCard)
|
||||||
},
|
},
|
||||||
async mountEntityCard(index) {
|
async mountEntityCard(index) {
|
||||||
|
@ -16,7 +16,6 @@ export default {
|
|||||||
|
|
||||||
// Set series sort by
|
// Set series sort by
|
||||||
if (params.id === 'series') {
|
if (params.id === 'series') {
|
||||||
console.log('Series page', query)
|
|
||||||
if (query.sort) {
|
if (query.sort) {
|
||||||
store.commit('libraries/setSeriesSortBy', query.sort)
|
store.commit('libraries/setSeriesSortBy', query.sort)
|
||||||
store.commit('libraries/setSeriesSortDesc', !!query.desc)
|
store.commit('libraries/setSeriesSortDesc', !!query.desc)
|
||||||
|
@ -12,7 +12,8 @@ export const state = () => ({
|
|||||||
seriesSortBy: 'name',
|
seriesSortBy: 'name',
|
||||||
seriesSortDesc: false,
|
seriesSortDesc: false,
|
||||||
seriesFilterBy: 'all',
|
seriesFilterBy: 'all',
|
||||||
collections: []
|
collections: [],
|
||||||
|
userPlaylists: []
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getters = {
|
export const getters = {
|
||||||
@ -102,6 +103,8 @@ export const actions = {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const libraryChanging = state.currentLibraryId !== libraryId
|
||||||
|
|
||||||
return this.$axios
|
return this.$axios
|
||||||
.$get(`/api/libraries/${libraryId}?include=filterdata`)
|
.$get(`/api/libraries/${libraryId}?include=filterdata`)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
@ -115,7 +118,10 @@ export const actions = {
|
|||||||
commit('setLibraryIssues', issues)
|
commit('setLibraryIssues', issues)
|
||||||
commit('setLibraryFilterData', filterData)
|
commit('setLibraryFilterData', filterData)
|
||||||
commit('setCurrentLibrary', libraryId)
|
commit('setCurrentLibrary', libraryId)
|
||||||
commit('setCollections', [])
|
if (libraryChanging) {
|
||||||
|
commit('setCollections', [])
|
||||||
|
commit('setUserPlaylists', [])
|
||||||
|
}
|
||||||
return data
|
return data
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@ -320,5 +326,19 @@ export const mutations = {
|
|||||||
},
|
},
|
||||||
removeCollection(state, collection) {
|
removeCollection(state, collection) {
|
||||||
state.collections = state.collections.filter(c => c.id !== collection.id)
|
state.collections = state.collections.filter(c => c.id !== collection.id)
|
||||||
|
},
|
||||||
|
setUserPlaylists(state, playlists) {
|
||||||
|
state.userPlaylists = playlists
|
||||||
|
},
|
||||||
|
addUpdateUserPlaylist(state, playlist) {
|
||||||
|
const index = state.userPlaylists.findIndex(p => p.id === playlist.id)
|
||||||
|
if (index >= 0) {
|
||||||
|
state.userPlaylists.splice(index, 1, playlist)
|
||||||
|
} else {
|
||||||
|
state.userPlaylists.push(playlist)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeUserPlaylist(state, playlist) {
|
||||||
|
state.userPlaylists = state.userPlaylists.filter(p => p.id !== playlist.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,8 +9,7 @@ export const state = () => ({
|
|||||||
collapseSeries: false,
|
collapseSeries: false,
|
||||||
collapseBookSeries: false
|
collapseBookSeries: false
|
||||||
},
|
},
|
||||||
settingsListeners: [],
|
settingsListeners: []
|
||||||
playlists: []
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getters = {
|
export const getters = {
|
||||||
@ -164,19 +163,5 @@ export const mutations = {
|
|||||||
},
|
},
|
||||||
removeSettingsListener(state, listenerId) {
|
removeSettingsListener(state, listenerId) {
|
||||||
state.settingsListeners = state.settingsListeners.filter(l => l.id !== listenerId)
|
state.settingsListeners = state.settingsListeners.filter(l => l.id !== listenerId)
|
||||||
},
|
|
||||||
setPlaylists(state, playlists) {
|
|
||||||
state.playlists = playlists
|
|
||||||
},
|
|
||||||
addUpdatePlaylist(state, playlist) {
|
|
||||||
const indexOf = state.playlists.findIndex(p => p.id == playlist.id)
|
|
||||||
if (indexOf >= 0) {
|
|
||||||
state.playlists.splice(indexOf, 1, playlist)
|
|
||||||
} else {
|
|
||||||
state.playlists.push(playlist)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removePlaylist(state, playlist) {
|
|
||||||
state.playlists = state.playlists.filter(p => p.id !== playlist.id)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -41,6 +41,7 @@
|
|||||||
"ButtonOpenManager": "Open Manager",
|
"ButtonOpenManager": "Open Manager",
|
||||||
"ButtonPlay": "Play",
|
"ButtonPlay": "Play",
|
||||||
"ButtonPlaying": "Playing",
|
"ButtonPlaying": "Playing",
|
||||||
|
"ButtonPlaylists": "Playlists",
|
||||||
"ButtonPurgeAllCache": "Purge All Cache",
|
"ButtonPurgeAllCache": "Purge All Cache",
|
||||||
"ButtonPurgeItemsCache": "Purge Items Cache",
|
"ButtonPurgeItemsCache": "Purge Items Cache",
|
||||||
"ButtonPurgeMediaProgress": "Purge Media Progress",
|
"ButtonPurgeMediaProgress": "Purge Media Progress",
|
||||||
|
@ -422,6 +422,26 @@ class LibraryController {
|
|||||||
res.json(payload)
|
res.json(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// api/libraries/:id/playlists
|
||||||
|
async getUserPlaylistsForLibrary(req, res) {
|
||||||
|
let playlistsForUser = this.db.playlists.filter(p => p.userId === req.user.id && p.libraryId === req.library.id).map(p => p.toJSONExpanded(this.db.libraryItems))
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
results: [],
|
||||||
|
total: playlistsForUser.length,
|
||||||
|
limit: req.query.limit && !isNaN(req.query.limit) ? Number(req.query.limit) : 0,
|
||||||
|
page: req.query.page && !isNaN(req.query.page) ? Number(req.query.page) : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.limit) {
|
||||||
|
const startIndex = payload.page * payload.limit
|
||||||
|
playlistsForUser = playlistsForUser.slice(startIndex, startIndex + payload.limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.results = playlistsForUser
|
||||||
|
res.json(payload)
|
||||||
|
}
|
||||||
|
|
||||||
async getLibraryFilterData(req, res) {
|
async getLibraryFilterData(req, res) {
|
||||||
res.json(libraryHelpers.getDistinctFilterDataNew(req.libraryItems))
|
res.json(libraryHelpers.getDistinctFilterDataNew(req.libraryItems))
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,7 @@ class ApiRouter {
|
|||||||
this.router.delete('/libraries/:id/issues', LibraryController.middleware.bind(this), LibraryController.removeLibraryItemsWithIssues.bind(this))
|
this.router.delete('/libraries/:id/issues', LibraryController.middleware.bind(this), LibraryController.removeLibraryItemsWithIssues.bind(this))
|
||||||
this.router.get('/libraries/:id/series', LibraryController.middleware.bind(this), LibraryController.getAllSeriesForLibrary.bind(this))
|
this.router.get('/libraries/:id/series', LibraryController.middleware.bind(this), LibraryController.getAllSeriesForLibrary.bind(this))
|
||||||
this.router.get('/libraries/:id/collections', LibraryController.middleware.bind(this), LibraryController.getCollectionsForLibrary.bind(this))
|
this.router.get('/libraries/:id/collections', LibraryController.middleware.bind(this), LibraryController.getCollectionsForLibrary.bind(this))
|
||||||
|
this.router.get('/libraries/:id/playlists', LibraryController.middleware.bind(this), LibraryController.getUserPlaylistsForLibrary.bind(this))
|
||||||
this.router.get('/libraries/:id/personalized', LibraryController.middleware.bind(this), LibraryController.getLibraryUserPersonalizedOptimal.bind(this))
|
this.router.get('/libraries/:id/personalized', LibraryController.middleware.bind(this), LibraryController.getLibraryUserPersonalizedOptimal.bind(this))
|
||||||
this.router.get('/libraries/:id/filterdata', LibraryController.middleware.bind(this), LibraryController.getLibraryFilterData.bind(this))
|
this.router.get('/libraries/:id/filterdata', LibraryController.middleware.bind(this), LibraryController.getLibraryFilterData.bind(this))
|
||||||
this.router.get('/libraries/:id/search', LibraryController.middleware.bind(this), LibraryController.search.bind(this))
|
this.router.get('/libraries/:id/search', LibraryController.middleware.bind(this), LibraryController.search.bind(this))
|
||||||
|
Loading…
Reference in New Issue
Block a user