mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-11-03 19:07:00 -05:00 
			
		
		
		
	If no progress had been set before, setting `startedAt` did not work and it would always been set to `finishedAt` or `Date.now()`. Settings this if any progress had already been recorded did work. This fixes the problem so that setting `startedAt` it properly works in both cases.
		
			
				
	
	
		
			126 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
class MediaProgress {
 | 
						|
  constructor(progress) {
 | 
						|
    this.id = null
 | 
						|
    this.libraryItemId = null
 | 
						|
    this.episodeId = null // For podcasts
 | 
						|
 | 
						|
    this.duration = null
 | 
						|
    this.progress = null // 0 to 1
 | 
						|
    this.currentTime = null // seconds
 | 
						|
    this.isFinished = false
 | 
						|
    this.hideFromContinueListening = false
 | 
						|
 | 
						|
    this.lastUpdate = null
 | 
						|
    this.startedAt = null
 | 
						|
    this.finishedAt = null
 | 
						|
 | 
						|
    if (progress) {
 | 
						|
      this.construct(progress)
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  toJSON() {
 | 
						|
    return {
 | 
						|
      id: this.id,
 | 
						|
      libraryItemId: this.libraryItemId,
 | 
						|
      episodeId: this.episodeId,
 | 
						|
      duration: this.duration,
 | 
						|
      progress: this.progress,
 | 
						|
      currentTime: this.currentTime,
 | 
						|
      isFinished: this.isFinished,
 | 
						|
      hideFromContinueListening: this.hideFromContinueListening,
 | 
						|
      lastUpdate: this.lastUpdate,
 | 
						|
      startedAt: this.startedAt,
 | 
						|
      finishedAt: this.finishedAt
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  construct(progress) {
 | 
						|
    this.id = progress.id
 | 
						|
    this.libraryItemId = progress.libraryItemId
 | 
						|
    this.episodeId = progress.episodeId
 | 
						|
    this.duration = progress.duration || 0
 | 
						|
    this.progress = progress.progress
 | 
						|
    this.currentTime = progress.currentTime
 | 
						|
    this.isFinished = !!progress.isFinished
 | 
						|
    this.hideFromContinueListening = !!progress.hideFromContinueListening
 | 
						|
    this.lastUpdate = progress.lastUpdate
 | 
						|
    this.startedAt = progress.startedAt
 | 
						|
    this.finishedAt = progress.finishedAt || null
 | 
						|
  }
 | 
						|
 | 
						|
  get inProgress() {
 | 
						|
    return !this.isFinished && this.progress > 0
 | 
						|
  }
 | 
						|
 | 
						|
  setData(libraryItemId, progress, episodeId = null) {
 | 
						|
    this.id = episodeId ? `${libraryItemId}-${episodeId}` : libraryItemId
 | 
						|
    this.libraryItemId = libraryItemId
 | 
						|
    this.episodeId = episodeId
 | 
						|
    this.duration = progress.duration || 0
 | 
						|
    this.progress = Math.min(1, (progress.progress || 0))
 | 
						|
    this.currentTime = progress.currentTime || 0
 | 
						|
    this.isFinished = !!progress.isFinished || this.progress == 1
 | 
						|
    this.hideFromContinueListening = !!progress.hideFromContinueListening
 | 
						|
    this.lastUpdate = Date.now()
 | 
						|
    this.finishedAt = null
 | 
						|
    if (this.isFinished) {
 | 
						|
      this.finishedAt = progress.finishedAt || Date.now()
 | 
						|
      this.progress = 1
 | 
						|
    }
 | 
						|
    this.startedAt = progress.startedAt || this.finishedAt || Date.now()
 | 
						|
  }
 | 
						|
 | 
						|
  update(payload) {
 | 
						|
    var hasUpdates = false
 | 
						|
    for (const key in payload) {
 | 
						|
      if (this[key] !== undefined && payload[key] !== this[key]) {
 | 
						|
        if (key === 'isFinished') {
 | 
						|
          if (!payload[key]) { // Updating to Not Finished - Reset progress and current time
 | 
						|
            this.finishedAt = null
 | 
						|
            this.progress = 0
 | 
						|
            this.currentTime = 0
 | 
						|
          } else { // Updating to Finished
 | 
						|
            if (!this.finishedAt) this.finishedAt = Date.now()
 | 
						|
            this.progress = 1
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        this[key] = payload[key]
 | 
						|
        hasUpdates = true
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    var timeRemaining = this.duration - this.currentTime
 | 
						|
    // If time remaining is less than 5 seconds then mark as finished
 | 
						|
    if ((this.progress >= 1 || (this.duration && !isNaN(timeRemaining) && timeRemaining < 5))) {
 | 
						|
      this.isFinished = true
 | 
						|
      this.finishedAt = payload.finishedAt || Date.now()
 | 
						|
      this.progress = 1
 | 
						|
    } else if (this.progress < 1 && this.isFinished) {
 | 
						|
      this.isFinished = false
 | 
						|
      this.finishedAt = null
 | 
						|
    }
 | 
						|
 | 
						|
    if (!this.startedAt) {
 | 
						|
      this.startedAt = this.finishedAt || Date.now()
 | 
						|
    }
 | 
						|
    if (hasUpdates) {
 | 
						|
      if (payload.hideFromContinueListening === undefined) {
 | 
						|
        // Reset this flag when the media progress is updated
 | 
						|
        this.hideFromContinueListening = false
 | 
						|
      }
 | 
						|
 | 
						|
      this.lastUpdate = Date.now()
 | 
						|
    }
 | 
						|
    return hasUpdates
 | 
						|
  }
 | 
						|
 | 
						|
  removeFromContinueListening() {
 | 
						|
    if (this.hideFromContinueListening) return false
 | 
						|
 | 
						|
    this.hideFromContinueListening = true
 | 
						|
    return true
 | 
						|
  }
 | 
						|
}
 | 
						|
module.exports = MediaProgress |