mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-08 21:08:43 +02:00
Finish lazy bookshelf,Fix:Async sql db,Fix:Load user progress
This commit is contained in:
@@ -80,9 +80,6 @@ export default {
|
||||
})
|
||||
this.$server.logout()
|
||||
this.$router.push('/connect')
|
||||
|
||||
this.$store.commit('audiobooks/reset')
|
||||
this.$store.dispatch('audiobooks/useDownloaded')
|
||||
},
|
||||
openAppStore() {
|
||||
AppUpdate.openAppStore()
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
<div class="flex">
|
||||
<div class="w-32">
|
||||
<div class="relative">
|
||||
<cards-book-cover :audiobook="audiobook" :download-cover="downloadedCover" :width="128" />
|
||||
<div class="absolute bottom-0 left-0 h-1.5 bg-yellow-400 shadow-sm" :style="{ width: 128 * progressPercent + 'px' }"></div>
|
||||
<covers-book-cover :audiobook="audiobook" :download-cover="downloadedCover" :width="128" :book-cover-aspect-ratio="bookCoverAspectRatio" />
|
||||
<div class="absolute bottom-0 left-0 h-1.5 bg-yellow-400 shadow-sm z-10" :style="{ width: 128 * progressPercent + 'px' }"></div>
|
||||
</div>
|
||||
<div class="flex my-4">
|
||||
<p v-if="numTracks" class="text-sm">{{ numTracks }} Tracks</p>
|
||||
@@ -64,7 +64,10 @@ export default {
|
||||
return false
|
||||
})
|
||||
} else {
|
||||
audiobook = store.getters['audiobooks/getAudiobook'](audiobookId)
|
||||
var download = store.getters['downloads/getDownload'](audiobookId)
|
||||
if (download) {
|
||||
audiobook = download.audiobook
|
||||
}
|
||||
}
|
||||
|
||||
if (!audiobook) {
|
||||
@@ -84,6 +87,9 @@ export default {
|
||||
isConnected() {
|
||||
return this.$store.state.socketConnected
|
||||
},
|
||||
bookCoverAspectRatio() {
|
||||
return this.$store.getters['getBookCoverAspectRatio']
|
||||
},
|
||||
audiobookId() {
|
||||
return this.audiobook.id
|
||||
},
|
||||
@@ -116,34 +122,20 @@ export default {
|
||||
size() {
|
||||
return this.audiobook.size
|
||||
},
|
||||
userAudiobooks() {
|
||||
return this.$store.state.user.user ? this.$store.state.user.user.audiobooks || {} : {}
|
||||
},
|
||||
userAudiobook() {
|
||||
return this.userAudiobooks[this.audiobookId] || null
|
||||
return this.$store.getters['user/getUserAudiobook'](this.audiobookId)
|
||||
},
|
||||
userToken() {
|
||||
return this.$store.getters['user/getToken']
|
||||
},
|
||||
localUserAudiobooks() {
|
||||
return this.$store.state.user.localUserAudiobooks || {}
|
||||
},
|
||||
localUserAudiobook() {
|
||||
return this.localUserAudiobooks[this.audiobookId] || null
|
||||
},
|
||||
mostRecentUserAudiobook() {
|
||||
if (!this.localUserAudiobook) return this.userAudiobook
|
||||
if (!this.userAudiobook) return this.localUserAudiobook
|
||||
return this.localUserAudiobook.lastUpdate > this.userAudiobook.lastUpdate ? this.localUserAudiobook : this.userAudiobook
|
||||
},
|
||||
userCurrentTime() {
|
||||
return this.mostRecentUserAudiobook ? this.mostRecentUserAudiobook.currentTime : 0
|
||||
return this.userAudiobook ? this.userAudiobook.currentTime : 0
|
||||
},
|
||||
userTimeRemaining() {
|
||||
return this.duration - this.userCurrentTime
|
||||
},
|
||||
progressPercent() {
|
||||
return this.mostRecentUserAudiobook ? this.mostRecentUserAudiobook.progress : 0
|
||||
return this.userAudiobook ? this.userAudiobook.progress : 0
|
||||
},
|
||||
isStreaming() {
|
||||
return this.$store.getters['isAudiobookStreaming'](this.audiobookId)
|
||||
@@ -242,16 +234,18 @@ export default {
|
||||
this.resettingProgress = false
|
||||
}
|
||||
},
|
||||
audiobookUpdated() {
|
||||
console.log('Audiobook Updated - Fetch full audiobook')
|
||||
this.$axios
|
||||
.$get(`/api/books/${this.audiobookId}`)
|
||||
.then((audiobook) => {
|
||||
this.audiobook = audiobook
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
})
|
||||
audiobookUpdated(audiobook) {
|
||||
if (audiobook.id === this.audiobookId) {
|
||||
console.log('Audiobook Updated - Fetch full audiobook')
|
||||
this.$axios
|
||||
.$get(`/api/books/${this.audiobookId}`)
|
||||
.then((audiobook) => {
|
||||
this.audiobook = audiobook
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
})
|
||||
}
|
||||
},
|
||||
downloadClick() {
|
||||
console.log('downloadClick ' + this.$server.connected + ' | ' + !!this.downloadObj)
|
||||
@@ -427,9 +421,8 @@ export default {
|
||||
this.$server.socket.on('download_ready', this.downloadReady)
|
||||
this.$server.socket.on('download_killed', this.downloadKilled)
|
||||
this.$server.socket.on('download_failed', this.downloadFailed)
|
||||
this.$server.socket.on('audiobook_updated', this.audiobookUpdated)
|
||||
}
|
||||
|
||||
this.$store.commit('audiobooks/addListener', { id: 'audiobook', audiobookId: this.audiobookId, meth: this.audiobookUpdated })
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.$server.socket) {
|
||||
@@ -438,9 +431,8 @@ export default {
|
||||
this.$server.socket.off('download_ready', this.downloadReady)
|
||||
this.$server.socket.off('download_killed', this.downloadKilled)
|
||||
this.$server.socket.off('download_failed', this.downloadFailed)
|
||||
this.$server.socket.off('audiobook_updated', this.audiobookUpdated)
|
||||
}
|
||||
|
||||
this.$store.commit('audiobooks/removeListener', 'audiobook')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -20,38 +20,7 @@ export default {
|
||||
computed: {
|
||||
isHome() {
|
||||
return this.$route.name === 'bookshelf'
|
||||
},
|
||||
currentLibrary() {
|
||||
return this.$store.getters['libraries/getCurrentLibrary']
|
||||
},
|
||||
currentLibraryName() {
|
||||
return this.currentLibrary ? this.currentLibrary.name : 'Main'
|
||||
},
|
||||
isSocketConnected() {
|
||||
return this.$store.state.socketConnected
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async loadCollections() {
|
||||
this.$store.dispatch('user/loadUserCollections')
|
||||
},
|
||||
socketConnected(isConnected) {
|
||||
// if (isConnected) {
|
||||
// console.log('Connected - Load from server')
|
||||
// this.loadAudiobooks()
|
||||
// if (this.$route.name === 'bookshelf-collections') this.loadCollections()
|
||||
// } else {
|
||||
// console.log('Disconnected - Reset to local storage')
|
||||
// this.$store.commit('audiobooks/reset')
|
||||
// this.$store.dispatch('audiobooks/useDownloaded')
|
||||
// }
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$server.on('connected', this.socketConnected)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$server.off('connected', this.socketConnected)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,52 +1,14 @@
|
||||
<template>
|
||||
<bookshelf-lazy-bookshelf page="collections" />
|
||||
<!-- <div class="w-full h-full">
|
||||
<template v-for="(shelf, index) in shelves">
|
||||
<bookshelf-group-shelf :key="shelf.id" group-type="collection" :groups="shelf.groups" :style="{ zIndex: shelves.length - index }" />
|
||||
</template>
|
||||
</div> -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
groupsPerRow: 2
|
||||
}
|
||||
return {}
|
||||
},
|
||||
watch: {},
|
||||
computed: {
|
||||
collections() {
|
||||
return this.$store.state.user.collections || []
|
||||
},
|
||||
shelves() {
|
||||
var shelves = []
|
||||
var shelf = {
|
||||
id: 0,
|
||||
groups: []
|
||||
}
|
||||
for (let i = 0; i < this.collections.length; i++) {
|
||||
var shelfNum = Math.floor((i + 1) / this.groupsPerRow)
|
||||
shelf.id = shelfNum
|
||||
shelf.groups.push(this.collections[i])
|
||||
|
||||
if ((i + 1) % this.groupsPerRow === 0) {
|
||||
shelves.push(shelf)
|
||||
shelf = {
|
||||
id: 0,
|
||||
groups: []
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shelf.groups.length) {
|
||||
shelves.push(shelf)
|
||||
}
|
||||
return shelves
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
mounted() {
|
||||
this.$store.dispatch('user/loadUserCollections')
|
||||
}
|
||||
computed: {},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
+101
-5
@@ -36,7 +36,13 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
books() {
|
||||
return this.$store.getters['downloads/getAudiobooks']
|
||||
return this.$store.getters['downloads/getDownloads'].map((dl) => {
|
||||
var download = { ...dl }
|
||||
var ab = { ...download.audiobook }
|
||||
delete download.audiobook
|
||||
ab.download = download
|
||||
return ab
|
||||
})
|
||||
},
|
||||
isSocketConnected() {
|
||||
return this.$store.state.socketConnected
|
||||
@@ -141,18 +147,108 @@ export default {
|
||||
} else {
|
||||
this.shelves = this.downloadOnlyShelves
|
||||
}
|
||||
},
|
||||
downloadsLoaded() {
|
||||
if (!this.isSocketConnected) {
|
||||
this.shelves = this.downloadOnlyShelves
|
||||
}
|
||||
},
|
||||
audiobookAdded(audiobook) {
|
||||
console.log('Audiobook added', audiobook)
|
||||
// TODO: Check if audiobook would be on this shelf
|
||||
if (!this.search) {
|
||||
this.fetchCategories()
|
||||
}
|
||||
},
|
||||
audiobookUpdated(audiobook) {
|
||||
console.log('Audiobook updated', audiobook)
|
||||
this.shelves.forEach((shelf) => {
|
||||
if (shelf.type === 'books') {
|
||||
shelf.entities = shelf.entities.map((ent) => {
|
||||
if (ent.id === audiobook.id) {
|
||||
return audiobook
|
||||
}
|
||||
return ent
|
||||
})
|
||||
} else if (shelf.type === 'series') {
|
||||
shelf.entities.forEach((ent) => {
|
||||
ent.books = ent.books.map((book) => {
|
||||
if (book.id === audiobook.id) return audiobook
|
||||
return book
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
removeBookFromShelf(audiobook) {
|
||||
this.shelves.forEach((shelf) => {
|
||||
if (shelf.type === 'books') {
|
||||
shelf.entities = shelf.entities.filter((ent) => {
|
||||
return ent.id !== audiobook.id
|
||||
})
|
||||
} else if (shelf.type === 'series') {
|
||||
shelf.entities.forEach((ent) => {
|
||||
ent.books = ent.books.filter((book) => {
|
||||
return book.id !== audiobook.id
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
audiobookRemoved(audiobook) {
|
||||
this.removeBookFromShelf(audiobook)
|
||||
},
|
||||
audiobooksAdded(audiobooks) {
|
||||
console.log('audiobooks added', audiobooks)
|
||||
// TODO: Check if audiobook would be on this shelf
|
||||
this.fetchCategories()
|
||||
},
|
||||
audiobooksUpdated(audiobooks) {
|
||||
audiobooks.forEach((ab) => {
|
||||
this.audiobookUpdated(ab)
|
||||
})
|
||||
},
|
||||
initListeners() {
|
||||
this.$server.on('initialized', this.socketInit)
|
||||
this.$eventBus.$on('library-changed', this.libraryChanged)
|
||||
this.$eventBus.$on('downloads-loaded', this.downloadsLoaded)
|
||||
|
||||
if (this.$server.socket) {
|
||||
this.$server.socket.on('audiobook_updated', this.audiobookUpdated)
|
||||
this.$server.socket.on('audiobook_added', this.audiobookAdded)
|
||||
this.$server.socket.on('audiobook_removed', this.audiobookRemoved)
|
||||
this.$server.socket.on('audiobooks_updated', this.audiobooksUpdated)
|
||||
this.$server.socket.on('audiobooks_added', this.audiobooksAdded)
|
||||
} else {
|
||||
console.error('Error socket not initialized')
|
||||
}
|
||||
},
|
||||
removeListeners() {
|
||||
this.$server.off('initialized', this.socketInit)
|
||||
this.$eventBus.$off('library-changed', this.libraryChanged)
|
||||
this.$eventBus.$off('downloads-loaded', this.downloadsLoaded)
|
||||
|
||||
if (this.$server.socket) {
|
||||
this.$server.socket.off('audiobook_updated', this.audiobookUpdated)
|
||||
this.$server.socket.off('audiobook_added', this.audiobookAdded)
|
||||
this.$server.socket.off('audiobook_removed', this.audiobookRemoved)
|
||||
this.$server.socket.off('audiobooks_updated', this.audiobooksUpdated)
|
||||
this.$server.socket.off('audiobooks_added', this.audiobooksAdded)
|
||||
} else {
|
||||
console.error('Error socket not initialized')
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$server.on('initialized', this.socketInit)
|
||||
this.$eventBus.$on('library-changed', this.libraryChanged)
|
||||
this.initListeners()
|
||||
if (this.$server.initialized) {
|
||||
this.fetchCategories()
|
||||
} else {
|
||||
this.shelves = this.downloadOnlyShelves
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$server.off('initialized', this.socketInit)
|
||||
this.$eventBus.$off('library-changed', this.libraryChanged)
|
||||
this.removeListeners()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,11 +1,5 @@
|
||||
<template>
|
||||
<bookshelf-lazy-bookshelf page="series" />
|
||||
<!-- <div class="w-full h-full">
|
||||
<template v-for="(shelf, index) in shelves">
|
||||
<bookshelf-group-shelf v-if="!selectedSeriesName" :key="shelf.id" group-type="series" :groups="shelf.groups" :style="{ zIndex: shelves.length - index }" />
|
||||
<bookshelf-library-shelf v-else :key="shelf.id" :books="shelf.books" :style="{ zIndex: shelves.length - index }" />
|
||||
</template>
|
||||
</div> -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="w-full h-full overflow-y-auto px-2 py-6 md:p-8">
|
||||
<div class="w-full flex justify-center md:block sm:w-32 md:w-52" style="min-width: 240px">
|
||||
<div class="relative" style="height: fit-content">
|
||||
<cards-collection-cover :book-items="bookItems" :width="240" :height="120 * 1.6" />
|
||||
<covers-collection-cover :book-items="bookItems" :width="240" :height="120 * bookCoverAspectRatio" :book-cover-aspect-ratio="bookCoverAspectRatio" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow px-2 py-6 md:py-0 md:px-10">
|
||||
@@ -48,15 +48,11 @@ export default {
|
||||
})
|
||||
|
||||
if (!collection) {
|
||||
return redirect('/')
|
||||
return redirect('/bookshelf')
|
||||
}
|
||||
|
||||
store.commit('user/addUpdateCollection', collection)
|
||||
collection.books.forEach((book) => {
|
||||
store.commit('audiobooks/addUpdate', book)
|
||||
})
|
||||
return {
|
||||
collectionId: collection.id
|
||||
collection
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -65,6 +61,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
bookCoverAspectRatio() {
|
||||
return this.$store.getters['getBookCoverAspectRatio']
|
||||
},
|
||||
bookItems() {
|
||||
return this.collection.books || []
|
||||
},
|
||||
@@ -74,9 +73,6 @@ export default {
|
||||
description() {
|
||||
return this.collection.description || ''
|
||||
},
|
||||
collection() {
|
||||
return this.$store.getters['user/getCollection'](this.collectionId)
|
||||
},
|
||||
playableBooks() {
|
||||
return this.bookItems.filter((book) => {
|
||||
return !book.isMissing && !book.isIncomplete && book.numTracks
|
||||
|
||||
@@ -161,8 +161,6 @@ export default {
|
||||
|
||||
await this.searchFolder()
|
||||
|
||||
// var audiobooks = this.$store.state.audiobooks.audiobooks || []
|
||||
// if (audiobooks.length) {
|
||||
if (this.isSocketConnected) {
|
||||
this.$store.dispatch('downloads/linkOrphanDownloads')
|
||||
}
|
||||
@@ -240,7 +238,6 @@ export default {
|
||||
AudioDownloader.addListener('onDownloadProgress', this.onDownloadProgress)
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
beforeDestroy() {
|
||||
AudioDownloader.removeListener('onDownloadProgress', this.onDownloadProgress)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user