362 lines
11 KiB
JavaScript
362 lines
11 KiB
JavaScript
const { Constants } = require('../plugins/constants')
|
|
|
|
export const state = () => ({
|
|
libraries: [],
|
|
lastLoad: 0,
|
|
listeners: [],
|
|
currentLibraryId: null,
|
|
folders: [],
|
|
issues: 0,
|
|
folderLastUpdate: 0,
|
|
filterData: null,
|
|
numUserPlaylists: 0,
|
|
collections: [],
|
|
userPlaylists: [],
|
|
ereaderDevices: []
|
|
})
|
|
|
|
export const getters = {
|
|
getCurrentLibrary: (state) => {
|
|
return state.libraries.find((lib) => lib.id === state.currentLibraryId)
|
|
},
|
|
getCurrentLibraryName: (state, getters) => {
|
|
var currentLibrary = getters.getCurrentLibrary
|
|
if (!currentLibrary) return ''
|
|
return currentLibrary.name
|
|
},
|
|
getCurrentLibraryMediaType: (state, getters) => {
|
|
if (!getters.getCurrentLibrary) return null
|
|
return getters.getCurrentLibrary.mediaType
|
|
},
|
|
getSortedLibraries: (state) => () => {
|
|
return state.libraries.map((lib) => ({ ...lib })).sort((a, b) => a.displayOrder - b.displayOrder)
|
|
},
|
|
getLibraryProvider: (state) => (libraryId) => {
|
|
var library = state.libraries.find((l) => l.id === libraryId)
|
|
if (!library) return null
|
|
return library.provider
|
|
},
|
|
getNextAccessibleLibrary: (state, getters, rootState, rootGetters) => {
|
|
var librariesSorted = getters['getSortedLibraries']()
|
|
if (!librariesSorted.length) return null
|
|
|
|
var canAccessAllLibraries = rootGetters['user/getUserCanAccessAllLibraries']
|
|
var userAccessibleLibraries = rootGetters['user/getLibrariesAccessible']
|
|
if (canAccessAllLibraries) return librariesSorted[0]
|
|
librariesSorted = librariesSorted.filter((lib) => {
|
|
return userAccessibleLibraries.includes(lib.id)
|
|
})
|
|
if (!librariesSorted.length) return null
|
|
return librariesSorted[0]
|
|
},
|
|
getCurrentLibrarySettings: (state, getters) => {
|
|
if (!getters.getCurrentLibrary) return null
|
|
return getters.getCurrentLibrary.settings
|
|
},
|
|
getBookCoverAspectRatio: (state, getters) => {
|
|
if (!getters.getCurrentLibrarySettings || isNaN(getters.getCurrentLibrarySettings.coverAspectRatio)) return 1
|
|
return getters.getCurrentLibrarySettings.coverAspectRatio === Constants.BookCoverAspectRatio.STANDARD ? 1.6 : 1
|
|
},
|
|
getLibraryIsAudiobooksOnly: (state, getters) => {
|
|
return !!getters.getCurrentLibrarySettings?.audiobooksOnly
|
|
},
|
|
getLibraryEpubsAllowScriptedContent: (state, getters) => {
|
|
return !!getters.getCurrentLibrarySettings?.epubsAllowScriptedContent
|
|
},
|
|
getCollection: (state) => (id) => {
|
|
return state.collections.find((c) => c.id === id)
|
|
},
|
|
getPlaylist: (state) => (id) => {
|
|
return state.userPlaylists.find((p) => p.id === id)
|
|
}
|
|
}
|
|
|
|
export const actions = {
|
|
requestLibraryScan({ state, commit }, { libraryId, force }) {
|
|
return this.$axios.$post(`/api/libraries/${libraryId}/scan?force=${force ? 1 : 0}`)
|
|
},
|
|
loadFolders({ state, commit }) {
|
|
if (state.folders.length) {
|
|
const lastCheck = Date.now() - state.folderLastUpdate
|
|
if (lastCheck < 1000 * 5) {
|
|
// 5 seconds
|
|
// Folders up to date
|
|
return state.folders
|
|
}
|
|
}
|
|
commit('setFoldersLastUpdate')
|
|
|
|
return this.$axios
|
|
.$get('/api/filesystem')
|
|
.then((res) => {
|
|
commit('setFolders', res.directories)
|
|
return res.directories
|
|
})
|
|
.catch((error) => {
|
|
console.error('Failed to load dirs', error)
|
|
commit('setFolders', [])
|
|
return []
|
|
})
|
|
},
|
|
fetch({ state, dispatch, commit, rootState, rootGetters }, libraryId) {
|
|
if (!rootState.user || !rootState.user.user) {
|
|
console.error('libraries/fetch - User not set')
|
|
return false
|
|
}
|
|
|
|
var canUserAccessLibrary = rootGetters['user/getCanAccessLibrary'](libraryId)
|
|
if (!canUserAccessLibrary) {
|
|
console.warn('Access not allowed to library')
|
|
return false
|
|
}
|
|
|
|
const libraryChanging = state.currentLibraryId !== libraryId
|
|
return this.$axios
|
|
.$get(`/api/libraries/${libraryId}?include=filterdata`)
|
|
.then((data) => {
|
|
const library = data.library
|
|
const filterData = data.filterdata
|
|
const issues = data.issues || 0
|
|
const customMetadataProviders = data.customMetadataProviders || []
|
|
const numUserPlaylists = data.numUserPlaylists
|
|
|
|
dispatch('user/checkUpdateLibrarySortFilter', library.mediaType, { root: true })
|
|
|
|
if (libraryChanging) {
|
|
commit('setCollections', [])
|
|
commit('setUserPlaylists', [])
|
|
}
|
|
|
|
commit('addUpdate', library)
|
|
commit('setLibraryIssues', issues)
|
|
commit('setLibraryFilterData', filterData)
|
|
commit('setNumUserPlaylists', numUserPlaylists)
|
|
commit('scanners/setCustomMetadataProviders', customMetadataProviders, { root: true })
|
|
|
|
commit('setCurrentLibrary', libraryId)
|
|
return data
|
|
})
|
|
.catch((error) => {
|
|
console.error('Failed', error)
|
|
return false
|
|
})
|
|
},
|
|
// Return true if calling load
|
|
load({ state, commit, rootState }) {
|
|
if (!rootState.user || !rootState.user.user) {
|
|
console.error('libraries/load - User not set')
|
|
return false
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
this.$axios
|
|
.$get(`/api/libraries`)
|
|
.then((data) => {
|
|
commit('set', data.libraries)
|
|
commit('setLastLoad')
|
|
})
|
|
.catch((error) => {
|
|
console.error('Failed', error)
|
|
commit('set', [])
|
|
})
|
|
return true
|
|
}
|
|
}
|
|
|
|
export const mutations = {
|
|
setFolders(state, folders) {
|
|
state.folders = folders
|
|
},
|
|
setFoldersLastUpdate(state) {
|
|
state.folderLastUpdate = Date.now()
|
|
},
|
|
setLastLoad(state) {
|
|
state.lastLoad = Date.now()
|
|
},
|
|
setLibraryIssues(state, val) {
|
|
state.issues = val
|
|
},
|
|
setCurrentLibrary(state, val) {
|
|
state.currentLibraryId = val
|
|
},
|
|
set(state, libraries) {
|
|
state.libraries = libraries
|
|
state.listeners.forEach((listener) => {
|
|
listener.meth()
|
|
})
|
|
},
|
|
addUpdate(state, library) {
|
|
var index = state.libraries.findIndex((a) => a.id === library.id)
|
|
if (index >= 0) {
|
|
state.libraries.splice(index, 1, library)
|
|
} else {
|
|
state.libraries.push(library)
|
|
}
|
|
|
|
state.listeners.forEach((listener) => {
|
|
listener.meth()
|
|
})
|
|
},
|
|
remove(state, library) {
|
|
state.libraries = state.libraries.filter((a) => a.id !== library.id)
|
|
|
|
state.listeners.forEach((listener) => {
|
|
listener.meth()
|
|
})
|
|
},
|
|
addListener(state, listener) {
|
|
var index = state.listeners.findIndex((l) => l.id === listener.id)
|
|
if (index >= 0) state.listeners.splice(index, 1, listener)
|
|
else state.listeners.push(listener)
|
|
},
|
|
removeListener(state, listenerId) {
|
|
state.listeners = state.listeners.filter((l) => l.id !== listenerId)
|
|
},
|
|
setLibraryFilterData(state, filterData) {
|
|
state.filterData = filterData
|
|
},
|
|
setNumUserPlaylists(state, numUserPlaylists) {
|
|
state.numUserPlaylists = numUserPlaylists
|
|
},
|
|
removeSeriesFromFilterData(state, seriesId) {
|
|
if (!seriesId || !state.filterData) return
|
|
state.filterData.series = state.filterData.series.filter((se) => se.id !== seriesId)
|
|
},
|
|
updateFilterDataWithItem(state, libraryItem) {
|
|
if (!libraryItem || !state.filterData) return
|
|
if (state.currentLibraryId !== libraryItem.libraryId) return
|
|
/*
|
|
structure of filterData:
|
|
{
|
|
authors: [],
|
|
genres: [],
|
|
tags: [],
|
|
series: [],
|
|
narrators: [],
|
|
languages: [],
|
|
publishers: [],
|
|
publishedDecades: []
|
|
}
|
|
*/
|
|
const mediaMetadata = libraryItem.media.metadata
|
|
|
|
// Add/update book authors
|
|
if (mediaMetadata.authors?.length) {
|
|
mediaMetadata.authors.forEach((author) => {
|
|
const indexOf = state.filterData.authors.findIndex((au) => au.id === author.id)
|
|
if (indexOf >= 0) {
|
|
state.filterData.authors.splice(indexOf, 1, author)
|
|
} else {
|
|
state.filterData.authors.push(author)
|
|
state.filterData.authors.sort((a, b) => (a.name || '').localeCompare(b.name || ''))
|
|
}
|
|
})
|
|
}
|
|
|
|
// Add/update series
|
|
if (mediaMetadata.series?.length) {
|
|
mediaMetadata.series.forEach((series) => {
|
|
const indexOf = state.filterData.series.findIndex((se) => se.id === series.id)
|
|
if (indexOf >= 0) {
|
|
state.filterData.series.splice(indexOf, 1, { id: series.id, name: series.name })
|
|
} else {
|
|
state.filterData.series.push({ id: series.id, name: series.name })
|
|
state.filterData.series.sort((a, b) => (a.name || '').localeCompare(b.name || ''))
|
|
}
|
|
})
|
|
}
|
|
|
|
// Add genres
|
|
if (mediaMetadata.genres?.length) {
|
|
mediaMetadata.genres.forEach((genre) => {
|
|
if (!state.filterData.genres.includes(genre)) {
|
|
state.filterData.genres.push(genre)
|
|
state.filterData.genres.sort((a, b) => a.localeCompare(b))
|
|
}
|
|
})
|
|
}
|
|
|
|
// Add tags
|
|
if (libraryItem.media.tags?.length) {
|
|
libraryItem.media.tags.forEach((tag) => {
|
|
if (!state.filterData.tags.includes(tag)) {
|
|
state.filterData.tags.push(tag)
|
|
state.filterData.tags.sort((a, b) => a.localeCompare(b))
|
|
}
|
|
})
|
|
}
|
|
|
|
// Add narrators
|
|
if (mediaMetadata.narrators?.length) {
|
|
mediaMetadata.narrators.forEach((narrator) => {
|
|
if (!state.filterData.narrators.includes(narrator)) {
|
|
state.filterData.narrators.push(narrator)
|
|
state.filterData.narrators.sort((a, b) => a.localeCompare(b))
|
|
}
|
|
})
|
|
}
|
|
|
|
// Add publishers
|
|
if (mediaMetadata.publisher && !state.filterData.publishers.includes(mediaMetadata.publisher)) {
|
|
state.filterData.publishers.push(mediaMetadata.publisher)
|
|
state.filterData.publishers.sort((a, b) => a.localeCompare(b))
|
|
}
|
|
|
|
// Add publishedDecades
|
|
if (mediaMetadata.publishedYear && !isNaN(mediaMetadata.publishedYear)) {
|
|
const publishedYear = parseInt(mediaMetadata.publishedYear, 10)
|
|
const decade = (Math.floor(publishedYear / 10) * 10).toString()
|
|
if (!state.filterData.publishedDecades.includes(decade)) {
|
|
state.filterData.publishedDecades.push(decade)
|
|
state.filterData.publishedDecades.sort((a, b) => a - b)
|
|
}
|
|
}
|
|
|
|
// Add language
|
|
if (mediaMetadata.language && !state.filterData.languages.includes(mediaMetadata.language)) {
|
|
state.filterData.languages.push(mediaMetadata.language)
|
|
state.filterData.languages.sort((a, b) => a.localeCompare(b))
|
|
}
|
|
},
|
|
setCollections(state, collections) {
|
|
state.collections = collections
|
|
},
|
|
addUpdateCollection(state, collection) {
|
|
var index = state.collections.findIndex((c) => c.id === collection.id)
|
|
if (index >= 0) {
|
|
state.collections.splice(index, 1, collection)
|
|
} else {
|
|
state.collections.push(collection)
|
|
}
|
|
},
|
|
removeCollection(state, collection) {
|
|
state.collections = state.collections.filter((c) => c.id !== collection.id)
|
|
},
|
|
setUserPlaylists(state, playlists) {
|
|
state.userPlaylists = playlists
|
|
state.numUserPlaylists = playlists.length
|
|
},
|
|
addUpdateUserPlaylist(state, playlist) {
|
|
const index = state.userPlaylists.findIndex((p) => p.id === playlist.id)
|
|
if (index >= 0) {
|
|
state.userPlaylists.splice(index, 1, playlist)
|
|
} else {
|
|
state.userPlaylists.push(playlist)
|
|
state.numUserPlaylists++
|
|
}
|
|
},
|
|
removeUserPlaylist(state, playlist) {
|
|
state.userPlaylists = state.userPlaylists.filter((p) => p.id !== playlist.id)
|
|
state.numUserPlaylists = state.userPlaylists.length
|
|
},
|
|
setEReaderDevices(state, ereaderDevices) {
|
|
state.ereaderDevices = ereaderDevices
|
|
}
|
|
}
|