mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			367 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			367 lines
		
	
	
		
			12 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
 | |
|   },
 | |
|   loadLibraryFilterData({ state, commit, rootState }) {
 | |
|     if (!rootState.user || !rootState.user.user) {
 | |
|       console.error('libraries/loadLibraryFilterData - User not set')
 | |
|       return false
 | |
|     }
 | |
| 
 | |
|     this.$axios
 | |
|       .$get(`/api/libraries/${state.currentLibraryId}/filterdata`)
 | |
|       .then((data) => {
 | |
|         commit('setLibraryFilterData', data)
 | |
|       })
 | |
|       .catch((error) => {
 | |
|         console.error('Failed', error)
 | |
|         commit('setLibraryFilterData', null)
 | |
|       })
 | |
|   }
 | |
| }
 | |
| 
 | |
| 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: []
 | |
|     }
 | |
|     */
 | |
|     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 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
 | |
|   }
 | |
| }
 |