mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			589 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			589 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <div class="text-white max-h-screen h-screen overflow-hidden bg-bg">
 | |
|     <app-appbar />
 | |
| 
 | |
|     <app-side-rail v-if="isShowingSideRail" class="hidden md:block" />
 | |
|     <div id="app-content" class="h-full" :class="{ 'has-siderail': isShowingSideRail }">
 | |
|       <Nuxt :key="currentLang" />
 | |
|     </div>
 | |
| 
 | |
|     <app-stream-container ref="streamContainer" />
 | |
| 
 | |
|     <modals-item-edit-modal />
 | |
|     <modals-collections-add-create-modal />
 | |
|     <modals-collections-edit-modal />
 | |
|     <modals-playlists-add-create-modal />
 | |
|     <modals-playlists-edit-modal />
 | |
|     <modals-podcast-edit-episode />
 | |
|     <modals-podcast-view-episode />
 | |
|     <modals-authors-edit-modal />
 | |
|     <modals-batch-quick-match-model />
 | |
|     <modals-rssfeed-open-close-modal />
 | |
|     <modals-raw-cover-preview-modal />
 | |
|     <prompt-confirm />
 | |
|     <readers-reader />
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| export default {
 | |
|   middleware: 'authenticated',
 | |
|   data() {
 | |
|     return {
 | |
|       socket: null,
 | |
|       isSocketConnected: false,
 | |
|       isFirstSocketConnection: true,
 | |
|       socketConnectionToastId: null,
 | |
|       currentLang: null,
 | |
|       multiSessionOtherSessionId: null, // Used for multiple sessions open warning toast
 | |
|       multiSessionCurrentSessionId: null // Used for multiple sessions open warning toast
 | |
|     }
 | |
|   },
 | |
|   watch: {
 | |
|     $route(newVal) {
 | |
|       if (this.$store.state.showEditModal) {
 | |
|         this.$store.commit('setShowEditModal', false)
 | |
|       }
 | |
| 
 | |
|       this.$store.commit('globals/resetSelectedMediaItems', [])
 | |
|       this.updateBodyClass()
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     user() {
 | |
|       return this.$store.state.user.user
 | |
|     },
 | |
|     isCasting() {
 | |
|       return this.$store.state.globals.isCasting
 | |
|     },
 | |
|     currentLibraryId() {
 | |
|       return this.$store.state.libraries.currentLibraryId
 | |
|     },
 | |
|     isShowingSideRail() {
 | |
|       if (!this.$route.name) return false
 | |
|       return !this.$route.name.startsWith('config') && this.currentLibraryId
 | |
|     },
 | |
|     isShowingToolbar() {
 | |
|       return this.isShowingSideRail && this.$route.name !== 'upload' && this.$route.name !== 'account'
 | |
|     },
 | |
|     appContentMarginLeft() {
 | |
|       return this.isShowingSideRail ? 80 : 0
 | |
|     }
 | |
|   },
 | |
|   methods: {
 | |
|     updateBodyClass() {
 | |
|       if (this.isShowingToolbar) {
 | |
|         document.body.classList.remove('no-bars', 'app-bar')
 | |
|         document.body.classList.add('app-bar-and-toolbar')
 | |
|       } else {
 | |
|         document.body.classList.remove('no-bars', 'app-bar-and-toolbar')
 | |
|         document.body.classList.add('app-bar')
 | |
|       }
 | |
|     },
 | |
|     updateSocketConnectionToast(content, type, timeout) {
 | |
|       if (this.socketConnectionToastId !== null && this.socketConnectionToastId !== undefined) {
 | |
|         this.$toast.update(this.socketConnectionToastId, { content: content, options: { timeout: timeout, type: type, closeButton: false, position: 'bottom-center', onClose: () => null, closeOnClick: timeout !== null } }, false)
 | |
|       } else {
 | |
|         this.socketConnectionToastId = this.$toast[type](content, { position: 'bottom-center', timeout: timeout, closeButton: false, closeOnClick: timeout !== null })
 | |
|       }
 | |
|     },
 | |
|     connect() {
 | |
|       console.log('[SOCKET] Connected')
 | |
|       var token = this.$store.getters['user/getToken']
 | |
|       this.socket.emit('auth', token)
 | |
| 
 | |
|       if (!this.isFirstSocketConnection || this.socketConnectionToastId !== null) {
 | |
|         this.updateSocketConnectionToast(this.$strings.ToastSocketConnected, 'success', 5000)
 | |
|       }
 | |
|       this.isFirstSocketConnection = false
 | |
|       this.isSocketConnected = true
 | |
|     },
 | |
|     connectError() {
 | |
|       console.error('[SOCKET] connect error')
 | |
|       this.updateSocketConnectionToast(this.$strings.ToastSocketFailedToConnect, 'error', null)
 | |
|     },
 | |
|     disconnect() {
 | |
|       console.log('[SOCKET] Disconnected')
 | |
|       this.isSocketConnected = false
 | |
|       this.updateSocketConnectionToast(this.$strings.ToastSocketDisconnected, 'error', null)
 | |
|     },
 | |
|     reconnect() {
 | |
|       console.error('[SOCKET] reconnected')
 | |
|     },
 | |
|     reconnectAttempt(val) {
 | |
|       console.log(`[SOCKET] reconnect attempt ${val}`)
 | |
|     },
 | |
|     reconnectError() {
 | |
|       // console.error('[SOCKET] reconnect error')
 | |
|     },
 | |
|     reconnectFailed() {
 | |
|       console.error('[SOCKET] reconnect failed')
 | |
|     },
 | |
|     init(payload) {
 | |
|       console.log('Init Payload', payload)
 | |
| 
 | |
|       if (payload.usersOnline) {
 | |
|         this.$store.commit('users/setUsersOnline', payload.usersOnline)
 | |
|       }
 | |
| 
 | |
|       this.$eventBus.$emit('socket_init')
 | |
|     },
 | |
|     streamOpen(stream) {
 | |
|       if (this.$refs.streamContainer) this.$refs.streamContainer.streamOpen(stream)
 | |
|     },
 | |
|     streamClosed(streamId) {
 | |
|       if (this.$refs.streamContainer) this.$refs.streamContainer.streamClosed(streamId)
 | |
|     },
 | |
|     streamProgress(data) {
 | |
|       if (this.$refs.streamContainer) this.$refs.streamContainer.streamProgress(data)
 | |
|     },
 | |
|     streamReady() {
 | |
|       if (this.$refs.streamContainer) this.$refs.streamContainer.streamReady()
 | |
|     },
 | |
|     streamReset(payload) {
 | |
|       if (this.$refs.streamContainer) this.$refs.streamContainer.streamReset(payload)
 | |
|     },
 | |
|     streamError({ id, errorMessage }) {
 | |
|       this.$toast.error(`Stream Failed: ${errorMessage}`)
 | |
|       if (this.$refs.streamContainer) this.$refs.streamContainer.streamError(id)
 | |
|     },
 | |
|     libraryAdded(library) {
 | |
|       this.$store.commit('libraries/addUpdate', library)
 | |
|     },
 | |
|     libraryUpdated(library) {
 | |
|       this.$store.commit('libraries/addUpdate', library)
 | |
|     },
 | |
|     async libraryRemoved(library) {
 | |
|       console.log('Library removed', library)
 | |
|       this.$store.commit('libraries/remove', library)
 | |
| 
 | |
|       // When removed currently selected library then set next accessible library
 | |
|       const currLibraryId = this.currentLibraryId
 | |
|       if (currLibraryId === library.id) {
 | |
|         var nextLibrary = this.$store.getters['libraries/getNextAccessibleLibrary']
 | |
|         if (nextLibrary) {
 | |
|           await this.$store.dispatch('libraries/fetch', nextLibrary.id)
 | |
| 
 | |
|           if (this.$route.name.startsWith('config')) {
 | |
|             // No need to refresh
 | |
|           } else if (this.$route.name.startsWith('library')) {
 | |
|             var newRoute = this.$route.path.replace(currLibraryId, nextLibrary.id)
 | |
|             this.$router.push(newRoute)
 | |
|           } else {
 | |
|             this.$router.push(`/library/${nextLibrary.id}`)
 | |
|           }
 | |
|         } else {
 | |
|           console.error('User has no more accessible libraries')
 | |
|           this.$store.commit('libraries/setCurrentLibrary', null)
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     libraryItemAdded(libraryItem) {
 | |
|       this.$store.commit('libraries/updateFilterDataWithItem', libraryItem)
 | |
|     },
 | |
|     libraryItemUpdated(libraryItem) {
 | |
|       if (this.$store.state.selectedLibraryItem && this.$store.state.selectedLibraryItem.id === libraryItem.id) {
 | |
|         this.$store.commit('setSelectedLibraryItem', libraryItem)
 | |
|         if (this.$store.state.globals.selectedEpisode && libraryItem.mediaType === 'podcast') {
 | |
|           const episode = libraryItem.media.episodes.find((ep) => ep.id === this.$store.state.globals.selectedEpisode.id)
 | |
|           if (episode) {
 | |
|             this.$store.commit('globals/setSelectedEpisode', episode)
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       this.$eventBus.$emit(`${libraryItem.id}_updated`, libraryItem)
 | |
|       this.$store.commit('libraries/updateFilterDataWithItem', libraryItem)
 | |
|     },
 | |
|     libraryItemRemoved(item) {
 | |
|       if (this.$route.name.startsWith('item')) {
 | |
|         if (this.$route.params.id === item.id) {
 | |
|           this.$router.replace(`/library/${this.currentLibraryId}`)
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     libraryItemsUpdated(libraryItems) {
 | |
|       libraryItems.forEach((li) => {
 | |
|         this.libraryItemUpdated(li)
 | |
|       })
 | |
|     },
 | |
|     libraryItemsAdded(libraryItems) {
 | |
|       libraryItems.forEach((ab) => {
 | |
|         this.libraryItemAdded(ab)
 | |
|       })
 | |
|     },
 | |
|     taskStarted(task) {
 | |
|       console.log('Task started', task)
 | |
|       this.$store.commit('tasks/addUpdateTask', task)
 | |
|     },
 | |
|     taskFinished(task) {
 | |
|       console.log('Task finished', task)
 | |
|       this.$store.commit('tasks/addUpdateTask', task)
 | |
|     },
 | |
|     metadataEmbedQueueUpdate(data) {
 | |
|       if (data.queued) {
 | |
|         this.$store.commit('tasks/addQueuedEmbedLId', data.libraryItemId)
 | |
|       } else {
 | |
|         this.$store.commit('tasks/removeQueuedEmbedLId', data.libraryItemId)
 | |
|       }
 | |
|     },
 | |
|     userUpdated(user) {
 | |
|       if (this.$store.state.user.user.id === user.id) {
 | |
|         this.$store.commit('user/setUser', user)
 | |
|       }
 | |
|     },
 | |
|     userOnline(user) {
 | |
|       this.$store.commit('users/updateUserOnline', user)
 | |
|     },
 | |
|     userOffline(user) {
 | |
|       this.$store.commit('users/removeUserOnline', user)
 | |
|     },
 | |
|     userStreamUpdate(user) {
 | |
|       this.$store.commit('users/updateUserOnline', user)
 | |
|     },
 | |
|     userSessionClosed(sessionId) {
 | |
|       // If this session or other session is closed then dismiss multiple sessions warning toast
 | |
|       if (sessionId === this.multiSessionOtherSessionId || this.multiSessionCurrentSessionId === sessionId) {
 | |
|         this.multiSessionOtherSessionId = null
 | |
|         this.multiSessionCurrentSessionId = null
 | |
|         this.$toast.dismiss('multiple-sessions')
 | |
|       }
 | |
|       if (this.$refs.streamContainer) this.$refs.streamContainer.sessionClosedEvent(sessionId)
 | |
|     },
 | |
|     userMediaProgressUpdate(payload) {
 | |
|       this.$store.commit('user/updateMediaProgress', payload)
 | |
| 
 | |
|       if (payload.data) {
 | |
|         if (this.$store.getters['getIsMediaStreaming'](payload.data.libraryItemId, payload.data.episodeId) && this.$store.state.playbackSessionId !== payload.sessionId) {
 | |
|           this.multiSessionOtherSessionId = payload.sessionId
 | |
|           this.multiSessionCurrentSessionId = this.$store.state.playbackSessionId
 | |
|           console.log(`Media progress was updated from another session (${this.multiSessionOtherSessionId}) for currently open media. Device description=${payload.deviceDescription}. Current session id=${this.multiSessionCurrentSessionId}`)
 | |
|           if (this.$store.state.streamIsPlaying) {
 | |
|             this.$toast.update('multiple-sessions', { content: `Another session is open for this item on device ${payload.deviceDescription}`, options: { timeout: 20000, type: 'warning', pauseOnFocusLoss: false } }, true)
 | |
|           } else {
 | |
|             this.$eventBus.$emit('playback-time-update', payload.data.currentTime)
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     collectionAdded(collection) {
 | |
|       if (this.currentLibraryId !== collection.libraryId) return
 | |
|       this.$store.commit('libraries/addUpdateCollection', collection)
 | |
|     },
 | |
|     collectionUpdated(collection) {
 | |
|       if (this.currentLibraryId !== collection.libraryId) return
 | |
|       this.$store.commit('libraries/addUpdateCollection', collection)
 | |
|     },
 | |
|     collectionRemoved(collection) {
 | |
|       if (this.currentLibraryId !== collection.libraryId) return
 | |
|       if (this.$route.name.startsWith('collection')) {
 | |
|         if (this.$route.params.id === collection.id) {
 | |
|           this.$router.replace(`/library/${this.currentLibraryId}/bookshelf/collections`)
 | |
|         }
 | |
|       }
 | |
|       this.$store.commit('libraries/removeCollection', collection)
 | |
|     },
 | |
|     seriesRemoved({ id, libraryId }) {
 | |
|       if (this.currentLibraryId !== libraryId) return
 | |
|       this.$store.commit('libraries/removeSeriesFromFilterData', id)
 | |
|     },
 | |
|     playlistAdded(playlist) {
 | |
|       if (playlist.userId !== this.user.id || this.currentLibraryId !== playlist.libraryId) return
 | |
|       this.$store.commit('libraries/addUpdateUserPlaylist', playlist)
 | |
|     },
 | |
|     playlistUpdated(playlist) {
 | |
|       if (playlist.userId !== this.user.id || this.currentLibraryId !== playlist.libraryId) return
 | |
|       this.$store.commit('libraries/addUpdateUserPlaylist', playlist)
 | |
|     },
 | |
|     playlistRemoved(playlist) {
 | |
|       if (playlist.userId !== this.user.id || this.currentLibraryId !== playlist.libraryId) return
 | |
| 
 | |
|       if (this.$route.name.startsWith('playlist')) {
 | |
|         if (this.$route.params.id === playlist.id) {
 | |
|           this.$router.replace(`/library/${this.currentLibraryId}/bookshelf/playlists`)
 | |
|         }
 | |
|       }
 | |
|       this.$store.commit('libraries/removeUserPlaylist', playlist)
 | |
|     },
 | |
|     backupApplied() {
 | |
|       // Force refresh
 | |
|       location.reload()
 | |
|     },
 | |
|     batchQuickMatchComplete(result) {
 | |
|       var success = result.success || false
 | |
|       var toast = 'Batch quick match complete!\n' + result.updates + ' Updated'
 | |
|       if (result.unmatched && result.unmatched > 0) {
 | |
|         toast += '\n' + result.unmatched + ' with no matches'
 | |
|       }
 | |
|       if (success) {
 | |
|         this.$toast.success(toast)
 | |
|       } else {
 | |
|         this.$toast.info(toast)
 | |
|       }
 | |
|     },
 | |
|     adminMessageEvt(message) {
 | |
|       this.$toast.info(message)
 | |
|     },
 | |
|     ereaderDevicesUpdated(data) {
 | |
|       if (!data?.ereaderDevices) return
 | |
| 
 | |
|       this.$store.commit('libraries/setEReaderDevices', data.ereaderDevices)
 | |
|     },
 | |
|     initializeSocket() {
 | |
|       this.socket = this.$nuxtSocket({
 | |
|         name: process.env.NODE_ENV === 'development' ? 'dev' : 'prod',
 | |
|         persist: 'main',
 | |
|         teardown: false,
 | |
|         transports: ['websocket'],
 | |
|         upgrade: false,
 | |
|         reconnection: true
 | |
|       })
 | |
|       this.$root.socket = this.socket
 | |
|       console.log('Socket initialized')
 | |
| 
 | |
|       // Pre-defined socket events
 | |
|       this.socket.on('connect', this.connect)
 | |
|       this.socket.on('connect_error', this.connectError)
 | |
|       this.socket.on('disconnect', this.disconnect)
 | |
|       this.socket.io.on('reconnect_attempt', this.reconnectAttempt)
 | |
|       this.socket.io.on('reconnect', this.reconnect)
 | |
|       this.socket.io.on('reconnect_error', this.reconnectError)
 | |
|       this.socket.io.on('reconnect_failed', this.reconnectFailed)
 | |
| 
 | |
|       // Event received after authorizing socket
 | |
|       this.socket.on('init', this.init)
 | |
| 
 | |
|       // Stream Listeners
 | |
|       this.socket.on('stream_open', this.streamOpen)
 | |
|       this.socket.on('stream_closed', this.streamClosed)
 | |
|       this.socket.on('stream_progress', this.streamProgress)
 | |
|       this.socket.on('stream_ready', this.streamReady)
 | |
|       this.socket.on('stream_reset', this.streamReset)
 | |
|       this.socket.on('stream_error', this.streamError)
 | |
| 
 | |
|       // Library Listeners
 | |
|       this.socket.on('library_updated', this.libraryUpdated)
 | |
|       this.socket.on('library_added', this.libraryAdded)
 | |
|       this.socket.on('library_removed', this.libraryRemoved)
 | |
| 
 | |
|       // Library Item Listeners
 | |
|       this.socket.on('item_added', this.libraryItemAdded)
 | |
|       this.socket.on('item_updated', this.libraryItemUpdated)
 | |
|       this.socket.on('item_removed', this.libraryItemRemoved)
 | |
|       this.socket.on('items_updated', this.libraryItemsUpdated)
 | |
|       this.socket.on('items_added', this.libraryItemsAdded)
 | |
| 
 | |
|       // User Listeners
 | |
|       this.socket.on('user_updated', this.userUpdated)
 | |
|       this.socket.on('user_online', this.userOnline)
 | |
|       this.socket.on('user_offline', this.userOffline)
 | |
|       this.socket.on('user_stream_update', this.userStreamUpdate)
 | |
|       this.socket.on('user_session_closed', this.userSessionClosed)
 | |
|       this.socket.on('user_item_progress_updated', this.userMediaProgressUpdate)
 | |
| 
 | |
|       // Collection Listeners
 | |
|       this.socket.on('collection_added', this.collectionAdded)
 | |
|       this.socket.on('collection_updated', this.collectionUpdated)
 | |
|       this.socket.on('collection_removed', this.collectionRemoved)
 | |
| 
 | |
|       // Series Listeners
 | |
|       this.socket.on('series_removed', this.seriesRemoved)
 | |
| 
 | |
|       // User Playlist Listeners
 | |
|       this.socket.on('playlist_added', this.playlistAdded)
 | |
|       this.socket.on('playlist_updated', this.playlistUpdated)
 | |
|       this.socket.on('playlist_removed', this.playlistRemoved)
 | |
| 
 | |
|       // Task Listeners
 | |
|       this.socket.on('task_started', this.taskStarted)
 | |
|       this.socket.on('task_finished', this.taskFinished)
 | |
|       this.socket.on('metadata_embed_queue_update', this.metadataEmbedQueueUpdate)
 | |
| 
 | |
|       // EReader Device Listeners
 | |
|       this.socket.on('ereader-devices-updated', this.ereaderDevicesUpdated)
 | |
| 
 | |
|       this.socket.on('backup_applied', this.backupApplied)
 | |
| 
 | |
|       this.socket.on('batch_quickmatch_complete', this.batchQuickMatchComplete)
 | |
| 
 | |
|       this.socket.on('admin_message', this.adminMessageEvt)
 | |
|     },
 | |
|     showUpdateToast(versionData) {
 | |
|       var ignoreVersion = localStorage.getItem('ignoreVersion')
 | |
|       var latestVersion = versionData.latestVersion
 | |
| 
 | |
|       if (!ignoreVersion || ignoreVersion !== latestVersion) {
 | |
|         this.$toast.info(`Update is available!\nCheck release notes for v${versionData.latestVersion}`, {
 | |
|           position: 'top-center',
 | |
|           toastClassName: 'cursor-pointer',
 | |
|           bodyClassName: 'custom-class-1',
 | |
|           timeout: 20000,
 | |
|           closeOnClick: false,
 | |
|           draggable: false,
 | |
|           hideProgressBar: false,
 | |
|           onClick: () => {
 | |
|             window.open(versionData.githubTagUrl, '_blank')
 | |
|           },
 | |
|           onClose: () => {
 | |
|             localStorage.setItem('ignoreVersion', versionData.latestVersion)
 | |
|           }
 | |
|         })
 | |
|       } else {
 | |
|         console.warn(`Update is available but user chose to dismiss it! v${versionData.latestVersion}`)
 | |
|       }
 | |
|     },
 | |
|     checkActiveElementIsInput() {
 | |
|       const activeElement = document.activeElement
 | |
|       const inputs = ['input', 'select', 'button', 'textarea', 'trix-editor']
 | |
|       return activeElement && inputs.some((i) => i === activeElement.tagName.toLowerCase())
 | |
|     },
 | |
|     getHotkeyName(e) {
 | |
|       var keyCode = e.keyCode || e.which
 | |
|       if (!this.$keynames[keyCode]) {
 | |
|         // Unused hotkey
 | |
|         return null
 | |
|       }
 | |
| 
 | |
|       var keyName = this.$keynames[keyCode]
 | |
|       var name = keyName
 | |
|       if (e.shiftKey) name = 'Shift-' + keyName
 | |
|       if (process.env.NODE_ENV !== 'production') {
 | |
|         console.log('Hotkey command', name)
 | |
|       }
 | |
|       return name
 | |
|     },
 | |
|     keyDown(e) {
 | |
|       var name = this.getHotkeyName(e)
 | |
|       if (!name) return
 | |
| 
 | |
|       // Input is focused then ignore key press
 | |
|       if (this.checkActiveElementIsInput()) {
 | |
|         return
 | |
|       }
 | |
| 
 | |
|       // Modal is open
 | |
|       if (this.$store.state.openModal && Object.values(this.$hotkeys.Modal).includes(name)) {
 | |
|         this.$eventBus.$emit('modal-hotkey', name)
 | |
|         e.preventDefault()
 | |
|         return
 | |
|       }
 | |
| 
 | |
|       // EReader is open
 | |
|       if (this.$store.state.showEReader && Object.values(this.$hotkeys.EReader).includes(name)) {
 | |
|         this.$eventBus.$emit('reader-hotkey', name)
 | |
|         e.preventDefault()
 | |
|         return
 | |
|       }
 | |
| 
 | |
|       // Batch selecting
 | |
|       if (this.$store.getters['globals/getIsBatchSelectingMediaItems'] && name === 'Escape') {
 | |
|         // ESCAPE key cancels batch selection
 | |
|         this.$store.commit('globals/resetSelectedMediaItems', [])
 | |
|         this.$eventBus.$emit('bookshelf_clear_selection')
 | |
|         e.preventDefault()
 | |
|         return
 | |
|       }
 | |
| 
 | |
|       // Playing audiobook
 | |
|       if (this.$store.state.streamLibraryItem && Object.values(this.$hotkeys.AudioPlayer).includes(name)) {
 | |
|         this.$eventBus.$emit('player-hotkey', name)
 | |
|         e.preventDefault()
 | |
|       }
 | |
|     },
 | |
|     resize() {
 | |
|       this.$store.commit('globals/updateWindowSize', { width: window.innerWidth, height: window.innerHeight })
 | |
|     },
 | |
|     checkVersionUpdate() {
 | |
|       this.$store
 | |
|         .dispatch('checkForUpdate')
 | |
|         .then((res) => {
 | |
|           if (res && res.hasUpdate) this.showUpdateToast(res)
 | |
|         })
 | |
|         .catch((err) => console.error(err))
 | |
|     },
 | |
|     initLocalStorage() {
 | |
|       // Queue auto play
 | |
|       var playerQueueAutoPlay = localStorage.getItem('playerQueueAutoPlay')
 | |
|       this.$store.commit('setPlayerQueueAutoPlay', playerQueueAutoPlay !== '0')
 | |
|     },
 | |
|     loadTasks() {
 | |
|       this.$axios
 | |
|         .$get('/api/tasks?include=queue')
 | |
|         .then((payload) => {
 | |
|           console.log('Fetched tasks', payload)
 | |
|           if (payload.tasks) {
 | |
|             this.$store.commit('tasks/setTasks', payload.tasks)
 | |
|           }
 | |
|           if (payload.queuedTaskData?.embedMetadata?.length) {
 | |
|             this.$store.commit(
 | |
|               'tasks/setQueuedEmbedLIds',
 | |
|               payload.queuedTaskData.embedMetadata.map((td) => td.libraryItemId)
 | |
|             )
 | |
|           }
 | |
|         })
 | |
|         .catch((error) => {
 | |
|           console.error('Failed to load tasks', error)
 | |
|         })
 | |
|     },
 | |
|     changeLanguage(code) {
 | |
|       console.log('Changed lang', code)
 | |
|       this.currentLang = code
 | |
|       document.documentElement.lang = code
 | |
|     }
 | |
|   },
 | |
|   beforeMount() {
 | |
|     this.initializeSocket()
 | |
|   },
 | |
|   mounted() {
 | |
|     this.updateBodyClass()
 | |
|     this.resize()
 | |
|     this.$eventBus.$on('change-lang', this.changeLanguage)
 | |
|     window.addEventListener('resize', this.resize)
 | |
|     window.addEventListener('keydown', this.keyDown)
 | |
| 
 | |
|     this.$store.dispatch('libraries/load')
 | |
| 
 | |
|     this.initLocalStorage()
 | |
| 
 | |
|     this.checkVersionUpdate()
 | |
| 
 | |
|     this.loadTasks()
 | |
| 
 | |
|     if (this.$route.query.error) {
 | |
|       this.$toast.error(this.$route.query.error)
 | |
|       this.$router.replace(this.$route.path)
 | |
|     }
 | |
| 
 | |
|     // Set lang on HTML tag
 | |
|     if (this.$languageCodes?.current) {
 | |
|       document.documentElement.lang = this.$languageCodes.current
 | |
|     }
 | |
|   },
 | |
|   beforeDestroy() {
 | |
|     this.$eventBus.$off('change-lang', this.changeLanguage)
 | |
|     window.removeEventListener('resize', this.resize)
 | |
|     window.removeEventListener('keydown', this.keyDown)
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <style>
 | |
| .Vue-Toastification__toast-body.custom-class-1 {
 | |
|   font-size: 14px;
 | |
| }
 | |
| 
 | |
| #app-content {
 | |
|   width: 100%;
 | |
| }
 | |
| #app-content.has-siderail {
 | |
|   width: calc(100% - 80px);
 | |
|   max-width: calc(100% - 80px);
 | |
|   margin-left: 80px;
 | |
| }
 | |
| @media (max-width: 768px) {
 | |
|   #app-content.has-siderail {
 | |
|     width: 100%;
 | |
|     max-width: 100%;
 | |
|     margin-left: 0px;
 | |
|   }
 | |
| }
 | |
| </style> |