File size: 3,216 Bytes
5c876be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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 {
  /** Callback with the message text when send is pressed */
  onSend: (text: string) => void;
  /** Callback when the location-attachment button is pressed */
  onSendLocation?: () => void;
  /** Placeholder text (default: "Type a message…") */
  placeholder?: string;
  /** Whether input is currently disabled */
  disabled?: boolean;
}

/**
 * Message input bar pinned to the bottom of a chat screen.
 * Features a flat TextInput, attachment button (📎) and send button (➤).
 */
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]);

  // On Android, handle the hardware keyboard's "send" key
  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,
  },
});