mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-28 22:27:14 +02:00
Add download UI indicator, download progress, update bookshelf item to show local items and items matches with local item, remove item before downloading if already exists in file system
This commit is contained in:
+32
-25
@@ -35,7 +35,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
shelves: [],
|
||||
loading: false
|
||||
loading: false,
|
||||
localLibraryItems: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -55,8 +56,9 @@ export default {
|
||||
methods: {
|
||||
async getLocalMediaItemCategories() {
|
||||
var localMedia = await this.$db.getLocalLibraryItems()
|
||||
console.log('Got local library items', localMedia ? localMedia.length : 'N/A')
|
||||
if (!localMedia || !localMedia.length) return []
|
||||
console.log('Got local library items', localMedia.length)
|
||||
|
||||
var categories = []
|
||||
var books = []
|
||||
var podcasts = []
|
||||
@@ -84,9 +86,11 @@ export default {
|
||||
entities: podcasts
|
||||
})
|
||||
}
|
||||
|
||||
return categories
|
||||
},
|
||||
async fetchCategories() {
|
||||
async fetchCategories(from = null) {
|
||||
console.log('[4breadcrumbs] fetchCategories', from)
|
||||
if (this.loading) {
|
||||
console.log('Already loading categories')
|
||||
return
|
||||
@@ -94,36 +98,39 @@ export default {
|
||||
this.loading = true
|
||||
this.shelves = []
|
||||
|
||||
this.localLibraryItems = await this.$db.getLocalLibraryItems()
|
||||
|
||||
var localCategories = await this.getLocalMediaItemCategories()
|
||||
this.shelves = this.shelves.concat(localCategories)
|
||||
|
||||
if (this.user && this.currentLibraryId) {
|
||||
var categories = await this.$axios
|
||||
.$get(`/api/libraries/${this.currentLibraryId}/personalized?minified=1`)
|
||||
.then((data) => {
|
||||
return data
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to fetch categories', error)
|
||||
return []
|
||||
})
|
||||
var categories = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/personalized?minified=1`).catch((error) => {
|
||||
console.error('Failed to fetch categories', error)
|
||||
return []
|
||||
})
|
||||
categories = categories.map((cat) => {
|
||||
console.log('[breadcrumb] Personalized category from server', cat.type)
|
||||
if (cat.type == 'book' || cat.type == 'podcast') {
|
||||
// Map localLibraryItem to entities
|
||||
cat.entities = cat.entities.map((entity) => {
|
||||
var localLibraryItem = this.localLibraryItems.find((lli) => {
|
||||
return lli.libraryItemId == entity.id
|
||||
})
|
||||
if (localLibraryItem) {
|
||||
entity.localLibraryItem = localLibraryItem
|
||||
}
|
||||
return entity
|
||||
})
|
||||
}
|
||||
return cat
|
||||
})
|
||||
this.shelves = this.shelves.concat(categories)
|
||||
}
|
||||
this.loading = false
|
||||
},
|
||||
// async socketInit(isConnected) {
|
||||
// if (isConnected && this.currentLibraryId) {
|
||||
// console.log('Connected - Load from server')
|
||||
// await this.fetchCategories()
|
||||
// } else {
|
||||
// console.log('Disconnected - Reset to local storage')
|
||||
// this.shelves = this.downloadOnlyShelves
|
||||
// }
|
||||
// this.loading = false
|
||||
// },
|
||||
async libraryChanged(libid) {
|
||||
if (this.isSocketConnected && this.currentLibraryId) {
|
||||
await this.fetchCategories()
|
||||
if (this.currentLibraryId) {
|
||||
await this.fetchCategories('libraryChanged')
|
||||
}
|
||||
},
|
||||
audiobookAdded(audiobook) {
|
||||
@@ -181,7 +188,7 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.initListeners()
|
||||
this.fetchCategories()
|
||||
this.fetchCategories('mounted')
|
||||
// if (this.$server.initialized && this.currentLibraryId) {
|
||||
// this.fetchCategories()
|
||||
// } else {
|
||||
|
||||
+49
-18
@@ -36,27 +36,27 @@
|
||||
<span class="material-icons">auto_stories</span>
|
||||
<span v-if="!showPlay" class="px-2 text-base">Read {{ ebookFormat }}</span>
|
||||
</ui-btn>
|
||||
<ui-btn v-if="isConnected && showPlay && !isIos" color="primary" class="flex items-center justify-center" :padding-x="2" @click="downloadClick">
|
||||
<span class="material-icons">download</span>
|
||||
<!-- <span class="material-icons" :class="downloadObj ? 'animate-pulse' : ''">{{ downloadObj ? (isDownloading || isDownloadPreparing ? 'downloading' : 'download_done') : 'download' }}</span> -->
|
||||
</ui-btn>
|
||||
</div>
|
||||
<div v-else-if="(isConnected && (showPlay || showRead)) || isDownloadPlayable" class="flex mt-4 -mr-2">
|
||||
<div v-else-if="(user && (showPlay || showRead)) || hasLocal" class="flex mt-4 -mr-2">
|
||||
<ui-btn v-if="showPlay" color="success" :disabled="isPlaying" class="flex items-center justify-center flex-grow mr-2" :padding-x="4" @click="playClick">
|
||||
<span v-show="!isPlaying" class="material-icons">play_arrow</span>
|
||||
<span class="px-1 text-sm">{{ isPlaying ? (isStreaming ? 'Streaming' : 'Playing') : isDownloadPlayable ? 'Play local' : 'Play stream' }}</span>
|
||||
<span class="px-1 text-sm">{{ isPlaying ? (isStreaming ? 'Streaming' : 'Playing') : hasLocal ? 'Play Local' : 'Play Stream' }}</span>
|
||||
</ui-btn>
|
||||
<ui-btn v-if="showRead && isConnected" color="info" class="flex items-center justify-center mr-2" :class="showPlay ? '' : 'flex-grow'" :padding-x="2" @click="readBook">
|
||||
<ui-btn v-if="showRead && user" color="info" class="flex items-center justify-center mr-2" :class="showPlay ? '' : 'flex-grow'" :padding-x="2" @click="readBook">
|
||||
<span class="material-icons">auto_stories</span>
|
||||
<span v-if="!showPlay" class="px-2 text-base">Read {{ ebookFormat }}</span>
|
||||
</ui-btn>
|
||||
<ui-btn v-if="isConnected && showPlay && !isIos" color="primary" class="flex items-center justify-center" :padding-x="2" @click="downloadClick">
|
||||
<span class="material-icons">download</span>
|
||||
<!-- <span class="material-icons" :class="downloadObj ? 'animate-pulse' : ''">{{ downloadObj ? (isDownloading || isDownloadPreparing ? 'downloading' : 'download_done') : 'download' }}</span> -->
|
||||
<ui-btn v-if="user && showPlay && !isIos && !hasLocal" :color="downloadItem ? 'warning' : 'primary'" class="flex items-center justify-center" :padding-x="2" @click="downloadClick">
|
||||
<span class="material-icons" :class="downloadItem ? 'animate-pulse' : ''">{{ downloadItem ? 'downloading' : 'download' }}</span>
|
||||
</ui-btn>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="downloadItem" class="py-3">
|
||||
<p class="text-center text-lg">Downloading! ({{ Math.round(downloadItem.itemProgress * 100) }}%)</p>
|
||||
</div>
|
||||
|
||||
<div class="w-full py-4">
|
||||
<p>{{ description }}</p>
|
||||
</div>
|
||||
@@ -81,6 +81,14 @@ export default {
|
||||
console.error('Failed', error)
|
||||
return false
|
||||
})
|
||||
// Check if
|
||||
if (libraryItem) {
|
||||
var localLibraryItem = await app.$db.getLocalLibraryItemByLLId(libraryItemId)
|
||||
if (localLibraryItem) {
|
||||
console.log('Library item has local library item also', localLibraryItem.id)
|
||||
libraryItem.localLibraryItem = localLibraryItem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!libraryItem) {
|
||||
@@ -104,6 +112,14 @@ export default {
|
||||
isLocal() {
|
||||
return this.libraryItem.isLocal
|
||||
},
|
||||
hasLocal() {
|
||||
// Server library item has matching local library item
|
||||
return this.isLocal || this.libraryItem.localLibraryItem
|
||||
},
|
||||
localLibraryItem() {
|
||||
if (this.isLocal) return this.libraryItem
|
||||
return this.libraryItem.localLibraryItem || null
|
||||
},
|
||||
isConnected() {
|
||||
return this.$store.state.socketConnected
|
||||
},
|
||||
@@ -140,6 +156,9 @@ export default {
|
||||
size() {
|
||||
return this.media.size
|
||||
},
|
||||
user() {
|
||||
return this.$store.state.user.user
|
||||
},
|
||||
userToken() {
|
||||
return this.$store.getters['user/getToken']
|
||||
},
|
||||
@@ -179,9 +198,6 @@ export default {
|
||||
isIncomplete() {
|
||||
return this.libraryItem.isIncomplete
|
||||
},
|
||||
isDownloading() {
|
||||
return this.downloadObj ? this.downloadObj.isDownloading : false
|
||||
},
|
||||
showPlay() {
|
||||
return !this.isMissing && !this.isIncomplete && this.numTracks
|
||||
},
|
||||
@@ -195,12 +211,14 @@ export default {
|
||||
if (!this.ebookFile) return null
|
||||
return this.ebookFile.ebookFormat
|
||||
},
|
||||
isDownloadPlayable() {
|
||||
return false
|
||||
// return this.downloadObj && !this.isDownloading && !this.isDownloadPreparing
|
||||
},
|
||||
hasStoragePermission() {
|
||||
return this.$store.state.hasStoragePermission
|
||||
},
|
||||
downloadItem() {
|
||||
return this.$store.getters['globals/getDownloadItem'](this.libraryItemId)
|
||||
},
|
||||
downloadItems() {
|
||||
return this.$store.state.globals.downloadItems || []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -208,6 +226,8 @@ export default {
|
||||
this.$store.commit('openReader', this.libraryItem)
|
||||
},
|
||||
playClick() {
|
||||
// Todo: Allow playing local or streaming
|
||||
if (this.hasLocal) return this.$eventBus.$emit('play-item', this.localLibraryItem.id)
|
||||
this.$eventBus.$emit('play-item', this.libraryItem.id)
|
||||
},
|
||||
async clearProgressClick() {
|
||||
@@ -249,6 +269,9 @@ export default {
|
||||
this.download(localFolder)
|
||||
},
|
||||
downloadClick() {
|
||||
if (this.downloadItem) {
|
||||
return
|
||||
}
|
||||
this.download()
|
||||
},
|
||||
async download(selectedLocalFolder = null) {
|
||||
@@ -296,11 +319,17 @@ export default {
|
||||
async startDownload(localFolder) {
|
||||
console.log('Starting download to local folder', localFolder.name)
|
||||
var downloadRes = await AbsDownloader.downloadLibraryItem({ libraryItemId: this.libraryItemId, localFolderId: localFolder.id })
|
||||
if (downloadRes.error) {
|
||||
if (downloadRes && downloadRes.error) {
|
||||
var errorMsg = downloadRes.error || 'Unknown error'
|
||||
console.error('Download error', errorMsg)
|
||||
this.$toast.error(errorMsg)
|
||||
}
|
||||
},
|
||||
newLocalLibraryItem(item) {
|
||||
if (item.libraryItemId == this.libraryItemId) {
|
||||
console.log('New local library item', item.id)
|
||||
this.$set(this.libraryItem, 'localLibraryItem', item)
|
||||
}
|
||||
}
|
||||
// async prepareDownload() {
|
||||
// var audiobook = this.libraryItem
|
||||
@@ -429,6 +458,7 @@ export default {
|
||||
// }
|
||||
},
|
||||
mounted() {
|
||||
this.$eventBus.$on('new-local-library-item', this.newLocalLibraryItem)
|
||||
// if (!this.$server.socket) {
|
||||
// console.warn('Library Item Page mounted: Server socket not set')
|
||||
// } else {
|
||||
@@ -439,6 +469,7 @@ export default {
|
||||
// }
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$eventBus.$off('new-local-library-item', this.newLocalLibraryItem)
|
||||
// if (!this.$server.socket) {
|
||||
// console.warn('Library Item Page beforeDestroy: Server socket not set')
|
||||
// } else {
|
||||
|
||||
@@ -131,10 +131,29 @@ export default {
|
||||
if (this.shouldScan) {
|
||||
this.scanFolder()
|
||||
}
|
||||
},
|
||||
newLocalLibraryItem(item) {
|
||||
if (item.folderId == this.folderId) {
|
||||
console.log('New local library item', item.id)
|
||||
if (this.localLibraryItems.find((li) => li.id == item.id)) {
|
||||
console.warn('Item already added', item.id)
|
||||
return
|
||||
}
|
||||
|
||||
var _item = {
|
||||
...item,
|
||||
coverPathSrc: item.coverContentUrl ? Capacitor.convertFileSrc(item.coverContentUrl) : null
|
||||
}
|
||||
this.localLibraryItems.push(_item)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$eventBus.$on('new-local-library-item', this.newLocalLibraryItem)
|
||||
this.init()
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$eventBus.$off('new-local-library-item', this.newLocalLibraryItem)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
</div>
|
||||
<p class="text-lg mb-0.5 text-white text-opacity-75">Folder: {{ folderName }}</p>
|
||||
<p class="mb-4 text-xl">{{ mediaMetadata.title }}</p>
|
||||
|
||||
<p class="mb-4 text-xs text-gray-400">{{ libraryItemId || 'Not linked to server library item' }}</p>
|
||||
|
||||
<div v-if="isScanning" class="w-full text-center p-4">
|
||||
<p>Scanning...</p>
|
||||
</div>
|
||||
@@ -88,6 +91,9 @@ export default {
|
||||
},
|
||||
mediaType() {
|
||||
return this.localLibraryItem ? this.localLibraryItem.mediaType : null
|
||||
},
|
||||
libraryItemId() {
|
||||
return this.localLibraryItem ? this.localLibraryItem.libraryItemId : null
|
||||
},
|
||||
media() {
|
||||
return this.localLibraryItem ? this.localLibraryItem.media : null
|
||||
|
||||
Reference in New Issue
Block a user