connect-x-reactnative-livechat-sdk 0.2.0 → 1.2.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.
@@ -1,38 +1,58 @@
1
1
  "use strict";
2
2
 
3
3
  // src/ChatScreen.tsx
4
- import { useState, useEffect, useRef, useMemo } from 'react';
5
- import { View, Text, TextInput, TouchableOpacity, SectionList, StyleSheet, SafeAreaView, KeyboardAvoidingView, Platform, Image, ActivityIndicator, Alert, Linking, Dimensions } from 'react-native';
4
+ import React, { useState, useEffect, useRef, useMemo } from 'react';
5
+ import { View, Text, TextInput, TouchableOpacity, SectionList, StyleSheet, SafeAreaView, KeyboardAvoidingView, Platform, Image, ActivityIndicator, Alert, Linking, Dimensions, Modal } from 'react-native';
6
6
  import io from 'socket.io-client';
7
7
  import { pick, types } from '@react-native-documents/picker';
8
8
  import { ConnectXMobileSdk } from 'connect-x-react-native-sdk';
9
9
  import { apiGet, uploadFile, BASE_URL_LIVE_CHAT, apiPost } from "./api.js";
10
- import Svg, { Path } from 'react-native-svg';
10
+ import Svg, { ClipPath, Defs, G, Path, Rect } from 'react-native-svg';
11
11
  import hexToRgba from 'hex-to-rgba';
12
+ import ImageViewer from 'react-native-image-zoom-viewer';
12
13
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
13
14
  const SendIcon = ({
14
- color,
15
- size
16
- }) => /*#__PURE__*/_jsx(Svg, {
15
+ size,
16
+ backgroundColor,
17
+ iconColor
18
+ }) => /*#__PURE__*/_jsxs(Svg, {
17
19
  width: size,
18
20
  height: size,
19
- viewBox: "0 0 24 24",
21
+ viewBox: "0 0 32 32",
20
22
  fill: "none",
21
- children: /*#__PURE__*/_jsx(Path, {
22
- d: "M22 2L15 22L11 13L2 9L22 2Z",
23
- stroke: color,
24
- strokeWidth: "2",
25
- strokeLinecap: "round",
26
- strokeLinejoin: "round"
27
- })
23
+ children: [/*#__PURE__*/_jsx(Rect, {
24
+ width: 32,
25
+ height: 32,
26
+ rx: 16,
27
+ fill: backgroundColor
28
+ }), /*#__PURE__*/_jsx(Defs, {
29
+ children: /*#__PURE__*/_jsx(ClipPath, {
30
+ id: "clip0_4087_14448",
31
+ children: /*#__PURE__*/_jsx(Rect, {
32
+ width: 20,
33
+ height: 20,
34
+ fill: "white",
35
+ transform: "translate(6 6)"
36
+ })
37
+ })
38
+ }), /*#__PURE__*/_jsx(G, {
39
+ clipPath: "url(#clip0_4087_14448)",
40
+ children: /*#__PURE__*/_jsx(Path, {
41
+ fillRule: "evenodd",
42
+ clipRule: "evenodd",
43
+ d: "M20.9918 11.0084L10.4985 14.8026L13.9943 16.826L17.0768 13.7426C17.2332 13.5864 17.4452 13.4986 17.6663 13.4987C17.8874 13.4988 18.0993 13.5867 18.2556 13.743C18.4118 13.8994 18.4996 14.1114 18.4995 14.3325C18.4994 14.5536 18.4115 14.7655 18.2552 14.9218L15.1718 18.0051L17.1968 21.5001L20.9918 11.0084ZM21.261 9.13845C22.2568 8.77762 23.2218 9.74262 22.861 10.7384L18.4593 22.9093C18.0977 23.9076 16.7343 24.0293 16.2018 23.1101L13.521 18.4784L8.88934 15.7976C7.97018 15.2651 8.09184 13.9018 9.09018 13.5401L21.261 9.13845Z",
44
+ fill: iconColor
45
+ })
46
+ })]
28
47
  });
29
-
30
48
  // Component หลักของหน้าแชท
31
49
  export const ChatScreen = ({
32
50
  onClose,
33
51
  token,
34
52
  orgId,
35
- channelId
53
+ channelId,
54
+ externalValue,
55
+ customHeader
36
56
  }) => {
37
57
  const [messages, setMessages] = useState([]);
38
58
  const [inputText, setInputText] = useState('');
@@ -40,15 +60,20 @@ export const ChatScreen = ({
40
60
  const socketRef = useRef(null);
41
61
  const [userId, setUserId] = useState(null);
42
62
  const [selectedFile, setSelectedFile] = useState(null);
43
- const [styleSettings, setStyleSettings] = useState(null);
63
+ const [settings, setSettings] = useState(null);
44
64
  const [styles, setStyles] = useState({});
45
65
  const sectionListRef = useRef(null);
46
66
  const [chatPhase, setChatPhase] = useState('chatting');
67
+ const [isSending, setIsSending] = useState(false);
68
+ const [isUploading, setIsUploading] = useState(false);
69
+ const [isImageViewerVisible, setImageViewerVisible] = useState(false);
70
+ const [viewerImages, setViewerImages] = useState([]);
71
+ const [viewerIndex, setViewerIndex] = useState(0);
47
72
  useEffect(() => {
48
73
  const findCustomer = async unknownId => {
49
74
  try {
50
75
  const res = await apiPost(`liveChat/${orgId}/${channelId}/setLiveChatConnector`, {
51
- externalValue: "Siwakorn'",
76
+ externalValue: externalValue,
52
77
  //'ปุ้นซู่ซ่า', //sdf0001111111111 //78e839c38397b8cac97437d17b1c91b568a5adb4
53
78
  userId: unknownId
54
79
  }, token);
@@ -59,11 +84,15 @@ export const ChatScreen = ({
59
84
  // initializeUserId();
60
85
  }
61
86
  } catch (error) {
62
- // initializeUserId();
87
+ onClose();
88
+ Alert.alert('Message', 'Customer not found. Please try again later.');
63
89
  console.log('Error finding customer:', error);
64
90
  }
65
91
  };
66
92
  const initializeUserId = async () => {
93
+ if (!(await checkAllowed())) {
94
+ return;
95
+ }
67
96
  try {
68
97
  const res = await ConnectXMobileSdk.getUnknownId();
69
98
  console.log('Generated userId:', res);
@@ -73,6 +102,25 @@ export const ChatScreen = ({
73
102
  console.log('Error generating userId:', error);
74
103
  }
75
104
  };
105
+ const checkAllowed = async () => {
106
+ try {
107
+ const res = await apiGet(`liveChat/${orgId}/checkAllowApp`, token);
108
+ console.log('App permissions:', res);
109
+ if (res) {
110
+ console.log('Permission granted for app access');
111
+ return true;
112
+ } else {
113
+ onClose();
114
+ Alert.alert('Permission Denied', `You do not have permission to access this chat`);
115
+ return false;
116
+ }
117
+ } catch (error) {
118
+ onClose();
119
+ console.log('Error checking permissions:', error);
120
+ Alert.alert('Permission Denied', `You do not have permission to access this chat.`);
121
+ return false;
122
+ }
123
+ };
76
124
  if (!userId) {
77
125
  initializeUserId();
78
126
  }
@@ -82,9 +130,10 @@ export const ChatScreen = ({
82
130
  if (!userId) return;
83
131
  try {
84
132
  console.log('Checking domain/app permissions...');
85
- const settings = await apiGet(`liveChat/${orgId}/${channelId}/getSettingConnector`, token);
86
- setStyleSettings(settings);
87
- setStyles(getDynamicStyles(settings.styles));
133
+ const resSettings = await apiGet(`liveChat/${orgId}/${channelId}/getSettingConnector`, token);
134
+ console.log('Settings received:', resSettings);
135
+ setSettings(resSettings);
136
+ setStyles(getDynamicStyles(resSettings.styles));
88
137
  const history = await apiGet(`liveChat/${orgId}/${channelId}/getChatHistory/${userId}`, token);
89
138
  console.log('Chat history:', history);
90
139
  setMessages(history);
@@ -121,7 +170,7 @@ export const ChatScreen = ({
121
170
  const messageSections = useMemo(() => {
122
171
  if (!messages || messages.length === 0) return [];
123
172
  const groupedMessages = messages.reduce((acc, message) => {
124
- const dateKey = new Date(message.timestamp).toLocaleDateString('en-CA'); // YYYY-MM-DD format for reliable sorting
173
+ const dateKey = new Date(message.timestamp).toLocaleDateString('en-CA'); // yyyy-MM-dd format for reliable sorting
125
174
  if (!acc[dateKey]) {
126
175
  acc[dateKey] = [];
127
176
  }
@@ -246,12 +295,23 @@ export const ChatScreen = ({
246
295
  animated: true
247
296
  });
248
297
  }
249
- }, 400);
298
+ }, 1000);
250
299
  }
251
300
  } catch (error) {
252
301
  console.error('Error scrolling to last section:', error);
253
302
  }
254
303
  }, [messageSections]);
304
+ const handleContentSizeChange = () => {
305
+ if (sectionListRef.current && messageSections.length > 0) {
306
+ const lastSectionIndex = messageSections.length - 1;
307
+ sectionListRef.current.scrollToLocation({
308
+ sectionIndex: lastSectionIndex,
309
+ itemIndex: messageSections[lastSectionIndex]?.data ? messageSections[lastSectionIndex].data.length - 1 : 0,
310
+ viewPosition: 0,
311
+ animated: true
312
+ });
313
+ }
314
+ };
255
315
  const handleScrollToIndexFailed = info => {
256
316
  console.warn('Scroll to index failed:', info);
257
317
  // As a fallback, scroll to the last rendered item, which is a safer option.
@@ -266,33 +326,25 @@ export const ChatScreen = ({
266
326
  console.log('Fallback scroll failed:', error);
267
327
  }
268
328
  };
269
- const sendMessage = messageBody => {
270
- if (!socketRef.current) return;
329
+ const handleSendText = () => {
330
+ if (inputText.trim() === '' || isSending) return;
331
+ setIsSending(true);
271
332
  const fullMessage = {
272
- ...messageBody,
333
+ type: 'text',
334
+ text: inputText.trim(),
273
335
  sender: 'user',
274
- timestamp: Date.now(),
275
- type: messageBody.type || 'text'
336
+ timestamp: Date.now()
276
337
  };
277
- socketRef.current.emit('sendMessage', {
338
+ socketRef.current?.emit('sendMessage', {
278
339
  organizeId: orgId,
279
340
  channelId: channelId,
280
341
  userId: userId,
281
342
  message: fullMessage
282
343
  }, () => {
283
- if (fullMessage.type === 'text') {
284
- setInputText('');
285
- }
344
+ setInputText('');
345
+ setIsSending(false);
286
346
  });
287
347
  };
288
- const handleSendText = () => {
289
- if (inputText.trim()) {
290
- sendMessage({
291
- type: 'text',
292
- text: inputText.trim()
293
- });
294
- }
295
- };
296
348
  const handleSelectFile = async () => {
297
349
  try {
298
350
  const result = await pick({
@@ -302,28 +354,80 @@ export const ChatScreen = ({
302
354
  setSelectedFile(result[0]);
303
355
  } catch (err) {
304
356
  if (err?.code !== 'DOCUMENT_PICKER_CANCELED') {
305
- Alert.alert('File-Picker Error', 'An error occurred during file selection.');
357
+ // Alert.alert(
358
+ // 'File-Picker Error',
359
+ // 'An error occurred during file selection.'
360
+ // );
306
361
  }
307
362
  }
308
363
  };
364
+ const MessageWithLinks = ({
365
+ text,
366
+ textStyle,
367
+ linkStyle
368
+ }) => {
369
+ const urlRegex = /(https?:\/\/[^\s]+)/g;
370
+ const parts = text.split(urlRegex);
371
+ return /*#__PURE__*/_jsx(Text, {
372
+ style: textStyle,
373
+ children: parts.map((part, index) => {
374
+ if (part.match(urlRegex)) {
375
+ return /*#__PURE__*/_jsx(Text, {
376
+ style: linkStyle,
377
+ onPress: () => Linking.openURL(part),
378
+ children: part
379
+ }, index);
380
+ }
381
+ return /*#__PURE__*/_jsx(Text, {
382
+ children: part
383
+ }, index);
384
+ })
385
+ });
386
+ };
387
+ const openImageViewer = tappedImageUrl => {
388
+ const allImages = messages.filter(msg => msg.type === 'image' && msg.url).map(msg => ({
389
+ url: msg.url
390
+ }));
391
+ const tappedIndex = allImages.findIndex(img => img.url === tappedImageUrl);
392
+ if (tappedIndex !== -1) {
393
+ setViewerImages(allImages);
394
+ setViewerIndex(tappedIndex);
395
+ setImageViewerVisible(true);
396
+ }
397
+ };
309
398
  const handleCancelUpload = () => {
399
+ if (isUploading) return;
310
400
  setSelectedFile(null);
311
401
  };
312
402
  const handleConfirmUpload = async () => {
313
- if (!selectedFile) return;
403
+ if (!selectedFile || isUploading) return;
404
+ setIsUploading(true);
314
405
  try {
315
406
  const fileUrl = await uploadFile(selectedFile, orgId, channelId);
316
407
  const type = selectedFile.type?.startsWith('image/') ? 'image' : 'file';
317
- sendMessage({
408
+ const messageBody = {
318
409
  type,
319
410
  fileName: selectedFile.name || 'file',
320
411
  url: fileUrl
412
+ };
413
+ const fullMessage = {
414
+ ...messageBody,
415
+ sender: 'user',
416
+ timestamp: Date.now(),
417
+ type
418
+ };
419
+ socketRef.current?.emit('sendMessage', {
420
+ organizeId: orgId,
421
+ channelId: channelId,
422
+ userId: userId,
423
+ message: fullMessage
321
424
  });
322
425
  } catch (error) {
323
426
  Alert.alert('Upload Error', 'Failed to upload the file.');
324
427
  console.error('Upload failed', error);
325
428
  } finally {
326
429
  setSelectedFile(null);
430
+ setIsUploading(false);
327
431
  }
328
432
  };
329
433
  const formatTimestamp = timestamp => {
@@ -352,27 +456,31 @@ export const ChatScreen = ({
352
456
  };
353
457
  return /*#__PURE__*/_jsxs(View, {
354
458
  style: [styles.messageRow, item.sender === 'user' ? styles.userRow : styles.agentRow],
355
- children: [item.sender === 'agent' && styleSettings?.styles?.styleLogoUrl && /*#__PURE__*/_jsx(Image, {
459
+ children: [item.sender === 'agent' && settings?.styles?.styleLogoUrl && /*#__PURE__*/_jsx(Image, {
356
460
  source: {
357
- uri: styleSettings.styles.styleLogoUrl
461
+ uri: settings.styles.styleLogoUrl
358
462
  },
359
463
  style: styles.avatar
464
+ }), item.sender === 'user' && /*#__PURE__*/_jsx(Text, {
465
+ style: styles.timestampText,
466
+ children: formatTimestamp(item.timestamp)
360
467
  }), /*#__PURE__*/_jsxs(View, {
361
468
  style: item.sender === 'agent' ? styles.messageAgentContainer : styles.messageContainer,
362
- children: [/*#__PURE__*/_jsx(Text, {
363
- style: styles.timestampText,
364
- children: formatTimestamp(item.timestamp)
365
- }), /*#__PURE__*/_jsxs(View, {
469
+ children: [/*#__PURE__*/_jsxs(View, {
366
470
  style: [styles.messageBubble, item.sender === 'user' ? styles.userBubble : styles.agentBubble],
367
- children: [item.type === 'text' && /*#__PURE__*/_jsx(Text, {
368
- style: item.sender === 'user' ? styles.customerChatText : styles.agentChatText,
369
- children: item.text
370
- }), item.type === 'image' && /*#__PURE__*/_jsx(Image, {
371
- source: {
372
- uri: item.url
373
- },
374
- style: styles.imageMessage,
375
- resizeMode: "cover"
471
+ children: [item.type === 'text' && /*#__PURE__*/_jsx(MessageWithLinks, {
472
+ text: item.text || '',
473
+ textStyle: item.sender === 'user' ? styles.customerChatText : styles.agentChatText,
474
+ linkStyle: styles.linkTextStyle
475
+ }), item.type === 'image' && /*#__PURE__*/_jsx(TouchableOpacity, {
476
+ onPress: () => openImageViewer(item.url),
477
+ children: /*#__PURE__*/_jsx(Image, {
478
+ source: {
479
+ uri: item.url
480
+ },
481
+ style: styles.imageMessage,
482
+ resizeMode: "cover"
483
+ })
376
484
  }), item.type === 'file' && /*#__PURE__*/_jsx(TouchableOpacity, {
377
485
  onPress: handleFilePress,
378
486
  children: /*#__PURE__*/_jsx(Text, {
@@ -380,6 +488,9 @@ export const ChatScreen = ({
380
488
  children: item.fileName
381
489
  })
382
490
  })]
491
+ }), item.sender === 'agent' && /*#__PURE__*/_jsx(Text, {
492
+ style: styles.timestampText,
493
+ children: formatTimestamp(item.timestamp)
383
494
  })]
384
495
  })]
385
496
  });
@@ -397,26 +508,37 @@ export const ChatScreen = ({
397
508
  })
398
509
  });
399
510
  }
400
-
401
- // const agentProfile = {
402
- // name: styleSettings?.name,
403
- // avatarUrl: styleSettings?.styleLogoUrl,
404
- // };
405
-
406
511
  return /*#__PURE__*/_jsxs(SafeAreaView, {
407
512
  style: styles.safeArea,
408
- children: [/*#__PURE__*/_jsxs(View, {
513
+ children: [/*#__PURE__*/_jsx(Modal, {
514
+ visible: isImageViewerVisible,
515
+ transparent: true,
516
+ children: /*#__PURE__*/_jsx(ImageViewer, {
517
+ imageUrls: viewerImages,
518
+ index: viewerIndex,
519
+ onCancel: () => setImageViewerVisible(false),
520
+ enableSwipeDown: true,
521
+ renderHeader: () => /*#__PURE__*/_jsx(TouchableOpacity, {
522
+ style: styles.imageViewerCloseButton,
523
+ onPress: () => setImageViewerVisible(false),
524
+ children: /*#__PURE__*/_jsx(Text, {
525
+ style: styles.imageViewerCloseButtonText,
526
+ children: "\u2715"
527
+ })
528
+ })
529
+ })
530
+ }), customHeader !== undefined ? customHeader : /*#__PURE__*/_jsxs(View, {
409
531
  style: styles.header,
410
532
  children: [/*#__PURE__*/_jsxs(View, {
411
533
  style: styles.headerProfile,
412
- children: [styleSettings?.styles?.styleLogoUrl && /*#__PURE__*/_jsx(Image, {
534
+ children: [settings?.styles?.styleLogoUrl && /*#__PURE__*/_jsx(Image, {
413
535
  source: {
414
- uri: styleSettings.styles.styleLogoUrl
536
+ uri: settings.styles.styleLogoUrl
415
537
  },
416
538
  style: styles.headerAvatar
417
539
  }), /*#__PURE__*/_jsx(Text, {
418
540
  style: styles.headerTitle,
419
- children: styleSettings?.styles.name || 'Live Chat'
541
+ children: settings?.styles.name || 'Live Chat'
420
542
  })]
421
543
  }), /*#__PURE__*/_jsx(TouchableOpacity, {
422
544
  onPress: onClose,
@@ -427,12 +549,13 @@ export const ChatScreen = ({
427
549
  })]
428
550
  }), /*#__PURE__*/_jsx(KeyboardAvoidingView, {
429
551
  style: styles.container,
552
+ behavior: Platform.OS === 'ios' ? 'padding' : undefined,
430
553
  children: chatPhase === 'pre-chat' ? /*#__PURE__*/_jsx(PreChatForm, {
431
554
  onSubmit: () => setChatPhase('chatting')
432
555
  // agentProfile={agentProfile}
433
556
  // styles={styles}
434
557
  ,
435
- headerColor: styleSettings?.styles?.styleHeadColor
558
+ headerColor: settings?.styles?.styleHeadColor
436
559
  }) : /*#__PURE__*/_jsxs(_Fragment, {
437
560
  children: [/*#__PURE__*/_jsx(SectionList, {
438
561
  ref: sectionListRef,
@@ -451,7 +574,8 @@ export const ChatScreen = ({
451
574
  }),
452
575
  keyExtractor: item => item.timestamp.toString(),
453
576
  style: styles.messageList,
454
- onScrollToIndexFailed: handleScrollToIndexFailed
577
+ onScrollToIndexFailed: handleScrollToIndexFailed,
578
+ onContentSizeChange: handleContentSizeChange
455
579
  }), /*#__PURE__*/_jsx(View, {
456
580
  style: styles.inputContainer,
457
581
  children: selectedFile ? /*#__PURE__*/_jsxs(View, {
@@ -468,23 +592,29 @@ export const ChatScreen = ({
468
592
  numberOfLines: 1,
469
593
  children: selectedFile.name
470
594
  })]
471
- }), /*#__PURE__*/_jsxs(View, {
595
+ }), /*#__PURE__*/_jsx(View, {
472
596
  style: styles.buttonRow,
473
- children: [/*#__PURE__*/_jsx(TouchableOpacity, {
474
- style: [styles.actionButton, styles.uploadButton],
475
- onPress: handleConfirmUpload,
476
- children: /*#__PURE__*/_jsx(Text, {
477
- style: styles.uploadButtonText,
478
- children: "Upload a file"
479
- })
480
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
481
- style: [styles.actionButton, styles.cancelButton],
482
- onPress: handleCancelUpload,
483
- children: /*#__PURE__*/_jsx(Text, {
484
- style: styles.cancelButtonText,
485
- children: "Cancel"
486
- })
487
- })]
597
+ children: isUploading ? /*#__PURE__*/_jsx(ActivityIndicator, {
598
+ color: styles.uploadButton.backgroundColor
599
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
600
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
601
+ style: [styles.actionButton, styles.uploadButton],
602
+ onPress: handleConfirmUpload,
603
+ disabled: isUploading,
604
+ children: /*#__PURE__*/_jsx(Text, {
605
+ style: styles.uploadButtonText,
606
+ children: "Upload a file"
607
+ })
608
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
609
+ style: [styles.actionButton, styles.cancelButton],
610
+ onPress: handleCancelUpload,
611
+ disabled: isUploading,
612
+ children: /*#__PURE__*/_jsx(Text, {
613
+ style: styles.cancelButtonText,
614
+ children: "Cancel"
615
+ })
616
+ })]
617
+ })
488
618
  })]
489
619
  }) : /*#__PURE__*/_jsxs(View, {
490
620
  style: styles.normalInputContainer,
@@ -507,10 +637,15 @@ export const ChatScreen = ({
507
637
  placeholderTextColor: "#9E9E9E"
508
638
  }), /*#__PURE__*/_jsx(TouchableOpacity, {
509
639
  onPress: handleSendText,
510
- style: styles.sendButton,
511
- children: /*#__PURE__*/_jsx(SendIcon, {
512
- size: 22,
513
- color: styleSettings?.styles?.styleTextColor || '#FFFFFF'
640
+ style: [styles.sendButton, isSending && styles.disabledButton],
641
+ disabled: isSending,
642
+ children: isSending ? /*#__PURE__*/_jsx(ActivityIndicator, {
643
+ size: "small",
644
+ color: "#FFFFFF"
645
+ }) : /*#__PURE__*/_jsx(SendIcon, {
646
+ size: 40,
647
+ backgroundColor: settings?.styles?.styleHeadColor || '#3761DF',
648
+ iconColor: settings?.styles?.styleTextColor || '#FFFFFF'
514
649
  })
515
650
  })]
516
651
  })
@@ -568,11 +703,11 @@ const getDynamicStyles = (settingStyle = {}) => {
568
703
  },
569
704
  messageList: {
570
705
  flex: 1,
571
- paddingHorizontal: 10
706
+ paddingHorizontal: 8
572
707
  },
573
708
  messageRow: {
574
709
  flexDirection: 'row',
575
- alignItems: 'flex-end',
710
+ alignItems: 'flex-start',
576
711
  marginVertical: 5
577
712
  },
578
713
  agentRow: {
@@ -582,28 +717,27 @@ const getDynamicStyles = (settingStyle = {}) => {
582
717
  justifyContent: 'flex-end'
583
718
  },
584
719
  messageContainer: {
585
- maxWidth: '80%',
586
- alignItems: 'flex-start',
587
- flexDirection: 'row'
588
- // marginBottom: 10,
720
+ maxWidth: screenWidth * 0.6,
721
+ flexWrap: 'wrap',
722
+ flexDirection: 'row',
723
+ alignItems: 'flex-end'
589
724
  },
590
725
  messageAgentContainer: {
591
- maxWidth: '80%',
592
- alignItems: 'flex-start',
593
- flexDirection: 'row-reverse',
594
- marginVertical: 0
726
+ maxWidth: screenWidth * 0.6,
727
+ alignItems: 'flex-end',
728
+ flexDirection: 'row'
595
729
  },
596
730
  avatar: {
597
731
  width: 36,
598
732
  height: 36,
599
733
  borderRadius: 20,
600
- marginRight: 8
734
+ marginRight: 6,
735
+ alignSelf: 'flex-end'
601
736
  },
602
737
  messageBubble: {
603
738
  paddingHorizontal: 8,
604
739
  paddingVertical: 8,
605
740
  borderRadius: 12
606
- // width: '80%',
607
741
  },
608
742
  agentBubble: {
609
743
  backgroundColor: settingStyle.styleAgentColor || '#E0E0E0'
@@ -618,16 +752,14 @@ const getDynamicStyles = (settingStyle = {}) => {
618
752
  color: settingStyle.styleAgentTextColor || '#000000'
619
753
  },
620
754
  fileLink: {
621
- textDecorationLine: 'underline',
622
- elevation: 4,
623
- width: screenWidth * 0.6
755
+ maxWidth: screenWidth * 0.6,
756
+ textDecorationLine: 'underline'
624
757
  },
625
758
  timestampText: {
626
759
  fontSize: 12,
627
760
  color: '#888',
628
- marginTop: 5,
629
- alignSelf: 'flex-end',
630
- marginHorizontal: 8
761
+ marginHorizontal: 4,
762
+ alignSelf: 'flex-end'
631
763
  },
632
764
  datePartition: {
633
765
  alignSelf: 'center',
@@ -655,12 +787,14 @@ const getDynamicStyles = (settingStyle = {}) => {
655
787
  },
656
788
  input: {
657
789
  flex: 1,
658
- height: 42,
659
- backgroundColor: '#F0F0F0',
790
+ height: 43,
791
+ backgroundColor: '#FFFFFF',
660
792
  borderRadius: 22.5,
661
793
  paddingHorizontal: 15,
662
794
  fontSize: 16,
663
- marginHorizontal: 10
795
+ marginHorizontal: 10,
796
+ borderColor: '#EAECEC',
797
+ borderWidth: 1
664
798
  },
665
799
  attachmentButton: {
666
800
  padding: 5
@@ -675,6 +809,13 @@ const getDynamicStyles = (settingStyle = {}) => {
675
809
  justifyContent: 'center',
676
810
  alignItems: 'center'
677
811
  },
812
+ disabledButton: {
813
+ opacity: 0.5,
814
+ justifyContent: 'center',
815
+ alignItems: 'center',
816
+ paddingRight: 0,
817
+ paddingTop: 0
818
+ },
678
819
  uploadPreviewContainer: {
679
820
  alignItems: 'center'
680
821
  },
@@ -723,29 +864,29 @@ const getDynamicStyles = (settingStyle = {}) => {
723
864
  fontSize: 16
724
865
  },
725
866
  plusIconContainer: {
726
- width: 24,
727
- height: 24,
867
+ width: 10,
868
+ height: 18,
728
869
  justifyContent: 'center',
729
870
  alignItems: 'center'
730
871
  },
731
872
  plusIconBar: {
732
873
  position: 'absolute',
733
- backgroundColor: '#8A8A8A'
874
+ backgroundColor: '#525E62'
734
875
  },
735
876
  plusIconBarHorizontal: {
736
- width: 20,
877
+ width: 18,
737
878
  height: 2,
738
879
  borderRadius: 1
739
880
  },
740
881
  plusIconBarVertical: {
741
882
  width: 2,
742
- height: 20,
883
+ height: 18,
743
884
  borderRadius: 1
744
885
  },
745
886
  imageMessage: {
746
887
  width: 200,
747
888
  height: 200,
748
- borderRadius: 10
889
+ borderRadius: 12
749
890
  },
750
891
  formContainer: {
751
892
  // flex: 1,
@@ -828,6 +969,23 @@ const getDynamicStyles = (settingStyle = {}) => {
828
969
  color: '#fff',
829
970
  fontSize: 12,
830
971
  fontWeight: 'bold'
972
+ },
973
+ imageViewerCloseButton: {
974
+ position: 'absolute',
975
+ top: 20,
976
+ right: 20,
977
+ zIndex: 20,
978
+ padding: 10
979
+ },
980
+ imageViewerCloseButtonText: {
981
+ color: 'white',
982
+ fontSize: 20,
983
+ zIndex: 20,
984
+ fontWeight: 'bold'
985
+ },
986
+ linkTextStyle: {
987
+ color: '#0066CC',
988
+ textDecorationLine: 'underline'
831
989
  }
832
990
  });
833
991
  };