Fix docx download: attach click handlers directly to file items, use iframe for reliable download

This commit is contained in:
keboss-m 2026-06-01 12:49:54 +03:00
parent fe0a2a0611
commit 0c1d671c8d

View File

@ -225,6 +225,7 @@ class TranscriptionApp {
} }
container.innerHTML = tree.map(folder => this.renderFolder(folder)).join(''); container.innerHTML = tree.map(folder => this.renderFolder(folder)).join('');
this.attachFileItemListeners();
} }
renderFolder(folder) { renderFolder(folder) {
@ -232,10 +233,9 @@ class TranscriptionApp {
const isMd = file.ext === '.md'; const isMd = file.ext === '.md';
const isDocx = file.ext === '.docx'; const isDocx = file.ext === '.docx';
const icon = isMd ? '📝' : isDocx ? '📄' : '📎'; const icon = isMd ? '📝' : isDocx ? '📄' : '📎';
const clickable = isMd || isDocx ? 'clickable' : '';
return ` return `
<div class="file-item ${clickable}" data-path="${this.escapeHtml(file.path)}" data-ext="${file.ext}"> <div class="file-item" data-path="${this.escapeHtml(file.path)}" data-ext="${file.ext}">
<span class="file-icon">${icon}</span> <span class="file-icon">${icon}</span>
<span class="file-name">${this.escapeHtml(file.name)}</span> <span class="file-name">${this.escapeHtml(file.name)}</span>
<span class="file-size">${this.formatBytes(file.size)}</span> <span class="file-size">${this.formatBytes(file.size)}</span>
@ -288,13 +288,18 @@ class TranscriptionApp {
return; return;
} }
// Open file });
const fileItem = e.target.closest('.file-item.clickable'); }
if (fileItem) {
const path = fileItem.dataset.path; attachFileItemListeners() {
const ext = fileItem.dataset.ext; const container = document.getElementById('fileTree');
container.querySelectorAll('.file-item').forEach(item => {
item.addEventListener('click', (e) => {
e.stopPropagation();
const path = item.dataset.path;
const ext = item.dataset.ext;
this.loadFileContent(path, ext); this.loadFileContent(path, ext);
} });
}); });
} }
@ -360,30 +365,22 @@ class TranscriptionApp {
} else if (ext === '.docx') { } else if (ext === '.docx') {
viewer.innerHTML = ` viewer.innerHTML = `
<div class="file-preview"> <div class="file-preview">
<p>Скачивание DOCX...</p> <p> Скачивание DOCX...</p>
</div> </div>
`; `;
// Принудительное скачивание через Blob (браузер не блокирует) // iframe method — работает без user-gesture restrictions
try { const iframe = document.createElement('iframe');
const resp = await fetch(`/api/files/download?path=${encodeURIComponent(path)}`); iframe.style.display = 'none';
if (!resp.ok) throw new Error('Download failed'); iframe.src = `/api/files/download?path=${encodeURIComponent(path)}`;
const blob = await resp.blob(); document.body.appendChild(iframe);
const url = URL.createObjectURL(blob); setTimeout(() => {
const a = document.createElement('a'); iframe.remove();
a.href = url;
a.download = path.split('/').pop();
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
viewer.innerHTML = ` viewer.innerHTML = `
<div class="file-preview"> <div class="file-preview">
<p> Файл скачан: ${this.escapeHtml(path)}</p> <p> Файл скачан</p>
</div> </div>
`; `;
} catch (err) { }, 3000);
viewer.innerHTML = `<div class="error">Ошибка скачивания: ${this.escapeHtml(err.message)}</div>`;
}
} }
} }