Bookshelf updates for music tracks

This commit is contained in:
advplyr 2023-01-03 18:00:01 -06:00
parent 84d2d00a30
commit 7f5356100d
12 changed files with 139 additions and 49 deletions

View File

@ -58,13 +58,13 @@
<span class="material-icons text-2xl -ml-2 pr-1 text-white">play_arrow</span> <span class="material-icons text-2xl -ml-2 pr-1 text-white">play_arrow</span>
{{ $strings.ButtonPlay }} {{ $strings.ButtonPlay }}
</ui-btn> </ui-btn>
<ui-tooltip v-if="userIsAdminOrUp && !isPodcastLibrary" :text="$strings.ButtonQuickMatch" direction="bottom"> <ui-tooltip v-if="userIsAdminOrUp && isBookLibrary" :text="$strings.ButtonQuickMatch" direction="bottom">
<ui-icon-btn :disabled="processingBatch" icon="auto_awesome" @click="batchAutoMatchClick" class="mx-1.5" /> <ui-icon-btn :disabled="processingBatch" icon="auto_awesome" @click="batchAutoMatchClick" class="mx-1.5" />
</ui-tooltip> </ui-tooltip>
<ui-tooltip v-if="!isPodcastLibrary" :text="selectedIsFinished ? $strings.MessageMarkAsNotFinished : $strings.MessageMarkAsFinished" direction="bottom"> <ui-tooltip v-if="isBookLibrary" :text="selectedIsFinished ? $strings.MessageMarkAsNotFinished : $strings.MessageMarkAsFinished" direction="bottom">
<ui-read-icon-btn :disabled="processingBatch" :is-read="selectedIsFinished" @click="toggleBatchRead" class="mx-1.5" /> <ui-read-icon-btn :disabled="processingBatch" :is-read="selectedIsFinished" @click="toggleBatchRead" class="mx-1.5" />
</ui-tooltip> </ui-tooltip>
<ui-tooltip v-if="userCanUpdate && !isPodcastLibrary" :text="$strings.LabelAddToCollection" direction="bottom"> <ui-tooltip v-if="userCanUpdate && isBookLibrary" :text="$strings.LabelAddToCollection" direction="bottom">
<ui-icon-btn :disabled="processingBatch" icon="collections_bookmark" @click="batchAddToCollectionClick" class="mx-1.5" /> <ui-icon-btn :disabled="processingBatch" icon="collections_bookmark" @click="batchAddToCollectionClick" class="mx-1.5" />
</ui-tooltip> </ui-tooltip>
<template v-if="userCanUpdate"> <template v-if="userCanUpdate">
@ -103,6 +103,9 @@ export default {
isPodcastLibrary() { isPodcastLibrary() {
return this.libraryMediaType === 'podcast' return this.libraryMediaType === 'podcast'
}, },
isBookLibrary() {
return this.libraryMediaType === 'book'
},
isHome() { isHome() {
return this.$route.name === 'library-library' return this.$route.name === 'library-library'
}, },
@ -181,12 +184,15 @@ export default {
const queueItems = [] const queueItems = []
libraryItems.forEach((item) => { libraryItems.forEach((item) => {
let subtitle = ''
if (item.mediaType === 'book') subtitle = item.media.metadata.authors.map((au) => au.name).join(', ')
else if (item.mediaType === 'music') subtitle = item.media.metadata.artists.join(', ')
queueItems.push({ queueItems.push({
libraryItemId: item.id, libraryItemId: item.id,
libraryId: item.libraryId, libraryId: item.libraryId,
episodeId: null, episodeId: null,
title: item.media.metadata.title, title: item.media.metadata.title,
subtitle: item.media.metadata.authors.map((au) => au.name).join(', '), subtitle,
caption: '', caption: '',
duration: item.media.duration || null, duration: item.media.duration || null,
coverPath: item.media.coverPath || null coverPath: item.media.coverPath || null

View File

@ -136,7 +136,7 @@ export default {
const mediaItem = { const mediaItem = {
id: thisEntity.id, id: thisEntity.id,
mediaType: thisEntity.mediaType, mediaType: thisEntity.mediaType,
hasTracks: thisEntity.mediaType === 'podcast' || thisEntity.media.numTracks || (thisEntity.media.tracks && thisEntity.media.tracks.length) hasTracks: thisEntity.mediaType === 'podcast' || thisEntity.media.audioFile || thisEntity.media.numTracks || (thisEntity.media.tracks && thisEntity.media.tracks.length)
} }
this.$store.commit('globals/setMediaItemSelected', { item: mediaItem, selected: isSelecting }) this.$store.commit('globals/setMediaItemSelected', { item: mediaItem, selected: isSelecting })
} else { } else {
@ -147,7 +147,7 @@ export default {
const mediaItem = { const mediaItem = {
id: entity.id, id: entity.id,
mediaType: entity.mediaType, mediaType: entity.mediaType,
hasTracks: entity.mediaType === 'podcast' || entity.media.numTracks || (entity.media.tracks && entity.media.tracks.length) hasTracks: entity.mediaType === 'podcast' || entity.media.audioFile || entity.media.numTracks || (entity.media.tracks && entity.media.tracks.length)
} }
this.$store.commit('globals/toggleMediaItemSelected', mediaItem) this.$store.commit('globals/toggleMediaItemSelected', mediaItem)
} }

View File

@ -6,7 +6,7 @@
</div> </div>
</template> </template>
<div v-if="initialized && !totalShelves && !hasFilter && entityName === 'books'" class="w-full flex flex-col items-center justify-center py-12"> <div v-if="initialized && !totalShelves && !hasFilter && entityName === 'items'" class="w-full flex flex-col items-center justify-center py-12">
<p class="text-center text-2xl font-book mb-4 py-4">{{ $getString('MessageXLibraryIsEmpty', [libraryName]) }}</p> <p class="text-center text-2xl font-book mb-4 py-4">{{ $getString('MessageXLibraryIsEmpty', [libraryName]) }}</p>
<div v-if="userIsAdminOrUp" class="flex"> <div v-if="userIsAdminOrUp" class="flex">
<ui-btn to="/config" color="primary" class="w-52 mr-2">{{ $strings.ButtonConfigureScanner }}</ui-btn> <ui-btn to="/config" color="primary" class="w-52 mr-2">{{ $strings.ButtonConfigureScanner }}</ui-btn>
@ -16,7 +16,7 @@
<div v-else-if="!totalShelves && initialized" class="w-full py-16"> <div v-else-if="!totalShelves && initialized" class="w-full py-16">
<p class="text-xl text-center">{{ emptyMessage }}</p> <p class="text-xl text-center">{{ emptyMessage }}</p>
<!-- Clear filter only available on Library bookshelf --> <!-- Clear filter only available on Library bookshelf -->
<div v-if="entityName === 'books'" class="flex justify-center mt-2"> <div v-if="entityName === 'items'" class="flex justify-center mt-2">
<ui-btn v-if="hasFilter" color="primary" @click="clearFilter">{{ $strings.ButtonClearFilter }}</ui-btn> <ui-btn v-if="hasFilter" color="primary" @click="clearFilter">{{ $strings.ButtonClearFilter }}</ui-btn>
</div> </div>
</div> </div>
@ -81,8 +81,11 @@ export default {
showExperimentalFeatures() { showExperimentalFeatures() {
return this.$store.state.showExperimentalFeatures return this.$store.state.showExperimentalFeatures
}, },
libraryMediaType() {
return this.$store.getters['libraries/getCurrentLibraryMediaType']
},
isPodcast() { isPodcast() {
return this.$store.getters['libraries/getCurrentLibraryMediaType'] == 'podcast' return this.libraryMediaType === 'podcast'
}, },
emptyMessage() { emptyMessage() {
if (this.page === 'series') return this.$strings.MessageBookshelfNoSeries if (this.page === 'series') return this.$strings.MessageBookshelfNoSeries
@ -96,7 +99,7 @@ export default {
return this.$strings.MessageNoResults return this.$strings.MessageNoResults
}, },
entityName() { entityName() {
if (!this.page) return 'books' if (!this.page) return 'items'
return this.page return this.page
}, },
seriesSortBy() { seriesSortBy() {
@ -158,11 +161,8 @@ export default {
libraryName() { libraryName() {
return this.$store.getters['libraries/getCurrentLibraryName'] return this.$store.getters['libraries/getCurrentLibraryName']
}, },
isEntityBook() {
return this.entityName === 'series-books' || this.entityName === 'books'
},
bookWidth() { bookWidth() {
var coverSize = this.$store.getters['user/getUserSetting']('bookshelfCoverSize') const coverSize = this.$store.getters['user/getUserSetting']('bookshelfCoverSize')
if (this.isCoverSquareAspectRatio || this.entityName === 'playlists') return coverSize * 1.6 if (this.isCoverSquareAspectRatio || this.entityName === 'playlists') return coverSize * 1.6
return coverSize return coverSize
}, },
@ -192,7 +192,8 @@ export default {
}, },
shelfHeight() { shelfHeight() {
if (this.isAlternativeBookshelfView) { if (this.isAlternativeBookshelfView) {
var extraTitleSpace = this.isEntityBook ? 80 : 40 const isItemEntity = this.entityName === 'series-books' || this.entityName === 'items'
const extraTitleSpace = isItemEntity ? 80 : this.entityName === 'albums' ? 60 : 40
return this.entityHeight + extraTitleSpace * this.sizeMultiplier return this.entityHeight + extraTitleSpace * this.sizeMultiplier
} }
return this.entityHeight + 40 return this.entityHeight + 40
@ -214,7 +215,7 @@ export default {
this.$store.dispatch('user/updateUserSettings', { filterBy: 'all' }) this.$store.dispatch('user/updateUserSettings', { filterBy: 'all' })
}, },
editEntity(entity) { editEntity(entity) {
if (this.entityName === 'books' || this.entityName === 'series-books') { if (this.entityName === 'items' || this.entityName === 'series-books') {
const bookIds = this.entities.map((e) => e.id) const bookIds = this.entities.map((e) => e.id)
this.$store.commit('setBookshelfBookIds', bookIds) this.$store.commit('setBookshelfBookIds', bookIds)
this.$store.commit('showEditModal', entity) this.$store.commit('showEditModal', entity)
@ -229,7 +230,7 @@ export default {
this.isSelectionMode = false this.isSelectionMode = false
}, },
selectEntity(entity, shiftKey) { selectEntity(entity, shiftKey) {
if (this.entityName === 'books' || this.entityName === 'series-books') { if (this.entityName === 'items' || this.entityName === 'series-books') {
const indexOf = this.entities.findIndex((ent) => ent && ent.id === entity.id) const indexOf = this.entities.findIndex((ent) => ent && ent.id === entity.id)
const lastLastItemIndexSelected = this.lastItemIndexSelected const lastLastItemIndexSelected = this.lastItemIndexSelected
if (!this.selectedMediaItems.some((i) => i.id === entity.id)) { if (!this.selectedMediaItems.some((i) => i.id === entity.id)) {
@ -273,9 +274,8 @@ export default {
const mediaItem = { const mediaItem = {
id: thisEntity.id, id: thisEntity.id,
mediaType: thisEntity.mediaType, mediaType: thisEntity.mediaType,
hasTracks: thisEntity.mediaType === 'podcast' || thisEntity.media.numTracks || (thisEntity.media.tracks && thisEntity.media.tracks.length) hasTracks: thisEntity.mediaType === 'podcast' || thisEntity.media.audioFile || thisEntity.media.numTracks || (thisEntity.media.tracks && thisEntity.media.tracks.length)
} }
console.log('Setting media item selected', mediaItem, 'Num Selected=', this.selectedMediaItems.length)
this.$store.commit('globals/setMediaItemSelected', { item: mediaItem, selected: isSelecting }) this.$store.commit('globals/setMediaItemSelected', { item: mediaItem, selected: isSelecting })
} else { } else {
console.error('Invalid entity index', i) console.error('Invalid entity index', i)
@ -285,7 +285,7 @@ export default {
const mediaItem = { const mediaItem = {
id: entity.id, id: entity.id,
mediaType: entity.mediaType, mediaType: entity.mediaType,
hasTracks: entity.mediaType === 'podcast' || entity.media.numTracks || (entity.media.tracks && entity.media.tracks.length) hasTracks: entity.mediaType === 'podcast' || entity.media.audioFile || entity.media.numTracks || (entity.media.tracks && entity.media.tracks.length)
} }
this.$store.commit('globals/toggleMediaItemSelected', mediaItem) this.$store.commit('globals/toggleMediaItemSelected', mediaItem)
} }
@ -316,7 +316,7 @@ export default {
this.currentSFQueryString = this.buildSearchParams() this.currentSFQueryString = this.buildSearchParams()
} }
const entityPath = this.entityName === 'books' || this.entityName === 'series-books' ? 'items' : this.entityName const entityPath = this.entityName === 'series-books' ? 'items' : this.entityName
const sfQueryString = this.currentSFQueryString ? this.currentSFQueryString + '&' : '' const sfQueryString = this.currentSFQueryString ? this.currentSFQueryString + '&' : ''
const fullQueryString = `?${sfQueryString}limit=${this.booksPerFetch}&page=${page}&minified=1&include=rssfeed` const fullQueryString = `?${sfQueryString}limit=${this.booksPerFetch}&page=${page}&minified=1&include=rssfeed`
@ -517,7 +517,7 @@ export default {
}, },
libraryItemUpdated(libraryItem) { libraryItemUpdated(libraryItem) {
console.log('Item updated', libraryItem) console.log('Item updated', libraryItem)
if (this.entityName === 'books' || this.entityName === 'series-books') { if (this.entityName === 'items' || this.entityName === 'series-books') {
var indexOf = this.entities.findIndex((ent) => ent && ent.id === libraryItem.id) var indexOf = this.entities.findIndex((ent) => ent && ent.id === libraryItem.id)
if (indexOf >= 0) { if (indexOf >= 0) {
this.entities[indexOf] = libraryItem this.entities[indexOf] = libraryItem
@ -528,7 +528,7 @@ export default {
} }
}, },
libraryItemRemoved(libraryItem) { libraryItemRemoved(libraryItem) {
if (this.entityName === 'books' || this.entityName === 'series-books') { if (this.entityName === 'items' || this.entityName === 'series-books') {
var indexOf = this.entities.findIndex((ent) => ent && ent.id === libraryItem.id) var indexOf = this.entities.findIndex((ent) => ent && ent.id === libraryItem.id)
if (indexOf >= 0) { if (indexOf >= 0) {
this.entities = this.entities.filter((ent) => ent.id !== libraryItem.id) this.entities = this.entities.filter((ent) => ent.id !== libraryItem.id)

View File

@ -12,6 +12,7 @@
<div v-if="!playerHandler.isVideo" class="text-gray-400 flex items-center"> <div v-if="!playerHandler.isVideo" class="text-gray-400 flex items-center">
<span class="material-icons text-sm">person</span> <span class="material-icons text-sm">person</span>
<p v-if="podcastAuthor" class="pl-1 sm:pl-1.5 text-xs sm:text-base">{{ podcastAuthor }}</p> <p v-if="podcastAuthor" class="pl-1 sm:pl-1.5 text-xs sm:text-base">{{ podcastAuthor }}</p>
<p v-else-if="musicArtists" class="pl-1 sm:pl-1.5 text-xs sm:text-base">{{ musicArtists }}</p>
<p v-else-if="authors.length" class="pl-1 sm:pl-1.5 text-xs sm:text-base"> <p v-else-if="authors.length" class="pl-1 sm:pl-1.5 text-xs sm:text-base">
<nuxt-link v-for="(author, index) in authors" :key="index" :to="`/author/${author.id}`" class="hover:underline">{{ author.name }}<span v-if="index < authors.length - 1">,&nbsp;</span></nuxt-link> <nuxt-link v-for="(author, index) in authors" :key="index" :to="`/author/${author.id}`" class="hover:underline">{{ author.name }}<span v-if="index < authors.length - 1">,&nbsp;</span></nuxt-link>
</p> </p>
@ -148,6 +149,10 @@ export default {
if (!this.isPodcast) return null if (!this.isPodcast) return null
return this.mediaMetadata.author || 'Unknown' return this.mediaMetadata.author || 'Unknown'
}, },
musicArtists() {
if (!this.isMusic) return null
return this.mediaMetadata.artists.join(', ')
},
playerQueueItems() { playerQueueItems() {
return this.$store.state.playerQueueItems || [] return this.$store.state.playerQueueItems || []
} }

View File

@ -12,6 +12,7 @@
</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"> <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> <p class="truncate" :style="{ fontSize: labelFontSize + 'rem' }">{{ title }}</p>
<p class="truncate text-gray-400" :style="{ fontSize: 0.8 * sizeMultiplier + 'rem' }">{{ artist || '&nbsp;' }}</p>
</div> </div>
</div> </div>
</template> </template>
@ -51,12 +52,15 @@ export default {
return 0.875 return 0.875
}, },
sizeMultiplier() { sizeMultiplier() {
if (this.bookCoverAspectRatio === 1) return this.width / (120 * 1.6 * 2) const baseSize = this.bookCoverAspectRatio === 1 ? 192 : 120
return this.width / 240 return this.width / baseSize
}, },
title() { title() {
return this.album ? this.album.title : '' return this.album ? this.album.title : ''
}, },
artist() {
return this.album ? this.album.artist : ''
},
store() { store() {
return this.$store || this.$nuxt.$store return this.$store || this.$nuxt.$store
}, },

View File

@ -70,7 +70,7 @@
</div> </div>
<!-- More Menu Icon --> <!-- More Menu Icon -->
<div ref="moreIcon" v-show="!isSelectionMode" class="hidden md:block absolute cursor-pointer hover:text-yellow-300 300 hover:scale-125 transform duration-150" :style="{ bottom: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem' }" @click.stop.prevent="clickShowMore"> <div ref="moreIcon" v-show="!isSelectionMode && moreMenuItems.length" class="hidden md:block absolute cursor-pointer hover:text-yellow-300 300 hover:scale-125 transform duration-150" :style="{ bottom: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem' }" @click.stop.prevent="clickShowMore">
<span class="material-icons" :style="{ fontSize: 1.2 * sizeMultiplier + 'rem' }">more_vert</span> <span class="material-icons" :style="{ fontSize: 1.2 * sizeMultiplier + 'rem' }">more_vert</span>
</div> </div>
</div> </div>
@ -276,6 +276,10 @@ export default {
authorLF() { authorLF() {
return this.mediaMetadata.authorNameLF return this.mediaMetadata.authorNameLF
}, },
artist() {
const artists = this.mediaMetadata.artists || []
return artists.join(', ')
},
displayTitle() { displayTitle() {
if (this.recentEpisode) return this.recentEpisode.title if (this.recentEpisode) return this.recentEpisode.title
const ignorePrefix = this.orderBy === 'media.metadata.title' && this.sortingIgnorePrefix const ignorePrefix = this.orderBy === 'media.metadata.title' && this.sortingIgnorePrefix
@ -285,6 +289,7 @@ export default {
displayLineTwo() { displayLineTwo() {
if (this.recentEpisode) return this.title if (this.recentEpisode) return this.title
if (this.isPodcast) return this.author if (this.isPodcast) return this.author
if (this.isMusic) return this.artist
if (this.collapsedSeries) return '' if (this.collapsedSeries) return ''
if (this.isAuthorBookshelfView) { if (this.isAuthorBookshelfView) {
return this.mediaMetadata.publishedYear || '' return this.mediaMetadata.publishedYear || ''
@ -345,7 +350,7 @@ export default {
return !this.isSelectionMode && !this.showPlayButton && this.hasEbook && (this.showExperimentalFeatures || this.enableEReader) return !this.isSelectionMode && !this.showPlayButton && this.hasEbook && (this.showExperimentalFeatures || this.enableEReader)
}, },
showPlayButton() { showPlayButton() {
return !this.isSelectionMode && !this.isMissing && !this.isInvalid && !this.isStreaming && (this.numTracks || this.recentEpisode) return !this.isSelectionMode && !this.isMissing && !this.isInvalid && !this.isStreaming && (this.numTracks || this.recentEpisode || this.isMusic)
}, },
showSmallEBookIcon() { showSmallEBookIcon() {
return !this.isSelectionMode && this.hasEbook && (this.showExperimentalFeatures || this.enableEReader) return !this.isSelectionMode && this.hasEbook && (this.showExperimentalFeatures || this.enableEReader)
@ -370,7 +375,7 @@ export default {
if (this.isPodcast) return 'Podcast has no episodes' if (this.isPodcast) return 'Podcast has no episodes'
return 'Item has no audio tracks & ebook' return 'Item has no audio tracks & ebook'
} }
var txt = '' let txt = ''
if (this.numMissingParts) { if (this.numMissingParts) {
txt += `${this.numMissingParts} missing parts.` txt += `${this.numMissingParts} missing parts.`
} }
@ -381,7 +386,7 @@ export default {
return txt || 'Unknown Error' return txt || 'Unknown Error'
}, },
overlayWrapperClasslist() { overlayWrapperClasslist() {
var classes = [] const classes = []
if (this.isSelectionMode) classes.push('bg-opacity-60') if (this.isSelectionMode) classes.push('bg-opacity-60')
else classes.push('bg-opacity-40') else classes.push('bg-opacity-40')
if (this.selected) { if (this.selected) {
@ -405,6 +410,8 @@ export default {
return this.store.getters['user/getIsAdminOrUp'] return this.store.getters['user/getIsAdminOrUp']
}, },
moreMenuItems() { moreMenuItems() {
if (this.isMusic) return []
if (this.recentEpisode) { if (this.recentEpisode) {
const items = [ const items = [
{ {
@ -442,7 +449,7 @@ export default {
return items return items
} }
var items = [] let items = []
if (!this.isPodcast) { if (!this.isPodcast) {
items = [ items = [
{ {

View File

@ -87,8 +87,14 @@ export default {
this.$emit('input', val) this.$emit('input', val)
} }
}, },
libraryMediaType() {
return this.$store.getters['libraries/getCurrentLibraryMediaType']
},
isPodcast() { isPodcast() {
return this.$store.getters['libraries/getCurrentLibraryMediaType'] == 'podcast' return this.libraryMediaType === 'podcast'
},
isMusic() {
return this.libraryMediaType === 'music'
}, },
seriesItems() { seriesItems() {
return [ return [
@ -214,9 +220,33 @@ export default {
} }
] ]
}, },
musicItems() {
return [
{
text: this.$strings.LabelAll,
value: 'all'
},
{
text: this.$strings.LabelGenre,
value: 'genres',
sublist: true
},
{
text: this.$strings.LabelTag,
value: 'tags',
sublist: true
},
{
text: this.$strings.ButtonIssues,
value: 'issues',
sublist: false
}
]
},
selectItems() { selectItems() {
if (this.isSeries) return this.seriesItems if (this.isSeries) return this.seriesItems
if (this.isPodcast) return this.podcastItems if (this.isPodcast) return this.podcastItems
if (this.isMusic) return this.musicItems
return this.bookItems return this.bookItems
}, },
selectedItemSublist() { selectedItemSublist() {

View File

@ -50,8 +50,14 @@ export default {
this.$emit('update:descending', val) this.$emit('update:descending', val)
} }
}, },
libraryMediaType() {
return this.$store.getters['libraries/getCurrentLibraryMediaType']
},
isPodcast() { isPodcast() {
return this.$store.getters['libraries/getCurrentLibraryMediaType'] == 'podcast' return this.libraryMediaType === 'podcast'
},
isMusic() {
return this.libraryMediaType === 'music'
}, },
podcastItems() { podcastItems() {
return [ return [
@ -134,10 +140,40 @@ export default {
} }
] ]
}, },
musicItems() {
return [
{
text: this.$strings.LabelTitle,
value: 'media.metadata.title'
},
{
text: this.$strings.LabelAddedAt,
value: 'addedAt'
},
{
text: this.$strings.LabelSize,
value: 'size'
},
{
text: this.$strings.LabelDuration,
value: 'media.duration'
},
{
text: this.$strings.LabelFileBirthtime,
value: 'birthtimeMs'
},
{
text: this.$strings.LabelFileModified,
value: 'mtimeMs'
}
]
},
selectItems() { selectItems() {
let items = null let items = null
if (this.isPodcast) { if (this.isPodcast) {
items = this.podcastItems items = this.podcastItems
} else if (this.isMusic) {
items = this.musicItems
} else if (this.$store.getters['user/getUserSetting']('filterBy').startsWith('series.')) { } else if (this.$store.getters['user/getUserSetting']('filterBy').startsWith('series.')) {
items = this.seriesItems items = this.seriesItems
} else { } else {

View File

@ -60,7 +60,7 @@ export default {
sortingIgnorePrefix: !!this.sortingIgnorePrefix sortingIgnorePrefix: !!this.sortingIgnorePrefix
} }
if (this.entityName === 'books') { if (this.entityName === 'items') {
props.filterBy = this.filterBy props.filterBy = this.filterBy
props.orderBy = this.orderBy props.orderBy = this.orderBy
} else if (this.entityName === 'series') { } else if (this.entityName === 'series') {

View File

@ -145,14 +145,12 @@ export default class PlayerHandler {
console.log('[PlayerHandler] Player state change', state) console.log('[PlayerHandler] Player state change', state)
this.playerState = state this.playerState = state
if (!this.isMusic) {
if (this.playerState === 'PLAYING') { if (this.playerState === 'PLAYING') {
this.setPlaybackRate(this.initialPlaybackRate) this.setPlaybackRate(this.initialPlaybackRate)
this.startPlayInterval() this.startPlayInterval()
} else { } else {
this.stopPlayInterval() this.stopPlayInterval()
} }
}
if (this.player) { if (this.player) {
if (this.playerState === 'LOADED' || this.playerState === 'PLAYING') { if (this.playerState === 'LOADED' || this.playerState === 'PLAYING') {
@ -260,14 +258,14 @@ export default class PlayerHandler {
startPlayInterval() { startPlayInterval() {
clearInterval(this.playInterval) clearInterval(this.playInterval)
var lastTick = Date.now() let lastTick = Date.now()
this.playInterval = setInterval(() => { this.playInterval = setInterval(() => {
// Update UI // Update UI
if (!this.player) return if (!this.player) return
var currentTime = this.player.getCurrentTime() const currentTime = this.player.getCurrentTime()
this.ctx.setCurrentTime(currentTime) this.ctx.setCurrentTime(currentTime)
var exactTimeElapsed = ((Date.now() - lastTick) / 1000) const exactTimeElapsed = ((Date.now() - lastTick) / 1000)
lastTick = Date.now() lastTick = Date.now()
this.listeningTimeSinceSync += exactTimeElapsed this.listeningTimeSinceSync += exactTimeElapsed
if (this.listeningTimeSinceSync >= 5) { if (this.listeningTimeSinceSync >= 5) {
@ -277,9 +275,9 @@ export default class PlayerHandler {
} }
sendCloseSession() { sendCloseSession() {
var syncData = null let syncData = null
if (this.player) { if (this.player) {
var listeningTimeToAdd = Math.max(0, Math.floor(this.listeningTimeSinceSync)) const listeningTimeToAdd = Math.max(0, Math.floor(this.listeningTimeSinceSync))
syncData = { syncData = {
timeListened: listeningTimeToAdd, timeListened: listeningTimeToAdd,
duration: this.getDuration(), duration: this.getDuration(),
@ -293,12 +291,14 @@ export default class PlayerHandler {
} }
sendProgressSync(currentTime) { sendProgressSync(currentTime) {
var diffSinceLastSync = Math.abs(this.lastSyncTime - currentTime) if (this.isMusic) return
const diffSinceLastSync = Math.abs(this.lastSyncTime - currentTime)
if (diffSinceLastSync < 1) return if (diffSinceLastSync < 1) return
this.lastSyncTime = currentTime this.lastSyncTime = currentTime
var listeningTimeToAdd = Math.max(0, Math.floor(this.listeningTimeSinceSync)) const listeningTimeToAdd = Math.max(0, Math.floor(this.listeningTimeSinceSync))
var syncData = { const syncData = {
timeListened: listeningTimeToAdd, timeListened: listeningTimeToAdd,
duration: this.getDuration(), duration: this.getDuration(),
currentTime currentTime

View File

@ -127,7 +127,7 @@ class Book {
}) })
} }
get duration() { get duration() {
var total = 0 let total = 0
this.tracks.forEach((track) => total += track.duration) this.tracks.forEach((track) => total += track.duration)
return total return total
} }

View File

@ -41,6 +41,7 @@ class Music {
coverPath: this.coverPath, coverPath: this.coverPath,
tags: [...this.tags], tags: [...this.tags],
audioFile: this.audioFile.toJSON(), audioFile: this.audioFile.toJSON(),
duration: this.duration,
size: this.size size: this.size
} }
} }
@ -52,6 +53,7 @@ class Music {
coverPath: this.coverPath, coverPath: this.coverPath,
tags: [...this.tags], tags: [...this.tags],
audioFile: this.audioFile.toJSON(), audioFile: this.audioFile.toJSON(),
duration: this.duration,
size: this.size size: this.size
} }
} }