Make fewer IQ Bible calls

- Load the narrator list only when the audio dropdown is opened
- Keep today's verse and devotional in memory for an hour (not saved)
- Back off for a minute after 'allowance used up' or unreachable; keep 'nothing here' answers
- Server shares one upstream call between identical simultaneous requests (nothing stored)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-06 13:25:51 -04:00
1 parent d29a66f984
commit 31ac6b9179
7 files changed
+129 -17

No files matched your search

+4 -3
View File
@@ -3,7 +3,7 @@ import { useApp } from '../context/AppContext.js';
import { filterStudies, groupBySeries, isTagQuery, seriesList, tagCounts } from '../utils/studyFilter.js';
import BookCover from '../components/BookCover.jsx';
import IqDailyCard from '../components/iq/IqDailyCard.jsx';
import IqNarratorOptions from '../components/iq/IqNarratorOptions.jsx';
import IqNarratorOptions, { useLazyNarrators } from '../components/iq/IqNarratorOptions.jsx';
import PageShell from '../components/study/PageShell.jsx';
import AudioPlayer from '../components/AudioPlayer.jsx';
import {
@@ -49,6 +49,7 @@ export default function HomePage() {
handleSeekAudio,
handleSeekAudioTo,
} = useApp();
const narrators = useLazyNarrators(audioNarrator);
const [homeSearch, setHomeSearch] = useState('');
const [homeSort, setHomeSort] = useState(() => {
try { return localStorage.getItem('homeSort') || 'recent'; } catch { return 'recent'; }
@@ -343,11 +344,11 @@ export default function HomePage() {
<select value={audioBook} onChange={(e) => setAudioBook(e.target.value)} disabled={audioState.status === 'playing' || audioState.status === 'paused'} className={fieldCls}>
{bookOptions.map((book) => <option key={book.abbrev} value={book.abbrev}>{book.name}</option>)}
</select>
<select value={audioNarrator} onChange={(e) => setAudioNarrator(e.target.value)} disabled={audioState.status === 'playing' || audioState.status === 'paused'} className={fieldCls}>
<select value={audioNarrator} onChange={(e) => setAudioNarrator(e.target.value)} disabled={audioState.status === 'playing' || audioState.status === 'paused'} className={fieldCls} {...narrators.selectProps}>
<option value="david">David</option>
<option value="hays">Hays</option>
<option value="souer">Souer</option>
<IqNarratorOptions />
<IqNarratorOptions enabled={narrators.enabled} />
</select>
</>
)}