@usechat/react-native 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,117 @@
1
+ UseChat SDK License Agreement
2
+
3
+ Copyright (c) 2024 Lukasz Ko and UseChat Team. All rights reserved.
4
+
5
+ USECHAT SDK LICENSE AGREEMENT
6
+
7
+ This License Agreement ("Agreement") governs your use of the UseChat SDK ("Software"),
8
+ a React Native chat UI SDK developed by Lukasz Ko and the UseChat Team ("Licensor").
9
+
10
+ BY USING, INSTALLING, OR ACCESSING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE TERMS
11
+ OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THESE TERMS, DO NOT USE THE SOFTWARE.
12
+
13
+ 1. GRANT OF LICENSE
14
+
15
+ Subject to the terms and conditions of this Agreement, Licensor hereby grants you a
16
+ limited, non-exclusive, non-transferable license to use the Software under the
17
+ following terms:
18
+
19
+ a) PERSONAL AND EDUCATIONAL USE: You may use the Software for personal projects,
20
+ educational purposes, and non-commercial applications at no cost.
21
+
22
+ b) COMMERCIAL USE: For commercial applications, you must obtain a commercial license
23
+ by contacting the Licensor. Commercial use includes but is not limited to:
24
+ - Applications that generate revenue
25
+ - Applications used by businesses or organizations
26
+ - Applications with more than 1,000 monthly active users
27
+ - Applications that compete directly with UseChat services
28
+
29
+ c) OPEN SOURCE PROJECTS: You may use the Software in open source projects that are
30
+ licensed under OSI-approved licenses, provided proper attribution is given.
31
+
32
+ 2. ATTRIBUTION REQUIREMENTS
33
+
34
+ When using the Software, you must:
35
+ - Include proper attribution to "UseChat SDK by Lukasz Ko" in your application
36
+ - Retain all copyright notices and license information
37
+ - Include a link to the official UseChat website or repository where feasible
38
+
39
+ 3. RESTRICTIONS
40
+
41
+ You may NOT:
42
+ - Remove or alter any copyright, trademark, or other proprietary notices
43
+ - Reverse engineer, decompile, or disassemble the Software
44
+ - Redistribute the Software as a standalone product
45
+ - Use the Software to create competing chat SDK products
46
+ - Use the Software in applications that violate laws or regulations
47
+ - Use the Software for harmful, malicious, or illegal purposes
48
+
49
+ 4. COMMERCIAL LICENSE TERMS
50
+
51
+ Commercial licenses are available with the following benefits:
52
+ - Removal of attribution requirements
53
+ - Priority support and updates
54
+ - Custom feature development
55
+ - White-label usage rights
56
+ - Extended warranty and liability coverage
57
+
58
+ Contact: hello@usechat.dev for commercial licensing inquiries.
59
+
60
+ 5. INTELLECTUAL PROPERTY
61
+
62
+ The Software and all intellectual property rights therein are and shall remain the
63
+ exclusive property of the Licensor. This Agreement does not grant you any ownership
64
+ rights in the Software.
65
+
66
+ 6. UPDATES AND MODIFICATIONS
67
+
68
+ Licensor may update or modify the Software at any time. Updates will be governed by
69
+ this Agreement unless accompanied by a new license agreement.
70
+
71
+ 7. SUPPORT AND MAINTENANCE
72
+
73
+ This license does not entitle you to support or maintenance services. Commercial
74
+ license holders may receive support as specified in their commercial agreement.
75
+
76
+ 8. WARRANTY DISCLAIMER
77
+
78
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
79
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
80
+ PARTICULAR PURPOSE, AND NON-INFRINGEMENT. IN NO EVENT SHALL THE LICENSOR BE LIABLE
81
+ FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING FROM THE USE OF THE SOFTWARE.
82
+
83
+ 9. LIMITATION OF LIABILITY
84
+
85
+ IN NO EVENT SHALL THE LICENSOR BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
86
+ CONSEQUENTIAL, OR PUNITIVE DAMAGES, INCLUDING WITHOUT LIMITATION, LOSS OF PROFITS,
87
+ DATA, OR USE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT OR THE USE OF
88
+ THE SOFTWARE.
89
+
90
+ 10. TERMINATION
91
+
92
+ This Agreement is effective until terminated. Your rights under this Agreement will
93
+ terminate automatically if you fail to comply with any terms. Upon termination, you
94
+ must cease all use of the Software and destroy all copies.
95
+
96
+ 11. GOVERNING LAW
97
+
98
+ This Agreement shall be governed by and construed in accordance with the laws of
99
+ [Your Jurisdiction]. Any disputes shall be resolved in the courts of [Your Jurisdiction].
100
+
101
+ 12. ENTIRE AGREEMENT
102
+
103
+ This Agreement constitutes the entire agreement between you and the Licensor regarding
104
+ the Software and supersedes all prior agreements and understandings.
105
+
106
+ 13. CONTACT INFORMATION
107
+
108
+ For questions about this license or to request commercial licensing:
109
+ - Email: hello@usechat.dev
110
+ - Website: https://usechat.dev
111
+ - GitHub: https://github.com/usechat-dev
112
+
113
+ ---
114
+
115
+ UseChat SDK - Professional React Native Chat Solution
116
+ Copyright (c) 2024 Lukasz Ko and UseChat Team
117
+ All rights reserved.
package/README.md ADDED
@@ -0,0 +1,317 @@
1
+ # UseChat SDK - React Native Chat UI Library
2
+
3
+ A professional, customizable chat component library for React Native with a modern architecture that separates UI from logic.
4
+
5
+ > **Note:** UseChat SDK is licensed under a custom license. See [LICENSING.md](./LICENSING.md) for details. Free for personal/educational use, commercial license required for business applications.
6
+
7
+ ## Features
8
+
9
+ - **Render Props Architecture**: Customize any part of the UI using render props
10
+ - **Standalone Hooks**: Use chat logic without UI components
11
+ - **Pluggable Attachment System**: Easy integration with your backend
12
+ - **TypeScript First**: Full type safety and IntelliSense support
13
+ - **Customizable Components**: Override any component with your own implementation
14
+
15
+ ## Architecture Overview
16
+
17
+ The library follows a clean separation of concerns:
18
+
19
+ - **Components**: UI components that can be customized via render props
20
+ - **Hooks**: Logic-only hooks that can be used independently
21
+ - **Types**: Shared TypeScript interfaces
22
+ - **Plugins**: Optional attachment plugins for different file types
23
+
24
+ ## Quick Start
25
+
26
+ ### Basic Usage
27
+
28
+ ```tsx
29
+ import { Chat } from '@your-org/chat';
30
+
31
+ const MyChat = () => (
32
+ <Chat
33
+ chatName="My Chat"
34
+ onMessageSend={(message) => console.log('Message sent:', message)}
35
+ onBack={() => navigation.goBack()}
36
+ />
37
+ );
38
+ ```
39
+
40
+ ### Using Render Props
41
+
42
+ ```tsx
43
+ <Chat
44
+ chatName="Custom Chat"
45
+ renderProps={{
46
+ renderMessage: (props) => <CustomMessage {...props} />,
47
+ renderInput: (props) => <CustomInput {...props} />,
48
+ renderHeader: (props) => <CustomHeader {...props} />,
49
+ }}
50
+ onMessageSend={handleMessageSend}
51
+ />
52
+ ```
53
+
54
+ ### Using Standalone Hooks
55
+
56
+
57
+ ## Components
58
+
59
+ ### Chat
60
+
61
+ The main chat component that orchestrates all functionality.
62
+
63
+ **Props:**
64
+ - `chatName`: Name displayed in the header
65
+ - `messages`: Array of messages to display
66
+ - `renderProps`: Object containing render functions for customization
67
+ - `components`: Object containing component overrides
68
+ - `attachmentUploader`: Function to handle file uploads
69
+ - `maxAttachments`: Maximum number of attachments per message
70
+ - `maxFileSize`: Maximum file size in bytes
71
+ - `allowedFileTypes`: Array of allowed MIME types
72
+
73
+ **Render Props:**
74
+ - `renderMessage`: Custom message rendering
75
+ - `renderInput`: Custom input component
76
+ - `renderHeader`: Custom header component
77
+ - `renderActionSheet`: Custom action sheet
78
+ - `renderReactionDetails`: Custom reaction details
79
+
80
+ ### MessageList
81
+
82
+ Displays a list of messages with scrolling and typing indicators.
83
+
84
+ ### MessageInput
85
+
86
+ Handles text input, attachments, and message sending.
87
+
88
+ ### ChatScreenHeader
89
+
90
+ Displays chat information and action buttons.
91
+
92
+ ### MessageActionSheet
93
+
94
+ Shows message actions (reply, copy, delete, reactions).
95
+
96
+ ### ReactionDetailsSheet
97
+
98
+ Displays detailed reaction information.
99
+
100
+ ## Hooks
101
+
102
+ ### useAttachments
103
+
104
+ Manages attachment lifecycle and uploads.
105
+
106
+ ```tsx
107
+ const {
108
+ attachments,
109
+ openPicker,
110
+ addAttachment,
111
+ removeAttachment,
112
+ uploadAttachments,
113
+ isUploading,
114
+ } = useAttachments({
115
+ uploader: myUploader,
116
+ maxAttachments: 10,
117
+ maxFileSize: 10 * 1024 * 1024,
118
+ });
119
+ ```
120
+
121
+ ### useTypingIndicator
122
+
123
+ Manages typing indicator state.
124
+
125
+ ```tsx
126
+ const {
127
+ isTyping,
128
+ startTyping,
129
+ stopTyping,
130
+ typingUsers,
131
+ } = useTypingIndicator({
132
+ typingTimeout: 3000,
133
+ });
134
+ ```
135
+
136
+ ### useMessageList
137
+
138
+ Manages message list scrolling and interactions.
139
+
140
+ ```tsx
141
+ const {
142
+ messageListRef,
143
+ showScrollToBottomButton,
144
+ scrollToBottom,
145
+ handleScroll,
146
+ } = useMessageList({
147
+ messages,
148
+ onMessageLongPress,
149
+ onReactionPress,
150
+ });
151
+ ```
152
+
153
+ ### useMessageInput
154
+
155
+ Manages message input state and validation.
156
+
157
+ ```tsx
158
+ const {
159
+ message,
160
+ composerHeight,
161
+ handleTextChange,
162
+ handleSend,
163
+ handleFocus,
164
+ } = useMessageInput({
165
+ onSend: handleMessageSend,
166
+ maxLength: 1000,
167
+ });
168
+ ```
169
+
170
+ ## Attachment System
171
+
172
+ The library provides a pluggable attachment system that supports:
173
+
174
+ - **Image Picker**: Select images from gallery or camera
175
+ - **Document Picker**: Select documents and files
176
+ - **Location Sharing**: Share current location
177
+ - **Contact Sharing**: Share contact information
178
+
179
+ ### Custom Uploader
180
+
181
+ ```tsx
182
+ const myUploader: AttachmentUploader = {
183
+ upload: async (file) => {
184
+ const formData = new FormData();
185
+ formData.append('file', file);
186
+
187
+ const response = await fetch('/api/upload', {
188
+ method: 'POST',
189
+ body: formData,
190
+ });
191
+
192
+ const result = await response.json();
193
+ return {
194
+ url: result.url,
195
+ metadata: result.metadata,
196
+ };
197
+ },
198
+
199
+ validate: (file) => {
200
+ if (file.size > 10 * 1024 * 1024) {
201
+ return 'File too large';
202
+ }
203
+ return true;
204
+ },
205
+ };
206
+ ```
207
+
208
+ ## Customization Examples
209
+
210
+ ### Custom Message Component
211
+
212
+ ```tsx
213
+ const CustomMessage = ({ message, onLongPress, onReactionPress }) => (
214
+ <View style={styles.message}>
215
+ <Text style={styles.text}>{message.text}</Text>
216
+ <Text style={styles.time}>
217
+ {new Date(message.timestamp).toLocaleTimeString()}
218
+ </Text>
219
+ {message.reactions?.map((reaction, index) => (
220
+ <TouchableOpacity
221
+ key={index}
222
+ onPress={() => onReactionPress(message)}
223
+ >
224
+ <Text>{reaction.emoji} {reaction.count}</Text>
225
+ </TouchableOpacity>
226
+ ))}
227
+ </View>
228
+ );
229
+ ```
230
+
231
+ ### Custom Input Component
232
+
233
+ ```tsx
234
+ const CustomInput = ({
235
+ value,
236
+ onChangeText,
237
+ onSend,
238
+ attachments,
239
+ onAttachmentAdd,
240
+ onAttachmentRemove
241
+ }) => (
242
+ <View style={styles.inputContainer}>
243
+ <TextInput
244
+ value={value}
245
+ onChangeText={onChangeText}
246
+ placeholder="Type a message..."
247
+ style={styles.textInput}
248
+ />
249
+ <TouchableOpacity onPress={onSend} style={styles.sendButton}>
250
+ <Text>Send</Text>
251
+ </TouchableOpacity>
252
+
253
+ {attachments.map(attachment => (
254
+ <View key={attachment.id} style={styles.attachment}>
255
+ <Text>{attachment.fileName}</Text>
256
+ <TouchableOpacity onPress={() => onAttachmentRemove(attachment.id)}>
257
+ <Text>×</Text>
258
+ </TouchableOpacity>
259
+ </View>
260
+ ))}
261
+ </View>
262
+ );
263
+ ```
264
+
265
+ ## TypeScript Support
266
+
267
+ All components and hooks are fully typed with TypeScript. The library exports comprehensive type definitions for:
268
+
269
+ - Message and attachment interfaces
270
+ - Hook return types
271
+ - Component prop types
272
+ - Render prop interfaces
273
+
274
+ ## Migration from v1
275
+
276
+ If you're upgrading from the previous version:
277
+
278
+ 1. **Replace `onMessageSend`**: The callback now receives a `Message` object instead of separate parameters
279
+ 2. **Update attachment handling**: Use the new `useAttachments` hook or `attachmentUploader` prop
280
+ 3. **Component overrides**: Use `renderProps` instead of `components` for UI customization
281
+ 4. **Hooks**: Extract logic into standalone hooks for better reusability
282
+
283
+ ## 📄 License
284
+
285
+ UseChat SDK is licensed under a **Custom License Agreement**:
286
+
287
+ - ✅ **Free** for personal, educational, and small-scale use
288
+ - 💼 **Commercial license required** for business applications
289
+ - 📋 **Full details:** See [LICENSING.md](./LICENSING.md)
290
+
291
+ ### Quick Licensing Guide
292
+
293
+ | Use Case | License Required | Attribution |
294
+ |----------|------------------|-------------|
295
+ | Personal projects | Free | Required |
296
+ | Educational use | Free | Required |
297
+ | Open source projects | Free | Required |
298
+ | Apps with <1,000 MAU | Free | Required |
299
+ | Commercial/Business apps | Commercial | Optional |
300
+ | Apps with 1,000+ MAU | Commercial | Optional |
301
+
302
+ **Contact:** hello@usechat.dev for commercial licensing
303
+
304
+ ## 🤝 Contributing
305
+
306
+ 1. Fork the repository
307
+ 2. Create a feature branch
308
+ 3. Make your changes
309
+ 4. Add tests if applicable
310
+ 5. Submit a pull request
311
+
312
+ ## 📞 Support
313
+
314
+ - **Documentation:** https://docs.usechat.dev
315
+ - **Issues:** [GitHub Issues](https://github.com/usechat-dev/react-native-chat/issues)
316
+ - **Email:** support@usechat.dev
317
+ - **Website:** https://usechat.dev
@@ -0,0 +1,64 @@
1
+ 'use client'
2
+
3
+ // src/utils/clipboard.ts
4
+ var copyToClipboard = async (text) => {
5
+ console.log("copyToClipboard called with text:", text);
6
+ try {
7
+ try {
8
+ const { setStringAsync } = await import("expo-clipboard");
9
+ console.log("expo-clipboard imported successfully");
10
+ console.log("setStringAsync function:", setStringAsync);
11
+ await setStringAsync(text);
12
+ console.log("Text copied to clipboard successfully");
13
+ } catch (importError) {
14
+ console.error("Failed to import expo-clipboard:", importError);
15
+ throw new Error("expo-clipboard not available");
16
+ }
17
+ try {
18
+ const toastModule = await import("react-native-toast-message");
19
+ const Toast = toastModule.default || toastModule;
20
+ console.log("react-native-toast-message imported successfully");
21
+ Toast.show({
22
+ type: "success",
23
+ text1: "Copied to clipboard",
24
+ text2: "Message copied successfully",
25
+ position: "bottom",
26
+ visibilityTime: 2e3
27
+ });
28
+ console.log("Toast shown successfully");
29
+ } catch (toastError) {
30
+ console.log("Toast not available, but message copied to clipboard");
31
+ console.error("Toast import error:", toastError);
32
+ }
33
+ return true;
34
+ } catch (error) {
35
+ console.error("Failed to copy to clipboard:", error);
36
+ try {
37
+ const toastModule = await import("react-native-toast-message");
38
+ const Toast = toastModule.default || toastModule;
39
+ Toast.show({
40
+ type: "error",
41
+ text1: "Copy failed",
42
+ text2: "Failed to copy message to clipboard",
43
+ position: "bottom",
44
+ visibilityTime: 2e3
45
+ });
46
+ } catch (toastError) {
47
+ console.error("Copy failed: expo-clipboard not available");
48
+ console.error("Toast import error:", toastError);
49
+ }
50
+ return false;
51
+ }
52
+ };
53
+ var isClipboardAvailable = async () => {
54
+ try {
55
+ await import("expo-clipboard");
56
+ return true;
57
+ } catch {
58
+ return false;
59
+ }
60
+ };
61
+ export {
62
+ copyToClipboard,
63
+ isClipboardAvailable
64
+ };