fix(ui): search instrument names inside SoundFont, not just SF names
Add sfPresetSearchQuery state + search input in instrument selector modal. Filters sfPresets by name (case-insensitive) when user types. Clear search on SoundFont switch / modal close.
This commit is contained in:
+19
-4
@@ -6424,6 +6424,7 @@ const App = () => {
|
|||||||
const [instrumentSelectorData, setInstrumentSelectorData] = useState(null);
|
const [instrumentSelectorData, setInstrumentSelectorData] = useState(null);
|
||||||
const openInstrumentSelector = trackId => {
|
const openInstrumentSelector = trackId => {
|
||||||
setInstrumentSelectorTrackId(trackId);
|
setInstrumentSelectorTrackId(trackId);
|
||||||
|
setSfPresetSearchQuery('');
|
||||||
const track = activeTracks.find(t => t.id === trackId);
|
const track = activeTracks.find(t => t.id === trackId);
|
||||||
if (track && track.instrumentId && track.instrumentId.startsWith('sf_')) {
|
if (track && track.instrumentId && track.instrumentId.startsWith('sf_')) {
|
||||||
// Track already has a SoundFont assigned → open instrument selection directly
|
// Track already has a SoundFont assigned → open instrument selection directly
|
||||||
@@ -6437,7 +6438,8 @@ const App = () => {
|
|||||||
} else {
|
} else {
|
||||||
// Reset synth state and always reload plugin data
|
// Reset synth state and always reload plugin data
|
||||||
setSynthCategory(null);
|
setSynthCategory(null);
|
||||||
setSelectedSoundFontId(null);
|
setSelectedSoundFontId(null);
|
||||||
|
setSfPresetSearchQuery('');
|
||||||
window.SonicAPI.listPlugins().then(data => setInstrumentSelectorData(data)).catch(e => console.error('listPlugins failed:', e));
|
window.SonicAPI.listPlugins().then(data => setInstrumentSelectorData(data)).catch(e => console.error('listPlugins failed:', e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -6445,6 +6447,7 @@ const App = () => {
|
|||||||
setInstrumentSelectorTrackId(null);
|
setInstrumentSelectorTrackId(null);
|
||||||
setSynthCategory(null);
|
setSynthCategory(null);
|
||||||
setSelectedSoundFontId(null);
|
setSelectedSoundFontId(null);
|
||||||
|
setSfPresetSearchQuery('');
|
||||||
};
|
};
|
||||||
const [synthCategory, setSynthCategory] = useState(null); // 'vst' | 'soundfont'
|
const [synthCategory, setSynthCategory] = useState(null); // 'vst' | 'soundfont'
|
||||||
const [selectedSoundFontId, setSelectedSoundFontId] = useState(null);
|
const [selectedSoundFontId, setSelectedSoundFontId] = useState(null);
|
||||||
@@ -6452,6 +6455,7 @@ const App = () => {
|
|||||||
const [instrumentDropdownTrackId, setInstrumentDropdownTrackId] = useState(null);
|
const [instrumentDropdownTrackId, setInstrumentDropdownTrackId] = useState(null);
|
||||||
const [instrumentDropdownBtnRect, setInstrumentDropdownBtnRect] = useState(null);
|
const [instrumentDropdownBtnRect, setInstrumentDropdownBtnRect] = useState(null);
|
||||||
const [instrumentSearchQuery, setInstrumentSearchQuery] = useState('');
|
const [instrumentSearchQuery, setInstrumentSearchQuery] = useState('');
|
||||||
|
const [sfPresetSearchQuery, setSfPresetSearchQuery] = useState('');
|
||||||
const filteredInstruments = useMemo(() => {
|
const filteredInstruments = useMemo(() => {
|
||||||
if (!instrumentSelectorData || !instrumentSearchQuery) return { soundfonts: instrumentSelectorData?.soundfonts || [], vst: instrumentSelectorData?.vst_instruments || [] };
|
if (!instrumentSelectorData || !instrumentSearchQuery) return { soundfonts: instrumentSelectorData?.soundfonts || [], vst: instrumentSelectorData?.vst_instruments || [] };
|
||||||
const q = instrumentSearchQuery.toLowerCase();
|
const q = instrumentSearchQuery.toLowerCase();
|
||||||
@@ -6568,6 +6572,7 @@ const App = () => {
|
|||||||
setSynthCategory('soundfont');
|
setSynthCategory('soundfont');
|
||||||
setInstrumentSelectorTrackId(trackId);
|
setInstrumentSelectorTrackId(trackId);
|
||||||
setSfPresets(null);
|
setSfPresets(null);
|
||||||
|
setSfPresetSearchQuery('');
|
||||||
// Fetch actual presets from the SoundFont
|
// Fetch actual presets from the SoundFont
|
||||||
const sfIdParam = instrumentId.replace('sf_', '');
|
const sfIdParam = instrumentId.replace('sf_', '');
|
||||||
window.SonicAPI.listSoundfontInstruments(sfIdParam)
|
window.SonicAPI.listSoundfontInstruments(sfIdParam)
|
||||||
@@ -16866,12 +16871,20 @@ const App = () => {
|
|||||||
/*#__PURE__*/React.createElement(React.Fragment, null,
|
/*#__PURE__*/React.createElement(React.Fragment, null,
|
||||||
/*#__PURE__*/React.createElement("div", { className: "flex justify-between items-center pb-3 border-b border-[#383838]" },
|
/*#__PURE__*/React.createElement("div", { className: "flex justify-between items-center pb-3 border-b border-[#383838]" },
|
||||||
/*#__PURE__*/React.createElement("div", null,
|
/*#__PURE__*/React.createElement("div", null,
|
||||||
/*#__PURE__*/React.createElement("button", { onClick: () => { setSynthCategory(null); setSelectedSoundFontId(null); }, className: "text-[10px] text-cyan-400 hover:text-cyan-300 mr-2" }, "\u2190 Back"),
|
/*#__PURE__*/React.createElement("button", { onClick: () => { setSynthCategory(null); setSelectedSoundFontId(null); setSfPresetSearchQuery(''); }, className: "text-[10px] text-cyan-400 hover:text-cyan-300 mr-2" }, "\u2190 Back"),
|
||||||
/*#__PURE__*/React.createElement("h3", { className: "text-sm font-bold inline text-amber-400" }, "Select Instrument")
|
/*#__PURE__*/React.createElement("h3", { className: "text-sm font-bold inline text-amber-400" }, "Select Instrument")
|
||||||
),
|
),
|
||||||
/*#__PURE__*/React.createElement("button", { onClick: closeInstrumentSelector, className: "text-slate-400 hover:text-slate-200" }, "\u2715")
|
/*#__PURE__*/React.createElement("button", { onClick: closeInstrumentSelector, className: "text-slate-400 hover:text-slate-200" }, "\u2715")
|
||||||
),
|
),
|
||||||
/*#__PURE__*/React.createElement("p", { className: "text-[10px] text-zinc-500 mt-2 mb-2" }, "SoundFont: ", selectedSoundFontId),
|
/*#__PURE__*/React.createElement("p", { className: "text-[10px] text-zinc-500 mt-2 mb-2" }, "SoundFont: ", selectedSoundFontId),
|
||||||
|
/*#__PURE__*/React.createElement("input", {
|
||||||
|
type: "text",
|
||||||
|
placeholder: "T\u00ecm nh\u1ea1c c\u1ee5 trong SoundFont...",
|
||||||
|
value: sfPresetSearchQuery,
|
||||||
|
onChange: e => setSfPresetSearchQuery(e.target.value),
|
||||||
|
autoFocus: true,
|
||||||
|
className: "w-full bg-black border border-zinc-700 rounded px-2 py-1.5 text-xs outline-none mb-2"
|
||||||
|
}),
|
||||||
/*#__PURE__*/React.createElement("div", { className: "mt-2 max-h-72 overflow-y-auto space-y-0.5" },
|
/*#__PURE__*/React.createElement("div", { className: "mt-2 max-h-72 overflow-y-auto space-y-0.5" },
|
||||||
/*#__PURE__*/React.createElement("button", {
|
/*#__PURE__*/React.createElement("button", {
|
||||||
onClick: () => setTrackInstrumentWithProgram(instrumentSelectorTrackId, selectedSoundFontId),
|
onClick: () => setTrackInstrumentWithProgram(instrumentSelectorTrackId, selectedSoundFontId),
|
||||||
@@ -16881,14 +16894,16 @@ const App = () => {
|
|||||||
React.createElement("p", { className: "text-[10px] text-zinc-500 py-2" }, "Loading instruments...")
|
React.createElement("p", { className: "text-[10px] text-zinc-500 py-2" }, "Loading instruments...")
|
||||||
) : sfPresets.length > 0 ? (
|
) : sfPresets.length > 0 ? (
|
||||||
React.createElement("div", { className: "grid grid-cols-2 gap-0.5" },
|
React.createElement("div", { className: "grid grid-cols-2 gap-0.5" },
|
||||||
sfPresets.map((p, i) => React.createElement("button", {
|
sfPresets
|
||||||
|
.filter(p => !sfPresetSearchQuery || (p.name || '').toLowerCase().includes(sfPresetSearchQuery.toLowerCase()))
|
||||||
|
.map((p, i) => React.createElement("button", {
|
||||||
key: i,
|
key: i,
|
||||||
onClick: () => setTrackInstrumentWithProgram(instrumentSelectorTrackId, selectedSoundFontId, p.program, p.name || 'Preset ' + p.program, p.bank),
|
onClick: () => setTrackInstrumentWithProgram(instrumentSelectorTrackId, selectedSoundFontId, p.program, p.name || 'Preset ' + p.program, p.bank),
|
||||||
className: "text-left px-2 py-1 text-[10px] rounded bg-zinc-800/60 hover:bg-amber-800 text-zinc-300 truncate"
|
className: "text-left px-2 py-1 text-[10px] rounded bg-zinc-800/60 hover:bg-amber-800 text-zinc-300 truncate"
|
||||||
}, p.bank === 128 ? /*#__PURE__*/React.createElement("span", { className: "mr-1" }, "🥁") : null, p.name || 'Preset ' + p.program)
|
}, p.bank === 128 ? /*#__PURE__*/React.createElement("span", { className: "mr-1" }, "🥁") : null, p.name || 'Preset ' + p.program)
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
React.createElement("p", { className: "text-[10px] text-zinc-500 py-2" }, "No presets found.")
|
React.createElement("p", { className: "text-[10px] text-zinc-500 py-2" }, sfPresetSearchQuery ? "Kh\u00f4ng t\u00ecm th\u1ea5y nh\u1ea1c c\u1ee5 ph\u00f9 h\u1ee3p." : "No presets found.")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user