mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Fix: hotkeys prevent default browser behavior #135, Fix: mark audiobook as read when less than 10s remaining
This commit is contained in:
		
							parent
							
								
									aca88f73ad
								
							
						
					
					
						commit
						874c910e24
					
				@ -346,7 +346,7 @@ export default {
 | 
				
			|||||||
        return
 | 
					        return
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      var lastbuff = this.getLastBufferedTime()
 | 
					      var lastbuff = this.getLastBufferedTime()
 | 
				
			||||||
      this.sendStreamUpdate()
 | 
					
 | 
				
			||||||
      var bufferlen = (lastbuff / this.audioEl.duration) * this.trackWidth
 | 
					      var bufferlen = (lastbuff / this.audioEl.duration) * this.trackWidth
 | 
				
			||||||
      bufferlen = Math.round(bufferlen)
 | 
					      bufferlen = Math.round(bufferlen)
 | 
				
			||||||
      if (this.bufferTrackWidth === bufferlen || !this.$refs.bufferTrack) return
 | 
					      if (this.bufferTrackWidth === bufferlen || !this.$refs.bufferTrack) return
 | 
				
			||||||
@ -372,6 +372,7 @@ export default {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.updateTimestamp()
 | 
					      this.updateTimestamp()
 | 
				
			||||||
 | 
					      this.sendStreamUpdate()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.currentTime = this.audioEl.currentTime
 | 
					      this.currentTime = this.audioEl.currentTime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -535,16 +536,16 @@ export default {
 | 
				
			|||||||
      this.$emit('close')
 | 
					      this.$emit('close')
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    hotkey(action) {
 | 
					    hotkey(action) {
 | 
				
			||||||
      if (action === 'Space') this.playPauseClick()
 | 
					      if (action === this.$hotkeys.AudioPlayer.PLAY_PAUSE) this.playPauseClick()
 | 
				
			||||||
      else if (action === 'ArrowRight') this.forward10()
 | 
					      else if (action === this.$hotkeys.AudioPlayer.JUMP_FORWARD) this.forward10()
 | 
				
			||||||
      else if (action === 'ArrowLeft') this.backward10()
 | 
					      else if (action === this.$hotkeys.AudioPlayer.JUMP_BACKWARD) this.backward10()
 | 
				
			||||||
      else if (action === 'ArrowUp') this.volumeUp()
 | 
					      else if (action === this.$hotkeys.AudioPlayer.VOLUME_UP) this.volumeUp()
 | 
				
			||||||
      else if (action === 'ArrowDown') this.volumeDown()
 | 
					      else if (action === this.$hotkeys.AudioPlayer.VOLUME_DOWN) this.volumeDown()
 | 
				
			||||||
      else if (action === 'KeyM') this.toggleMute()
 | 
					      else if (action === this.$hotkeys.AudioPlayer.MUTE_UNMUTE) this.toggleMute()
 | 
				
			||||||
      else if (action === 'KeyL') this.showChapters()
 | 
					      else if (action === this.$hotkeys.AudioPlayer.SHOW_CHAPTERS) this.showChapters()
 | 
				
			||||||
      else if (action === 'Shift-ArrowUp') this.increasePlaybackRate()
 | 
					      else if (action === this.$hotkeys.AudioPlayer.INCREASE_PLAYBACK_RATE) this.increasePlaybackRate()
 | 
				
			||||||
      else if (action === 'Shift-ArrowDown') this.decreasePlaybackRate()
 | 
					      else if (action === this.$hotkeys.AudioPlayer.DECREASE_PLAYBACK_RATE) this.decreasePlaybackRate()
 | 
				
			||||||
      else if (action === 'Escape') this.closePlayer()
 | 
					      else if (action === this.$hotkeys.AudioPlayer.CLOSE) this.closePlayer()
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    windowResize() {
 | 
					    windowResize() {
 | 
				
			||||||
      this.setTrackWidth()
 | 
					      this.setTrackWidth()
 | 
				
			||||||
 | 
				
			|||||||
@ -148,7 +148,10 @@ export default {
 | 
				
			|||||||
          currentTime,
 | 
					          currentTime,
 | 
				
			||||||
          streamId: this.streamId
 | 
					          streamId: this.streamId
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        console.log('Stream update', updatePayload.currentTime)
 | 
				
			||||||
        this.$root.socket.emit('stream_update', updatePayload)
 | 
					        this.$root.socket.emit('stream_update', updatePayload)
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        console.log('Do not update time', diff)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    streamReset({ startTime, streamId }) {
 | 
					    streamReset({ startTime, streamId }) {
 | 
				
			||||||
 | 
				
			|||||||
@ -218,9 +218,9 @@ export default {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    hotkey(action) {
 | 
					    hotkey(action) {
 | 
				
			||||||
      if (action === 'ArrowRight') {
 | 
					      if (action === this.$hotkeys.Modal.NEXT_PAGE) {
 | 
				
			||||||
        this.goNextBook()
 | 
					        this.goNextBook()
 | 
				
			||||||
      } else if (action === 'ArrowLeft') {
 | 
					      } else if (action === this.$hotkeys.Modal.PREV_PAGE) {
 | 
				
			||||||
        this.goPrevBook()
 | 
					        this.goPrevBook()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
				
			|||||||
@ -84,7 +84,7 @@ export default {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    hotkey(action) {
 | 
					    hotkey(action) {
 | 
				
			||||||
      if (action === 'Escape') {
 | 
					      if (action === this.$hotkeys.Modal.CLOSE) {
 | 
				
			||||||
        this.show = false
 | 
					        this.show = false
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
				
			|||||||
@ -91,11 +91,11 @@ export default {
 | 
				
			|||||||
      console.log('Reader hotkey', action)
 | 
					      console.log('Reader hotkey', action)
 | 
				
			||||||
      if (!this.$refs.readerComponent) return
 | 
					      if (!this.$refs.readerComponent) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (action === 'ArrowRight') {
 | 
					      if (action === this.$hotkeys.EReader.NEXT_PAGE) {
 | 
				
			||||||
        if (this.$refs.readerComponent.next) this.$refs.readerComponent.next()
 | 
					        if (this.$refs.readerComponent.next) this.$refs.readerComponent.next()
 | 
				
			||||||
      } else if (action === 'ArrowLeft') {
 | 
					      } else if (action === this.$hotkeys.EReader.PREV_PAGE) {
 | 
				
			||||||
        if (this.$refs.readerComponent.prev) this.$refs.readerComponent.prev()
 | 
					        if (this.$refs.readerComponent.prev) this.$refs.readerComponent.prev()
 | 
				
			||||||
      } else if (action === 'Escape') {
 | 
					      } else if (action === this.$hotkeys.EReader.CLOSE) {
 | 
				
			||||||
        this.close()
 | 
					        this.close()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@ -114,21 +114,17 @@ export default {
 | 
				
			|||||||
          this.ebookType = 'pdf'
 | 
					          this.ebookType = 'pdf'
 | 
				
			||||||
        } else if (this.selectedAudiobookFile.ext === '.mobi' || this.selectedAudiobookFile.ext === '.azw3') {
 | 
					        } else if (this.selectedAudiobookFile.ext === '.mobi' || this.selectedAudiobookFile.ext === '.azw3') {
 | 
				
			||||||
          this.ebookType = 'mobi'
 | 
					          this.ebookType = 'mobi'
 | 
				
			||||||
          // this.initMobi()
 | 
					 | 
				
			||||||
        } else if (this.selectedAudiobookFile.ext === '.epub') {
 | 
					        } else if (this.selectedAudiobookFile.ext === '.epub') {
 | 
				
			||||||
          this.ebookType = 'epub'
 | 
					          this.ebookType = 'epub'
 | 
				
			||||||
          // this.initEpub()
 | 
					 | 
				
			||||||
        } else if (this.selectedAudiobookFile.ext === '.cbr' || this.selectedAudiobookFile.ext === '.cbz') {
 | 
					        } else if (this.selectedAudiobookFile.ext === '.cbr' || this.selectedAudiobookFile.ext === '.cbz') {
 | 
				
			||||||
          this.ebookType = 'comic'
 | 
					          this.ebookType = 'comic'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } else if (this.epubEbook) {
 | 
					      } else if (this.epubEbook) {
 | 
				
			||||||
        this.ebookType = 'epub'
 | 
					        this.ebookType = 'epub'
 | 
				
			||||||
        this.ebookUrl = this.getEbookUrl(this.epubEbook.path)
 | 
					        this.ebookUrl = this.getEbookUrl(this.epubEbook.path)
 | 
				
			||||||
        // this.initEpub()
 | 
					 | 
				
			||||||
      } else if (this.mobiEbook) {
 | 
					      } else if (this.mobiEbook) {
 | 
				
			||||||
        this.ebookType = 'mobi'
 | 
					        this.ebookType = 'mobi'
 | 
				
			||||||
        this.ebookUrl = this.getEbookUrl(this.mobiEbook.path)
 | 
					        this.ebookUrl = this.getEbookUrl(this.mobiEbook.path)
 | 
				
			||||||
        // this.initMobi()
 | 
					 | 
				
			||||||
      } else if (this.pdfEbook) {
 | 
					      } else if (this.pdfEbook) {
 | 
				
			||||||
        this.ebookType = 'pdf'
 | 
					        this.ebookType = 'pdf'
 | 
				
			||||||
        this.ebookUrl = this.getEbookUrl(this.pdfEbook.path)
 | 
					        this.ebookUrl = this.getEbookUrl(this.pdfEbook.path)
 | 
				
			||||||
 | 
				
			|||||||
@ -331,20 +331,24 @@ export default {
 | 
				
			|||||||
      var inputs = ['input', 'select', 'button', 'textarea']
 | 
					      var inputs = ['input', 'select', 'button', 'textarea']
 | 
				
			||||||
      return activeElement && inputs.indexOf(activeElement.tagName.toLowerCase()) !== -1
 | 
					      return activeElement && inputs.indexOf(activeElement.tagName.toLowerCase()) !== -1
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    keyUp(e) {
 | 
					    getHotkeyName(e) {
 | 
				
			||||||
      var keyCode = e.keyCode || e.which
 | 
					      var keyCode = e.keyCode || e.which
 | 
				
			||||||
      if (!this.$keynames[keyCode]) {
 | 
					      if (!this.$keynames[keyCode]) {
 | 
				
			||||||
        // Unused hotkey
 | 
					        // Unused hotkey
 | 
				
			||||||
        return
 | 
					        return null
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      var keyName = this.$keynames[keyCode]
 | 
					      var keyName = this.$keynames[keyCode]
 | 
				
			||||||
      var name = keyName
 | 
					      var name = keyName
 | 
				
			||||||
      if (e.shiftKey) name = 'Shift-' + keyName
 | 
					      if (e.shiftKey) name = 'Shift-' + keyName
 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (process.env.NODE_ENV !== 'production') {
 | 
					      if (process.env.NODE_ENV !== 'production') {
 | 
				
			||||||
        console.log('Hotkey command', name)
 | 
					        console.log('Hotkey command', name)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      return name
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    keyDown(e) {
 | 
				
			||||||
 | 
					      var name = this.getHotkeyName(e)
 | 
				
			||||||
 | 
					      if (!name) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Input is focused then ignore key press
 | 
					      // Input is focused then ignore key press
 | 
				
			||||||
      if (this.checkActiveElementIsInput()) {
 | 
					      if (this.checkActiveElementIsInput()) {
 | 
				
			||||||
@ -352,34 +356,36 @@ export default {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Modal is open
 | 
					      // Modal is open
 | 
				
			||||||
      if (this.$store.state.openModal) {
 | 
					      if (this.$store.state.openModal && Object.values(this.$hotkeys.Modal).includes(name)) {
 | 
				
			||||||
        this.$eventBus.$emit('modal-hotkey', name)
 | 
					        this.$eventBus.$emit('modal-hotkey', name)
 | 
				
			||||||
 | 
					        e.preventDefault()
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // EReader is open
 | 
					      // EReader is open
 | 
				
			||||||
      if (this.$store.state.showEReader) {
 | 
					      if (this.$store.state.showEReader && Object.values(this.$hotkeys.EReader).includes(name)) {
 | 
				
			||||||
        this.$eventBus.$emit('reader-hotkey', name)
 | 
					        this.$eventBus.$emit('reader-hotkey', name)
 | 
				
			||||||
 | 
					        e.preventDefault()
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Batch selecting
 | 
					      // Batch selecting
 | 
				
			||||||
      if (this.$store.getters['getNumAudiobooksSelected']) {
 | 
					      if (this.$store.getters['getNumAudiobooksSelected'] && name === 'Escape') {
 | 
				
			||||||
        // ESCAPE key cancels batch selection
 | 
					        // ESCAPE key cancels batch selection
 | 
				
			||||||
        if (name === 'Escape') {
 | 
					 | 
				
			||||||
        this.$store.commit('setSelectedAudiobooks', [])
 | 
					        this.$store.commit('setSelectedAudiobooks', [])
 | 
				
			||||||
        }
 | 
					        e.preventDefault()
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Playing audiobook
 | 
					      // Playing audiobook
 | 
				
			||||||
      if (this.$store.state.streamAudiobook) {
 | 
					      if (this.$store.state.streamAudiobook && Object.values(this.$hotkeys.AudioPlayer).includes(name)) {
 | 
				
			||||||
        this.$eventBus.$emit('player-hotkey', name)
 | 
					        this.$eventBus.$emit('player-hotkey', name)
 | 
				
			||||||
 | 
					        e.preventDefault()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  mounted() {
 | 
					  mounted() {
 | 
				
			||||||
    document.addEventListener('keyup', this.keyUp)
 | 
					    window.addEventListener('keydown', this.keyDown)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.initializeSocket()
 | 
					    this.initializeSocket()
 | 
				
			||||||
    this.$store.dispatch('libraries/load')
 | 
					    this.$store.dispatch('libraries/load')
 | 
				
			||||||
@ -403,7 +409,7 @@ export default {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  beforeDestroy() {
 | 
					  beforeDestroy() {
 | 
				
			||||||
    document.removeEventListener('keyup', this.keyUp)
 | 
					    window.removeEventListener('keydown', this.keyDown)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
@ -25,8 +25,33 @@ const KeyNames = {
 | 
				
			|||||||
  76: 'KeyL',
 | 
					  76: 'KeyL',
 | 
				
			||||||
  77: 'KeyM'
 | 
					  77: 'KeyM'
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					const Hotkeys = {
 | 
				
			||||||
 | 
					  AudioPlayer: {
 | 
				
			||||||
 | 
					    PLAY_PAUSE: 'Space',
 | 
				
			||||||
 | 
					    JUMP_FORWARD: 'ArrowRight',
 | 
				
			||||||
 | 
					    JUMP_BACKWARD: 'ArrowLeft',
 | 
				
			||||||
 | 
					    VOLUME_UP: 'ArrowUp',
 | 
				
			||||||
 | 
					    VOLUME_DOWN: 'ArrowDown',
 | 
				
			||||||
 | 
					    MUTE_UNMUTE: 'KeyM',
 | 
				
			||||||
 | 
					    SHOW_CHAPTERS: 'KeyL',
 | 
				
			||||||
 | 
					    INCREASE_PLAYBACK_RATE: 'Shift-ArrowUp',
 | 
				
			||||||
 | 
					    DECREASE_PLAYBACK_RATE: 'Shift-ArrowDown',
 | 
				
			||||||
 | 
					    CLOSE: 'Escape'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  EReader: {
 | 
				
			||||||
 | 
					    NEXT_PAGE: 'ArrowRight',
 | 
				
			||||||
 | 
					    PREV_PAGE: 'ArrowLeft',
 | 
				
			||||||
 | 
					    CLOSE: 'Escape'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  Modal: {
 | 
				
			||||||
 | 
					    NEXT_PAGE: 'ArrowRight',
 | 
				
			||||||
 | 
					    PREV_PAGE: 'ArrowLeft',
 | 
				
			||||||
 | 
					    CLOSE: 'Escape'
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default ({ app }, inject) => {
 | 
					export default ({ app }, inject) => {
 | 
				
			||||||
  inject('constants', Constants)
 | 
					  inject('constants', Constants)
 | 
				
			||||||
  inject('keynames', KeyNames)
 | 
					  inject('keynames', KeyNames)
 | 
				
			||||||
 | 
					  inject('hotkeys', Hotkeys)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -54,11 +54,9 @@ class AudiobookProgress {
 | 
				
			|||||||
    // If has < 10 seconds remaining mark as read
 | 
					    // If has < 10 seconds remaining mark as read
 | 
				
			||||||
    var timeRemaining = this.totalDuration - this.currentTime
 | 
					    var timeRemaining = this.totalDuration - this.currentTime
 | 
				
			||||||
    if (timeRemaining < 10) {
 | 
					    if (timeRemaining < 10) {
 | 
				
			||||||
      if (!this.isRead) {
 | 
					 | 
				
			||||||
      this.isRead = true
 | 
					      this.isRead = true
 | 
				
			||||||
      this.progress = 1
 | 
					      this.progress = 1
 | 
				
			||||||
      this.finishedAt = Date.now()
 | 
					      this.finishedAt = Date.now()
 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      this.isRead = false
 | 
					      this.isRead = false
 | 
				
			||||||
      this.finishedAt = null
 | 
					      this.finishedAt = null
 | 
				
			||||||
 | 
				
			|||||||
@ -88,7 +88,8 @@ class Stream extends EventEmitter {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  get clientProgress() {
 | 
					  get clientProgress() {
 | 
				
			||||||
    if (!this.clientCurrentTime) return 0
 | 
					    if (!this.clientCurrentTime) return 0
 | 
				
			||||||
    return Number((this.clientCurrentTime / this.totalDuration).toFixed(3))
 | 
					    var prog = Math.max(1, this.clientCurrentTime / this.totalDuration)
 | 
				
			||||||
 | 
					    return Number(prog.toFixed(3))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  toJSON() {
 | 
					  toJSON() {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user