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
126
127
128
129
130
131
| | import React, { useEffect, useRef, useState } from "react";
| | import {
| | Dimensions,
| | Image,
| | KeyboardAvoidingView,
| | Modal,
| | Platform,
| | Pressable,
| | Text,
| | TextInput,
| | View,
| | } from "react-native";
| | import { useTheme } from "../../contexts/ThemeContext";
| |
| | interface ImageCaptionModalProps {
| | visible: boolean;
| | imageUri: string;
| | onSend: (caption: string) => void;
| | onCancel: () => void;
| | }
| |
| | export function ImageCaptionModal({ visible, imageUri, onSend, onCancel }: ImageCaptionModalProps) {
| | const { colors } = useTheme();
| | const [caption, setCaption] = useState("");
| | const inputRef = useRef<TextInput>(null);
| | const { width, height } = Dimensions.get("window");
| |
| | useEffect(() => {
| | if (visible) {
| | setCaption("");
| | setTimeout(() => inputRef.current?.focus(), 300);
| | }
| | }, [visible]);
| |
| | const handleSend = () => {
| | onSend(caption.trim());
| | setCaption("");
| | };
| |
| | return (
| | <Modal visible={visible} animationType="slide" transparent={false} onRequestClose={onCancel}>
| | <View style={{ flex: 1, backgroundColor: "#000" }}>
| | <KeyboardAvoidingView
| | style={{ flex: 1 }}
| | behavior={Platform.OS === "ios" ? "padding" : undefined}
| | keyboardVerticalOffset={0}
| | >
| | {/* Top bar with cancel */}
| | <View
| | style={{
| | paddingTop: 54,
| | paddingHorizontal: 16,
| | paddingBottom: 12,
| | flexDirection: "row",
| | alignItems: "center",
| | justifyContent: "space-between",
| | }}
| | >
| | <Pressable
| | onPress={onCancel}
| | hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}
| | style={{
| | paddingHorizontal: 12,
| | paddingVertical: 6,
| | borderRadius: 16,
| | backgroundColor: "rgba(255,255,255,0.15)",
| | }}
| | >
| | <Text style={{ color: "#fff", fontSize: 16, fontWeight: "600" }}>Cancel</Text>
| | </Pressable>
| | </View>
| |
| | {/* Image preview */}
| | <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
| | <Image
| | source={{ uri: imageUri }}
| | style={{ width, height: height * 0.55 }}
| | resizeMode="contain"
| | />
| | </View>
| |
| | {/* Caption input + send */}
| | <View
| | style={{
| | flexDirection: "row",
| | alignItems: "flex-end",
| | paddingHorizontal: 12,
| | paddingVertical: 10,
| | paddingBottom: 34,
| | gap: 8,
| | }}
| | >
| | <TextInput
| | ref={inputRef}
| | value={caption}
| | onChangeText={setCaption}
| | placeholder="Add a caption..."
| | placeholderTextColor="rgba(255,255,255,0.4)"
| | multiline
| | maxLength={2000}
| | style={{
| | flex: 1,
| | backgroundColor: "rgba(255,255,255,0.12)",
| | borderRadius: 20,
| | paddingHorizontal: 16,
| | paddingVertical: 10,
| | maxHeight: 100,
| | color: "#fff",
| | fontSize: 16,
| | }}
| | />
| | <Pressable
| | onPress={handleSend}
| | style={{
| | width: 44,
| | height: 44,
| | borderRadius: 22,
| | alignItems: "center",
| | justifyContent: "center",
| | backgroundColor: colors.accent,
| | marginBottom: 1,
| | }}
| | >
| | <Text style={{ fontSize: 20, fontWeight: "bold", color: "#fff" }}>{"\u2191"}</Text>
| | </Pressable>
| | </View>
| | </KeyboardAvoidingView>
| | </View>
| | </Modal>
| | );
| | }
|
|