diff options
Diffstat (limited to 'beamer/viewer/viewer.js')
-rw-r--r-- | beamer/viewer/viewer.js | 100 |
1 files changed, 68 insertions, 32 deletions
diff --git a/beamer/viewer/viewer.js b/beamer/viewer/viewer.js index 414ff1c..e8deb51 100644 --- a/beamer/viewer/viewer.js +++ b/beamer/viewer/viewer.js | |||
@@ -1,19 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Beamer Viewer, a web-based PDF presentation viewer | 2 | * Beamer Viewer, a web-based PDF presentation viewer |
3 | * Copyright (C) 2018 Pacien TRAN-GIRARD | 3 | * Copyright 2018-2024 Pacien TRAN-GIRARD |
4 | * | 4 | * SPDX-License-Identifier: EUPL-1.2 |
5 | * This program is free software: you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU Affero General Public License as | ||
7 | * published by the Free Software Foundation, either version 3 of the | ||
8 | * License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | */ | 5 | */ |
18 | 6 | ||
19 | "use strict"; | 7 | "use strict"; |
@@ -21,13 +9,23 @@ | |||
21 | class Viewer { | 9 | class Viewer { |
22 | constructor() { | 10 | constructor() { |
23 | this.fileInput = document.getElementById("fileInput"); | 11 | this.fileInput = document.getElementById("fileInput"); |
12 | this.startButton = document.getElementById("startButton"); | ||
13 | |||
14 | this.fileReader = new FileReader(); | ||
15 | this.presentation = null; | ||
16 | |||
17 | document.addEventListener("DOMContentLoaded", () => this._unlockUi()); | ||
24 | this._listenForInput(); | 18 | this._listenForInput(); |
25 | } | 19 | } |
26 | 20 | ||
27 | load(source) { | 21 | _unlockUi() { |
28 | pdfjsLib.getDocument(source).then(function(pdf) { | 22 | this.fileInput.disabled = false; |
29 | const presentation = new Presentation(pdf); | 23 | } |
30 | }).catch(function(error) { | 24 | |
25 | _preparePresentation(source) { | ||
26 | pdfjsLib.getDocument(source).then(pdf => { | ||
27 | this.presentation = new Presentation(pdf); | ||
28 | }).catch(error => { | ||
31 | console.error(error); | 29 | console.error(error); |
32 | window.alert("Error while loading presentation:\n\n" + error.message); | 30 | window.alert("Error while loading presentation:\n\n" + error.message); |
33 | window.location.href = window.location.pathname; // reload without "?file=..." | 31 | window.location.href = window.location.pathname; // reload without "?file=..." |
@@ -35,31 +33,69 @@ class Viewer { | |||
35 | } | 33 | } |
36 | 34 | ||
37 | _readFile(file) { | 35 | _readFile(file) { |
38 | const fileReader = new FileReader(); | 36 | this.fileReader.onload = () => { |
39 | const self = this; | 37 | this._setPresentation(new Uint8Array(this.fileReader.result)); |
40 | fileReader.onload = function() { | 38 | }; |
41 | const byteArray = new Uint8Array(this.result); | 39 | |
42 | self.load(byteArray); | 40 | this.fileReader.abort(); |
43 | } | 41 | this.fileReader.readAsArrayBuffer(file); |
44 | 42 | } | |
45 | fileReader.readAsArrayBuffer(file); | 43 | |
44 | _setPresentation(presentation) { | ||
45 | this._preparePresentation(presentation); | ||
46 | this.startButton.disabled = false; | ||
47 | } | ||
48 | |||
49 | _setFileName(name) { | ||
50 | const dummy = new DataTransfer(); | ||
51 | dummy.items.add(new File([], name)); | ||
52 | this.fileInput.files = dummy.files; | ||
53 | } | ||
54 | |||
55 | _loadFromUrl(url) { | ||
56 | this._setFileName(url); | ||
57 | this._setPresentation(url); | ||
46 | } | 58 | } |
47 | 59 | ||
48 | _listenForInput() { | 60 | _listenForInput() { |
49 | const self = this; | 61 | fileInput.addEventListener("change", event => { |
50 | fileInput.addEventListener("change", function(event) { | 62 | this._readFile(event.target.files[0]); |
51 | self._readFile(event.target.files[0]); | 63 | }); |
64 | |||
65 | startButton.addEventListener("click", event => { | ||
66 | event.preventDefault(); | ||
67 | event.stopPropagation(); | ||
68 | this.presentation.start(); | ||
52 | }); | 69 | }); |
53 | 70 | ||
54 | document.body.addEventListener("drop", function(event) { | 71 | document.body.addEventListener("drop", event => { |
55 | event.preventDefault(); | 72 | event.preventDefault(); |
56 | event.stopPropagation(); | 73 | event.stopPropagation(); |
57 | self._readFile(event.dataTransfer.files[0]); | 74 | this.fileInput.files = event.dataTransfer.files; |
75 | this._readFile(event.dataTransfer.files[0]); | ||
58 | }); | 76 | }); |
59 | 77 | ||
60 | document.body.addEventListener("dragover", function(event) { | 78 | document.body.addEventListener("dragover", event => { |
61 | event.preventDefault(); | 79 | event.preventDefault(); |
62 | event.stopPropagation(); | 80 | event.stopPropagation(); |
63 | }); | 81 | }); |
82 | |||
83 | window.addEventListener('load', () => this._on_hash_change()); | ||
84 | window.addEventListener('hashchange', () => this._on_hash_change()); | ||
85 | } | ||
86 | |||
87 | _on_hash_change() { | ||
88 | const params = this._hash_params(); | ||
89 | if ("file" in params) | ||
90 | this._loadFromUrl(params["file"]); | ||
91 | } | ||
92 | |||
93 | _hash_params() { | ||
94 | return Object.fromEntries( | ||
95 | location.hash | ||
96 | .slice(1) // skip # | ||
97 | .split("&") | ||
98 | .map(item => item.split("=")) | ||
99 | ); | ||
64 | } | 100 | } |
65 | } | 101 | } |