mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-07-24 20:54:43 +02:00
Add:Continue listening shelf for offline books/episodes #112
This commit is contained in:
parent
7462eb3bc4
commit
0583ce617e
4 changed files with 71 additions and 20 deletions
|
@ -453,7 +453,7 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
initListeners() {
|
initListeners() {
|
||||||
var bookshelf = document.getElementById('bookshelf-wrapper')
|
const bookshelf = document.getElementById('bookshelf-wrapper')
|
||||||
if (bookshelf) {
|
if (bookshelf) {
|
||||||
bookshelf.addEventListener('scroll', this.scroll)
|
bookshelf.addEventListener('scroll', this.scroll)
|
||||||
}
|
}
|
||||||
|
@ -468,7 +468,7 @@ export default {
|
||||||
this.$socket.$on('items_added', this.libraryItemsAdded)
|
this.$socket.$on('items_added', this.libraryItemsAdded)
|
||||||
},
|
},
|
||||||
removeListeners() {
|
removeListeners() {
|
||||||
var bookshelf = document.getElementById('bookshelf-wrapper')
|
const bookshelf = document.getElementById('bookshelf-wrapper')
|
||||||
if (bookshelf) {
|
if (bookshelf) {
|
||||||
bookshelf.removeEventListener('scroll', this.scroll)
|
bookshelf.removeEventListener('scroll', this.scroll)
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,14 +45,15 @@ export default {
|
||||||
watch: {
|
watch: {
|
||||||
networkConnected(newVal) {
|
networkConnected(newVal) {
|
||||||
// Update shelves when network connect status changes
|
// Update shelves when network connect status changes
|
||||||
console.log(`Network changed to ${newVal} - fetch categories`)
|
console.log(`[categories] Network changed to ${newVal} - fetch categories`)
|
||||||
|
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
if (!this.lastServerFetch || Date.now() - this.lastServerFetch < 4000) {
|
setTimeout(() => {
|
||||||
setTimeout(() => {
|
// Using timeout because making this fetch as soon as network gets connected will often fail on Android
|
||||||
|
if (!this.lastServerFetch || Date.now() - this.lastServerFetch < 4000) {
|
||||||
this.fetchCategories()
|
this.fetchCategories()
|
||||||
}, 4000)
|
}
|
||||||
}
|
}, 4000)
|
||||||
} else {
|
} else {
|
||||||
this.fetchCategories()
|
this.fetchCategories()
|
||||||
}
|
}
|
||||||
|
@ -74,6 +75,9 @@ export default {
|
||||||
currentLibraryMediaType() {
|
currentLibraryMediaType() {
|
||||||
return this.$store.getters['libraries/getCurrentLibraryMediaType']
|
return this.$store.getters['libraries/getCurrentLibraryMediaType']
|
||||||
},
|
},
|
||||||
|
currentLibraryIsPodcast() {
|
||||||
|
return this.currentLibraryMediaType === 'podcast'
|
||||||
|
},
|
||||||
altViewEnabled() {
|
altViewEnabled() {
|
||||||
return this.$store.getters['getAltViewEnabled']
|
return this.$store.getters['getAltViewEnabled']
|
||||||
},
|
},
|
||||||
|
@ -83,22 +87,66 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getLocalMediaItemCategories() {
|
async getLocalMediaItemCategories() {
|
||||||
var localMedia = await this.$db.getLocalLibraryItems()
|
const localMedia = await this.$db.getLocalLibraryItems()
|
||||||
console.log('Got local library items', localMedia ? localMedia.length : 'N/A')
|
|
||||||
if (!localMedia || !localMedia.length) return []
|
if (!localMedia || !localMedia.length) return []
|
||||||
|
|
||||||
var categories = []
|
const categories = []
|
||||||
var books = []
|
const books = []
|
||||||
var podcasts = []
|
const podcasts = []
|
||||||
|
const booksContinueListening = []
|
||||||
|
const podcastEpisodesContinueListening = []
|
||||||
localMedia.forEach((item) => {
|
localMedia.forEach((item) => {
|
||||||
if (item.mediaType == 'book') {
|
if (item.mediaType == 'book') {
|
||||||
item.progress = this.localMediaProgress.find((lmp) => lmp.id === item.id)
|
item.progress = this.$store.getters['globals/getLocalMediaProgressById'](item.id)
|
||||||
|
if (item.progress && !item.progress.isFinished && item.progress.progress > 0) booksContinueListening.push(item)
|
||||||
books.push(item)
|
books.push(item)
|
||||||
} else if (item.mediaType == 'podcast') {
|
} else if (item.mediaType == 'podcast') {
|
||||||
|
const podcastEpisodeItemCloner = { ...item }
|
||||||
|
item.media.episodes = item.media.episodes.map((ep) => {
|
||||||
|
ep.progress = this.$store.getters['globals/getLocalMediaProgressById'](item.id, ep.id)
|
||||||
|
if (ep.progress && !ep.progress.isFinished && ep.progress.progress > 0) {
|
||||||
|
podcastEpisodesContinueListening.push({
|
||||||
|
...podcastEpisodeItemCloner,
|
||||||
|
recentEpisode: ep
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return ep
|
||||||
|
})
|
||||||
podcasts.push(item)
|
podcasts.push(item)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Local continue listening shelves, only shown offline
|
||||||
|
if (booksContinueListening.length) {
|
||||||
|
categories.push({
|
||||||
|
id: 'local-books-continue',
|
||||||
|
label: 'Continue Books',
|
||||||
|
type: 'book',
|
||||||
|
localOnly: true,
|
||||||
|
entities: booksContinueListening.sort((a, b) => {
|
||||||
|
if (a.progress && b.progress) {
|
||||||
|
return b.progress.lastUpdate > a.progress.lastUpdate ? 1 : -1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (podcastEpisodesContinueListening.length) {
|
||||||
|
categories.push({
|
||||||
|
id: 'local-episodes-continue',
|
||||||
|
label: 'Continue Episodes',
|
||||||
|
type: 'episode',
|
||||||
|
localOnly: true,
|
||||||
|
entities: podcastEpisodesContinueListening.sort((a, b) => {
|
||||||
|
if (a.recentEpisode.progress && b.recentEpisode.progress) {
|
||||||
|
return b.recentEpisode.progress.lastUpdate > a.recentEpisode.progress.lastUpdate ? 1 : -1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local books and local podcast shelves
|
||||||
if (books.length) {
|
if (books.length) {
|
||||||
categories.push({
|
categories.push({
|
||||||
id: 'local-books',
|
id: 'local-books',
|
||||||
|
@ -107,6 +155,9 @@ export default {
|
||||||
entities: books.sort((a, b) => {
|
entities: books.sort((a, b) => {
|
||||||
if (a.progress && a.progress.isFinished) return 1
|
if (a.progress && a.progress.isFinished) return 1
|
||||||
else if (b.progress && b.progress.isFinished) return -1
|
else if (b.progress && b.progress.isFinished) return -1
|
||||||
|
else if (a.progress && b.progress) {
|
||||||
|
return b.progress.lastUpdate > a.progress.lastUpdate ? 1 : -1
|
||||||
|
}
|
||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -124,9 +175,10 @@ export default {
|
||||||
},
|
},
|
||||||
async fetchCategories() {
|
async fetchCategories() {
|
||||||
if (this.loading) {
|
if (this.loading) {
|
||||||
console.log('Already loading categories')
|
console.log('[categories] Already loading categories')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
console.log(`[categories] fetchCategories networkConnected=${this.networkConnected}`)
|
||||||
this.loading = true
|
this.loading = true
|
||||||
this.shelves = []
|
this.shelves = []
|
||||||
|
|
||||||
|
@ -140,7 +192,7 @@ export default {
|
||||||
return []
|
return []
|
||||||
})
|
})
|
||||||
this.shelves = categories.map((cat) => {
|
this.shelves = categories.map((cat) => {
|
||||||
console.log('[breadcrumb] Personalized category from server', cat.type)
|
console.log('[categories] Personalized category from server', cat.type)
|
||||||
if (cat.type == 'book' || cat.type == 'podcast' || cat.type == 'episode') {
|
if (cat.type == 'book' || cat.type == 'podcast' || cat.type == 'episode') {
|
||||||
// Map localLibraryItem to entities
|
// Map localLibraryItem to entities
|
||||||
cat.entities = cat.entities.map((entity) => {
|
cat.entities = cat.entities.map((entity) => {
|
||||||
|
@ -157,11 +209,12 @@ export default {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Only add the local shelf with the same media type
|
// Only add the local shelf with the same media type
|
||||||
const localShelves = localCategories.filter((cat) => cat.type === this.currentLibraryMediaType)
|
const localShelves = localCategories.filter((cat) => cat.type === this.currentLibraryMediaType && !cat.localOnly)
|
||||||
this.shelves.push(...localShelves)
|
this.shelves.push(...localShelves)
|
||||||
} else {
|
} else {
|
||||||
// Offline only local
|
// Offline only local
|
||||||
this.shelves = localCategories
|
this.shelves = localCategories
|
||||||
|
this.lastServerFetch = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
@ -172,14 +225,12 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
audiobookAdded(audiobook) {
|
audiobookAdded(audiobook) {
|
||||||
console.log('Audiobook added', audiobook)
|
|
||||||
// TODO: Check if audiobook would be on this shelf
|
// TODO: Check if audiobook would be on this shelf
|
||||||
if (!this.search) {
|
if (!this.search) {
|
||||||
this.fetchCategories()
|
this.fetchCategories()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
audiobookUpdated(audiobook) {
|
audiobookUpdated(audiobook) {
|
||||||
console.log('Audiobook updated', audiobook)
|
|
||||||
this.shelves.forEach((shelf) => {
|
this.shelves.forEach((shelf) => {
|
||||||
if (shelf.type === 'books') {
|
if (shelf.type === 'books') {
|
||||||
shelf.entities = shelf.entities.map((ent) => {
|
shelf.entities = shelf.entities.map((ent) => {
|
||||||
|
|
|
@ -91,7 +91,7 @@ export const getters = {
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
async loadLocalMediaProgress({ state, commit }) {
|
async loadLocalMediaProgress({ state, commit }) {
|
||||||
var mediaProgress = await this.$db.getAllLocalMediaProgress()
|
const mediaProgress = await this.$db.getAllLocalMediaProgress()
|
||||||
commit('setLocalMediaProgress', mediaProgress)
|
commit('setLocalMediaProgress', mediaProgress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ export const actions = {
|
||||||
if (state.isNetworkListenerInit) return
|
if (state.isNetworkListenerInit) return
|
||||||
commit('setNetworkListenerInit', true)
|
commit('setNetworkListenerInit', true)
|
||||||
|
|
||||||
var status = await Network.getStatus()
|
const status = await Network.getStatus()
|
||||||
console.log('Network status', status)
|
console.log('Network status', status)
|
||||||
commit('setNetworkStatus', status)
|
commit('setNetworkStatus', status)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue