mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-11-03 19:07:00 -05:00 
			
		
		
		
	New data model update bookmarks and bookmark routes to use API
This commit is contained in:
		
							parent
							
								
									099ae7c776
								
							
						
					
					
						commit
						14a8f84446
					
				@ -24,7 +24,6 @@
 | 
				
			|||||||
      <div class="flex-grow" />
 | 
					      <div class="flex-grow" />
 | 
				
			||||||
      <span class="material-icons px-2 py-1 md:p-4 cursor-pointer" @click="closePlayer">close</span>
 | 
					      <span class="material-icons px-2 py-1 md:p-4 cursor-pointer" @click="closePlayer">close</span>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
    <audio-player
 | 
					    <audio-player
 | 
				
			||||||
      ref="audioPlayer"
 | 
					      ref="audioPlayer"
 | 
				
			||||||
      :chapters="chapters"
 | 
					      :chapters="chapters"
 | 
				
			||||||
@ -44,7 +43,7 @@
 | 
				
			|||||||
      @showSleepTimer="showSleepTimerModal = true"
 | 
					      @showSleepTimer="showSleepTimerModal = true"
 | 
				
			||||||
    />
 | 
					    />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <modals-bookmarks-modal v-model="showBookmarksModal" :bookmarks="bookmarks" :audiobook-id="bookmarkAudiobookId" :current-time="bookmarkCurrentTime" @select="selectBookmark" />
 | 
					    <modals-bookmarks-modal v-model="showBookmarksModal" :bookmarks="bookmarks" :current-time="bookmarkCurrentTime" :library-item-id="libraryItemId" @select="selectBookmark" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <modals-sleep-timer-modal v-model="showSleepTimerModal" :timer-set="sleepTimerSet" :timer-time="sleepTimerTime" :remaining="sleepTimerRemaining" @set="setSleepTimer" @cancel="cancelSleepTimer" @increment="incrementSleepTimer" @decrement="decrementSleepTimer" />
 | 
					    <modals-sleep-timer-modal v-model="showSleepTimerModal" :timer-set="sleepTimerSet" :timer-time="sleepTimerTime" :remaining="sleepTimerRemaining" @set="setSleepTimer" @cancel="cancelSleepTimer" @increment="incrementSleepTimer" @decrement="decrementSleepTimer" />
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
@ -60,7 +59,6 @@ export default {
 | 
				
			|||||||
      totalDuration: 0,
 | 
					      totalDuration: 0,
 | 
				
			||||||
      showBookmarksModal: false,
 | 
					      showBookmarksModal: false,
 | 
				
			||||||
      bookmarkCurrentTime: 0,
 | 
					      bookmarkCurrentTime: 0,
 | 
				
			||||||
      bookmarkAudiobookId: null,
 | 
					 | 
				
			||||||
      playerLoading: false,
 | 
					      playerLoading: false,
 | 
				
			||||||
      isPlaying: false,
 | 
					      isPlaying: false,
 | 
				
			||||||
      currentTime: 0,
 | 
					      currentTime: 0,
 | 
				
			||||||
@ -103,9 +101,8 @@ export default {
 | 
				
			|||||||
      return this.userLibraryItemProgress ? this.userLibraryItemProgress.currentTime || 0 : 0
 | 
					      return this.userLibraryItemProgress ? this.userLibraryItemProgress.currentTime || 0 : 0
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    bookmarks() {
 | 
					    bookmarks() {
 | 
				
			||||||
      return []
 | 
					      if (!this.libraryItemId) return []
 | 
				
			||||||
      // if (!this.userAudiobook) return []
 | 
					      return this.$store.getters['user/getUserBookmarksForItem'](this.libraryItemId)
 | 
				
			||||||
      // return (this.userAudiobook.bookmarks || []).map((bm) => ({ ...bm })).sort((a, b) => a.time - b.time)
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    streamLibraryItem() {
 | 
					    streamLibraryItem() {
 | 
				
			||||||
      return this.$store.state.streamLibraryItem
 | 
					      return this.$store.state.streamLibraryItem
 | 
				
			||||||
@ -215,7 +212,6 @@ export default {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    showBookmarks() {
 | 
					    showBookmarks() {
 | 
				
			||||||
      this.bookmarkAudiobookId = this.libraryItemId
 | 
					 | 
				
			||||||
      this.bookmarkCurrentTime = this.currentTime
 | 
					      this.bookmarkCurrentTime = this.currentTime
 | 
				
			||||||
      this.showBookmarksModal = true
 | 
					      this.showBookmarksModal = true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@ export default {
 | 
				
			|||||||
      type: Number,
 | 
					      type: Number,
 | 
				
			||||||
      default: 0
 | 
					      default: 0
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    audiobookId: String
 | 
					    libraryItemId: String
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
@ -76,8 +76,15 @@ export default {
 | 
				
			|||||||
      this.showBookmarkTitleInput = true
 | 
					      this.showBookmarkTitleInput = true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    deleteBookmark(bm) {
 | 
					    deleteBookmark(bm) {
 | 
				
			||||||
      var bookmark = { ...bm, audiobookId: this.audiobookId }
 | 
					      this.$axios
 | 
				
			||||||
      this.$root.socket.emit('delete_bookmark', bookmark)
 | 
					        .$delete(`/api/me/item/${this.libraryItemId}/bookmark/${bm.time}`)
 | 
				
			||||||
 | 
					        .then(() => {
 | 
				
			||||||
 | 
					          this.$toast.success('Bookmark removed')
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch((error) => {
 | 
				
			||||||
 | 
					          this.$toast.error(`Failed to remove bookmark`)
 | 
				
			||||||
 | 
					          console.error(error)
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
      this.show = false
 | 
					      this.show = false
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    clickBookmark(bm) {
 | 
					    clickBookmark(bm) {
 | 
				
			||||||
@ -85,9 +92,15 @@ export default {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    submitUpdateBookmark(updatedBookmark) {
 | 
					    submitUpdateBookmark(updatedBookmark) {
 | 
				
			||||||
      var bookmark = { ...updatedBookmark }
 | 
					      var bookmark = { ...updatedBookmark }
 | 
				
			||||||
      bookmark.audiobookId = this.audiobookId
 | 
					      this.$axios
 | 
				
			||||||
 | 
					        .$patch(`/api/me/item/${this.libraryItemId}/bookmark`, bookmark)
 | 
				
			||||||
      this.$root.socket.emit('update_bookmark', bookmark)
 | 
					        .then(() => {
 | 
				
			||||||
 | 
					          this.$toast.success('Bookmark updated')
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch((error) => {
 | 
				
			||||||
 | 
					          this.$toast.error(`Failed to update bookmark`)
 | 
				
			||||||
 | 
					          console.error(error)
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
      this.show = false
 | 
					      this.show = false
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    submitCreateBookmark() {
 | 
					    submitCreateBookmark() {
 | 
				
			||||||
@ -95,11 +108,18 @@ export default {
 | 
				
			|||||||
        this.newBookmarkTitle = this.$formatDate(Date.now(), 'MMM dd, yyyy HH:mm')
 | 
					        this.newBookmarkTitle = this.$formatDate(Date.now(), 'MMM dd, yyyy HH:mm')
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      var bookmark = {
 | 
					      var bookmark = {
 | 
				
			||||||
        audiobookId: this.audiobookId,
 | 
					 | 
				
			||||||
        title: this.newBookmarkTitle,
 | 
					        title: this.newBookmarkTitle,
 | 
				
			||||||
        time: this.currentTime
 | 
					        time: Math.floor(this.currentTime)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this.$root.socket.emit('create_bookmark', bookmark)
 | 
					      this.$axios
 | 
				
			||||||
 | 
					        .$post(`/api/me/item/${this.libraryItemId}/bookmark`, bookmark)
 | 
				
			||||||
 | 
					        .then(() => {
 | 
				
			||||||
 | 
					          this.$toast.success('Bookmark added')
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch((error) => {
 | 
				
			||||||
 | 
					          this.$toast.error(`Failed to create bookmark`)
 | 
				
			||||||
 | 
					          console.error(error)
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.newBookmarkTitle = ''
 | 
					      this.newBookmarkTitle = ''
 | 
				
			||||||
      this.showBookmarkTitleInput = false
 | 
					      this.showBookmarkTitleInput = false
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,10 @@ export const getters = {
 | 
				
			|||||||
    if (!state.user.libraryItemProgress) return null
 | 
					    if (!state.user.libraryItemProgress) return null
 | 
				
			||||||
    return state.user.libraryItemProgress.find(li => li.id == libraryItemId)
 | 
					    return state.user.libraryItemProgress.find(li => li.id == libraryItemId)
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  getUserBookmarksForItem: (state) => (libraryItemId) => {
 | 
				
			||||||
 | 
					    if (!state.user.bookmarks) return []
 | 
				
			||||||
 | 
					    return state.user.bookmarks.filter(bm => bm.libraryItemId === libraryItemId)
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  getUserSetting: (state) => (key) => {
 | 
					  getUserSetting: (state) => (key) => {
 | 
				
			||||||
    return state.settings ? state.settings[key] : null
 | 
					    return state.settings ? state.settings[key] : null
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
@ -97,7 +101,6 @@ export const actions = {
 | 
				
			|||||||
export const mutations = {
 | 
					export const mutations = {
 | 
				
			||||||
  setUser(state, user) {
 | 
					  setUser(state, user) {
 | 
				
			||||||
    state.user = user
 | 
					    state.user = user
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (user) {
 | 
					    if (user) {
 | 
				
			||||||
      if (user.token) localStorage.setItem('token', user.token)
 | 
					      if (user.token) localStorage.setItem('token', user.token)
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 | 
				
			|||||||
@ -247,11 +247,6 @@ class Server {
 | 
				
			|||||||
      socket.on('create_backup', () => this.backupManager.requestCreateBackup(socket))
 | 
					      socket.on('create_backup', () => this.backupManager.requestCreateBackup(socket))
 | 
				
			||||||
      socket.on('apply_backup', (id) => this.backupManager.requestApplyBackup(socket, id))
 | 
					      socket.on('apply_backup', (id) => this.backupManager.requestApplyBackup(socket, id))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Bookmarks
 | 
					 | 
				
			||||||
      socket.on('create_bookmark', (payload) => this.createBookmark(socket, payload))
 | 
					 | 
				
			||||||
      socket.on('update_bookmark', (payload) => this.updateBookmark(socket, payload))
 | 
					 | 
				
			||||||
      socket.on('delete_bookmark', (payload) => this.deleteBookmark(socket, payload))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      socket.on('disconnect', () => {
 | 
					      socket.on('disconnect', () => {
 | 
				
			||||||
        Logger.removeSocketListener(socket.id)
 | 
					        Logger.removeSocketListener(socket.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -459,91 +454,6 @@ class Server {
 | 
				
			|||||||
    res.sendStatus(200)
 | 
					    res.sendStatus(200)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // async audiobookProgressUpdate(socket, progressPayload) {
 | 
					 | 
				
			||||||
  //   var client = socket.sheepClient
 | 
					 | 
				
			||||||
  //   if (!client || !client.user) {
 | 
					 | 
				
			||||||
  //     Logger.error('[Server] audiobookProgressUpdate invalid socket client')
 | 
					 | 
				
			||||||
  //     return
 | 
					 | 
				
			||||||
  //   }
 | 
					 | 
				
			||||||
  //   var audiobookProgress = client.user.createUpdateLibraryItemProgress(progressPayload.audiobookId, progressPayload)
 | 
					 | 
				
			||||||
  //   if (audiobookProgress) {
 | 
					 | 
				
			||||||
  //     await this.db.updateEntity('user', client.user)
 | 
					 | 
				
			||||||
  //     this.clientEmitter(client.user.id, 'current_user_audiobook_update', {
 | 
					 | 
				
			||||||
  //       id: progressPayload.audiobookId,
 | 
					 | 
				
			||||||
  //       data: audiobookProgress || null
 | 
					 | 
				
			||||||
  //     })
 | 
					 | 
				
			||||||
  //   }
 | 
					 | 
				
			||||||
  // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async createBookmark(socket, payload) {
 | 
					 | 
				
			||||||
    // var client = socket.sheepClient
 | 
					 | 
				
			||||||
    // if (!client || !client.user) {
 | 
					 | 
				
			||||||
    //   Logger.error('[Server] createBookmark invalid socket client')
 | 
					 | 
				
			||||||
    //   return
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
    // var userAudiobook = client.user.createBookmark(payload)
 | 
					 | 
				
			||||||
    // if (!userAudiobook || userAudiobook.error) {
 | 
					 | 
				
			||||||
    //   var failMessage = (userAudiobook ? userAudiobook.error : null) || 'Unknown Error'
 | 
					 | 
				
			||||||
    //   socket.emit('show_error_toast', `Failed to create Bookmark: ${failMessage}`)
 | 
					 | 
				
			||||||
    //   return
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // await this.db.updateEntity('user', client.user)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // socket.emit('show_success_toast', `${secondsToTimestamp(payload.time)} Bookmarked`)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // this.clientEmitter(client.user.id, 'current_user_audiobook_update', {
 | 
					 | 
				
			||||||
    //   id: userAudiobook.audiobookId,
 | 
					 | 
				
			||||||
    //   data: userAudiobook || null
 | 
					 | 
				
			||||||
    // })
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async updateBookmark(socket, payload) {
 | 
					 | 
				
			||||||
    // var client = socket.sheepClient
 | 
					 | 
				
			||||||
    // if (!client || !client.user) {
 | 
					 | 
				
			||||||
    //   Logger.error('[Server] updateBookmark invalid socket client')
 | 
					 | 
				
			||||||
    //   return
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
    // var userAudiobook = client.user.updateBookmark(payload)
 | 
					 | 
				
			||||||
    // if (!userAudiobook || userAudiobook.error) {
 | 
					 | 
				
			||||||
    //   var failMessage = (userAudiobook ? userAudiobook.error : null) || 'Unknown Error'
 | 
					 | 
				
			||||||
    //   socket.emit('show_error_toast', `Failed to update Bookmark: ${failMessage}`)
 | 
					 | 
				
			||||||
    //   return
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // await this.db.updateEntity('user', client.user)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // socket.emit('show_success_toast', `Bookmark ${secondsToTimestamp(payload.time)} Updated`)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // this.clientEmitter(client.user.id, 'current_user_audiobook_update', {
 | 
					 | 
				
			||||||
    //   id: userAudiobook.audiobookId,
 | 
					 | 
				
			||||||
    //   data: userAudiobook || null
 | 
					 | 
				
			||||||
    // })
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async deleteBookmark(socket, payload) {
 | 
					 | 
				
			||||||
    // var client = socket.sheepClient
 | 
					 | 
				
			||||||
    // if (!client || !client.user) {
 | 
					 | 
				
			||||||
    //   Logger.error('[Server] deleteBookmark invalid socket client')
 | 
					 | 
				
			||||||
    //   return
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
    // var userAudiobook = client.user.deleteBookmark(payload)
 | 
					 | 
				
			||||||
    // if (!userAudiobook || userAudiobook.error) {
 | 
					 | 
				
			||||||
    //   var failMessage = (userAudiobook ? userAudiobook.error : null) || 'Unknown Error'
 | 
					 | 
				
			||||||
    //   socket.emit('show_error_toast', `Failed to delete Bookmark: ${failMessage}`)
 | 
					 | 
				
			||||||
    //   return
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // await this.db.updateEntity('user', client.user)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // socket.emit('show_success_toast', `Bookmark ${secondsToTimestamp(payload.time)} Removed`)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // this.clientEmitter(client.user.id, 'current_user_audiobook_update', {
 | 
					 | 
				
			||||||
    //   id: userAudiobook.audiobookId,
 | 
					 | 
				
			||||||
    //   data: userAudiobook || null
 | 
					 | 
				
			||||||
    // })
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async authenticateSocket(socket, token) {
 | 
					  async authenticateSocket(socket, token) {
 | 
				
			||||||
    var user = await this.auth.authenticateUser(token)
 | 
					    var user = await this.auth.authenticateUser(token)
 | 
				
			||||||
    if (!user) {
 | 
					    if (!user) {
 | 
				
			||||||
 | 
				
			|||||||
@ -69,6 +69,50 @@ class MeController {
 | 
				
			|||||||
    res.sendStatus(200)
 | 
					    res.sendStatus(200)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // POST: api/me/item/:id/bookmark
 | 
				
			||||||
 | 
					  async createBookmark(req, res) {
 | 
				
			||||||
 | 
					    var libraryItem = this.db.libraryItems.find(li => li.id === req.params.id)
 | 
				
			||||||
 | 
					    if (!libraryItem) return res.sendStatus(404)
 | 
				
			||||||
 | 
					    const { time, title } = req.body
 | 
				
			||||||
 | 
					    var bookmark = req.user.createBookmark(libraryItem.id, time, title)
 | 
				
			||||||
 | 
					    await this.db.updateEntity('user', req.user)
 | 
				
			||||||
 | 
					    this.clientEmitter(req.user.id, 'user_updated', req.user.toJSONForBrowser())
 | 
				
			||||||
 | 
					    res.json(bookmark)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // PATCH: api/me/item/:id/bookmark
 | 
				
			||||||
 | 
					  async updateBookmark(req, res) {
 | 
				
			||||||
 | 
					    var libraryItem = this.db.libraryItems.find(li => li.id === req.params.id)
 | 
				
			||||||
 | 
					    if (!libraryItem) return res.sendStatus(404)
 | 
				
			||||||
 | 
					    const { time, title } = req.body
 | 
				
			||||||
 | 
					    if (!req.user.findBookmark(libraryItem.id, time)) {
 | 
				
			||||||
 | 
					      Logger.error(`[MeController] updateBookmark not found`)
 | 
				
			||||||
 | 
					      return res.sendStatus(404)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    var bookmark = req.user.updateBookmark(libraryItem.id, time, title)
 | 
				
			||||||
 | 
					    if (!bookmark) return res.sendStatus(500)
 | 
				
			||||||
 | 
					    await this.db.updateEntity('user', req.user)
 | 
				
			||||||
 | 
					    this.clientEmitter(req.user.id, 'user_updated', req.user.toJSONForBrowser())
 | 
				
			||||||
 | 
					    res.json(bookmark)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // DELETE: api/me/item/:id/bookmark/:time
 | 
				
			||||||
 | 
					  async removeBookmark(req, res) {
 | 
				
			||||||
 | 
					    var libraryItem = this.db.libraryItems.find(li => li.id === req.params.id)
 | 
				
			||||||
 | 
					    if (!libraryItem) return res.sendStatus(404)
 | 
				
			||||||
 | 
					    var time = Number(req.params.time)
 | 
				
			||||||
 | 
					    if (isNaN(time)) return res.sendStatus(500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!req.user.findBookmark(libraryItem.id, time)) {
 | 
				
			||||||
 | 
					      Logger.error(`[MeController] removeBookmark not found`)
 | 
				
			||||||
 | 
					      return res.sendStatus(404)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    req.user.removeBookmark(libraryItem.id, time)
 | 
				
			||||||
 | 
					    await this.db.updateEntity('user', req.user)
 | 
				
			||||||
 | 
					    this.clientEmitter(req.user.id, 'user_updated', req.user.toJSONForBrowser())
 | 
				
			||||||
 | 
					    res.sendStatus(200)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // PATCH: api/me/password
 | 
					  // PATCH: api/me/password
 | 
				
			||||||
  updatePassword(req, res) {
 | 
					  updatePassword(req, res) {
 | 
				
			||||||
    this.auth.userChangePassword(req, res)
 | 
					    this.auth.userChangePassword(req, res)
 | 
				
			||||||
 | 
				
			|||||||
@ -98,6 +98,7 @@ class User {
 | 
				
			|||||||
      type: this.type,
 | 
					      type: this.type,
 | 
				
			||||||
      token: this.token,
 | 
					      token: this.token,
 | 
				
			||||||
      libraryItemProgress: this.libraryItemProgress ? this.libraryItemProgress.map(li => li.toJSON()) : [],
 | 
					      libraryItemProgress: this.libraryItemProgress ? this.libraryItemProgress.map(li => li.toJSON()) : [],
 | 
				
			||||||
 | 
					      bookmarks: this.bookmarks ? this.bookmarks.map(b => b.toJSON()) : [],
 | 
				
			||||||
      isActive: this.isActive,
 | 
					      isActive: this.isActive,
 | 
				
			||||||
      isLocked: this.isLocked,
 | 
					      isLocked: this.isLocked,
 | 
				
			||||||
      lastSeen: this.lastSeen,
 | 
					      lastSeen: this.lastSeen,
 | 
				
			||||||
@ -136,7 +137,7 @@ class User {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    this.bookmarks = []
 | 
					    this.bookmarks = []
 | 
				
			||||||
    if (user.bookmarks) {
 | 
					    if (user.bookmarks) {
 | 
				
			||||||
      this.bookmarks = user.bookmarks.map(bm => new AudioBookmark(bm))
 | 
					      this.bookmarks = user.bookmarks.filter(bm => typeof bm.libraryItemId == 'string').map(bm => new AudioBookmark(bm))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.isActive = (user.isActive === undefined || user.type === 'root') ? true : !!user.isActive
 | 
					    this.isActive = (user.isActive === undefined || user.type === 'root') ? true : !!user.isActive
 | 
				
			||||||
@ -260,54 +261,35 @@ class User {
 | 
				
			|||||||
    return this.librariesAccessible.includes(libraryId)
 | 
					    return this.librariesAccessible.includes(libraryId)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  createBookmark({ libraryItemId, time, title }) {
 | 
					  findBookmark(libraryItemId, time) {
 | 
				
			||||||
    // if (!this.audiobooks) this.audiobooks = {}
 | 
					    return this.bookmarks.find(bm => bm.libraryItemId === libraryItemId && bm.time == time)
 | 
				
			||||||
    // if (!this.audiobooks[audiobookId]) {
 | 
					 | 
				
			||||||
    //   this.audiobooks[audiobookId] = new UserAudiobookData()
 | 
					 | 
				
			||||||
    //   this.audiobooks[audiobookId].audiobookId = audiobookId
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
    // if (this.audiobooks[audiobookId].checkBookmarkExists(time)) {
 | 
					 | 
				
			||||||
    //   return {
 | 
					 | 
				
			||||||
    //     error: 'Bookmark already exists'
 | 
					 | 
				
			||||||
    //   }
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // var success = this.audiobooks[audiobookId].createBookmark(time, title)
 | 
					 | 
				
			||||||
    // if (success) return this.audiobooks[audiobookId]
 | 
					 | 
				
			||||||
    // return null
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateBookmark({ audiobookId, time, title }) {
 | 
					  createBookmark(libraryItemId, time, title) {
 | 
				
			||||||
    // if (!this.audiobooks || !this.audiobooks[audiobookId]) {
 | 
					    var existingBookmark = this.findBookmark(libraryItemId, time)
 | 
				
			||||||
    //   return {
 | 
					    if (existingBookmark) {
 | 
				
			||||||
    //     error: 'Invalid Audiobook'
 | 
					      Logger.warn('[User] Create Bookmark already exists for this time')
 | 
				
			||||||
    //   }
 | 
					      existingBookmark.title = title
 | 
				
			||||||
    // }
 | 
					      return existingBookmark
 | 
				
			||||||
    // if (!this.audiobooks[audiobookId].checkBookmarkExists(time)) {
 | 
					    }
 | 
				
			||||||
    //   return {
 | 
					    var newBookmark = new AudioBookmark()
 | 
				
			||||||
    //     error: 'Bookmark does not exist'
 | 
					    newBookmark.setData(libraryItemId, time, title)
 | 
				
			||||||
    //   }
 | 
					    this.bookmarks.push(newBookmark)
 | 
				
			||||||
    // }
 | 
					    return newBookmark
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // var success = this.audiobooks[audiobookId].updateBookmark(time, title)
 | 
					 | 
				
			||||||
    // if (success) return this.audiobooks[audiobookId]
 | 
					 | 
				
			||||||
    // return null
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  deleteBookmark({ audiobookId, time }) {
 | 
					  updateBookmark(libraryItemId, time, title) {
 | 
				
			||||||
    // if (!this.audiobooks || !this.audiobooks[audiobookId]) {
 | 
					    var bookmark = this.findBookmark(libraryItemId, time)
 | 
				
			||||||
    //   return {
 | 
					    if (!bookmark) {
 | 
				
			||||||
    //     error: 'Invalid Audiobook'
 | 
					      Logger.error(`[User] updateBookmark not found`)
 | 
				
			||||||
    //   }
 | 
					      return null
 | 
				
			||||||
    // }
 | 
					    }
 | 
				
			||||||
    // if (!this.audiobooks[audiobookId].checkBookmarkExists(time)) {
 | 
					    bookmark.title = title
 | 
				
			||||||
    //   return {
 | 
					    return bookmark
 | 
				
			||||||
    //     error: 'Bookmark does not exist'
 | 
					  }
 | 
				
			||||||
    //   }
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // this.audiobooks[audiobookId].deleteBookmark(time)
 | 
					  removeBookmark(libraryItemId, time) {
 | 
				
			||||||
    // return this.audiobooks[audiobookId]
 | 
					    this.bookmarks = this.bookmarks.filter(bm => (bm.libraryItemId !== libraryItemId || bm.time !== time))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  syncLocalUserAudiobookData(localUserAudiobookData, audiobook) {
 | 
					  syncLocalUserAudiobookData(localUserAudiobookData, audiobook) {
 | 
				
			||||||
 | 
				
			|||||||
@ -134,6 +134,9 @@ class ApiRouter {
 | 
				
			|||||||
    this.router.patch('/me/progress/:id', MeController.createUpdateLibraryItemProgress.bind(this))
 | 
					    this.router.patch('/me/progress/:id', MeController.createUpdateLibraryItemProgress.bind(this))
 | 
				
			||||||
    this.router.delete('/me/progress/:id', MeController.removeLibraryItemProgress.bind(this))
 | 
					    this.router.delete('/me/progress/:id', MeController.removeLibraryItemProgress.bind(this))
 | 
				
			||||||
    this.router.patch('/me/progress/batch/update', MeController.batchUpdateLibraryItemProgress.bind(this))
 | 
					    this.router.patch('/me/progress/batch/update', MeController.batchUpdateLibraryItemProgress.bind(this))
 | 
				
			||||||
 | 
					    this.router.post('/me/item/:id/bookmark', MeController.createBookmark.bind(this))
 | 
				
			||||||
 | 
					    this.router.patch('/me/item/:id/bookmark', MeController.updateBookmark.bind(this))
 | 
				
			||||||
 | 
					    this.router.delete('/me/item/:id/bookmark/:time', MeController.removeBookmark.bind(this))
 | 
				
			||||||
    this.router.patch('/me/password', MeController.updatePassword.bind(this))
 | 
					    this.router.patch('/me/password', MeController.updatePassword.bind(this))
 | 
				
			||||||
    this.router.patch('/me/settings', MeController.updateSettings.bind(this))
 | 
					    this.router.patch('/me/settings', MeController.updateSettings.bind(this))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -262,9 +262,37 @@ async function migrateLibraryItems(db) {
 | 
				
			|||||||
        lip.libraryItemId = libraryItemWithAudiobook.id
 | 
					        lip.libraryItemId = libraryItemWithAudiobook.id
 | 
				
			||||||
        return lip
 | 
					        return lip
 | 
				
			||||||
      }).filter(lip => !!lip)
 | 
					      }).filter(lip => !!lip)
 | 
				
			||||||
      await db.updateEntity('user', user)
 | 
					 | 
				
			||||||
      Logger.debug(`>>> User ${user.username} with ${user.libraryItemProgress.length} progress entries were updated`)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (user.bookmarks.length) {
 | 
				
			||||||
 | 
					      user.bookmarks = user.bookmarks.map((bookmark) => {
 | 
				
			||||||
 | 
					        var audiobookId = bookmark.libraryItemId
 | 
				
			||||||
 | 
					        var libraryItemWithAudiobook = libraryItems.find(li => li.media.getAudiobookById && !!li.media.getAudiobookById(audiobookId))
 | 
				
			||||||
 | 
					        if (!libraryItemWithAudiobook) {
 | 
				
			||||||
 | 
					          Logger.error('[dbMigration] Failed to find library item with audiobook id', audiobookId)
 | 
				
			||||||
 | 
					          return null
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        bookmark.libraryItemId = libraryItemWithAudiobook.id
 | 
				
			||||||
 | 
					        return bookmark
 | 
				
			||||||
 | 
					      }).filter(bm => !!bm)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (user.libraryItemProgress.length || user.bookmarks.length) {
 | 
				
			||||||
 | 
					      await db.updateEntity('user', user)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Update session LibraryItemId's
 | 
				
			||||||
 | 
					  var sessions = await db.sessionsDb.select(() => true).then((results) => results.data)
 | 
				
			||||||
 | 
					  if (sessions.length) {
 | 
				
			||||||
 | 
					    sessions = sessions.map(se => {
 | 
				
			||||||
 | 
					      var libraryItemWithAudiobook = libraryItems.find(li => li.media.getAudiobookById && !!li.media.getAudiobookById(se.mediaEntityId))
 | 
				
			||||||
 | 
					      if (!libraryItemWithAudiobook) {
 | 
				
			||||||
 | 
					        Logger.error('[dbMigration] Failed to find library item with audiobook id', audiobookId)
 | 
				
			||||||
 | 
					        return null
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      se.libraryItemId = libraryItemWithAudiobook.id
 | 
				
			||||||
 | 
					      return se
 | 
				
			||||||
 | 
					    }).filter(se => !!se)
 | 
				
			||||||
 | 
					    await db.updateEntities('session', sessions)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Logger.info(`>>> ${libraryItems.length} Library Items made`)
 | 
					  Logger.info(`>>> ${libraryItems.length} Library Items made`)
 | 
				
			||||||
@ -300,7 +328,7 @@ function cleanUserObject(db, userObj) {
 | 
				
			|||||||
        // Bookmarks now live on User.js object instead of inside UserAudiobookData
 | 
					        // Bookmarks now live on User.js object instead of inside UserAudiobookData
 | 
				
			||||||
        if (userObj.audiobooks[audiobookId].bookmarks) {
 | 
					        if (userObj.audiobooks[audiobookId].bookmarks) {
 | 
				
			||||||
          const cleanedBookmarks = userObj.audiobooks[audiobookId].bookmarks.map((bm) => {
 | 
					          const cleanedBookmarks = userObj.audiobooks[audiobookId].bookmarks.map((bm) => {
 | 
				
			||||||
            bm.libraryItemId = audiobookId
 | 
					            bm.libraryItemId = audiobookId // Temp placeholder replace with libraryItemId when created
 | 
				
			||||||
            return bm
 | 
					            return bm
 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
          cleanedUserPayload.bookmarks = cleanedUserPayload.bookmarks.concat(cleanedBookmarks)
 | 
					          cleanedUserPayload.bookmarks = cleanedUserPayload.bookmarks.concat(cleanedBookmarks)
 | 
				
			||||||
@ -308,7 +336,7 @@ function cleanUserObject(db, userObj) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        var userAudiobookData = new UserAudiobookData(userObj.audiobooks[audiobookId]) // Legacy object
 | 
					        var userAudiobookData = new UserAudiobookData(userObj.audiobooks[audiobookId]) // Legacy object
 | 
				
			||||||
        var liProgress = new LibraryItemProgress() // New Progress Object
 | 
					        var liProgress = new LibraryItemProgress() // New Progress Object
 | 
				
			||||||
        liProgress.id = userAudiobookData.audiobookId // This ID is INCORRECT, will be updated when library item is created
 | 
					        liProgress.id = userAudiobookData.audiobookId // This ID will be updated when library item is created
 | 
				
			||||||
        liProgress.libraryItemId = userAudiobookData.audiobookId
 | 
					        liProgress.libraryItemId = userAudiobookData.audiobookId
 | 
				
			||||||
        liProgress.isFinished = !!userAudiobookData.isRead
 | 
					        liProgress.isFinished = !!userAudiobookData.isRead
 | 
				
			||||||
        Object.keys(liProgress.toJSON()).forEach((key) => {
 | 
					        Object.keys(liProgress.toJSON()).forEach((key) => {
 | 
				
			||||||
@ -333,9 +361,10 @@ function cleanUserObject(db, userObj) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function cleanSessionObj(db, userListeningSession) {
 | 
					function cleanSessionObj(db, userListeningSession) {
 | 
				
			||||||
  var newPlaybackSession = new PlaybackSession(userListeningSession)
 | 
					  var newPlaybackSession = new PlaybackSession(userListeningSession)
 | 
				
			||||||
 | 
					  newPlaybackSession.id = getId('play')
 | 
				
			||||||
  newPlaybackSession.mediaType = 'book'
 | 
					  newPlaybackSession.mediaType = 'book'
 | 
				
			||||||
  newPlaybackSession.updatedAt = userListeningSession.lastUpdate
 | 
					  newPlaybackSession.updatedAt = userListeningSession.lastUpdate
 | 
				
			||||||
  newPlaybackSession.libraryItemId = userListeningSession.audiobookId
 | 
					  newPlaybackSession.libraryItemId = userListeningSession.audiobookId // Temp
 | 
				
			||||||
  newPlaybackSession.mediaEntityId = userListeningSession.audiobookId
 | 
					  newPlaybackSession.mediaEntityId = userListeningSession.audiobookId
 | 
				
			||||||
  newPlaybackSession.playMethod = PlayMethod.TRANSCODE
 | 
					  newPlaybackSession.playMethod = PlayMethod.TRANSCODE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user