feat: tab navigation in modal (Index/Transkript/Zusammenfassung)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-02 12:10:50 +02:00
parent 336628341b
commit d3582eaeb7
4 changed files with 68 additions and 15 deletions
+40 -8
View File
@@ -12,9 +12,11 @@ const modalObsidianBtn = document.getElementById('modal-obsidian-btn');
const modalFolderBtn = document.getElementById('modal-folder-btn');
const modalOpenBtn = document.getElementById('modal-open-btn');
const modalCloseBtn = document.getElementById('modal-close-btn');
const modalTabs = document.getElementById('modal-tabs');
let _modalPath = null;
let _modalPaths = null;
let _modalFilename = null;
let _modalRelated = null;
const speakerCard = document.getElementById('speaker-card');
const speakerRows = document.getElementById('speaker-rows');
@@ -54,18 +56,47 @@ logoutBtn.addEventListener('click', () => {
});
});
function openModal(filename, path, paths) {
function _loadModalContent(filename, activeTab) {
modalBody.innerHTML = '';
apiFetch(`/transcripts/${filename.split('/').map(encodeURIComponent).join('/')}`)
.then(r => r.text())
.then(md => { modalBody.innerHTML = DOMPurify.sanitize(marked.parse(md)); });
// update active tab
modalTabs.querySelectorAll('.modal-tab').forEach(t => {
t.classList.toggle('active', t.dataset.file === filename);
});
}
function openModal(filename, path, paths, related) {
_modalPath = path;
_modalPaths = paths || null;
_modalFilename = filename;
modalTitle.textContent = filename.replace(/\.md$/, '').replace(/^\d{4}-\d{2}-\d{2}-\d{4}-/, '');
modalBody.innerHTML = '';
_modalRelated = related || null;
modalTitle.textContent = filename.replace(/\.md$/, '').replace(/^\d{4}-\d{2}-\d{2}-\d{4}-/, '').replace(/-index$/, '');
modal.classList.remove('hidden');
apiFetch(`/transcripts/${encodeURIComponent(filename)}`)
.then(r => r.text())
.then(md => {
modalBody.innerHTML = DOMPurify.sanitize(marked.parse(md));
// Build tabs if there are related files
modalTabs.innerHTML = '';
if (related && (related.transkript || related.zusammenfassung)) {
modalTabs.style.display = 'flex';
const tabDefs = [
{ label: 'Index', file: filename },
{ label: 'Transkript', file: related.transkript },
{ label: 'Zusammenfassung', file: related.zusammenfassung },
].filter(t => t.file);
tabDefs.forEach(({ label, file }) => {
const btn = document.createElement('button');
btn.className = 'modal-tab';
btn.textContent = label;
btn.dataset.file = file;
btn.addEventListener('click', () => _loadModalContent(file, file));
modalTabs.appendChild(btn);
});
} else {
modalTabs.style.display = 'none';
}
_loadModalContent(filename, filename);
}
function closeModal() {
@@ -73,6 +104,7 @@ function closeModal() {
_modalPath = null;
_modalPaths = null;
_modalFilename = null;
_modalRelated = null;
}
modalCloseBtn.addEventListener('click', closeModal);
@@ -239,7 +271,7 @@ async function loadTranscripts() {
meta.className = 'meta';
meta.textContent = `${Math.round(t.size / 1024 * 10) / 10} KB`;
div.addEventListener('click', () => openModal(t.filename, t.path));
div.addEventListener('click', () => openModal(t.filename, t.path, null, t.related || null));
const reprocessBtn = document.createElement('button');
reprocessBtn.className = 'del-btn';