| import React, { useState, useCallback, useRef, useEffect } from 'react'; |
| import { StyleSheet, View, Keyboard, Platform } from 'react-native'; |
| import { useTheme, TextInput, IconButton } from 'react-native-paper'; |
|
|
| export interface ChatInputProps { |
| |
| onSend: (text: string) => void; |
| |
| onSendLocation?: () => void; |
| |
| placeholder?: string; |
| |
| disabled?: boolean; |
| } |
|
|
| |
| |
| |
| |
| export function ChatInput({ |
| onSend, |
| onSendLocation, |
| placeholder = 'Type a message…', |
| disabled = false, |
| }: ChatInputProps) { |
| const theme = useTheme(); |
| const [text, setText] = useState(''); |
| const inputRef = useRef<any>(null); |
|
|
| const handleSend = useCallback(() => { |
| const trimmed = text.trim(); |
| if (!trimmed) return; |
| onSend(trimmed); |
| setText(''); |
| inputRef.current?.focus(); |
| }, [text, onSend]); |
|
|
| const onSubmitEditing = useCallback(() => { |
| handleSend(); |
| }, [handleSend]); |
|
|
| |
| const keyboardType = Platform.OS === 'android' ? 'default' : 'default'; |
|
|
| return ( |
| <View |
| style={[ |
| styles.container, |
| { |
| backgroundColor: theme.colors.surfaceContainerHigh, |
| borderTopColor: theme.colors.outlineVariant, |
| }, |
| ]} |
| > |
| {/* Location attachment button */} |
| <IconButton |
| icon="map-marker-plus-outline" |
| size={22} |
| iconColor={theme.colors.onSurfaceVariant} |
| onPress={onSendLocation} |
| style={styles.attachButton} |
| disabled={disabled} |
| /> |
| |
| {/* Text input */} |
| <TextInput |
| ref={inputRef} |
| mode="flat" |
| value={text} |
| onChangeText={setText} |
| onSubmitEditing={onSubmitEditing} |
| placeholder={placeholder} |
| placeholderTextColor={theme.colors.onSurfaceVariant} |
| disabled={disabled} |
| style={styles.input} |
| contentStyle={styles.inputContent} |
| underlineColor="transparent" |
| activeUnderlineColor="transparent" |
| multiline |
| maxLength={2000} |
| right={ |
| text.trim().length > 0 ? ( |
| <TextInput.Icon |
| icon="send" |
| size={22} |
| iconColor={theme.colors.primary} |
| onPress={handleSend} |
| style={styles.sendIcon} |
| /> |
| ) : null |
| } |
| /> |
| </View> |
| ); |
| } |
|
|
| const styles = StyleSheet.create({ |
| container: { |
| flexDirection: 'row', |
| alignItems: 'flex-end', |
| paddingHorizontal: 4, |
| paddingVertical: 4, |
| borderTopWidth: StyleSheet.hairlineWidth, |
| }, |
| attachButton: { |
| margin: 0, |
| }, |
| input: { |
| flex: 1, |
| backgroundColor: 'transparent', |
| maxHeight: 120, |
| marginVertical: 0, |
| paddingHorizontal: 0, |
| }, |
| inputContent: { |
| minHeight: 40, |
| paddingTop: 8, |
| paddingBottom: 8, |
| }, |
| sendIcon: { |
| margin: 0, |
| paddingBottom: 4, |
| }, |
| }); |
|
|