import { useState, useCallback, useImperativeHandle, forwardRef, useRef, type FormEvent, type KeyboardEvent } from 'react'; import { Input } from './ui/input'; import { Button } from './ui/button'; interface MessageInputProps { onSend: (text: string) => Promise; disabled: boolean; placeholder?: string; /** When true, input becomes password field for repeater telemetry */ isRepeaterMode?: boolean; } export interface MessageInputHandle { appendText: (text: string) => void; } export const MessageInput = forwardRef( function MessageInput({ onSend, disabled, placeholder, isRepeaterMode }, ref) { const [text, setText] = useState(''); const [sending, setSending] = useState(false); const inputRef = useRef(null); useImperativeHandle(ref, () => ({ appendText: (appendedText: string) => { setText((prev) => prev + appendedText); // Focus the input after appending inputRef.current?.focus(); }, })); const handleSubmit = useCallback( async (e: FormEvent) => { e.preventDefault(); const trimmed = text.trim(); // For repeater mode, allow empty password via "." if (isRepeaterMode) { if (sending || disabled) return; // "." means empty password const password = trimmed === '.' ? '' : trimmed; setSending(true); try { await onSend(password); setText(''); } catch (err) { console.error('Failed to request telemetry:', err); } finally { setSending(false); } } else { if (!trimmed || sending || disabled) return; setSending(true); try { await onSend(trimmed); setText(''); } catch (err) { console.error('Failed to send message:', err); } finally { setSending(false); } } }, [text, sending, disabled, onSend, isRepeaterMode] ); const handleKeyDown = useCallback( (e: KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSubmit(e as unknown as FormEvent); } }, [handleSubmit] ); // For repeater mode, enable submit if there's text OR if it's just "." for empty password const canSubmit = isRepeaterMode ? text.trim().length > 0 || text === '.' : text.trim().length > 0; return (
setText(e.target.value)} onKeyDown={handleKeyDown} placeholder={placeholder || (isRepeaterMode ? 'Enter password (or . for none)...' : 'Type a message...')} disabled={disabled || sending} className="flex-1" />
); });