diff --git a/client/components/AudioPlayer.vue b/client/components/AudioPlayer.vue index b4ce3d22..cf3e8e96 100644 --- a/client/components/AudioPlayer.vue +++ b/client/components/AudioPlayer.vue @@ -346,7 +346,7 @@ export default { return } var lastbuff = this.getLastBufferedTime() - this.sendStreamUpdate() + var bufferlen = (lastbuff / this.audioEl.duration) * this.trackWidth bufferlen = Math.round(bufferlen) if (this.bufferTrackWidth === bufferlen || !this.$refs.bufferTrack) return @@ -372,6 +372,7 @@ export default { } this.updateTimestamp() + this.sendStreamUpdate() this.currentTime = this.audioEl.currentTime @@ -535,16 +536,16 @@ export default { this.$emit('close') }, hotkey(action) { - if (action === 'Space') this.playPauseClick() - else if (action === 'ArrowRight') this.forward10() - else if (action === 'ArrowLeft') this.backward10() - else if (action === 'ArrowUp') this.volumeUp() - else if (action === 'ArrowDown') this.volumeDown() - else if (action === 'KeyM') this.toggleMute() - else if (action === 'KeyL') this.showChapters() - else if (action === 'Shift-ArrowUp') this.increasePlaybackRate() - else if (action === 'Shift-ArrowDown') this.decreasePlaybackRate() - else if (action === 'Escape') this.closePlayer() + if (action === this.$hotkeys.AudioPlayer.PLAY_PAUSE) this.playPauseClick() + else if (action === this.$hotkeys.AudioPlayer.JUMP_FORWARD) this.forward10() + else if (action === this.$hotkeys.AudioPlayer.JUMP_BACKWARD) this.backward10() + else if (action === this.$hotkeys.AudioPlayer.VOLUME_UP) this.volumeUp() + else if (action === this.$hotkeys.AudioPlayer.VOLUME_DOWN) this.volumeDown() + else if (action === this.$hotkeys.AudioPlayer.MUTE_UNMUTE) this.toggleMute() + else if (action === this.$hotkeys.AudioPlayer.SHOW_CHAPTERS) this.showChapters() + else if (action === this.$hotkeys.AudioPlayer.INCREASE_PLAYBACK_RATE) this.increasePlaybackRate() + else if (action === this.$hotkeys.AudioPlayer.DECREASE_PLAYBACK_RATE) this.decreasePlaybackRate() + else if (action === this.$hotkeys.AudioPlayer.CLOSE) this.closePlayer() }, windowResize() { this.setTrackWidth() diff --git a/client/components/app/StreamContainer.vue b/client/components/app/StreamContainer.vue index 721138b0..8980c906 100644 --- a/client/components/app/StreamContainer.vue +++ b/client/components/app/StreamContainer.vue @@ -148,7 +148,10 @@ export default { currentTime, streamId: this.streamId } + console.log('Stream update', updatePayload.currentTime) this.$root.socket.emit('stream_update', updatePayload) + } else { + console.log('Do not update time', diff) } }, streamReset({ startTime, streamId }) { diff --git a/client/components/modals/EditModal.vue b/client/components/modals/EditModal.vue index 3ba9a523..aaa44f10 100644 --- a/client/components/modals/EditModal.vue +++ b/client/components/modals/EditModal.vue @@ -218,9 +218,9 @@ export default { } }, hotkey(action) { - if (action === 'ArrowRight') { + if (action === this.$hotkeys.Modal.NEXT_PAGE) { this.goNextBook() - } else if (action === 'ArrowLeft') { + } else if (action === this.$hotkeys.Modal.PREV_PAGE) { this.goPrevBook() } }, diff --git a/client/components/modals/Modal.vue b/client/components/modals/Modal.vue index e3c42ff2..d9b667eb 100644 --- a/client/components/modals/Modal.vue +++ b/client/components/modals/Modal.vue @@ -84,7 +84,7 @@ export default { } }, hotkey(action) { - if (action === 'Escape') { + if (action === this.$hotkeys.Modal.CLOSE) { this.show = false } }, diff --git a/client/components/readers/Reader.vue b/client/components/readers/Reader.vue index ac41776a..b2db883f 100644 --- a/client/components/readers/Reader.vue +++ b/client/components/readers/Reader.vue @@ -91,11 +91,11 @@ export default { console.log('Reader hotkey', action) if (!this.$refs.readerComponent) return - if (action === 'ArrowRight') { + if (action === this.$hotkeys.EReader.NEXT_PAGE) { 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() - } else if (action === 'Escape') { + } else if (action === this.$hotkeys.EReader.CLOSE) { this.close() } }, @@ -114,21 +114,17 @@ export default { this.ebookType = 'pdf' } else if (this.selectedAudiobookFile.ext === '.mobi' || this.selectedAudiobookFile.ext === '.azw3') { this.ebookType = 'mobi' - // this.initMobi() } else if (this.selectedAudiobookFile.ext === '.epub') { this.ebookType = 'epub' - // this.initEpub() } else if (this.selectedAudiobookFile.ext === '.cbr' || this.selectedAudiobookFile.ext === '.cbz') { this.ebookType = 'comic' } } else if (this.epubEbook) { this.ebookType = 'epub' this.ebookUrl = this.getEbookUrl(this.epubEbook.path) - // this.initEpub() } else if (this.mobiEbook) { this.ebookType = 'mobi' this.ebookUrl = this.getEbookUrl(this.mobiEbook.path) - // this.initMobi() } else if (this.pdfEbook) { this.ebookType = 'pdf' this.ebookUrl = this.getEbookUrl(this.pdfEbook.path) diff --git a/client/layouts/default.vue b/client/layouts/default.vue index 661e2d12..6bff319f 100644 --- a/client/layouts/default.vue +++ b/client/layouts/default.vue @@ -331,20 +331,24 @@ export default { var inputs = ['input', 'select', 'button', 'textarea'] return activeElement && inputs.indexOf(activeElement.tagName.toLowerCase()) !== -1 }, - keyUp(e) { + getHotkeyName(e) { var keyCode = e.keyCode || e.which if (!this.$keynames[keyCode]) { // Unused hotkey - return + 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()) { @@ -352,34 +356,36 @@ export default { } // 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) + e.preventDefault() return } // 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) + e.preventDefault() return } // Batch selecting - if (this.$store.getters['getNumAudiobooksSelected']) { + if (this.$store.getters['getNumAudiobooksSelected'] && name === 'Escape') { // ESCAPE key cancels batch selection - if (name === 'Escape') { - this.$store.commit('setSelectedAudiobooks', []) - } + this.$store.commit('setSelectedAudiobooks', []) + e.preventDefault() return } // 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) + e.preventDefault() } } }, mounted() { - document.addEventListener('keyup', this.keyUp) + window.addEventListener('keydown', this.keyDown) this.initializeSocket() this.$store.dispatch('libraries/load') @@ -403,7 +409,7 @@ export default { } }, beforeDestroy() { - document.removeEventListener('keyup', this.keyUp) + window.removeEventListener('keydown', this.keyDown) } } diff --git a/client/plugins/constants.js b/client/plugins/constants.js index a4e4849a..6c2fb551 100644 --- a/client/plugins/constants.js +++ b/client/plugins/constants.js @@ -25,8 +25,33 @@ const KeyNames = { 76: 'KeyL', 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) => { inject('constants', Constants) inject('keynames', KeyNames) + inject('hotkeys', Hotkeys) } \ No newline at end of file diff --git a/server/objects/AudiobookProgress.js b/server/objects/AudiobookProgress.js index 8202a884..aad56489 100644 --- a/server/objects/AudiobookProgress.js +++ b/server/objects/AudiobookProgress.js @@ -54,11 +54,9 @@ class AudiobookProgress { // If has < 10 seconds remaining mark as read var timeRemaining = this.totalDuration - this.currentTime if (timeRemaining < 10) { - if (!this.isRead) { - this.isRead = true - this.progress = 1 - this.finishedAt = Date.now() - } + this.isRead = true + this.progress = 1 + this.finishedAt = Date.now() } else { this.isRead = false this.finishedAt = null diff --git a/server/objects/Stream.js b/server/objects/Stream.js index b58d4676..a6d3717f 100644 --- a/server/objects/Stream.js +++ b/server/objects/Stream.js @@ -88,7 +88,8 @@ class Stream extends EventEmitter { get clientProgress() { 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() {