Enhance note management: add corrected transcript field, update UI for reading mode, and improve archive display
This commit is contained in:
+38
-18
@@ -6,7 +6,8 @@ const MAX_RECORDING_MS = 30 * 60 * 1000;
|
||||
const elements = Object.fromEntries([
|
||||
'record-button', 'record-title', 'record-help', 'record-time', 'record-meter-fill', 'audio-level', 'audio-level-fill', 'capture-message', 'audio-file-input',
|
||||
'queue-list', 'queue-empty', 'queue-count', 'sync-button', 'archive-list', 'archive-empty',
|
||||
'network-state', 'storage-status', 'voice-mode', 'write-mode', 'voice-panel', 'write-panel', 'written-note', 'draft-status', 'save-written-note',
|
||||
'network-state', 'storage-status', 'main', 'voice-mode', 'write-mode', 'read-mode', 'voice-panel', 'write-panel', 'written-note', 'draft-status', 'save-written-note',
|
||||
'queue-section', 'archive-section', 'archive-title',
|
||||
'settings-button', 'settings-dialog', 'backup-form', 'backup-fields', 'backup-url', 'backup-username', 'backup-password',
|
||||
'clear-backup-password', 'close-settings', 'test-backup', 'backup-status', 'retry-backup',
|
||||
].map((id) => [id, document.getElementById(id)]));
|
||||
@@ -71,12 +72,18 @@ const deleteTextRecord = (id) => textTransaction('readwrite', (store) => store.d
|
||||
|
||||
function setCaptureMode(mode) {
|
||||
const writing = mode === 'write';
|
||||
elements['voice-mode'].classList.toggle('active', !writing);
|
||||
const reading = mode === 'read';
|
||||
elements['voice-mode'].classList.toggle('active', !writing && !reading);
|
||||
elements['write-mode'].classList.toggle('active', writing);
|
||||
elements['voice-mode'].setAttribute('aria-selected', String(!writing));
|
||||
elements['read-mode'].classList.toggle('active', reading);
|
||||
elements['voice-mode'].setAttribute('aria-selected', String(!writing && !reading));
|
||||
elements['write-mode'].setAttribute('aria-selected', String(writing));
|
||||
elements['voice-panel'].hidden = writing;
|
||||
elements['write-panel'].hidden = !writing;
|
||||
elements['read-mode'].setAttribute('aria-selected', String(reading));
|
||||
elements['voice-panel'].hidden = writing || reading;
|
||||
elements['write-panel'].hidden = !writing || reading;
|
||||
elements['main'].classList.toggle('reading', reading);
|
||||
elements['archive-title'].textContent = reading ? 'Stored transcriptions' : 'Saved notes';
|
||||
loadAwaitingNotes();
|
||||
}
|
||||
|
||||
async function saveDraft() {
|
||||
@@ -537,12 +544,19 @@ function renderArchive(notes) {
|
||||
const transcript = document.createElement('textarea');
|
||||
transcript.className = 'archive-transcript';
|
||||
transcript.placeholder = isWrittenNote ? 'Write or edit your note…' : note.status === 'transcribing' ? 'Transcription in progress…' : 'Transcript not available yet. Add or correct it here.';
|
||||
transcript.value = note.transcript;
|
||||
transcript.setAttribute('aria-label', `${isWrittenNote ? 'Note' : 'Transcript'} for ${note.filename}`);
|
||||
transcript.value = note.corrected_transcript || note.transcript;
|
||||
transcript.setAttribute('aria-label', `${isWrittenNote ? 'Note' : 'Edited transcript'} for ${note.filename}`);
|
||||
const original = document.createElement('details');
|
||||
original.className = 'original-transcript';
|
||||
const originalLabel = document.createElement('summary');
|
||||
originalLabel.textContent = 'Original transcript';
|
||||
const originalText = document.createElement('p');
|
||||
originalText.textContent = note.transcript || 'No original transcript is available.';
|
||||
original.append(originalLabel, originalText);
|
||||
const save = document.createElement('button');
|
||||
save.className = 'save-transcript';
|
||||
save.type = 'button';
|
||||
save.textContent = isWrittenNote ? 'SAVE NOTE' : 'SAVE TRANSCRIPT';
|
||||
save.textContent = isWrittenNote ? 'SAVE NOTE' : 'SAVE EDIT';
|
||||
save.addEventListener('click', async () => {
|
||||
save.disabled = true;
|
||||
try {
|
||||
@@ -550,7 +564,10 @@ function renderArchive(notes) {
|
||||
method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ transcript: transcript.value }),
|
||||
});
|
||||
if (!response.ok) throw new Error('Save failed');
|
||||
await loadAwaitingNotes();
|
||||
save.textContent = 'SAVED';
|
||||
window.setTimeout(() => {
|
||||
if (save.isConnected) save.textContent = isWrittenNote ? 'SAVE NOTE' : 'SAVE EDIT';
|
||||
}, 1500);
|
||||
} catch {
|
||||
save.textContent = 'RETRY SAVE';
|
||||
} finally {
|
||||
@@ -569,9 +586,9 @@ function renderArchive(notes) {
|
||||
progress.setAttribute('aria-valuemax', '100');
|
||||
progress.setAttribute('aria-valuetext', 'In progress');
|
||||
progress.append(document.createElement('span'));
|
||||
body.append(name, transcript, save, status, progress);
|
||||
body.append(name, original, transcript, save, status, progress);
|
||||
} else {
|
||||
body.append(name, transcript, save, status);
|
||||
body.append(name, original, transcript, save, status);
|
||||
}
|
||||
const remove = createDeleteButton(`Delete note ${note.filename}`);
|
||||
remove.addEventListener('click', async () => {
|
||||
@@ -596,13 +613,15 @@ async function loadAwaitingNotes() {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
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'),
|
||||
]);
|
||||
const responses = elements['main'].classList.contains('reading')
|
||||
? [await fetch('/api/notes')]
|
||||
: 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();
|
||||
notes.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
|
||||
@@ -617,6 +636,7 @@ async function loadAwaitingNotes() {
|
||||
elements['record-button'].addEventListener('click', () => mediaRecorder?.state === 'recording' ? stopRecording() : startRecording());
|
||||
elements['voice-mode'].addEventListener('click', () => setCaptureMode('voice'));
|
||||
elements['write-mode'].addEventListener('click', () => setCaptureMode('write'));
|
||||
elements['read-mode'].addEventListener('click', () => setCaptureMode('read'));
|
||||
elements['written-note'].addEventListener('input', scheduleDraftSave);
|
||||
elements['save-written-note'].addEventListener('click', queueWrittenNote);
|
||||
window.addEventListener('pagehide', () => {
|
||||
|
||||
Reference in New Issue
Block a user