feat: eager soundfont catalog scan at startup, cache presets locally

- App startup fetches full catalog with all instrument presets
- Merges presets into instrumentSelectorData.soundfonts
- Synth button shows presets from cache (no per-SF API call)
- Fallback: if cache miss, fetch individual SF presets on demand
This commit is contained in:
2026-07-27 09:28:34 +07:00
parent d04442ad45
commit 7544ee2e5f
2 changed files with 43 additions and 12 deletions
+36 -8
View File
@@ -6487,10 +6487,17 @@ const App = () => {
setSynthCategory('soundfont');
setSelectedSoundFontId(track.instrumentId);
setSfPresets(null);
setSfPresetSearchQuery('');
// Use cached presets from instrumentSelectorData
const sfIdParam = track.instrumentId.replace('sf_', '');
window.SonicAPI.listSoundfontInstruments(sfIdParam)
.then(data => setSfPresets(data.presets || []))
.catch(() => setSfPresets([]));
const cachedSf = (instrumentSelectorData?.soundfonts || []).find(s => s.id === track.instrumentId || s.id === sfIdParam);
if (cachedSf && cachedSf.presets) {
setSfPresets(cachedSf.presets);
} else {
window.SonicAPI.listSoundfontInstruments(sfIdParam)
.then(data => setSfPresets(data.presets || []))
.catch(() => setSfPresets([]));
}
} else {
// Reset synth state and always reload plugin data
setSynthCategory(null);
@@ -6522,7 +6529,23 @@ const App = () => {
}, [instrumentSearchQuery, instrumentSelectorData]);
useEffect(() => {
if (!instrumentSelectorData) {
window.SonicAPI.listPlugins().then(data => setInstrumentSelectorData(data)).catch(() => {});
window.SonicAPI.listPlugins().then(async data => {
// Eagerly fetch full catalog with all instrument presets
try {
const catResp = await window.SonicAPI.getSoundfontCatalog?.() ?? await fetch('/api/v1/plugins/soundfonts/catalog').then(r => r.json());
const catalog = catResp.full_catalog || {};
// Merge presets into each soundfont entry
data.soundfonts = (data.soundfonts || []).map(sf => {
const sfId = sf.id.replace('sf_', '');
const catEntry = catalog[sfId];
if (catEntry && catEntry.instruments) {
return { ...sf, presets: catEntry.instruments };
}
return sf;
});
} catch (e) { console.warn('Catalog fetch error:', e); }
setInstrumentSelectorData(data);
}).catch(() => {});
}
}, []);
useEffect(() => {
@@ -6635,11 +6658,16 @@ const App = () => {
setInstrumentSelectorTrackId(trackId);
setSfPresets(null);
setSfPresetSearchQuery('');
// Fetch actual presets from the SoundFont
const sfIdParam = instrumentId.replace('sf_', '');
window.SonicAPI.listSoundfontInstruments(sfIdParam)
.then(data => setSfPresets(data.presets || []))
.catch(e => { console.error('listSoundfontInstruments failed:', e); setSfPresets([]); });
// Use cached presets from instrumentSelectorData
const cachedSf = (instrumentSelectorData?.soundfonts || []).find(s => s.id === instrumentId || s.id === sfIdParam);
if (cachedSf && cachedSf.presets) {
setSfPresets(cachedSf.presets);
} else {
window.SonicAPI.listSoundfontInstruments(sfIdParam)
.then(data => setSfPresets(data.presets || []))
.catch(e => { console.error('listSoundfontInstruments failed:', e); setSfPresets([]); });
}
} else {
setTrackInstrumentWithProgram(trackId, instrumentId, undefined, displayName);
}