Refactor code structure for improved readability and maintainability

This commit is contained in:
2026-09-28 15:54:49 +02:00
parent 0fb66f2cee
commit 01f2a92a84
6 changed files with 118 additions and 3 deletions
+28 -2
View File
@@ -19,6 +19,7 @@ let recordingStartedAt = 0;
let recordingTimer;
let syncing = false;
let draftSaveTimer;
let transcriptionPoll;
function openDatabase() {
if (databasePromise) return databasePromise;
@@ -421,6 +422,16 @@ function renderArchive(notes) {
elements['archive-empty'].hidden = notes.length > 0;
if (!navigator.onLine) elements['archive-empty'].textContent = 'Reconnect to view saved notes.';
else elements['archive-empty'].textContent = 'No saved notes yet.';
if (notes.some((note) => note.status === 'transcribing')) {
if (!transcriptionPoll) {
transcriptionPoll = window.setInterval(() => {
if (navigator.onLine && document.visibilityState === 'visible') loadAwaitingNotes();
}, 5000);
}
} else {
clearInterval(transcriptionPoll);
transcriptionPoll = undefined;
}
for (const note of notes) {
const item = document.createElement('article');
item.className = 'archive-item';
@@ -458,7 +469,20 @@ function renderArchive(notes) {
});
const status = document.createElement('div');
status.className = 'archive-status';
status.textContent = isWrittenNote ? 'WRITTEN NOTE' : note.status === 'transcribing' ? 'TRANSCRIBING' : note.status === 'transcribed' ? 'TRANSCRIPT SAVED' : 'AWAITING TRANSCRIPTION';
status.textContent = isWrittenNote ? 'WRITTEN NOTE' : note.status === 'transcribing' ? 'TRANSCRIBING' : note.status === 'transcribed' ? 'TRANSCRIPT SAVED' : note.status === 'transcription_failed' ? 'TRANSCRIPTION FAILED; AUDIO RETAINED' : note.status === 'empty_transcript' ? 'NO SPEECH DETECTED; AUDIO RETAINED' : 'AWAITING TRANSCRIPTION';
if (note.status === 'transcribing') {
const progress = document.createElement('div');
progress.className = 'transcription-progress';
progress.setAttribute('role', 'progressbar');
progress.setAttribute('aria-label', 'Transcription in progress');
progress.setAttribute('aria-valuemin', '0');
progress.setAttribute('aria-valuemax', '100');
progress.setAttribute('aria-valuetext', 'In progress');
progress.append(document.createElement('span'));
body.append(name, transcript, save, status, progress);
} else {
body.append(name, transcript, save, status);
}
const remove = createDeleteButton(`Delete note ${note.filename}`);
remove.addEventListener('click', async () => {
remove.disabled = true;
@@ -471,7 +495,6 @@ function renderArchive(notes) {
setMessage('Could not delete this note. Please try again.', true);
}
});
body.append(name, transcript, save, status);
item.append(date, body, remove);
elements['archive-list'].append(item);
}
@@ -486,6 +509,9 @@ async function loadAwaitingNotes() {
const responses = await Promise.all([
fetch('/api/notes?status=awaiting_transcription'),
fetch('/api/notes?status=written'),
fetch('/api/notes?status=transcribing'),
fetch('/api/notes?status=transcription_failed'),
fetch('/api/notes?status=empty_transcript'),
]);
if (responses.some((response) => !response.ok)) throw new Error('Archive unavailable');
const notes = (await Promise.all(responses.map((response) => response.json()))).flat();
+3
View File
@@ -87,8 +87,11 @@ h2 { margin: 8px 0 0; font: 500 25px/1.1 var(--serif); }
.archive-transcript:focus { border-bottom-color: var(--moss); }
.save-transcript { margin-top: 7px; border: 0; padding: 0; color: var(--moss-dark); background: transparent; font: 11px var(--mono); cursor: pointer; }
.archive-status { color: var(--muted); font: 10px var(--mono); margin-top: 7px; }
.transcription-progress { width: min(240px, 100%); height: 3px; margin-top: 9px; overflow: hidden; background: #e4e3dc; }
.transcription-progress span { display: block; width: 34%; height: 100%; background: var(--moss); animation: transcription-progress 1.4s ease-in-out infinite; }
footer { max-width: 1040px; margin: auto; padding: 18px 24px calc(18px + env(safe-area-inset-bottom)); display: flex; justify-content: space-between; gap: 20px; color: var(--muted); font: 9px var(--mono); }
@keyframes reveal { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } }
@keyframes transcription-progress { from { transform: translateX(-110%); } to { transform: translateX(300%); } }
@media (max-width: 600px) {
.topbar { height: 58px; padding: 0 18px; }
main { padding: 0 18px; }