forked from izu/student-web-if-development-kit
123 lines
4.4 KiB
JavaScript
123 lines
4.4 KiB
JavaScript
import { FileDownloader } from '../services/file-downloader.js';
|
|
import { ViewerApi } from './viewer-api.js';
|
|
|
|
export class FileViewer {
|
|
constructor() {
|
|
const params = new URLSearchParams(window.location.search);
|
|
this.id = params.get('id');
|
|
this.name = params.get('name') || 'Dokumen';
|
|
this.type = (params.get('type') || 'pdf').toLowerCase();
|
|
|
|
this.titleEl = document.getElementById('viewer-title');
|
|
this.typeBadgeEl = document.getElementById('viewer-type');
|
|
this.downloadEl = document.getElementById('viewer-download');
|
|
this.contentEl = document.getElementById('viewer-content');
|
|
|
|
this.assetUrl = this.id ? ViewerApi.assetUrl(this.id) : null;
|
|
}
|
|
|
|
async init() {
|
|
if (!this.id) {
|
|
this._renderError('Parameter berkas tidak ditemukan di URL.');
|
|
return;
|
|
}
|
|
|
|
document.title = `${this.name} — Pratinjau Dokumen`;
|
|
this.titleEl.textContent = this.name;
|
|
this.typeBadgeEl.textContent = this.type.toUpperCase();
|
|
this._setupDownload();
|
|
|
|
try {
|
|
if (this._isOfficeType()) {
|
|
this._renderOfficeOnline();
|
|
} else if (this.type === 'pdf') {
|
|
this._renderPdf();
|
|
} else {
|
|
this._renderUnsupported();
|
|
}
|
|
} catch (err) {
|
|
console.error(err);
|
|
this._renderError('Gagal memuat pratinjau berkas. Silakan unduh berkas untuk membuka secara lokal.');
|
|
}
|
|
}
|
|
|
|
_setupDownload() {
|
|
const ext = `.${this.type}`;
|
|
const filename = this.name.toLowerCase().endsWith(ext) ? this.name : `${this.name}${ext}`;
|
|
|
|
this.downloadEl.href = FileDownloader.originalDownloadUrl(this.assetUrl);
|
|
this.downloadEl.download = filename;
|
|
this.downloadEl.style.cursor = 'pointer';
|
|
this.downloadEl.addEventListener('click', async event => {
|
|
event.preventDefault();
|
|
const originalHtml = this.downloadEl.innerHTML;
|
|
this.downloadEl.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Mengunduh…';
|
|
this.downloadEl.style.pointerEvents = 'none';
|
|
try {
|
|
await FileDownloader.download(this.assetUrl, filename);
|
|
} catch (err) {
|
|
console.warn('Blob download failed, falling back:', err);
|
|
window.open(FileDownloader.originalDownloadUrl(this.assetUrl), '_blank');
|
|
} finally {
|
|
this.downloadEl.innerHTML = originalHtml;
|
|
this.downloadEl.style.pointerEvents = '';
|
|
}
|
|
});
|
|
}
|
|
|
|
_isOfficeType() {
|
|
return ['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx'].includes(this.type);
|
|
}
|
|
|
|
_renderOfficeOnline() {
|
|
const iframe = document.createElement('iframe');
|
|
iframe.className = 'viewer-office-frame';
|
|
iframe.title = this.name;
|
|
iframe.src = `https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(this.assetUrl)}`;
|
|
iframe.setAttribute('frameborder', '0');
|
|
iframe.setAttribute('allowfullscreen', '');
|
|
this.contentEl.replaceChildren(iframe);
|
|
}
|
|
|
|
_renderPdf() {
|
|
const iframe = document.createElement('iframe');
|
|
iframe.className = 'viewer-pdf-frame';
|
|
iframe.title = this.name;
|
|
iframe.src = this.assetUrl;
|
|
this.contentEl.replaceChildren(iframe);
|
|
}
|
|
|
|
_renderUnsupported() {
|
|
const wrapper = document.createElement('div');
|
|
wrapper.className = 'viewer-error';
|
|
|
|
const icon = document.createElement('i');
|
|
icon.className = 'fas fa-file';
|
|
|
|
const span = document.createElement('span');
|
|
span.textContent = `Pratinjau tidak tersedia untuk format ${this.type.toUpperCase()}. Silakan unduh berkas.`;
|
|
|
|
wrapper.append(icon, span);
|
|
this.contentEl.replaceChildren(wrapper);
|
|
}
|
|
|
|
_renderError(message) {
|
|
const wrapper = document.createElement('div');
|
|
wrapper.className = 'viewer-error';
|
|
|
|
const icon = document.createElement('i');
|
|
icon.className = 'fas fa-exclamation-triangle';
|
|
|
|
const span = document.createElement('span');
|
|
span.textContent = message;
|
|
|
|
const back = document.createElement('a');
|
|
back.href = 'index.html#repository';
|
|
back.className = 'btn-back-mini';
|
|
back.textContent = 'Kembali ke Repositori';
|
|
|
|
wrapper.append(icon, span, back);
|
|
this.contentEl.replaceChildren(wrapper);
|
|
}
|
|
}
|