mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-24 12:49:38 +00:00
Lazy bookshelf finalized
This commit is contained in:
parent
5c92aef048
commit
1ef9a689bc
53 changed files with 914 additions and 795 deletions
|
|
@ -1,159 +1,17 @@
|
|||
import { sort } from '@/assets/fastSort'
|
||||
import { decode } from '@/plugins/init.client'
|
||||
|
||||
const STANDARD_GENRES = ['Adventure', 'Autobiography', 'Biography', 'Childrens', 'Comedy', 'Crime', 'Dystopian', 'Fantasy', 'Fiction', 'Health', 'History', 'Horror', 'Mystery', 'New Adult', 'Nonfiction', 'Philosophy', 'Politics', 'Religion', 'Romance', 'Sci-Fi', 'Self-Help', 'Short Story', 'Technology', 'Thriller', 'True Crime', 'Western', 'Young Adult']
|
||||
|
||||
export const state = () => ({
|
||||
audiobooks: [],
|
||||
loadedLibraryId: '',
|
||||
lastLoad: 0,
|
||||
listeners: [],
|
||||
genres: [...STANDARD_GENRES],
|
||||
tags: [],
|
||||
series: [],
|
||||
keywordFilter: null,
|
||||
selectedSeries: null,
|
||||
libraryPage: null,
|
||||
searchResults: {},
|
||||
searchResultAudiobooks: []
|
||||
selectedSeries: null
|
||||
})
|
||||
|
||||
export const getters = {
|
||||
getAudiobook: (state) => id => {
|
||||
return state.audiobooks.find(ab => ab.id === id)
|
||||
},
|
||||
getAudiobooksWithIssues: (state) => {
|
||||
return state.audiobooks.filter(ab => {
|
||||
return ab.hasMissingParts || ab.hasInvalidParts || ab.isMissing || ab.isIncomplete
|
||||
})
|
||||
},
|
||||
getEntitiesShowing: (state, getters, rootState, rootGetters) => () => {
|
||||
if (!state.libraryPage) {
|
||||
return getters.getFiltered()
|
||||
} else if (state.libraryPage === 'search') {
|
||||
return state.searchResultAudiobooks
|
||||
} else if (state.libraryPage === 'series') {
|
||||
var series = getters.getSeriesGroups()
|
||||
if (state.selectedSeries) {
|
||||
var _series = series.find(__series => __series.name === state.selectedSeries)
|
||||
if (!_series) return []
|
||||
return _series.books || []
|
||||
}
|
||||
return series
|
||||
}
|
||||
return []
|
||||
},
|
||||
getFiltered: (state, getters, rootState, rootGetters) => () => {
|
||||
var filtered = state.audiobooks
|
||||
var settings = rootState.user.settings || {}
|
||||
var filterBy = settings.filterBy || ''
|
||||
|
||||
var searchGroups = ['genres', 'tags', 'series', 'authors', 'progress', 'narrators']
|
||||
var group = searchGroups.find(_group => filterBy.startsWith(_group + '.'))
|
||||
if (group) {
|
||||
var filterVal = filterBy.replace(`${group}.`, '')
|
||||
var filter = decode(filterVal)
|
||||
if (group === 'genres') filtered = filtered.filter(ab => ab.book && ab.book.genres.includes(filter))
|
||||
else if (group === 'tags') filtered = filtered.filter(ab => ab.tags.includes(filter))
|
||||
else if (group === 'series') {
|
||||
if (filter === 'No Series') filtered = filtered.filter(ab => ab.book && !ab.book.series)
|
||||
else filtered = filtered.filter(ab => ab.book && ab.book.series === filter)
|
||||
}
|
||||
else if (group === 'authors') filtered = filtered.filter(ab => ab.book && ab.book.authorFL && ab.book.authorFL.split(', ').includes(filter))
|
||||
else if (group === 'narrators') filtered = filtered.filter(ab => ab.book && ab.book.narratorFL && ab.book.narratorFL.split(', ').includes(filter))
|
||||
else if (group === 'progress') {
|
||||
filtered = filtered.filter(ab => {
|
||||
var userAudiobook = rootGetters['user/getUserAudiobook'](ab.id)
|
||||
var isRead = userAudiobook && userAudiobook.isRead
|
||||
if (filter === 'Read' && isRead) return true
|
||||
if (filter === 'Unread' && !isRead) return true
|
||||
if (filter === 'In Progress' && (userAudiobook && !userAudiobook.isRead && userAudiobook.progress > 0)) return true
|
||||
return false
|
||||
})
|
||||
}
|
||||
} else if (filterBy === 'issues') {
|
||||
filtered = filtered.filter(ab => {
|
||||
return ab.hasMissingParts || ab.hasInvalidParts || ab.isMissing || ab.isIncomplete
|
||||
})
|
||||
}
|
||||
|
||||
if (state.keywordFilter) {
|
||||
const keywordFilterKeys = ['title', 'subtitle', 'author', 'series', 'narrator']
|
||||
const keyworkFilter = state.keywordFilter.toLowerCase()
|
||||
return filtered.filter(ab => {
|
||||
if (!ab.book) return false
|
||||
return !!keywordFilterKeys.find(key => (ab.book[key] && ab.book[key].toLowerCase().includes(keyworkFilter)))
|
||||
})
|
||||
}
|
||||
return filtered
|
||||
},
|
||||
getFilteredAndSorted: (state, getters, rootState) => () => {
|
||||
var settings = rootState.user.settings
|
||||
var direction = settings.orderDesc ? 'desc' : 'asc'
|
||||
|
||||
var filtered = getters.getFiltered()
|
||||
|
||||
var orderByNumber = settings.orderBy === 'book.volumeNumber'
|
||||
return sort(filtered)[direction]((ab) => {
|
||||
// Supports dot notation strings i.e. "book.title"
|
||||
var value = settings.orderBy.split('.').reduce((a, b) => a[b], ab)
|
||||
if (orderByNumber && !isNaN(value)) return Number(value)
|
||||
return value
|
||||
})
|
||||
},
|
||||
getSeriesGroups: (state, getters, rootState) => () => {
|
||||
var series = {}
|
||||
state.audiobooks.forEach((audiobook) => {
|
||||
if (audiobook.book && audiobook.book.series) {
|
||||
if (series[audiobook.book.series]) {
|
||||
var bookLastUpdate = audiobook.book.lastUpdate
|
||||
if (bookLastUpdate > series[audiobook.book.series].lastUpdate) series[audiobook.book.series].lastUpdate = bookLastUpdate
|
||||
series[audiobook.book.series].books.push(audiobook)
|
||||
} else {
|
||||
series[audiobook.book.series] = {
|
||||
type: 'series',
|
||||
name: audiobook.book.series || '',
|
||||
books: [audiobook],
|
||||
lastUpdate: audiobook.book.lastUpdate
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
var seriesArray = Object.values(series).map((_series) => {
|
||||
_series.books = sort(_series.books)['asc']((ab) => {
|
||||
return ab.book && ab.book.volumeNumber && !isNaN(ab.book.volumeNumber) ? Number(ab.book.volumeNumber) : null
|
||||
})
|
||||
return _series
|
||||
})
|
||||
if (state.keywordFilter) {
|
||||
const keywordFilter = state.keywordFilter.toLowerCase()
|
||||
return seriesArray.filter((_series) => _series.name.toLowerCase().includes(keywordFilter))
|
||||
}
|
||||
return seriesArray
|
||||
},
|
||||
getUniqueAuthors: (state) => {
|
||||
var abAuthors = []
|
||||
state.audiobooks.forEach((ab) => {
|
||||
if (ab.book && ab.book.authorFL) {
|
||||
abAuthors = abAuthors.concat(ab.book.authorFL.split(', '))
|
||||
}
|
||||
})
|
||||
return [...new Set(abAuthors)].sort((a, b) => a.toLowerCase() < b.toLowerCase() ? -1 : 1)
|
||||
},
|
||||
getUniqueNarrators: (state) => {
|
||||
var narrators = []
|
||||
state.audiobooks.forEach((ab) => {
|
||||
if (ab.book && ab.book.narratorFL) {
|
||||
narrators = narrators.concat(ab.book.narratorFL.split(', '))
|
||||
}
|
||||
})
|
||||
return [...new Set(narrators)].sort((a, b) => a.toLowerCase() < b.toLowerCase() ? -1 : 1)
|
||||
},
|
||||
getGenresUsed: (state) => {
|
||||
var _genres = []
|
||||
state.audiobooks.filter(ab => !!(ab.book && ab.book.genres)).forEach(ab => _genres = _genres.concat(ab.book.genres))
|
||||
return [...new Set(_genres)].sort((a, b) => a.toLowerCase() < b.toLowerCase() ? -1 : 1)
|
||||
},
|
||||
getBookCoverSrc: (state, getters, rootState, rootGetters) => (bookItem, placeholder = '/book_placeholder.jpg') => {
|
||||
if (!bookItem) return placeholder
|
||||
var book = bookItem.book
|
||||
|
|
@ -192,60 +50,16 @@ export const getters = {
|
|||
}
|
||||
|
||||
export const actions = {
|
||||
// Return true if calling load
|
||||
load({ state, commit, rootState }) {
|
||||
if (!rootState.user || !rootState.user.user) {
|
||||
console.error('audiobooks/load - User not set')
|
||||
return false
|
||||
}
|
||||
|
||||
var currentLibraryId = rootState.libraries.currentLibraryId
|
||||
|
||||
if (currentLibraryId === state.loadedLibraryId) {
|
||||
// Don't load again if already loaded in the last 5 minutes
|
||||
var lastLoadDiff = Date.now() - state.lastLoad
|
||||
if (lastLoadDiff < 5 * 60 * 1000) {
|
||||
// Already up to date
|
||||
return false
|
||||
}
|
||||
}
|
||||
commit('setLoadedLibrary', currentLibraryId)
|
||||
|
||||
this.$axios
|
||||
.$get(`/api/libraries/${currentLibraryId}/books`)
|
||||
.then((data) => {
|
||||
commit('set', data)
|
||||
commit('setLastLoad')
|
||||
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
commit('set', [])
|
||||
})
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
setLoadedLibrary(state, val) {
|
||||
state.loadedLibraryId = val
|
||||
},
|
||||
setLastLoad(state) {
|
||||
state.lastLoad = Date.now()
|
||||
},
|
||||
setKeywordFilter(state, val) {
|
||||
state.keywordFilter = val
|
||||
},
|
||||
setSelectedSeries(state, val) {
|
||||
state.selectedSeries = val
|
||||
},
|
||||
setLibraryPage(state, val) {
|
||||
state.libraryPage = val
|
||||
},
|
||||
setSearchResults(state, val) {
|
||||
state.searchResults = val
|
||||
state.searchResultAudiobooks = val && val.audiobooks ? val.audiobooks.map(ab => ab.audiobook) : []
|
||||
},
|
||||
set(state, audiobooks) {
|
||||
// GENRES
|
||||
var genres = [...state.genres]
|
||||
|
|
@ -382,5 +196,12 @@ export const mutations = {
|
|||
},
|
||||
removeListener(state, listenerId) {
|
||||
state.listeners = state.listeners.filter(l => l.id !== listenerId)
|
||||
},
|
||||
audiobookUpdated(state, audiobook) {
|
||||
state.listeners.forEach((listener) => {
|
||||
if (!listener.audiobookId || listener.audiobookId === audiobook.id) {
|
||||
listener.meth()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ export const state = () => ({
|
|||
listeners: [],
|
||||
currentLibraryId: 'main',
|
||||
folders: [],
|
||||
issues: 0,
|
||||
folderLastUpdate: 0,
|
||||
filterData: null
|
||||
})
|
||||
|
|
@ -53,7 +54,6 @@ export const actions = {
|
|||
console.warn('Access not allowed to library')
|
||||
return false
|
||||
}
|
||||
|
||||
// var library = state.libraries.find(lib => lib.id === libraryId)
|
||||
// if (library) {
|
||||
// commit('setCurrentLibrary', libraryId)
|
||||
|
|
@ -65,7 +65,9 @@ export const actions = {
|
|||
.then((data) => {
|
||||
var library = data.library
|
||||
var filterData = data.filterdata
|
||||
var issues = data.issues || 0
|
||||
commit('addUpdate', library)
|
||||
commit('setLibraryIssues', issues)
|
||||
commit('setLibraryFilterData', filterData)
|
||||
commit('setCurrentLibrary', libraryId)
|
||||
return data
|
||||
|
|
@ -129,6 +131,9 @@ export const mutations = {
|
|||
setLastLoad(state) {
|
||||
state.lastLoad = Date.now()
|
||||
},
|
||||
setLibraryIssues(state, val) {
|
||||
state.issues = val
|
||||
},
|
||||
setCurrentLibrary(state, val) {
|
||||
state.currentLibraryId = val
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue