Spaces:
Running
Running
Commit ·
e31557b
1
Parent(s): 8849c11
Fix PDF preview in DocumentVault
Browse files- js/main.js +50 -3
js/main.js
CHANGED
|
@@ -11,6 +11,7 @@ class App {
|
|
| 11 |
this.pendingDelete = null;
|
| 12 |
this.pendingRename = null;
|
| 13 |
this.cachedFolders = [];
|
|
|
|
| 14 |
this.init();
|
| 15 |
}
|
| 16 |
|
|
@@ -167,7 +168,12 @@ class App {
|
|
| 167 |
// Modals Close via X button
|
| 168 |
document.querySelectorAll('.close-modal').forEach(btn => {
|
| 169 |
btn.onclick = () => {
|
| 170 |
-
btn.closest('.modal-overlay')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
};
|
| 172 |
});
|
| 173 |
|
|
@@ -175,7 +181,11 @@ class App {
|
|
| 175 |
document.querySelectorAll('.modal-overlay').forEach(overlay => {
|
| 176 |
overlay.addEventListener('click', (e) => {
|
| 177 |
if (e.target === overlay) {
|
| 178 |
-
overlay.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
sidebar.classList.remove('mobile-open');
|
| 180 |
}
|
| 181 |
});
|
|
@@ -500,6 +510,13 @@ class App {
|
|
| 500 |
body.innerHTML = '<div class="loading-state"><div class="spinner"></div><p>Loading preview...</p></div>';
|
| 501 |
modal.classList.add('active');
|
| 502 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 503 |
if (downloadBtn) {
|
| 504 |
downloadBtn.onclick = () => this.downloadFile(`${url}?download=true`, file.name);
|
| 505 |
}
|
|
@@ -509,6 +526,7 @@ class App {
|
|
| 509 |
}
|
| 510 |
|
| 511 |
if (isImage(file.name)) {
|
|
|
|
| 512 |
const img = new Image();
|
| 513 |
img.src = url;
|
| 514 |
img.className = 'preview-image';
|
|
@@ -523,11 +541,30 @@ class App {
|
|
| 523 |
}
|
| 524 |
|
| 525 |
if (isPDF(file.name)) {
|
| 526 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 527 |
return;
|
| 528 |
}
|
| 529 |
|
| 530 |
if (isText(file.name)) {
|
|
|
|
| 531 |
try {
|
| 532 |
const response = await fetch(url, { headers: { 'X-User-ID': 'default_user' } });
|
| 533 |
if (!response.ok) {
|
|
@@ -546,6 +583,7 @@ class App {
|
|
| 546 |
return;
|
| 547 |
}
|
| 548 |
|
|
|
|
| 549 |
body.innerHTML = this.previewFallback(
|
| 550 |
file.name,
|
| 551 |
`${url}?download=true`,
|
|
@@ -575,6 +613,15 @@ class App {
|
|
| 575 |
link.remove();
|
| 576 |
}
|
| 577 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 578 |
async openHistory(path, name) {
|
| 579 |
this.ui.showHistoryModal(name);
|
| 580 |
try {
|
|
|
|
| 11 |
this.pendingDelete = null;
|
| 12 |
this.pendingRename = null;
|
| 13 |
this.cachedFolders = [];
|
| 14 |
+
this.currentPreviewObjectUrl = null;
|
| 15 |
this.init();
|
| 16 |
}
|
| 17 |
|
|
|
|
| 168 |
// Modals Close via X button
|
| 169 |
document.querySelectorAll('.close-modal').forEach(btn => {
|
| 170 |
btn.onclick = () => {
|
| 171 |
+
const modal = btn.closest('.modal-overlay');
|
| 172 |
+
if (modal && modal.id === 'previewModal') {
|
| 173 |
+
this.closePreviewModal();
|
| 174 |
+
return;
|
| 175 |
+
}
|
| 176 |
+
modal.classList.remove('active');
|
| 177 |
};
|
| 178 |
});
|
| 179 |
|
|
|
|
| 181 |
document.querySelectorAll('.modal-overlay').forEach(overlay => {
|
| 182 |
overlay.addEventListener('click', (e) => {
|
| 183 |
if (e.target === overlay) {
|
| 184 |
+
if (overlay.id === 'previewModal') {
|
| 185 |
+
this.closePreviewModal();
|
| 186 |
+
} else {
|
| 187 |
+
overlay.classList.remove('active');
|
| 188 |
+
}
|
| 189 |
sidebar.classList.remove('mobile-open');
|
| 190 |
}
|
| 191 |
});
|
|
|
|
| 510 |
body.innerHTML = '<div class="loading-state"><div class="spinner"></div><p>Loading preview...</p></div>';
|
| 511 |
modal.classList.add('active');
|
| 512 |
|
| 513 |
+
const clearPreviewObjectUrl = () => {
|
| 514 |
+
if (this.currentPreviewObjectUrl) {
|
| 515 |
+
URL.revokeObjectURL(this.currentPreviewObjectUrl);
|
| 516 |
+
this.currentPreviewObjectUrl = null;
|
| 517 |
+
}
|
| 518 |
+
};
|
| 519 |
+
|
| 520 |
if (downloadBtn) {
|
| 521 |
downloadBtn.onclick = () => this.downloadFile(`${url}?download=true`, file.name);
|
| 522 |
}
|
|
|
|
| 526 |
}
|
| 527 |
|
| 528 |
if (isImage(file.name)) {
|
| 529 |
+
clearPreviewObjectUrl();
|
| 530 |
const img = new Image();
|
| 531 |
img.src = url;
|
| 532 |
img.className = 'preview-image';
|
|
|
|
| 541 |
}
|
| 542 |
|
| 543 |
if (isPDF(file.name)) {
|
| 544 |
+
try {
|
| 545 |
+
clearPreviewObjectUrl();
|
| 546 |
+
const response = await fetch(`${url}?download=true`, {
|
| 547 |
+
headers: { 'X-User-ID': 'default_user' }
|
| 548 |
+
});
|
| 549 |
+
if (!response.ok) {
|
| 550 |
+
throw new Error(`PDF preview failed: ${response.status}`);
|
| 551 |
+
}
|
| 552 |
+
|
| 553 |
+
const pdfBlob = await response.blob();
|
| 554 |
+
this.currentPreviewObjectUrl = URL.createObjectURL(pdfBlob);
|
| 555 |
+
body.innerHTML = `<iframe src="${this.currentPreviewObjectUrl}" class="preview-iframe" title="${file.name}"></iframe>`;
|
| 556 |
+
} catch (err) {
|
| 557 |
+
body.innerHTML = this.previewFallback(
|
| 558 |
+
file.name,
|
| 559 |
+
`${url}?download=true`,
|
| 560 |
+
err.message || 'PDF preview is unavailable.'
|
| 561 |
+
);
|
| 562 |
+
}
|
| 563 |
return;
|
| 564 |
}
|
| 565 |
|
| 566 |
if (isText(file.name)) {
|
| 567 |
+
clearPreviewObjectUrl();
|
| 568 |
try {
|
| 569 |
const response = await fetch(url, { headers: { 'X-User-ID': 'default_user' } });
|
| 570 |
if (!response.ok) {
|
|
|
|
| 583 |
return;
|
| 584 |
}
|
| 585 |
|
| 586 |
+
clearPreviewObjectUrl();
|
| 587 |
body.innerHTML = this.previewFallback(
|
| 588 |
file.name,
|
| 589 |
`${url}?download=true`,
|
|
|
|
| 613 |
link.remove();
|
| 614 |
}
|
| 615 |
|
| 616 |
+
closePreviewModal() {
|
| 617 |
+
if (this.currentPreviewObjectUrl) {
|
| 618 |
+
URL.revokeObjectURL(this.currentPreviewObjectUrl);
|
| 619 |
+
this.currentPreviewObjectUrl = null;
|
| 620 |
+
}
|
| 621 |
+
const modal = document.getElementById('previewModal');
|
| 622 |
+
if (modal) modal.classList.remove('active');
|
| 623 |
+
}
|
| 624 |
+
|
| 625 |
async openHistory(path, name) {
|
| 626 |
this.ui.showHistoryModal(name);
|
| 627 |
try {
|