MCPcopy
hub / github.com/stephengpope/thepopebot / ChatInput

Function ChatInput

lib/chat/components/chat-input.jsx:46–478  ·  view source on GitHub ↗
({ input, setInput, onSubmit, status, stop, files, setFiles, disabled = false, placeholder = 'Send a message...', canSendOverride, bare = false, className, codeMode = false, codeModeSettings })

Source from the content-addressed store, hash-verified

44}
45
46export function ChatInput({ input, setInput, onSubmit, status, stop, files, setFiles, disabled = false, placeholder = 'Send a message...', canSendOverride, bare = false, className, codeMode = false, codeModeSettings }) {
47 const textareaRef = useRef(null);
48 const fileInputRef = useRef(null);
49 const [isDragging, setIsDragging] = useState(false);
50 const [modeDropdownOpen, setModeDropdownOpen] = useState(false);
51 const [agentPickerOpen, setAgentPickerOpen] = useState(false);
52 const [partialText, setPartialText] = useState('');
53 const [secretsOpen, setSecretsOpen] = useState(false);
54 const dropdownRef = useRef(null);
55 const agentPickerRef = useRef(null);
56 const isStreaming = status === 'streaming' || status === 'submitted';
57 const volumeRef = useRef(0);
58
59 const { voiceAvailable, isConnecting, isRecording, startRecording, stopRecording } = useVoiceInput({
60 getToken: getVoiceTokenFetch,
61 onVolumeChange: (rms) => { volumeRef.current = rms; },
62 onTranscript: (text) => {
63 setInput((prev) => {
64 const needsSpace = prev && !prev.endsWith(' ');
65 return prev + (needsSpace ? ' ' : '') + text;
66 });
67 },
68 onPartialTranscript: (text) => setPartialText(text),
69 onError: (err) => console.error('[voice]', err),
70 });
71
72 // Auto-resize textarea
73 const adjustHeight = useCallback(() => {
74 const textarea = textareaRef.current;
75 if (!textarea) return;
76 textarea.style.height = 'auto';
77 textarea.style.height = `${textarea.scrollHeight}px`;
78 textarea.scrollTop = textarea.scrollHeight;
79 }, []);
80
81 useEffect(() => {
82 adjustHeight();
83 }, [input, adjustHeight]);
84
85 // Focus textarea on mount
86 useEffect(() => {
87 textareaRef.current?.focus();
88 }, []);
89
90 // Refocus textarea when streaming ends so the user can immediately type the next message
91 const wasStreaming = useRef(isStreaming);
92 useEffect(() => {
93 if (wasStreaming.current && !isStreaming) {
94 textareaRef.current?.focus();
95 }
96 wasStreaming.current = isStreaming;
97 }, [isStreaming]);
98
99 // Close dropdown on outside click
100 useEffect(() => {
101 if (!modeDropdownOpen) return;
102 const handleClickOutside = (e) => {
103 if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {

Callers

nothing calls this directly

Calls 3

useVoiceInputFunction · 0.90
cnFunction · 0.90
removeFileFunction · 0.85

Tested by

no test coverage detected