mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-06 20:08:48 +02:00
Add:PDF EReader #420
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div class="w-full h-full pt-20 relative">
|
||||
<div v-show="canGoPrev" class="absolute top-0 left-0 h-full w-1/2 hover:opacity-100 opacity-0 z-10 cursor-pointer" @click.stop.prevent="prev" @mousedown.prevent>
|
||||
<div class="flex items-center justify-center h-full w-1/2">
|
||||
<span class="material-icons text-5xl text-white cursor-pointer text-opacity-30 hover:text-opacity-90">arrow_back_ios</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="canGoNext" class="absolute top-0 right-0 h-full w-1/2 hover:opacity-100 opacity-0 z-10 cursor-pointer" @click.stop.prevent="next" @mousedown.prevent>
|
||||
<div class="flex items-center justify-center h-full w-1/2 ml-auto">
|
||||
<span class="material-icons text-5xl text-white cursor-pointer text-opacity-30 hover:text-opacity-90">arrow_forward_ios</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="absolute top-0 right-1 bg-bg text-gray-100 border-b border-l border-r border-gray-400 rounded-b-md px-2 h-6 flex items-center text-center">
|
||||
<p class="font-mono text-xs">{{ page }} / {{ numPages }}</p>
|
||||
</div>
|
||||
|
||||
<div :style="{ height: pdfHeight + 'px' }" class="overflow-hidden m-auto">
|
||||
<div class="flex items-center justify-center">
|
||||
<div :style="{ width: pdfWidth + 'px', height: pdfHeight + 'px' }" class="w-full h-full overflow-auto">
|
||||
<div v-if="loadedRatio > 0 && loadedRatio < 1" style="background-color: green; color: white; text-align: center" :style="{ width: loadedRatio * 100 + '%' }">{{ Math.floor(loadedRatio * 100) }}%</div>
|
||||
<pdf ref="pdf" class="m-auto z-10 border border-black border-opacity-20 shadow-md bg-white" :src="url" :page="page" :rotate="rotate" @progress="loadedRatio = $event" @error="error" @num-pages="numPagesLoaded" @link-clicked="page = $event"></pdf>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import pdf from 'vue-pdf'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
pdf
|
||||
},
|
||||
props: {
|
||||
url: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
rotate: 0,
|
||||
loadedRatio: 0,
|
||||
page: 1,
|
||||
numPages: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pdfWidth() {
|
||||
return this.pdfHeight * 0.6667
|
||||
},
|
||||
pdfHeight() {
|
||||
return window.innerHeight - 120
|
||||
},
|
||||
canGoNext() {
|
||||
return this.page < this.numPages
|
||||
},
|
||||
canGoPrev() {
|
||||
return this.page > 1
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
numPagesLoaded(e) {
|
||||
this.numPages = e
|
||||
},
|
||||
prev() {
|
||||
if (this.page <= 1) return
|
||||
this.page--
|
||||
},
|
||||
next() {
|
||||
if (this.page >= this.numPages) return
|
||||
this.page++
|
||||
},
|
||||
error(err) {
|
||||
console.error(err)
|
||||
}
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
@@ -14,7 +14,10 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
touchstartX: 0,
|
||||
touchendX: 0
|
||||
touchstartY: 0,
|
||||
touchendX: 0,
|
||||
touchendY: 0,
|
||||
touchstartTime: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -53,6 +56,7 @@ export default {
|
||||
if (this.ebookType === 'epub') return 'readers-epub-reader'
|
||||
else if (this.ebookType === 'mobi') return 'readers-mobi-reader'
|
||||
else if (this.ebookType === 'comic') return 'readers-comic-reader'
|
||||
else if (this.ebookType === 'pdf') return 'readers-pdf-reader'
|
||||
return null
|
||||
},
|
||||
folderId() {
|
||||
@@ -100,7 +104,8 @@ export default {
|
||||
|
||||
filepath = this.$encodeUriPath(`${itemRelPath}/${relPath}`)
|
||||
}
|
||||
return `/ebook/${this.libraryId}/${this.folderId}/${filepath}`
|
||||
const serverAddress = this.$store.getters['user/getServerAddress']
|
||||
return `${serverAddress}/ebook/${this.libraryId}/${this.folderId}/${filepath}`
|
||||
},
|
||||
playerLibraryItemId() {
|
||||
return this.$store.state.playerLibraryItemId
|
||||
@@ -118,9 +123,19 @@ export default {
|
||||
}
|
||||
},
|
||||
handleGesture() {
|
||||
// Touch must be less than 1s. Must be > 100px drag and X distance > Y distance
|
||||
const touchTimeMs = Date.now() - this.touchstartTime
|
||||
if (touchTimeMs >= 1000) {
|
||||
console.log('Touch too long', touchTimeMs)
|
||||
return
|
||||
}
|
||||
|
||||
const touchDistanceX = Math.abs(this.touchendX - this.touchstartX)
|
||||
const touchDistanceY = Math.abs(this.touchendY - this.touchstartY)
|
||||
if (touchDistanceX < 100 || touchDistanceY > touchDistanceX) return
|
||||
|
||||
if (this.touchendX < this.touchstartX) {
|
||||
console.log('swiped left')
|
||||
|
||||
this.next()
|
||||
}
|
||||
if (this.touchendX > this.touchstartX) {
|
||||
@@ -130,9 +145,12 @@ export default {
|
||||
},
|
||||
touchstart(e) {
|
||||
this.touchstartX = e.changedTouches[0].screenX
|
||||
this.touchstartY = e.changedTouches[0].screenY
|
||||
this.touchstartTime = Date.now()
|
||||
},
|
||||
touchend(e) {
|
||||
this.touchendX = e.changedTouches[0].screenX
|
||||
this.touchendY = e.changedTouches[0].screenY
|
||||
this.handleGesture()
|
||||
},
|
||||
registerListeners() {
|
||||
|
||||
Reference in New Issue
Block a user