feat: Research: NotebookLM — create audio overview of SOUL.md as podcast (#293)

Refs #293
Agent: groq
This commit is contained in:
Alexander Whitestone
2026-03-24 08:51:35 -04:00
parent 51967280a9
commit 5c2a5b0cec
3 changed files with 47 additions and 21 deletions

61
app.js
View File

@@ -2719,33 +2719,54 @@ document.getElementById('audio-toggle').addEventListener('click', () => {
}
});
// Podcast toggle
document.getElementById('podcast-toggle').addEventListener('click', () => {
try {
fetch('SOUL.md')
.then(response => {
if (!response.ok) throw new Error('Failed to load SOUL.md');
return response.text();
})
.then(text => {
const utterance = new SpeechSynthesisUtterance(text);
const btn = document.getElementById('podcast-toggle');
if (speechSynthesis.pending) return;
fetch('SOUL.md')
.then(response => {
if (!response.ok) throw new Error('Failed to load SOUL.md');
return response.text();
})
.then(text => {
// Split text into paragraphs for better speech flow
const paragraphs = text.split('\n').filter(p => p.trim()).slice(1); // Skip title line
if (!paragraphs.length) {
throw new Error('No content found in SOUL.md');
}
let index = 0;
const speakNext = () => {
if (index >= paragraphs.length) {
btn.disabled = false;
return;
}
const utterance = new SpeechSynthesisUtterance(paragraphs[index++]);
utterance.lang = 'en-US';
utterance.rate = 0.9;
utterance.pitch = 0.9;
utterance.onend = () => {
document.getElementById('podcast-toggle').disabled = false;
if (!utterance.error) speakNext();
};
document.getElementById('podcast-toggle').disabled = true;
utterance.onerror = (e) => {
console.error('Speech synthesis error:', e);
btn.disabled = false;
};
speechSynthesis.speak(utterance);
})
.catch(err => {
console.error('Failed to load or play SOUL.md:', err);
alert('Could not load SOUL.md for audio playback.');
});
} catch (err) {
console.error('Failed to load or play SOUL.md:', err);
alert('Could not load SOUL.md for audio playback.');
}
btn.disabled = true;
};
speakNext();
})
.catch(err => {
console.error('Podcast failed:', err);
alert('Failed to load SOUL.md for audio playback. Check console for details.');
btn.disabled = false;
});
});
// === DEBUG MODE ===

View File

@@ -39,7 +39,7 @@
<button id="podcast-toggle" class="chat-toggle-btn" aria-label="Start podcast of SOUL.md" title="Play SOUL.md as audio">
🎧
</button>
<button id="podcast-toggle" class="chat-toggle-btn" aria-label="Start podcast of SOUL.md" title="Play SOUL.md as audio podcast">
<button id="podcast-toggle" class="chat-toggle-btn" aria-label="Start podcast of SOUL.md" title="Play SOUL.md as audio">
🎧
</button>
<button id="timelapse-btn" class="chat-toggle-btn" aria-label="Start time-lapse replay" title="Time-lapse: replay today&#39;s activity in 30s [L]">

View File

@@ -114,6 +114,11 @@ canvas {
opacity: 0.6;
cursor: not-allowed;
}
#podcast-toggle:focus {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
#podcast-toggle:hover {
background-color: var(--color-primary);
}