Skip to content

Commit 2606062

Browse files
André DietrichAndré Dietrich
authored andcommitted
Add pdf preview support
1 parent dc9c51e commit 2606062

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

src/components/Editor.vue

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
isImageFile,
1212
isAudioFile,
1313
isVideoFile,
14+
isPdfFile,
1415
} from "../ts/ProjectDoc";
1516
import { editor, KeyMod, KeyCode, languages, IDisposable } from "monaco-editor";
1617
import * as Utils from "../ts/utils";
@@ -133,10 +134,11 @@ export default {
133134
activePath: "",
134135
previewPath: "",
135136
activeMime: "",
136-
activeView: "text" as "text" | "image" | "video" | "audio" | "binary",
137+
activeView: "text" as "text" | "image" | "video" | "audio" | "pdf" | "binary",
137138
imageUrl: "",
138139
videoUrl: "",
139140
audioUrl: "",
141+
pdfUrl: "",
140142
};
141143
},
142144
@@ -313,6 +315,13 @@ export default {
313315
this.videoUrl = url;
314316
},
315317
318+
setPdf(url: string) {
319+
if (this.pdfUrl && this.pdfUrl !== url) {
320+
URL.revokeObjectURL(this.pdfUrl);
321+
}
322+
this.pdfUrl = url;
323+
},
324+
316325
// Swap the Monaco model + collaborative binding to a different Y.Text.
317326
bindDoc(yText: any, language: string) {
318327
if (!Editor) return;
@@ -347,6 +356,8 @@ export default {
347356
if (!this.projectDoc) return;
348357
this.setImage("");
349358
this.setVideo("");
359+
this.setAudio("");
360+
this.setPdf("");
350361
this.activePath = "";
351362
this.activeMime = "";
352363
this.activeView = "text";
@@ -371,6 +382,7 @@ export default {
371382
const data = this.projectDoc.readFileData(path);
372383
this.setVideo("");
373384
this.setAudio("");
385+
this.setPdf("");
374386
this.setImage(
375387
data ? URL.createObjectURL(new Blob([data as BlobPart], { type: mime || "" })) : ""
376388
);
@@ -382,6 +394,7 @@ export default {
382394
const data = this.projectDoc.readFileData(path);
383395
this.setImage("");
384396
this.setVideo("");
397+
this.setPdf("");
385398
this.setAudio(
386399
data ? URL.createObjectURL(new Blob([data as BlobPart], { type: mime || "audio/mpeg" })) : ""
387400
);
@@ -393,17 +406,31 @@ export default {
393406
const data = this.projectDoc.readFileData(path);
394407
this.setImage("");
395408
this.setAudio("");
409+
this.setPdf("");
396410
this.setVideo(
397411
data ? URL.createObjectURL(new Blob([data as BlobPart], { type: mime || "video/webm" })) : ""
398412
);
399413
this.activeView = "video";
400414
return;
401415
}
402416
417+
if (isPdfFile(path, mime)) {
418+
const data = this.projectDoc.readFileData(path);
419+
this.setImage("");
420+
this.setAudio("");
421+
this.setVideo("");
422+
this.setPdf(
423+
data ? URL.createObjectURL(new Blob([data as BlobPart], { type: "application/pdf" })) : ""
424+
);
425+
this.activeView = "pdf";
426+
return;
427+
}
428+
403429
if (isTextFile(path, mime)) {
404430
this.setImage("");
405431
this.setVideo("");
406432
this.setAudio("");
433+
this.setPdf("");
407434
this.activeView = "text";
408435
const language = this.languageFor(path);
409436
this.bindDoc(this.projectDoc.getText(path), language);
@@ -417,6 +444,8 @@ export default {
417444
418445
this.setImage("");
419446
this.setVideo("");
447+
this.setAudio("");
448+
this.setPdf("");
420449
this.activeView = "binary";
421450
},
422451
@@ -2045,6 +2074,10 @@ I (study) ~[[ am going to study ]]~ harder this term.
20452074
<video v-if="videoUrl" :key="videoUrl" :src="videoUrl" controls></video>
20462075
</div>
20472076

2077+
<div v-show="activeView === 'pdf'" class="lia-file-view lia-pdf-view">
2078+
<iframe v-if="pdfUrl" :key="pdfUrl" :src="pdfUrl" :title="activePath"></iframe>
2079+
</div>
2080+
20482081
<div v-show="activeView === 'binary'" class="lia-file-view lia-binary-view">
20492082
<p>
20502083
<i class="bi bi-file-earmark-binary"></i><br />
@@ -2101,6 +2134,16 @@ I (study) ~[[ am going to study ]]~ harder this term.
21012134
max-height: 100%;
21022135
}
21032136
2137+
.lia-pdf-view {
2138+
padding: 0;
2139+
}
2140+
2141+
.lia-pdf-view iframe {
2142+
width: 100%;
2143+
height: 100%;
2144+
border: none;
2145+
}
2146+
21042147
.lia-binary-view {
21052148
background-color: #f6f6f6;
21062149
color: #777;

src/ts/ProjectDoc.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ export function isVideoFile(path: string, mime?: string): boolean {
7878
return VIDEO_EXTENSIONS.has(extensionOf(path));
7979
}
8080

81+
/** Decide whether a path should be displayed as a PDF document. */
82+
export function isPdfFile(path: string, mime?: string): boolean {
83+
if ((mime || "").toLowerCase() === "application/pdf") return true;
84+
return extensionOf(path) === "pdf";
85+
}
86+
8187
export type FileType = "file" | "folder";
8288

8389
export interface FileMeta {

0 commit comments

Comments
 (0)