@traiyani/chatsdk-react 1.0.1 → 1.0.3

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.
Files changed (2) hide show
  1. package/README.md +585 -173
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -2,19 +2,47 @@
2
2
 
3
3
  React SDK for ChatSDK - Real-time chat solution with product-based conversations, Socket.io, instant messaging, and file sharing.
4
4
 
5
- ## Installation
5
+ ## Features
6
+
7
+ - Real-time messaging via Socket.IO
8
+ - Product-based conversations with metadata
9
+ - File/image/video uploads and sharing
10
+ - Block/unblock users
11
+ - Internationalization (English + Arabic with RTL)
12
+ - Dark mode support (light / dark / auto)
13
+ - Typing indicators
14
+ - Read receipts and message status
15
+ - Unread message counts
16
+ - Ready-made UI components (Conversation List + Chat Window)
17
+ - Pre-built — works with any bundler, zero config
18
+
19
+ ## Table of Contents
20
+
21
+ 1. [Installation](#1-installation)
22
+ 2. [SDK Initialization](#2-sdk-initialization)
23
+ 3. [User Authentication](#3-user-authentication)
24
+ 4. [Start a New Conversation](#4-start-a-new-conversation)
25
+ 5. [Using Ready-Made UI Components](#5-using-ready-made-ui-components)
26
+ 6. [Sending Messages](#6-sending-messages)
27
+ 7. [File Uploads & Attachments](#7-file-uploads--attachments)
28
+ 8. [Unread Message Counts](#8-unread-message-counts)
29
+ 9. [Block & Unblock Users](#9-block--unblock-users)
30
+ 10. [Real-Time Events](#10-real-time-events)
31
+ 11. [Theme Support](#11-theme-support)
32
+ 12. [Internationalization (i18n)](#12-internationalization-i18n)
33
+ 13. [Logout & Cleanup](#13-logout--cleanup)
34
+ 14. [TypeScript Support](#14-typescript-support)
35
+ 15. [Troubleshooting](#15-troubleshooting)
36
+
37
+ ---
38
+
39
+ ## 1. Installation
6
40
 
7
41
  ```bash
8
42
  npm install @traiyani/chatsdk-react axios socket.io-client
9
43
  ```
10
44
 
11
- ### Peer Dependencies
12
-
13
- Ensure your project has these installed:
14
-
15
- ```bash
16
- npm install react react-dom axios socket.io-client
17
- ```
45
+ ### Requirements
18
46
 
19
47
  | Dependency | Minimum Version |
20
48
  |---|---|
@@ -23,36 +51,343 @@ npm install react react-dom axios socket.io-client
23
51
  | `axios` | >= 0.21.0 |
24
52
  | `socket.io-client` | >= 4.0.0 |
25
53
 
26
- ## Quick Start
54
+ **No build configuration changes needed.** Works with Vite, webpack, Next.js, Create React App, Parcel, and any React bundler out of the box.
55
+
56
+ ### Import CSS
57
+
58
+ Import the stylesheet once in your app's entry point:
59
+
60
+ ```tsx
61
+ import '@traiyani/chatsdk-react/dist/chatsdk.css';
62
+ ```
63
+
64
+ ---
65
+
66
+ ## 2. SDK Initialization
67
+
68
+ Initialize the SDK once in your app, before any authentication or chat operations.
69
+
70
+ ```tsx
71
+ import { ChatSDK } from '@traiyani/chatsdk-react';
72
+
73
+ const sdk = ChatSDK.getInstance();
74
+
75
+ await sdk.init({
76
+ apiBaseUrl: 'https://your-chat-api.com/api', // Your Mzad Chat API URL
77
+ appId: 'your-app-id', // Your application ID
78
+ environment: 'production', // 'development' | 'staging' | 'production'
79
+ enableLogging: true, // Enable console logs (set false in production)
80
+ autoConnect: true, // Auto-connect WebSocket after auth
81
+ });
82
+ ```
83
+
84
+ ### Configuration Options
85
+
86
+ ```typescript
87
+ interface ChatSDKConfig {
88
+ apiBaseUrl: string; // Required - API server URL
89
+ appId: string; // Required - Your application ID
90
+ environment: 'development' | 'staging' | 'production'; // Required
91
+ wsUrl?: string; // WebSocket URL (defaults to apiBaseUrl)
92
+ apiKey?: string; // API key (if required by server)
93
+ enableLogging?: boolean; // Enable debug logging (default: false)
94
+ autoConnect?: boolean; // Auto-connect WebSocket (default: true)
95
+ timeout?: number; // HTTP request timeout in ms (default: 30000)
96
+ }
97
+ ```
98
+
99
+ ### Environment Variables
100
+
101
+ Config values can come from any source:
102
+
103
+ ```tsx
104
+ // Create React App
105
+ await sdk.init({ apiBaseUrl: process.env.REACT_APP_API_URL, appId: process.env.REACT_APP_APP_ID, ... });
106
+
107
+ // Vite
108
+ await sdk.init({ apiBaseUrl: import.meta.env.VITE_API_URL, appId: import.meta.env.VITE_APP_ID, ... });
109
+
110
+ // Next.js
111
+ await sdk.init({ apiBaseUrl: process.env.NEXT_PUBLIC_API_URL, appId: process.env.NEXT_PUBLIC_APP_ID, ... });
112
+ ```
113
+
114
+ ---
115
+
116
+ ## 3. User Authentication
117
+
118
+ The SDK uses the `chatUsers.authenticate()` method which tries login first and falls back to registration automatically.
119
+
120
+ ### 3.1 Login the Current User (`isLoggedinUser = true`)
121
+
122
+ Use `isLoggedinUser = true` when the user is the **currently logged-in user** of your app. This saves the auth token so the SDK can make API calls on behalf of this user.
123
+
124
+ ```tsx
125
+ const sdk = ChatSDK.getInstance();
126
+
127
+ // Authenticate the current logged-in user
128
+ const currentUser = await sdk.chatUsers.authenticate(
129
+ 'external-user-123', // Your app's user ID
130
+ 'your-app-id', // App ID (must match sdk.init)
131
+ 'John Doe', // Display name
132
+ 'john@example.com', // Email
133
+ true // isLoggedinUser = true → saves token
134
+ );
135
+
136
+ // Connect WebSocket for real-time messaging
137
+ await sdk.connect(currentUser.id);
138
+
139
+ console.log('Logged in:', currentUser.name);
140
+ ```
141
+
142
+ **What happens under the hood:**
143
+ 1. Tries to **login** the user (if already registered in chat system)
144
+ 2. If login fails, **registers** the user automatically
145
+ 3. Saves the auth token to localStorage (because `isLoggedinUser = true`)
146
+ 4. All subsequent API calls use this token
147
+
148
+ ### 3.2 Verify Another User's Existence (`isLoggedinUser = false`)
149
+
150
+ Use `isLoggedinUser = false` when you need to verify or register **another user** (e.g., a seller, the other participant) without switching the current session. This does NOT save the token.
151
+
152
+ ```tsx
153
+ // Verify/register the other user (seller) without switching sessions
154
+ const otherUser = await sdk.chatUsers.authenticate(
155
+ 'seller-456', // The other user's external ID
156
+ 'your-app-id', // App ID
157
+ 'Jane Smith', // Their display name
158
+ 'jane@example.com', // Their email
159
+ false // isLoggedinUser = false → does NOT save token
160
+ );
161
+
162
+ console.log('Other user verified:', otherUser.name, otherUser.id);
163
+ // Now you can use otherUser.id to start a chat
164
+ ```
165
+
166
+ **Why this matters:** Before starting a chat with another user, you must ensure they exist in the chat system. Calling `authenticate` with `isLoggedinUser = false` creates or verifies the user without disrupting your current session.
167
+
168
+ ### 3.3 Check Login Status
169
+
170
+ ```tsx
171
+ const isLoggedIn = sdk.chatUsers.isAuthenticated();
172
+ const currentUser = sdk.getCurrentUser();
173
+ ```
174
+
175
+ ---
176
+
177
+ ## 4. Start a New Conversation
178
+
179
+ ### 4.1 Understanding `externalGroupId` (Required)
180
+
181
+ All `startChat` methods require an `externalGroupId`. This is a unique identifier your app generates to enable fast room lookup (98% faster) and prevent duplicate conversations.
182
+
183
+ **How to generate it:**
184
+
185
+ ```tsx
186
+ async function generateExternalGroupId(userId1, userId2, productId) {
187
+ const sorted = [userId1, userId2].sort();
188
+ const base = productId
189
+ ? `${sorted[0]}_${sorted[1]}_product_${productId}`
190
+ : `${sorted[0]}_${sorted[1]}`;
191
+
192
+ const encoder = new TextEncoder();
193
+ const data = encoder.encode(base);
194
+ const hashBuffer = await crypto.subtle.digest('SHA-256', data);
195
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
196
+ return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
197
+ }
198
+ ```
199
+
200
+ **Usage:**
201
+
202
+ ```tsx
203
+ const currentUserId = sdk.getCurrentUser().id;
204
+ const externalGroupId = await generateExternalGroupId(currentUserId, otherUser.id, 'PRODUCT_123');
205
+ ```
206
+
207
+ ### 4.2 Simple Direct Chat
208
+
209
+ ```tsx
210
+ const conversation = await sdk.chatUsers.startChat(
211
+ externalGroupId, // Generated GUID
212
+ otherUser.id // The other participant's chat user ID
213
+ );
214
+
215
+ console.log('Chat started:', conversation.id);
216
+ ```
217
+
218
+ ### 4.3 Chat with Product Context & Metadata
219
+
220
+ ```tsx
221
+ // Create product context
222
+ const productContext = {
223
+ productId: 'CAR_456',
224
+ productName: 'Toyota Camry 2023',
225
+ productImage: 'https://example.com/car.jpg',
226
+ price: 25000,
227
+ currency: 'QAR',
228
+ category: 'Vehicles',
229
+ productMetadata: {
230
+ mileage: '50000',
231
+ transmission: 'Automatic',
232
+ year: '2023',
233
+ },
234
+ };
235
+
236
+ // Optional: custom chat metadata
237
+ const chatMetadata = {
238
+ dealType: 'sale',
239
+ negotiable: true,
240
+ priority: 'high',
241
+ source: 'featured_listing',
242
+ };
243
+
244
+ // Start product chat
245
+ const conversation = await sdk.chatUsers.startChatWithProduct(
246
+ externalGroupId, // Generated GUID (include productId in generation)
247
+ otherUser.id, // Seller's chat user ID
248
+ productContext, // Product information
249
+ chatMetadata // Optional chat metadata
250
+ );
251
+
252
+ console.log('Product chat started:', conversation.id);
253
+ ```
254
+
255
+ ### 4.4 Complete Flow: Login → Verify Seller → Start Product Chat
256
+
257
+ ```tsx
258
+ import { ChatSDK } from '@traiyani/chatsdk-react';
259
+
260
+ const sdk = ChatSDK.getInstance();
261
+
262
+ // Step 1: Initialize SDK
263
+ await sdk.init({
264
+ apiBaseUrl: 'https://your-chat-api.com/api',
265
+ appId: 'your-app-id',
266
+ environment: 'production',
267
+ });
268
+
269
+ // Step 2: Login the current user (buyer)
270
+ const currentUser = await sdk.chatUsers.authenticate(
271
+ 'buyer-external-id',
272
+ 'your-app-id',
273
+ 'Ahmed',
274
+ 'ahmed@example.com',
275
+ true // isLoggedinUser = true → this is the logged-in user
276
+ );
277
+ await sdk.connect(currentUser.id);
278
+
279
+ // Step 3: Verify/register the other user (seller) — does NOT switch session
280
+ const seller = await sdk.chatUsers.authenticate(
281
+ 'seller-external-id',
282
+ 'your-app-id',
283
+ 'Mohammed',
284
+ 'mohammed@example.com',
285
+ false // isLoggedinUser = false → just verify existence
286
+ );
287
+
288
+ // Step 4: Generate externalGroupId
289
+ const externalGroupId = await generateExternalGroupId(
290
+ currentUser.id,
291
+ seller.id,
292
+ 'PRODUCT_789'
293
+ );
294
+
295
+ // Step 5: Start chat with product
296
+ const conversation = await sdk.chatUsers.startChatWithProduct(
297
+ externalGroupId,
298
+ seller.id,
299
+ {
300
+ productId: 'PRODUCT_789',
301
+ productName: 'iPhone 15 Pro',
302
+ productImage: 'https://example.com/iphone.jpg',
303
+ price: 4999,
304
+ currency: 'QAR',
305
+ category: 'Electronics',
306
+ }
307
+ );
308
+
309
+ // Step 6: Now show ChatWindow component with this conversation
310
+ ```
311
+
312
+ ---
313
+
314
+ ## 5. Using Ready-Made UI Components
315
+
316
+ The SDK includes two ready-made React components with full functionality.
317
+
318
+ ### 5.1 Conversation List
319
+
320
+ Displays all conversations with last message preview, unread badges, product context, and real-time updates.
321
+
322
+ ```tsx
323
+ import { ConversationList } from '@traiyani/chatsdk-react';
324
+
325
+ <ConversationList
326
+ currentUser={currentUser}
327
+ onSelectConversation={(conversation) => setSelectedConversation(conversation)}
328
+ selectedConversationId={selectedConversation?.id}
329
+ />
330
+ ```
331
+
332
+ **Props:**
333
+
334
+ ```typescript
335
+ interface ConversationListProps {
336
+ currentUser: ChatSDKUser; // Required - authenticated user
337
+ onSelectConversation: (conv: Conversation) => void; // Required - selection callback
338
+ selectedConversationId?: string; // Highlights active conversation
339
+ }
340
+ ```
341
+
342
+ ### 5.2 Chat Window
343
+
344
+ Full chat interface with messaging, file uploads, typing indicators, message status, block/unblock, and product context bar.
345
+
346
+ ```tsx
347
+ import { ChatWindow } from '@traiyani/chatsdk-react';
348
+
349
+ <ChatWindow
350
+ conversation={selectedConversation}
351
+ currentUser={currentUser}
352
+ onClose={() => setSelectedConversation(null)}
353
+ onBack={() => setSelectedConversation(null)}
354
+ />
355
+ ```
356
+
357
+ **Props:**
358
+
359
+ ```typescript
360
+ interface ChatWindowProps {
361
+ conversation: Conversation | null; // Required - active conversation
362
+ currentUser: ChatSDKUser; // Required - authenticated user
363
+ onClose?: () => void; // Called when close button pressed
364
+ onBack?: () => void; // Called when back button pressed (mobile)
365
+ }
366
+ ```
367
+
368
+ ### 5.3 Complete App Example
27
369
 
28
370
  ```tsx
29
371
  import React, { useState, useEffect } from 'react';
30
- import { ChatSDK, ChatWindow, ConversationList } from '@traiyani/chatsdk-react';
372
+ import { ChatSDK, ConversationList, ChatWindow } from '@traiyani/chatsdk-react';
31
373
  import '@traiyani/chatsdk-react/dist/chatsdk.css';
32
374
 
33
- function App() {
375
+ function ChatApp() {
34
376
  const [currentUser, setCurrentUser] = useState(null);
35
377
  const [selectedConversation, setSelectedConversation] = useState(null);
36
378
 
37
379
  useEffect(() => {
38
380
  const init = async () => {
39
381
  const sdk = ChatSDK.getInstance();
40
-
41
382
  await sdk.init({
42
- apiBaseUrl: 'https://your-chat-api.com',
43
- appId: 'your-app-id',
383
+ apiBaseUrl: process.env.REACT_APP_API_URL,
384
+ appId: process.env.REACT_APP_APP_ID,
44
385
  environment: 'production',
45
- enableLogging: false,
46
- autoConnect: false,
47
386
  });
48
387
 
49
388
  const user = await sdk.chatUsers.authenticate(
50
- 'user-123', // your app's user ID
51
- 'your-app-id', // your ChatSDK app ID
52
- 'John Doe', // display name
53
- 'john@example.com' // email
389
+ 'user-123', 'your-app-id', 'John Doe', 'john@example.com', true
54
390
  );
55
-
56
391
  await sdk.connect(user.id);
57
392
  setCurrentUser(user);
58
393
  };
@@ -63,241 +398,318 @@ function App() {
63
398
 
64
399
  return (
65
400
  <div style={{ display: 'flex', height: '100vh' }}>
66
- <ConversationList
67
- currentUser={currentUser}
68
- onSelectConversation={setSelectedConversation}
69
- selectedConversationId={selectedConversation?.id}
70
- />
71
- {selectedConversation && (
72
- <ChatWindow
73
- conversation={selectedConversation}
401
+ <div style={{ width: '350px', borderRight: '1px solid #e0e0e0' }}>
402
+ <ConversationList
74
403
  currentUser={currentUser}
75
- onClose={() => setSelectedConversation(null)}
76
- onBack={() => setSelectedConversation(null)}
404
+ onSelectConversation={setSelectedConversation}
405
+ selectedConversationId={selectedConversation?.id}
77
406
  />
78
- )}
407
+ </div>
408
+ <div style={{ flex: 1 }}>
409
+ {selectedConversation ? (
410
+ <ChatWindow
411
+ conversation={selectedConversation}
412
+ currentUser={currentUser}
413
+ onClose={() => setSelectedConversation(null)}
414
+ onBack={() => setSelectedConversation(null)}
415
+ />
416
+ ) : (
417
+ <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
418
+ Select a conversation
419
+ </div>
420
+ )}
421
+ </div>
79
422
  </div>
80
423
  );
81
424
  }
82
425
  ```
83
426
 
84
- **Zero build configuration changes required. Works with Vite, webpack, Next.js, Create React App, Parcel, and any React bundler.**
85
-
86
- ## Components
427
+ ---
87
428
 
88
- ### ChatWindow
429
+ ## 6. Sending Messages
89
430
 
90
- Displays the chat interface with messages, file uploads, block/unblock, and real-time updates.
431
+ ### Send a Text Message
91
432
 
92
433
  ```tsx
93
- <ChatWindow
94
- conversation={selectedConversation}
95
- currentUser={currentUser}
96
- onClose={handleClose}
97
- onBack={handleBack}
98
- />
99
- ```
434
+ const sdk = ChatSDK.getInstance();
100
435
 
101
- | Prop | Type | Required | Description |
102
- |---|---|---|---|
103
- | `conversation` | `ChatSDKConversation \| null` | Yes | Active conversation object |
104
- | `currentUser` | `ChatSDKUser` | Yes | Authenticated user object |
105
- | `onClose` | `() => void` | No | Called when user clicks close |
106
- | `onBack` | `() => void` | No | Called when user clicks back (mobile) |
436
+ const message = await sdk.messages.sendMessage(
437
+ conversationId,
438
+ 'Hello! Is this still available?'
439
+ );
107
440
 
108
- ### ConversationList
441
+ console.log('Message sent:', message.id);
442
+ ```
109
443
 
110
- Displays the list of conversations with search, unread counts, and real-time updates.
444
+ ### Send with Metadata
111
445
 
112
446
  ```tsx
113
- <ConversationList
114
- currentUser={currentUser}
115
- onSelectConversation={handleSelect}
116
- selectedConversationId={activeConversationId}
117
- />
447
+ const message = await sdk.messages.sendMessageWithOptions({
448
+ conversationId: conversationId,
449
+ content: 'Here is my offer',
450
+ type: 'text',
451
+ metadata: { offerAmount: 4500, currency: 'QAR' },
452
+ });
118
453
  ```
119
454
 
120
- | Prop | Type | Required | Description |
121
- |---|---|---|---|
122
- | `currentUser` | `ChatSDKUser` | Yes | Authenticated user object |
123
- | `onSelectConversation` | `(conv: ChatSDKConversation) => void` | Yes | Called when user selects a conversation |
124
- | `selectedConversationId` | `string` | No | ID of currently selected conversation |
455
+ ### Load Messages (with Pagination)
125
456
 
126
- ### ThemeToggle
457
+ ```tsx
458
+ const messages = await sdk.messages.getMessages({
459
+ conversationId: conversationId,
460
+ limit: 50,
461
+ offset: 0,
462
+ });
463
+
464
+ messages.forEach(msg => {
465
+ console.log(`${msg.senderName}: ${msg.content}`);
466
+ });
467
+ ```
127
468
 
128
- A button that cycles through light, dark, and auto themes. Must be wrapped in `<ThemeProvider>`.
469
+ ### Send Typing Indicator
129
470
 
130
471
  ```tsx
131
- <ThemeProvider>
132
- <ThemeToggle showLabel />
133
- </ThemeProvider>
472
+ // User started typing
473
+ await sdk.messages.sendTypingIndicator(conversationId, true);
474
+
475
+ // User stopped typing
476
+ await sdk.messages.sendTypingIndicator(conversationId, false);
134
477
  ```
135
478
 
136
- | Prop | Type | Required | Description |
137
- |---|---|---|---|
138
- | `className` | `string` | No | Additional CSS class name |
139
- | `showLabel` | `boolean` | No | Show current theme label text |
479
+ ### Mark Messages as Read
480
+
481
+ ```tsx
482
+ // Mark all messages in a conversation as read
483
+ await sdk.chatUsers.markRoomMessagesRead(conversationId);
484
+
485
+ // Mark a specific message as read
486
+ await sdk.chatUsers.markMessageRead(messageId);
487
+ ```
140
488
 
141
- ## Hooks
489
+ ---
142
490
 
143
- ### useTheme
491
+ ## 7. File Uploads & Attachments
144
492
 
145
- Theme management (light, dark, auto).
493
+ ### Upload and Send a File
146
494
 
147
495
  ```tsx
148
- import { useTheme } from '@traiyani/chatsdk-react';
496
+ const sdk = ChatSDK.getInstance();
149
497
 
150
- function MyComponent() {
151
- const { theme, actualTheme, setTheme, toggleTheme } = useTheme();
152
- return <button onClick={toggleTheme}>Current: {actualTheme}</button>;
153
- }
498
+ const result = await sdk.media.uploadMedia({
499
+ file: selectedFile, // File object from input
500
+ type: 'image', // 'image' | 'video' | 'audio' | 'document'
501
+ conversationId: conversationId,
502
+ caption: 'Check this out',
503
+ onProgress: (progress) => {
504
+ console.log(`Upload: ${progress}%`);
505
+ },
506
+ });
507
+
508
+ console.log('Uploaded:', result.fileUrl);
154
509
  ```
155
510
 
156
- ### useThemeContext
157
-
158
- Same API as `useTheme`, but reads from the nearest `<ThemeProvider>` so all descendants share state.
511
+ ### Convenience Methods
159
512
 
160
513
  ```tsx
161
- import { useThemeContext } from '@traiyani/chatsdk-react';
514
+ // Send image
515
+ await sdk.media.sendImage(conversationId, imageFile, 'Photo caption');
516
+
517
+ // Send video
518
+ await sdk.media.sendVideo(conversationId, videoFile);
162
519
 
163
- const { theme, actualTheme, setTheme, toggleTheme } = useThemeContext();
520
+ // Send document (PDF, DOC, etc.)
521
+ await sdk.media.sendDocument(conversationId, pdfFile);
522
+
523
+ // Send audio
524
+ await sdk.media.sendAudio(conversationId, audioFile);
164
525
  ```
165
526
 
166
- ## Configuration
527
+ **Supported file types:** Images (`.jpg`, `.png`, `.gif`, `.webp`), Videos (`.mp4`, `.mov`), Documents (`.pdf`, `.doc`, `.docx`), Audio (`.mp3`, `.wav`)
167
528
 
168
- Config values can come from any source environment variables, server-rendered props, a config file, or hardcoded values:
529
+ **Note:** The built-in `<ChatWindow />` component handles file picking, uploading, and preview automatically.
169
530
 
170
- ```tsx
171
- // Create React App
172
- await sdk.init({ apiBaseUrl: process.env.REACT_APP_API_URL, ... })
531
+ ---
173
532
 
174
- // Vite
175
- await sdk.init({ apiBaseUrl: import.meta.env.VITE_API_URL, ... })
533
+ ## 8. Unread Message Counts
176
534
 
177
- // Next.js
178
- await sdk.init({ apiBaseUrl: process.env.NEXT_PUBLIC_API_URL, ... })
535
+ ### Get Unread Conversations Count
179
536
 
180
- // Hardcoded / server-rendered
181
- await sdk.init({ apiBaseUrl: 'https://chat-api.example.com', ... })
537
+ ```tsx
538
+ const count = await sdk.chatUsers.getUnreadConversationsCount();
539
+ console.log(`${count} conversations with unread messages`);
182
540
  ```
183
541
 
184
- ### Full Configuration
542
+ ### Get Total Unread Message Count
185
543
 
186
- ```typescript
187
- interface ChatSDKConfig {
188
- apiBaseUrl: string;
189
- wsUrl?: string;
190
- appId: string;
191
- apiKey?: string;
192
- environment: 'development' | 'staging' | 'production';
193
- enableLogging?: boolean;
194
- autoConnect?: boolean;
195
- timeout?: number;
196
- }
544
+ ```tsx
545
+ const total = await sdk.chatUsers.getTotalUnreadCount();
546
+ console.log(`${total} total unread messages`);
197
547
  ```
198
548
 
199
- ## Starting a Product-Based Chat
549
+ ### Get Detailed Unread Summary
200
550
 
201
551
  ```tsx
202
- const sdk = ChatSDK.getInstance();
552
+ const summary = await sdk.chatUsers.getUnreadSummary();
553
+ console.log('Total unread conversations:', summary.totalConversationsWithUnread);
554
+ console.log('Total unread messages:', summary.totalUnreadMessages);
203
555
 
204
- const conversation = await sdk.chatUsers.startChatWithProduct(
205
- 'unique-group-id', // externalGroupId for deduplication
206
- 'seller-user-id', // the other participant's chat user ID
207
- {
208
- productId: 'prod-123',
209
- productName: 'iPhone 15 Pro',
210
- productImage: 'https://example.com/iphone.jpg',
211
- price: 4999,
212
- currency: 'QAR',
213
- category: 'Electronics',
214
- }
215
- );
556
+ summary.unreadSummary.forEach(item => {
557
+ console.log(`${item.room_name}: ${item.unread_count} unread`);
558
+ });
216
559
  ```
217
560
 
218
- ## Manager Classes (Advanced Usage)
561
+ ### Auto-Mark as Read
219
562
 
220
- Access individual managers through the SDK instance for fine-grained control:
563
+ ```tsx
564
+ // When user opens a conversation
565
+ sdk.chatUsers.startViewingConversation(conversationId);
566
+
567
+ // When user leaves the conversation
568
+ sdk.chatUsers.stopViewingConversation(conversationId);
569
+ ```
570
+
571
+ ---
572
+
573
+ ## 9. Block & Unblock Users
221
574
 
222
575
  ```tsx
223
- const sdk = ChatSDK.getInstance();
576
+ await sdk.users.blockUser(userIdToBlock);
577
+ await sdk.users.unblockUser(userIdToUnblock);
578
+ const blockedUsers = await sdk.users.getBlockedUsers();
579
+ ```
224
580
 
225
- // Users
226
- const users = await sdk.users.searchUsers({ query: 'john', limit: 10 });
581
+ **Notes:**
582
+ - Blocking is per-conversation, not global
583
+ - Blocked users cannot send messages in that conversation
584
+ - The built-in `<ChatWindow />` has a block/unblock UI built in
227
585
 
228
- // Conversations
229
- const convos = await sdk.conversations.getConversations({ limit: 20 });
586
+ ---
230
587
 
231
- // Messages
232
- const msgs = await sdk.messages.getMessages({ conversationId: 'abc', limit: 50 });
588
+ ## 10. Real-Time Events
233
589
 
234
- // Media
235
- const result = await sdk.media.uploadMedia({ file, type: 'image', conversationId: 'abc' });
590
+ ### Listen for Events
236
591
 
237
- // Real-time events
238
- sdk.socket.on('message_received', (data) => console.log('New message:', data));
592
+ ```tsx
593
+ const sdk = ChatSDK.getInstance();
594
+
595
+ sdk.socket.on('message_received', (data) => {
596
+ console.log('New message:', data.message.content);
597
+ });
598
+
599
+ sdk.socket.on('typing_indicator', (data) => {
600
+ console.log(data.isTyping ? 'User is typing...' : 'User stopped typing');
601
+ });
602
+
603
+ sdk.socket.on('user_status_changed', (data) => {
604
+ console.log('User status:', data.status);
605
+ });
606
+
607
+ sdk.socket.on('connection_status', (status) => {
608
+ console.log('WebSocket:', status);
609
+ });
239
610
  ```
240
611
 
241
- ## Internationalization
612
+ ### Available Event Types
613
+
614
+ | Event | Description |
615
+ |-------|-------------|
616
+ | `message_received` | New message arrived |
617
+ | `typing_indicator` | User started/stopped typing |
618
+ | `user_status_changed` | User online/offline status changed |
619
+ | `conversation_updated` | Conversation metadata changed |
620
+ | `connection_status` | WebSocket connected/disconnected/error |
621
+
622
+ ### Socket Direct Operations
242
623
 
243
624
  ```tsx
244
- import { t, changeLanguage, getCurrentLanguage, isRTL } from '@traiyani/chatsdk-react';
625
+ sdk.socket.joinConversation(conversationId);
626
+ sdk.socket.leaveConversation(conversationId);
627
+ sdk.socket.sendTypingIndicator(conversationId, true);
628
+ const isConnected = sdk.socket.isConnected();
629
+ ```
630
+
631
+ ---
245
632
 
246
- // Get translated string
247
- const message = t('welcome_message');
633
+ ## 11. Theme Support
248
634
 
249
- // Change language
250
- changeLanguage('ar'); // or 'en'
635
+ ```tsx
636
+ import { ThemeProvider, ThemeToggle, useTheme } from '@traiyani/chatsdk-react';
251
637
 
252
- // Check if RTL
253
- if (isRTL()) {
254
- // Apply RTL styles
638
+ // Option 1: ThemeProvider + ThemeToggle
639
+ function App() {
640
+ return (
641
+ <ThemeProvider>
642
+ <ThemeToggle showLabel />
643
+ </ThemeProvider>
644
+ );
255
645
  }
646
+
647
+ // Option 2: useTheme hook
648
+ function MyComponent() {
649
+ const { theme, actualTheme, setTheme, toggleTheme } = useTheme();
650
+ return <button onClick={toggleTheme}>Current: {actualTheme}</button>;
651
+ }
652
+
653
+ // Option 3: Imperative
654
+ import { initializeTheme } from '@traiyani/chatsdk-react';
655
+ initializeTheme();
256
656
  ```
257
657
 
258
- Supported locales: `en`, `ar`.
658
+ ---
259
659
 
260
- ## TypeScript Support
660
+ ## 12. Internationalization (i18n)
261
661
 
262
- Full type definitions are included. Import types directly:
662
+ Supported languages: **English** (`en`), **Arabic** (`ar` with RTL)
263
663
 
264
664
  ```tsx
265
- import type {
266
- ChatSDKUser,
267
- ChatSDKMessage,
268
- ChatSDKConversation,
269
- ChatSDKConfig,
270
- ProductContext,
271
- ChatWindowProps,
272
- ConversationListProps,
273
- } from '@traiyani/chatsdk-react';
665
+ import { changeLanguage, getCurrentLanguage, isRTL, t } from '@traiyani/chatsdk-react';
666
+
667
+ const title = t('conversations_title');
668
+ changeLanguage('ar'); // Switches to Arabic + sets RTL
669
+ const lang = getCurrentLanguage(); // 'en' or 'ar'
670
+ const rtl = isRTL(); // true if Arabic
274
671
  ```
275
672
 
276
- ## Styling
673
+ ---
277
674
 
278
- Import the CSS file once in your app entry point:
675
+ ## 13. Logout & Cleanup
279
676
 
280
677
  ```tsx
281
- import '@traiyani/chatsdk-react/dist/chatsdk.css';
678
+ const sdk = ChatSDK.getInstance();
679
+
680
+ // Disconnect WebSocket
681
+ sdk.socket.disconnect();
682
+
683
+ // Logout (clears token)
684
+ await sdk.chatUsers.logout();
282
685
  ```
283
686
 
284
- All theme colors, conversation styles, and utility classes are bundled into this single file.
687
+ ---
285
688
 
286
- ## Features
689
+ ## 14. TypeScript Support
287
690
 
288
- - React 16.8+ with TypeScript
289
- - Real-time messaging via Socket.io
290
- - File/image uploads with progress
291
- - Product-based conversations
292
- - Block/unblock users
293
- - Theme support (light / dark / auto)
294
- - Internationalization (EN / AR with RTL)
295
- - Responsive design (desktop + mobile)
296
- - Message status (sending, sent, delivered, read)
297
- - Typing indicators
298
- - Unread message counts with badges
299
- - Search conversations
300
- - Pre-built — works with any bundler, no build config needed
691
+ Full type declarations are included. No extra `@types/*` packages needed.
692
+
693
+ ```tsx
694
+ import type {
695
+ ChatSDKConfig, ChatSDKUser, ChatSDKMessage, ChatSDKConversation,
696
+ ProductContext, Product, ChatState, ChatWindowProps, ConversationListProps,
697
+ SendMessageOptions, MediaUploadOptions, MediaUploadResult,
698
+ CreateConversationOptions, EventCallback,
699
+ } from '@traiyani/chatsdk-react';
700
+ ```
701
+
702
+ ---
703
+
704
+ ## 15. Troubleshooting
705
+
706
+ | Problem | Solution |
707
+ |---------|----------|
708
+ | WebSocket not connecting | Ensure `autoConnect: true` in config, verify API URL is reachable, check CORS |
709
+ | Messages not loading | Ensure user is authenticated first, verify `conversationId` is valid |
710
+ | CSS not applying | Ensure `import '@traiyani/chatsdk-react/dist/chatsdk.css'` is in your entry file |
711
+ | Authentication fails | Verify `apiBaseUrl` and `appId`, check browser console, ensure CORS is configured |
712
+ | "SDK not initialized" | Ensure `await sdk.init()` is called before any other SDK method |
301
713
 
302
714
  ## License
303
715
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@traiyani/chatsdk-react",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "ChatSDK React SDK - Pre-built, plug-and-play real-time chat components for React",
5
5
  "main": "dist/chatsdk-react.cjs",
6
6
  "module": "dist/chatsdk-react.mjs",