shadow-over-bishkek001/dialogEditor/src/components/RightPanel/shared/SpeakerField.tsx
2026-06-05 21:17:51 +03:00

59 lines
1.8 KiB
TypeScript

import { useState } from 'react';
import { CHARACTER_PRESETS, CUSTOM_CHARACTER_LABEL } from '../../../constants/characters';
import styles from '../RightPanel.module.css';
interface Props {
speaker: string;
portrait: string;
onSpeakerChange: (speaker: string, portrait: string) => void;
}
export function SpeakerField({ speaker, portrait, onSpeakerChange }: Props) {
const isPreset = CHARACTER_PRESETS.some(p => p.label === speaker);
const [isCustom, setIsCustom] = useState(!isPreset);
function handleSelect(e: React.ChangeEvent<HTMLSelectElement>) {
const val = e.target.value;
if (val === CUSTOM_CHARACTER_LABEL) {
setIsCustom(true);
onSpeakerChange(speaker, portrait);
} else {
setIsCustom(false);
const preset = CHARACTER_PRESETS.find(p => p.label === val);
onSpeakerChange(val, preset?.portrait ?? '');
}
}
return (
<div>
<label className={styles.label}>Speaker</label>
<select
className={styles.select}
value={isCustom ? CUSTOM_CHARACTER_LABEL : speaker}
onChange={handleSelect}
>
{CHARACTER_PRESETS.map(p => (
<option key={p.label} value={p.label}>{p.label}</option>
))}
<option value={CUSTOM_CHARACTER_LABEL}>{CUSTOM_CHARACTER_LABEL}</option>
</select>
{isCustom && (
<input
className={styles.input}
style={{ marginTop: 4 }}
value={speaker}
placeholder="Speaker name"
onChange={e => onSpeakerChange(e.target.value, portrait)}
/>
)}
<label className={styles.label} style={{ marginTop: 8 }}>Portrait path</label>
<input
className={styles.input}
value={portrait}
placeholder="resources/dialogue/portrait_..."
onChange={e => onSpeakerChange(speaker, e.target.value)}
/>
</div>
);
}