mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-23 20:29:37 +00:00
New data model edit tracks page, match, quick match, clean out old files
This commit is contained in:
parent
be1e1e7ba0
commit
7d66f1eec9
68 changed files with 354 additions and 1529 deletions
|
|
@ -103,9 +103,6 @@ export default {
|
|||
userAudiobooks() {
|
||||
return this.$store.state.user.user.audiobooks || {}
|
||||
},
|
||||
selectedSeries() {
|
||||
return this.$store.state.audiobooks.selectedSeries
|
||||
},
|
||||
userCanUpdate() {
|
||||
return this.$store.getters['user/getUserCanUpdate']
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<covers-hover-book-cover :audiobook="book" />
|
||||
</td>
|
||||
<td class="body-cell min-w-64 max-w-64 px-2">
|
||||
<nuxt-link :to="`/audiobook/${book.id}`" class="hover:underline">
|
||||
<nuxt-link :to="`/item/${book.id}`" class="hover:underline">
|
||||
<p class="truncate">
|
||||
{{ book.book.title }}<span v-if="book.book.subtitle">: {{ book.book.subtitle }}</span>
|
||||
</p>
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
<p class="truncate">{{ seriesText }}</p>
|
||||
</td>
|
||||
<td class="body-cell min-w-24 max-w-24 px-2">
|
||||
<p class="truncate">{{ book.book.publishYear }}</p>
|
||||
<p class="truncate">{{ book.book.publishedYear }}</p>
|
||||
</td>
|
||||
<td class="body-cell min-w-80 max-w-80 px-2">
|
||||
<p class="truncate">{{ book.book.description }}</p>
|
||||
|
|
@ -148,7 +148,7 @@ export default {
|
|||
this.$store.commit('showEReader', this.book)
|
||||
},
|
||||
downloadClick() {
|
||||
this.$store.commit('showEditModalOnTab', { audiobook: this.book, tab: 'download' })
|
||||
this.$store.commit('showEditModalOnTab', { libraryItem: this.book, tab: 'download' })
|
||||
},
|
||||
toggleRead() {
|
||||
var updatePayload = {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<p class="text-center text-2xl font-book mb-4 py-4">Audiobookshelf is empty!</p>
|
||||
<div class="flex">
|
||||
<ui-btn to="/config" color="primary" class="w-52 mr-2">Configure Scanner</ui-btn>
|
||||
<ui-btn color="success" class="w-52" @click="scan">Scan Audiobooks</ui-btn>
|
||||
<ui-btn color="success" class="w-52" @click="scan">Scan Library</ui-btn>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="loaded && !shelves.length && search" class="w-full h-40 flex items-center justify-center">
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<div v-show="routeName === route.iod" class="h-full w-0.5 bg-yellow-400 absolute top-0 left-0" />
|
||||
</nuxt-link>
|
||||
|
||||
<div class="w-full h-10 px-4 border-t border-black border-opacity-20 absolute left-0 flex flex-col justify-center" :style="{ bottom: streamAudiobook && isMobileLandscape ? '300px' : '65px' }">
|
||||
<div class="w-full h-10 px-4 border-t border-black border-opacity-20 absolute left-0 flex flex-col justify-center" :style="{ bottom: streamLibraryItem && isMobileLandscape ? '300px' : '65px' }">
|
||||
<p class="font-mono text-sm">v{{ $config.version }}</p>
|
||||
<a v-if="hasUpdate" :href="githubTagUrl" target="_blank" class="text-warning text-sm">Update available: {{ latestVersion }}</a>
|
||||
</div>
|
||||
|
|
@ -109,8 +109,8 @@ export default {
|
|||
githubTagUrl() {
|
||||
return this.versionData.githubTagUrl
|
||||
},
|
||||
streamAudiobook() {
|
||||
return this.$store.state.streamAudiobook
|
||||
streamLibraryItem() {
|
||||
return this.$store.state.streamLibraryItem
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<div class="flex items-center">
|
||||
<h1>{{ book.title }}</h1>
|
||||
<div class="flex-grow" />
|
||||
<p>{{ book.publishYear }}</p>
|
||||
<p>{{ book.publishedYear }}</p>
|
||||
</div>
|
||||
<p class="text-gray-400">{{ book.author }}</p>
|
||||
<div class="w-full max-h-12 overflow-hidden">
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ export default {
|
|||
return '/book_placeholder.jpg'
|
||||
},
|
||||
bookCoverSrc() {
|
||||
return this.store.getters['audiobooks/getLibraryItemCoverSrc'](this._libraryItem, this.placeholderUrl)
|
||||
return this.store.getters['globals/getLibraryItemCoverSrc'](this._libraryItem, this.placeholderUrl)
|
||||
},
|
||||
libraryItemId() {
|
||||
return this._libraryItem.id
|
||||
|
|
@ -418,7 +418,7 @@ export default {
|
|||
toast.error(`Failed to mark as ${updatePayload.isRead ? 'Read' : 'Not Read'}`)
|
||||
})
|
||||
},
|
||||
audiobookScanComplete(result) {
|
||||
itemScanComplete(result) {
|
||||
this.rescanning = false
|
||||
var toast = this.$toast || this.$nuxt.$toast
|
||||
if (!result) {
|
||||
|
|
@ -433,23 +433,23 @@ export default {
|
|||
},
|
||||
rescan() {
|
||||
this.rescanning = true
|
||||
this._socket.once('audiobook_scan_complete', this.audiobookScanComplete)
|
||||
this._socket.emit('scan_libraryItem', this.libraryItemId)
|
||||
this._socket.once('item_scan_complete', this.itemScanComplete)
|
||||
this._socket.emit('scan_item', this.libraryItemId)
|
||||
},
|
||||
showEditModalTracks() {
|
||||
// More menu func
|
||||
this.store.commit('showEditModalOnTab', { audiobook: this.audiobook, tab: 'tracks' })
|
||||
this.store.commit('showEditModalOnTab', { libraryItem: this.audiobook, tab: 'tracks' })
|
||||
},
|
||||
showEditModalMatch() {
|
||||
// More menu func
|
||||
this.store.commit('showEditModalOnTab', { audiobook: this.audiobook, tab: 'match' })
|
||||
this.store.commit('showEditModalOnTab', { libraryItem: this.audiobook, tab: 'match' })
|
||||
},
|
||||
showEditModalDownload() {
|
||||
// More menu func
|
||||
this.store.commit('showEditModalOnTab', { audiobook: this.audiobook, tab: 'download' })
|
||||
this.store.commit('showEditModalOnTab', { libraryItem: this.audiobook, tab: 'download' })
|
||||
},
|
||||
openCollections() {
|
||||
this.store.commit('setSelectedAudiobook', this.audiobook)
|
||||
this.store.commit('setSelectedLibraryItem', this.audiobook)
|
||||
this.store.commit('globals/setShowUserCollectionsModal', true)
|
||||
},
|
||||
createMoreMenu() {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ export default {
|
|||
fullCoverUrl() {
|
||||
if (!this.libraryItem) return null
|
||||
var store = this.$store || this.$nuxt.$store
|
||||
return store.getters['audiobooks/getLibraryItemCoverSrc'](this.libraryItem, this.placeholderUrl)
|
||||
return store.getters['globals/getLibraryItemCoverSrc'](this.libraryItem, this.placeholderUrl)
|
||||
},
|
||||
cover() {
|
||||
return this.media.coverPath || this.placeholderUrl
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
getCoverUrl(book) {
|
||||
return this.store.getters['audiobooks/getLibraryItemCoverSrc'](book, '')
|
||||
return this.store.getters['globals/getLibraryItemCoverSrc'](book, '')
|
||||
},
|
||||
async buildCoverImg(coverData, bgCoverWidth, offsetLeft, zIndex, forceCoverBg = false) {
|
||||
var src = coverData.coverUrl
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export default {
|
|||
return '/book_placeholder.jpg'
|
||||
},
|
||||
fullCoverUrl() {
|
||||
return this.$store.getters['audiobooks/getLibraryItemCoverSrc'](this.audiobook, this.placeholderUrl)
|
||||
return this.$store.getters['globals/getLibraryItemCoverSrc'](this.audiobook, this.placeholderUrl)
|
||||
},
|
||||
hasCover() {
|
||||
return !!this.audiobook.book.cover
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ export default {
|
|||
if (this.currentBookshelfIndex - 1 < 0) return
|
||||
var prevBookId = this.bookshelfBookIds[this.currentBookshelfIndex - 1]
|
||||
this.processing = true
|
||||
var prevBook = await this.$axios.$get(`/api/books/${prevBookId}`).catch((error) => {
|
||||
var prevBook = await this.$axios.$get(`/api/items/${prevBookId}`).catch((error) => {
|
||||
var errorMsg = error.response && error.response.data ? error.response.data : 'Failed to fetch book'
|
||||
this.$toast.error(errorMsg)
|
||||
return null
|
||||
|
|
@ -186,7 +186,7 @@ export default {
|
|||
if (this.currentBookshelfIndex >= this.bookshelfBookIds.length - 1) return
|
||||
this.processing = true
|
||||
var nextBookId = this.bookshelfBookIds[this.currentBookshelfIndex + 1]
|
||||
var nextBook = await this.$axios.$get(`/api/books/${nextBookId}`).catch((error) => {
|
||||
var nextBook = await this.$axios.$get(`/api/items/${nextBookId}`).catch((error) => {
|
||||
var errorMsg = error.response && error.response.data ? error.response.data : 'Failed to fetch book'
|
||||
this.$toast.error(errorMsg)
|
||||
return null
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<div class="w-full overflow-y-auto overflow-x-hidden max-h-96">
|
||||
<transition-group name="list-complete" tag="div">
|
||||
<template v-for="collection in sortedCollections">
|
||||
<modals-collections-user-collection-item :key="collection.id" :collection="collection" class="list-complete-item" @add="addToCollection" @remove="removeFromCollection" @close="show = false" />
|
||||
<modals-collections-user-collection-item :key="collection.id" :collection="collection" :book-cover-aspect-ratio="bookCoverAspectRatio" class="list-complete-item" @add="addToCollection" @remove="removeFromCollection" @close="show = false" />
|
||||
</template>
|
||||
</transition-group>
|
||||
</div>
|
||||
|
|
@ -50,7 +50,7 @@ export default {
|
|||
this.loadCollections()
|
||||
this.newCollectionName = ''
|
||||
} else {
|
||||
this.$store.commit('setSelectedAudiobook', null)
|
||||
this.$store.commit('setSelectedLibraryItem', null)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -65,15 +65,18 @@ export default {
|
|||
},
|
||||
title() {
|
||||
if (this.showBatchUserCollectionModal) {
|
||||
return `${this.selectedBookIds.length} Books Selected`
|
||||
return `${this.selectedBookIds.length} Items Selected`
|
||||
}
|
||||
return this.selectedAudiobook ? this.selectedAudiobook.book.title : ''
|
||||
return this.selectedLibraryItem ? this.selectedLibraryItem.media.metadata.title : ''
|
||||
},
|
||||
selectedAudiobook() {
|
||||
return this.$store.state.selectedAudiobook
|
||||
bookCoverAspectRatio() {
|
||||
return this.$store.getters['getBookCoverAspectRatio']
|
||||
},
|
||||
selectedAudiobookId() {
|
||||
return this.selectedAudiobook ? this.selectedAudiobook.id : null
|
||||
selectedLibraryItem() {
|
||||
return this.$store.state.selectedLibraryItem
|
||||
},
|
||||
selectedLibraryItemId() {
|
||||
return this.selectedLibraryItem ? this.selectedLibraryItem.id : null
|
||||
},
|
||||
collections() {
|
||||
return this.$store.state.user.collections || []
|
||||
|
|
@ -87,7 +90,7 @@ export default {
|
|||
var collectionBookIds = c.books.map((b) => b.id)
|
||||
includesBook = !this.selectedBookIds.find((id) => !collectionBookIds.includes(id))
|
||||
} else {
|
||||
includesBook = !!c.books.find((b) => b.id === this.selectedAudiobookId)
|
||||
includesBook = !!c.books.find((b) => b.id === this.selectedLibraryItemId)
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
@ -112,7 +115,7 @@ export default {
|
|||
this.$store.dispatch('user/loadUserCollections')
|
||||
},
|
||||
removeFromCollection(collection) {
|
||||
if (!this.selectedAudiobookId && !this.selectedBookIds.length) return
|
||||
if (!this.selectedLibraryItemId && !this.selectedBookIds.length) return
|
||||
this.processing = true
|
||||
|
||||
if (this.showBatchUserCollectionModal) {
|
||||
|
|
@ -132,7 +135,7 @@ export default {
|
|||
} else {
|
||||
// Remove single book
|
||||
this.$axios
|
||||
.$delete(`/api/collections/${collection.id}/book/${this.selectedAudiobookId}`)
|
||||
.$delete(`/api/collections/${collection.id}/book/${this.selectedLibraryItemId}`)
|
||||
.then((updatedCollection) => {
|
||||
console.log(`Book removed from collection`, updatedCollection)
|
||||
this.$toast.success('Book removed from collection')
|
||||
|
|
@ -146,7 +149,7 @@ export default {
|
|||
}
|
||||
},
|
||||
addToCollection(collection) {
|
||||
if (!this.selectedAudiobookId && !this.selectedBookIds.length) return
|
||||
if (!this.selectedLibraryItemId && !this.selectedBookIds.length) return
|
||||
this.processing = true
|
||||
|
||||
if (this.showBatchUserCollectionModal) {
|
||||
|
|
@ -164,10 +167,10 @@ export default {
|
|||
this.processing = false
|
||||
})
|
||||
} else {
|
||||
if (!this.selectedAudiobookId) return
|
||||
if (!this.selectedLibraryItemId) return
|
||||
|
||||
this.$axios
|
||||
.$post(`/api/collections/${collection.id}/book`, { id: this.selectedAudiobookId })
|
||||
.$post(`/api/collections/${collection.id}/book`, { id: this.selectedLibraryItemId })
|
||||
.then((updatedCollection) => {
|
||||
console.log(`Book added to collection`, updatedCollection)
|
||||
this.$toast.success('Book added to collection')
|
||||
|
|
@ -181,12 +184,12 @@ export default {
|
|||
}
|
||||
},
|
||||
submitCreateCollection() {
|
||||
if (!this.newCollectionName || (!this.selectedAudiobookId && !this.selectedBookIds.length)) {
|
||||
if (!this.newCollectionName || (!this.selectedLibraryItemId && !this.selectedBookIds.length)) {
|
||||
return
|
||||
}
|
||||
this.processing = true
|
||||
|
||||
var books = this.showBatchUserCollectionModal ? this.selectedBookIds : [this.selectedAudiobookId]
|
||||
var books = this.showBatchUserCollectionModal ? this.selectedBookIds : [this.selectedLibraryItemId]
|
||||
var newCollection = {
|
||||
books: books,
|
||||
libraryId: this.currentLibraryId,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<!-- <span class="material-icons" :class="highlight ? 'text-success' : 'text-white text-opacity-80'">{{ highlight ? 'bookmark' : 'bookmark_border' }}</span> -->
|
||||
<div class="w-20 max-w-20 text-center">
|
||||
<!-- <img src="/Logo.png" /> -->
|
||||
<covers-collection-cover :book-items="books" :width="80" :height="40 * 1.6" />
|
||||
<covers-collection-cover :book-items="books" :width="80" :height="40 * bookCoverAspectRatio" :book-cover-aspect-ratio="bookCoverAspectRatio" />
|
||||
</div>
|
||||
<div class="flex-grow overflow-hidden px-2">
|
||||
<!-- <template v-if="isEditing">
|
||||
|
|
@ -38,7 +38,8 @@ export default {
|
|||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
highlight: Boolean
|
||||
highlight: Boolean,
|
||||
bookCoverAspectRatio: Number
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ export default {
|
|||
var coverPayload = {
|
||||
url: updatePayload.cover
|
||||
}
|
||||
var success = await this.$axios.$post(`/api/books/${this.audiobook.id}/cover`, coverPayload).catch((error) => {
|
||||
var success = await this.$axios.$post(`/api/items/${this.audiobook.id}/cover`, coverPayload).catch((error) => {
|
||||
console.error('Failed to update', error)
|
||||
return false
|
||||
})
|
||||
|
|
@ -171,7 +171,7 @@ export default {
|
|||
var bookUpdatePayload = {
|
||||
book: updatePayload
|
||||
}
|
||||
var success = await this.$axios.$patch(`/api/books/${this.audiobook.id}`, bookUpdatePayload).catch((error) => {
|
||||
var success = await this.$axios.$patch(`/api/items/${this.audiobook.id}`, bookUpdatePayload).catch((error) => {
|
||||
console.error('Failed to update', error)
|
||||
return false
|
||||
})
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
<div v-if="showLocalCovers" class="flex items-center justify-center">
|
||||
<template v-for="cover in localCovers">
|
||||
<div :key="cover.path" class="m-0.5 border-2 border-transparent hover:border-yellow-300 cursor-pointer" :class="cover.localPath === imageUrl ? 'border-yellow-300' : ''" @click="setCover(cover)">
|
||||
<div :key="cover.path" class="m-0.5 border-2 border-transparent hover:border-yellow-300 cursor-pointer" :class="cover.metadata.path === coverPath ? 'border-yellow-300' : ''" @click="setCover(cover)">
|
||||
<div class="h-24 bg-primary" :style="{ width: 96 / bookCoverAspectRatio + 'px' }">
|
||||
<img :src="`${cover.localPath}?token=${userToken}`" class="h-full w-full object-contain" />
|
||||
</div>
|
||||
|
|
@ -140,6 +140,9 @@ export default {
|
|||
media() {
|
||||
return this.libraryItem ? this.libraryItem.media || {} : {}
|
||||
},
|
||||
coverPath() {
|
||||
return this.media.coverPath
|
||||
},
|
||||
mediaMetadata() {
|
||||
return this.media.metadata || {}
|
||||
},
|
||||
|
|
@ -222,7 +225,7 @@ export default {
|
|||
this.updateCover(this.imageUrl)
|
||||
},
|
||||
async updateCover(cover) {
|
||||
if (cover === this.media.coverPath) {
|
||||
if (cover === this.coverPath) {
|
||||
console.warn('Cover has not changed..', cover)
|
||||
return
|
||||
}
|
||||
|
|
@ -299,23 +302,7 @@ export default {
|
|||
this.hasSearched = true
|
||||
},
|
||||
setCover(coverFile) {
|
||||
this.isProcessing = true
|
||||
this.$axios
|
||||
.$patch(`/api/books/${this.libraryItemId}/coverfile`, coverFile)
|
||||
.then((data) => {
|
||||
console.log('response data', data)
|
||||
if (data && typeof data === 'string') {
|
||||
this.$toast.success(data)
|
||||
}
|
||||
this.isProcessing = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to update', error)
|
||||
if (error.response && error.response.data) {
|
||||
this.$toast.error(error.response.data)
|
||||
}
|
||||
this.isProcessing = false
|
||||
})
|
||||
this.updateCover(coverFile.metadata.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,14 +84,22 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
quickMatch() {
|
||||
if (this.quickMatching) return
|
||||
if (!this.$refs.itemDetailsEdit) return
|
||||
|
||||
var { title, author } = this.$refs.itemDetailsEdit.getTitleAndAuthorName()
|
||||
if (!title) {
|
||||
this.$toast.error('Must have a title for quick match')
|
||||
return
|
||||
}
|
||||
this.quickMatching = true
|
||||
var matchOptions = {
|
||||
provider: this.libraryProvider,
|
||||
title: this.details.title,
|
||||
author: this.details.author !== this.book.author ? this.details.author : null
|
||||
title: title || null,
|
||||
author: author || null
|
||||
}
|
||||
this.$axios
|
||||
.$post(`/api/books/${this.libraryItemId}/match`, matchOptions)
|
||||
.$post(`/api/items/${this.libraryItemId}/match`, matchOptions)
|
||||
.then((res) => {
|
||||
this.quickMatching = false
|
||||
if (res.warning) {
|
||||
|
|
|
|||
|
|
@ -61,9 +61,9 @@
|
|||
<ui-checkbox v-model="selectedMatchUsage.publisher" />
|
||||
<ui-text-input-with-label v-model="selectedMatch.publisher" :disabled="!selectedMatchUsage.publisher" label="Publisher" class="flex-grow ml-4" />
|
||||
</div>
|
||||
<div v-if="selectedMatch.publishYear" class="flex items-center py-2">
|
||||
<ui-checkbox v-model="selectedMatchUsage.publishYear" />
|
||||
<ui-text-input-with-label v-model="selectedMatch.publishYear" :disabled="!selectedMatchUsage.publishYear" label="Publish Year" class="flex-grow ml-4" />
|
||||
<div v-if="selectedMatch.publishedYear" class="flex items-center py-2">
|
||||
<ui-checkbox v-model="selectedMatchUsage.publishedYear" />
|
||||
<ui-text-input-with-label v-model="selectedMatch.publishedYear" :disabled="!selectedMatchUsage.publishedYear" label="Published Year" class="flex-grow ml-4" />
|
||||
</div>
|
||||
|
||||
<div v-if="selectedMatch.series" class="flex items-center py-2">
|
||||
|
|
@ -117,7 +117,7 @@ export default {
|
|||
narrator: true,
|
||||
description: true,
|
||||
publisher: true,
|
||||
publishYear: true,
|
||||
publishedYear: true,
|
||||
series: true,
|
||||
volumeNumber: true,
|
||||
asin: true,
|
||||
|
|
@ -202,7 +202,7 @@ export default {
|
|||
narrator: true,
|
||||
description: true,
|
||||
publisher: true,
|
||||
publishYear: true,
|
||||
publishedYear: true,
|
||||
series: true,
|
||||
volumeNumber: true,
|
||||
asin: true,
|
||||
|
|
@ -247,7 +247,7 @@ export default {
|
|||
var coverPayload = {
|
||||
url: updatePayload.cover
|
||||
}
|
||||
var success = await this.$axios.$post(`/api/books/${this.libraryItemId}/cover`, coverPayload).catch((error) => {
|
||||
var success = await this.$axios.$post(`/api/items/${this.libraryItemId}/cover`, coverPayload).catch((error) => {
|
||||
console.error('Failed to update', error)
|
||||
return false
|
||||
})
|
||||
|
|
@ -264,7 +264,7 @@ export default {
|
|||
var bookUpdatePayload = {
|
||||
book: updatePayload
|
||||
}
|
||||
var success = await this.$axios.$patch(`/api/books/${this.libraryItemId}`, bookUpdatePayload).catch((error) => {
|
||||
var success = await this.$axios.$patch(`/api/items/${this.libraryItemId}`, bookUpdatePayload).catch((error) => {
|
||||
console.error('Failed to update', error)
|
||||
return false
|
||||
})
|
||||
|
|
|
|||
|
|
@ -47,22 +47,22 @@ export default {
|
|||
return null
|
||||
},
|
||||
abTitle() {
|
||||
return this.selectedAudiobook.book.title
|
||||
return this.selectedLibraryItem.media.metadata.title
|
||||
},
|
||||
abAuthor() {
|
||||
return this.selectedAudiobook.book.author
|
||||
return this.selectedLibraryItem.media.metadata.authorName
|
||||
},
|
||||
selectedAudiobook() {
|
||||
return this.$store.state.selectedAudiobook
|
||||
selectedLibraryItem() {
|
||||
return this.$store.state.selectedLibraryItem
|
||||
},
|
||||
libraryId() {
|
||||
return this.selectedAudiobook.libraryId
|
||||
return this.selectedLibraryItem.libraryId
|
||||
},
|
||||
folderId() {
|
||||
return this.selectedAudiobook.folderId
|
||||
return this.selectedLibraryItem.folderId
|
||||
},
|
||||
ebooks() {
|
||||
return this.selectedAudiobook.ebooks || []
|
||||
return this.selectedLibraryItem.media.ebooks || []
|
||||
},
|
||||
epubEbook() {
|
||||
return this.ebooks.find((eb) => eb.ext === '.epub')
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<p class="pr-4">Other Audio Files</p>
|
||||
<span class="bg-black-400 rounded-xl py-1 px-2 text-sm font-mono">{{ files.length }}</span>
|
||||
<div class="flex-grow" />
|
||||
<nuxt-link v-if="userCanUpdate" :to="`/audiobook/${audiobookId}/edit`" class="mr-4">
|
||||
<nuxt-link v-if="userCanUpdate" :to="`/item/${audiobookId}/edit`" class="mr-4">
|
||||
<ui-btn small color="primary">Manage Tracks</ui-btn>
|
||||
</nuxt-link>
|
||||
<div class="cursor-pointer h-10 w-10 rounded-full hover:bg-black-400 flex justify-center items-center duration-500" :class="showTracks ? 'transform rotate-180' : ''">
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<!-- <span class="bg-black-400 rounded-xl py-1 px-2 text-sm font-mono">{{ tracks.length }}</span> -->
|
||||
<div class="flex-grow" />
|
||||
<ui-btn small :color="showFullPath ? 'gray-600' : 'primary'" class="mr-2 hidden md:block" @click.stop="showFullPath = !showFullPath">Full Path</ui-btn>
|
||||
<nuxt-link v-if="userCanUpdate" :to="`/audiobook/${libraryItemId}/edit`" class="mr-2 md:mr-4">
|
||||
<nuxt-link v-if="userCanUpdate" :to="`/item/${libraryItemId}/edit`" class="mr-2 md:mr-4">
|
||||
<ui-btn small color="primary">Manage Tracks</ui-btn>
|
||||
</nuxt-link>
|
||||
<div class="cursor-pointer h-10 w-10 rounded-full hover:bg-black-400 flex justify-center items-center duration-500" :class="showTracks ? 'transform rotate-180' : ''">
|
||||
|
|
|
|||
|
|
@ -76,9 +76,6 @@ export default {
|
|||
currentUserId() {
|
||||
return this.$store.state.user.user.id
|
||||
},
|
||||
userStream() {
|
||||
return this.$store.state.streamAudiobook
|
||||
},
|
||||
usersOnline() {
|
||||
var usermap = {}
|
||||
this.$store.state.users.users.forEach((u) => (usermap[u.id] = { online: true, stream: u.stream }))
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<ui-multi-select-query-input ref="authorsSelect" v-model="details.authors" label="Authors" endpoint="authors/search" />
|
||||
</div>
|
||||
<div class="flex-grow px-1">
|
||||
<ui-text-input-with-label v-model="details.publishYear" type="number" label="Publish Year" />
|
||||
<ui-text-input-with-label v-model="details.publishedYear" type="number" label="Publish Year" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ export default {
|
|||
authors: [],
|
||||
narrators: [],
|
||||
series: [],
|
||||
publishYear: null,
|
||||
publishedYear: null,
|
||||
publisher: null,
|
||||
language: null,
|
||||
isbn: null,
|
||||
|
|
@ -173,6 +173,13 @@ export default {
|
|||
this.forceBlur()
|
||||
return this.checkForChanges()
|
||||
},
|
||||
getTitleAndAuthorName() {
|
||||
this.forceBlur()
|
||||
return {
|
||||
title: this.details.title,
|
||||
author: (this.details.authors || []).map((au) => au.name).join(', ')
|
||||
}
|
||||
},
|
||||
mapBatchDetails(batchDetails) {
|
||||
for (const key in batchDetails) {
|
||||
if (key === 'tags') {
|
||||
|
|
@ -317,7 +324,7 @@ export default {
|
|||
this.details.narrators = [...(this.mediaMetadata.narrators || [])]
|
||||
this.details.genres = [...(this.mediaMetadata.genres || [])]
|
||||
this.details.series = (this.mediaMetadata.series || []).map((se) => ({ ...se }))
|
||||
this.details.publishYear = this.mediaMetadata.publishYear
|
||||
this.details.publishedYear = this.mediaMetadata.publishedYear
|
||||
this.details.publisher = this.mediaMetadata.publisher || null
|
||||
this.details.language = this.mediaMetadata.language || null
|
||||
this.details.isbn = this.mediaMetadata.isbn || null
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue