import React, { useMemo, useState, useEffect } from 'react'; import './InstrumentSelection.css'; import { useProjectStore } from '../stores/projectStore'; import { INSTRUMENT_GROUPS, FLUIDR3_INSTRUMENT_MAP } from '../constants/generalMidiConstants'; import { KGMidiTrack, type InstrumentType } from '../core/track/KGMidiTrack'; import { KGAudioTrack } from '../core/track/KGAudioTrack'; import { useI18n } from '../i18n/useI18n'; import { getInstrumentDisplayName, getInstrumentGroupLabel, type InstrumentGroupKey } from '../i18n/instruments'; const InstrumentSelection: React.FC = () => { const { t } = useI18n(); const { tracks, selectedTrackId, closeInstrumentSelection, setTrackInstrument } = useProjectStore(); const targetTrack = useMemo(() => { return tracks.find(t => t.getId().toString() === selectedTrackId) || null; }, [tracks, selectedTrackId]); const currentInstrumentKey: InstrumentType = (targetTrack && targetTrack instanceof KGMidiTrack) ? (targetTrack.getInstrument() as InstrumentType) : 'acoustic_grand_piano'; const currentInstrumentDef = FLUIDR3_INSTRUMENT_MAP[currentInstrumentKey] || FLUIDR3_INSTRUMENT_MAP['acoustic_grand_piano']; // Maintain selected group in local state; selected instrument derives from model const [selectedGroupKey, setSelectedGroupKey] = useState(currentInstrumentDef?.group || 'PIANO_AND_KEYBOARDS'); useEffect(() => { // Sync when the target track or its instrument changes setSelectedGroupKey(currentInstrumentDef?.group || 'PIANO_AND_KEYBOARDS'); }, [selectedTrackId, currentInstrumentKey, currentInstrumentDef]); const groups = useMemo(() => Object.keys(INSTRUMENT_GROUPS) as InstrumentGroupKey[], []); const instrumentsInGroup = useMemo>(() => { return Object.entries(FLUIDR3_INSTRUMENT_MAP) .filter((entry) => entry[1].group === selectedGroupKey) .map((entry) => ({ key: entry[0] as InstrumentType, label: getInstrumentDisplayName(entry[0] as InstrumentType, t) })); }, [selectedGroupKey, t]); const handleSelectGroup = (groupKey: string) => { setSelectedGroupKey(groupKey); }; const handleSelectInstrument = async (instrumentKey: InstrumentType) => { // If no valid target track, ignore user interaction if (!targetTrack || !(targetTrack instanceof KGMidiTrack)) return; try { await setTrackInstrument(targetTrack.getId(), instrumentKey); } catch (err) { console.error('Failed to change instrument from panel:', err); } }; const isAudioTrack = targetTrack instanceof KGAudioTrack; const previewImage = isAudioTrack ? 'speaker.png' : (FLUIDR3_INSTRUMENT_MAP[currentInstrumentKey]?.image || 'piano.png'); const previewAlt = isAudioTrack ? 'Audio Track' : getInstrumentDisplayName(currentInstrumentKey, t); const hasTargetTrack = !!targetTrack; return (

{hasTargetTrack ? previewAlt : ''}

{hasTargetTrack && (
{previewAlt.toString()}
)}
{hasTargetTrack ? targetTrack.getName() : ''}
{!isAudioTrack && (
{groups.map((key) => (
handleSelectGroup(key)} > {getInstrumentGroupLabel(key, t)}
))}
{instrumentsInGroup.map((inst) => (
handleSelectInstrument(inst.key)} > {inst.label}
))}
)}
); }; export default InstrumentSelection;