From 75666e523f84ab1e1f41fd050e8a0c179cc5b24f Mon Sep 17 00:00:00 2001 From: advplyr Date: Tue, 6 Dec 2022 17:07:27 -0600 Subject: [PATCH] Add:PDF EReader #420 --- components/readers/PdfReader.vue | 79 +++++++++++ components/readers/Reader.vue | 24 +++- package-lock.json | 218 +++++++++++++++++++++++++++++++ package.json | 1 + pages/item/_id.vue | 2 +- 5 files changed, 320 insertions(+), 4 deletions(-) create mode 100644 components/readers/PdfReader.vue diff --git a/components/readers/PdfReader.vue b/components/readers/PdfReader.vue new file mode 100644 index 00000000..a8c69dac --- /dev/null +++ b/components/readers/PdfReader.vue @@ -0,0 +1,79 @@ + + + \ No newline at end of file diff --git a/components/readers/Reader.vue b/components/readers/Reader.vue index 5744fc45..98dedbf8 100644 --- a/components/readers/Reader.vue +++ b/components/readers/Reader.vue @@ -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() { diff --git a/package-lock.json b/package-lock.json index 4d7ae4ac..afa3df39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "libarchive.js": "^1.3.0", "nuxt": "^2.15.7", "socket.io-client": "^4.1.3", + "vue-pdf": "^4.2.0", "vue-toastification": "^1.7.11", "vuedraggable": "^2.24.3" }, @@ -4546,6 +4547,11 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha512-MioUE+LfjCEz65Wf7Z/Rm4XCP5k2c+TbMd2Z2JKc7U9uwjBhAfNPE48KC4GTGKhppMeYVepwDBNO/nGY6NYHBA==" + }, "node_modules/backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", @@ -10958,6 +10964,11 @@ "node": ">=0.12" } }, + "node_modules/pdfjs-dist": { + "version": "2.6.347", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.6.347.tgz", + "integrity": "sha512-QC+h7hG2su9v/nU1wEI3SnpPIrqJODL7GTDFvR74ANKGq1AFJW16PH8VWnhpiTi9YcLSFV9xLeWSgq+ckHLdVQ==" + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -14451,6 +14462,25 @@ "node": ">= 0.6" } }, + "node_modules/raw-loader": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", + "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, "node_modules/rc9": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/rc9/-/rc9-1.2.0.tgz", @@ -17184,6 +17214,48 @@ "resolved": "https://registry.npmjs.org/vue-no-ssr/-/vue-no-ssr-1.1.1.tgz", "integrity": "sha512-ZMjqRpWabMPqPc7gIrG0Nw6vRf1+itwf0Itft7LbMXs2g3Zs/NFmevjZGN1x7K3Q95GmIjWbQZTVerxiBxI+0g==" }, + "node_modules/vue-pdf": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/vue-pdf/-/vue-pdf-4.2.0.tgz", + "integrity": "sha512-GpAbZfM48Hom1R8f4XL5ZzoVBLlbyy+4z0VYmTQORVOSieVIIu+XtnNl0RY6EXg60Qni6T6nIgrmsCcCkWv39A==", + "dependencies": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "loader-utils": "^1.4.0", + "pdfjs-dist": "^2.5.207", + "raw-loader": "^4.0.1", + "vue-resize-sensor": "^2.0.0", + "worker-loader": "^2.0.0" + } + }, + "node_modules/vue-pdf/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/vue-pdf/node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/vue-resize-sensor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vue-resize-sensor/-/vue-resize-sensor-2.0.0.tgz", + "integrity": "sha512-W+y2EAI/BxS4Vlcca9scQv8ifeBFck56DRtSwWJ2H4Cw1GLNUYxiZxUHHkuzuI5JPW/cYtL1bPO5xPyEXx4LmQ==" + }, "node_modules/vue-router": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.3.tgz", @@ -18492,6 +18564,57 @@ "errno": "~0.1.7" } }, + "node_modules/worker-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-2.0.0.tgz", + "integrity": "sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==", + "dependencies": { + "loader-utils": "^1.0.0", + "schema-utils": "^0.4.0" + }, + "engines": { + "node": ">= 6.9.0 || >= 8.9.0" + }, + "peerDependencies": { + "webpack": "^3.0.0 || ^4.0.0-alpha.0 || ^4.0.0" + } + }, + "node_modules/worker-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/worker-loader/node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/worker-loader/node_modules/schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -22173,6 +22296,11 @@ "@babel/helper-define-polyfill-provider": "^0.2.4" } }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha512-MioUE+LfjCEz65Wf7Z/Rm4XCP5k2c+TbMd2Z2JKc7U9uwjBhAfNPE48KC4GTGKhppMeYVepwDBNO/nGY6NYHBA==" + }, "backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", @@ -27091,6 +27219,11 @@ "sha.js": "^2.4.8" } }, + "pdfjs-dist": { + "version": "2.6.347", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.6.347.tgz", + "integrity": "sha512-QC+h7hG2su9v/nU1wEI3SnpPIrqJODL7GTDFvR74ANKGq1AFJW16PH8VWnhpiTi9YcLSFV9xLeWSgq+ckHLdVQ==" + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -29674,6 +29807,15 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, + "raw-loader": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", + "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + } + }, "rc9": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/rc9/-/rc9-1.2.0.tgz", @@ -31803,6 +31945,44 @@ "resolved": "https://registry.npmjs.org/vue-no-ssr/-/vue-no-ssr-1.1.1.tgz", "integrity": "sha512-ZMjqRpWabMPqPc7gIrG0Nw6vRf1+itwf0Itft7LbMXs2g3Zs/NFmevjZGN1x7K3Q95GmIjWbQZTVerxiBxI+0g==" }, + "vue-pdf": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/vue-pdf/-/vue-pdf-4.2.0.tgz", + "integrity": "sha512-GpAbZfM48Hom1R8f4XL5ZzoVBLlbyy+4z0VYmTQORVOSieVIIu+XtnNl0RY6EXg60Qni6T6nIgrmsCcCkWv39A==", + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "loader-utils": "^1.4.0", + "pdfjs-dist": "^2.5.207", + "raw-loader": "^4.0.1", + "vue-resize-sensor": "^2.0.0", + "worker-loader": "^2.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "vue-resize-sensor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vue-resize-sensor/-/vue-resize-sensor-2.0.0.tgz", + "integrity": "sha512-W+y2EAI/BxS4Vlcca9scQv8ifeBFck56DRtSwWJ2H4Cw1GLNUYxiZxUHHkuzuI5JPW/cYtL1bPO5xPyEXx4LmQ==" + }, "vue-router": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.3.tgz", @@ -32820,6 +33000,44 @@ "errno": "~0.1.7" } }, + "worker-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-2.0.0.tgz", + "integrity": "sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==", + "requires": { + "loader-utils": "^1.0.0", + "schema-utils": "^0.4.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index 46c85f8b..84ae328f 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "libarchive.js": "^1.3.0", "nuxt": "^2.15.7", "socket.io-client": "^4.1.3", + "vue-pdf": "^4.2.0", "vue-toastification": "^1.7.11", "vuedraggable": "^2.24.3" }, diff --git a/pages/item/_id.vue b/pages/item/_id.vue index e4a4bcee..de4115c5 100644 --- a/pages/item/_id.vue +++ b/pages/item/_id.vue @@ -335,7 +335,7 @@ export default { return !this.isMissing && !this.isIncomplete && (this.numTracks || this.episodes.length) }, showRead() { - return this.ebookFile && this.ebookFormat !== 'pdf' + return this.ebookFile }, showDownload() { if (this.isPodcast) return false