react-native-chatbot-ai 0.1.22 → 0.1.24
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/lib/module/components/Drawer/DeleteSessionPopup.js +5 -5
- package/lib/module/components/Drawer/DeleteSessionPopup.js.map +1 -1
- package/lib/module/components/Drawer/RenameSessionPopup.js +34 -24
- package/lib/module/components/Drawer/RenameSessionPopup.js.map +1 -1
- package/lib/module/components/Drawer/SessionItem.js +6 -5
- package/lib/module/components/Drawer/SessionItem.js.map +1 -1
- package/lib/module/components/Drawer/SessionList.js +5 -4
- package/lib/module/components/Drawer/SessionList.js.map +1 -1
- package/lib/module/components/Drawer/SessionOptionsBottomSheet.js +13 -7
- package/lib/module/components/Drawer/SessionOptionsBottomSheet.js.map +1 -1
- package/lib/module/components/Drawer/ShareSessionPopup.js +6 -6
- package/lib/module/components/Drawer/ShareSessionPopup.js.map +1 -1
- package/lib/module/components/chat/footer/index.js +40 -33
- package/lib/module/components/chat/footer/index.js.map +1 -1
- package/lib/module/components/chat/item/ChatAIAnswerMessageItem.js +26 -13
- package/lib/module/components/chat/item/ChatAIAnswerMessageItem.js.map +1 -1
- package/lib/module/components/chat/item/DeeplinkItem.js +3 -3
- package/lib/module/components/chat/item/DeeplinkItem.js.map +1 -1
- package/lib/module/components/chat/item/MessageActionsBar.js +9 -9
- package/lib/module/components/chat/item/MessageActionsBar.js.map +1 -1
- package/lib/module/components/portal/Popup.js +8 -3
- package/lib/module/components/portal/Popup.js.map +1 -1
- package/lib/module/components/product/CardHorizontal.js +50 -46
- package/lib/module/components/product/CardHorizontal.js.map +1 -1
- package/lib/module/hooks/message/useStreamMessage.js +13 -2
- package/lib/module/hooks/message/useStreamMessage.js.map +1 -1
- package/lib/module/hooks/messageActions/useAudioPlayer.js +109 -24
- package/lib/module/hooks/messageActions/useAudioPlayer.js.map +1 -1
- package/lib/module/hooks/messageActions/useFeedback.js +2 -2
- package/lib/module/hooks/messageActions/useFeedback.js.map +1 -1
- package/lib/module/hooks/messageActions/useShareMessage.js +1 -1
- package/lib/module/hooks/messageActions/useShareMessage.js.map +1 -1
- package/lib/module/store/session.js +1 -1
- package/lib/module/store/session.js.map +1 -1
- package/lib/module/utils/ui.js.map +1 -1
- package/lib/typescript/src/components/Drawer/RenameSessionPopup.d.ts +1 -1
- package/lib/typescript/src/components/Drawer/RenameSessionPopup.d.ts.map +1 -1
- package/lib/typescript/src/components/Drawer/SessionItem.d.ts.map +1 -1
- package/lib/typescript/src/components/Drawer/SessionList.d.ts.map +1 -1
- package/lib/typescript/src/components/Drawer/SessionOptionsBottomSheet.d.ts.map +1 -1
- package/lib/typescript/src/components/chat/item/ChatAIAnswerMessageItem.d.ts.map +1 -1
- package/lib/typescript/src/components/portal/Popup.d.ts +4 -0
- package/lib/typescript/src/components/portal/Popup.d.ts.map +1 -1
- package/lib/typescript/src/components/product/CardHorizontal.d.ts +1 -0
- package/lib/typescript/src/components/product/CardHorizontal.d.ts.map +1 -1
- package/lib/typescript/src/hooks/message/useStreamMessage.d.ts.map +1 -1
- package/lib/typescript/src/hooks/messageActions/useAudioPlayer.d.ts +1 -0
- package/lib/typescript/src/hooks/messageActions/useAudioPlayer.d.ts.map +1 -1
- package/lib/typescript/src/store/products.d.ts +1 -1
- package/lib/typescript/src/store/products.d.ts.map +1 -1
- package/lib/typescript/src/types/ui.d.ts +3 -2
- package/lib/typescript/src/types/ui.d.ts.map +1 -1
- package/lib/typescript/src/utils/ui.d.ts +3 -2
- package/lib/typescript/src/utils/ui.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/components/Drawer/DeleteSessionPopup.tsx +5 -5
- package/src/components/Drawer/RenameSessionPopup.tsx +49 -40
- package/src/components/Drawer/SessionItem.tsx +5 -4
- package/src/components/Drawer/SessionList.tsx +8 -3
- package/src/components/Drawer/SessionOptionsBottomSheet.tsx +12 -6
- package/src/components/Drawer/ShareSessionPopup.tsx +6 -6
- package/src/components/chat/footer/index.tsx +37 -35
- package/src/components/chat/item/ChatAIAnswerMessageItem.tsx +29 -13
- package/src/components/chat/item/DeeplinkItem.tsx +3 -3
- package/src/components/chat/item/MessageActionsBar.tsx +9 -9
- package/src/components/portal/Popup.tsx +14 -4
- package/src/components/product/CardHorizontal.tsx +46 -45
- package/src/hooks/message/useStreamMessage.ts +17 -5
- package/src/hooks/messageActions/useAudioPlayer.ts +116 -22
- package/src/hooks/messageActions/useFeedback.ts +2 -2
- package/src/hooks/messageActions/useSendFeedback.ts +1 -1
- package/src/hooks/messageActions/useShareMessage.ts +1 -1
- package/src/store/products.ts +1 -1
- package/src/store/session.ts +1 -1
- package/src/types/ui.ts +3 -2
- package/src/utils/ui.tsx +3 -2
|
@@ -70,15 +70,19 @@ export type UploadItem = ImageUpload | FileUpload;
|
|
|
70
70
|
const MAX_FILE_UPLOAD = 3;
|
|
71
71
|
const MAX_FILE_SIZE = 30 * 1024 * 1024;
|
|
72
72
|
const MAX_IMAGE_SIZE = 7 * 1024 * 1024;
|
|
73
|
-
const
|
|
73
|
+
const COUNTDOWN_MS = 60000;
|
|
74
74
|
|
|
75
75
|
interface IChatFooterProps {
|
|
76
76
|
lastMessage?: IMessageItem;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
const ChatFooter = ({ lastMessage }: IChatFooterProps) => {
|
|
80
|
-
const
|
|
81
|
-
const
|
|
80
|
+
const countdownRef = useRef<NodeJS.Timeout | null>(null);
|
|
81
|
+
const isInCountdownRef = useRef(false);
|
|
82
|
+
const firstVisibleItemRef = useRef<ISuggestionItem | null>(null);
|
|
83
|
+
|
|
84
|
+
const viewabilityConfig = useRef({ itemVisiblePercentThreshold: 10 }).current;
|
|
85
|
+
|
|
82
86
|
const menuRef = useRef(null);
|
|
83
87
|
const logGA = useChatContext().logGA;
|
|
84
88
|
const { onSendMessage, stopStream } = useSendMessage();
|
|
@@ -92,9 +96,9 @@ const ChatFooter = ({ lastMessage }: IChatFooterProps) => {
|
|
|
92
96
|
|
|
93
97
|
const isDisabledSend = useMemo(() => {
|
|
94
98
|
return (
|
|
95
|
-
isStreaming
|
|
96
|
-
message.trim() === '' ||
|
|
97
|
-
|
|
99
|
+
!isStreaming &&
|
|
100
|
+
(message.trim() === '' ||
|
|
101
|
+
(fileUpload.length > 0 && fileUpload.some((i) => !i.remoteUrl)))
|
|
98
102
|
);
|
|
99
103
|
}, [isStreaming, message, fileUpload]);
|
|
100
104
|
|
|
@@ -364,39 +368,34 @@ const ChatFooter = ({ lastMessage }: IChatFooterProps) => {
|
|
|
364
368
|
[onPressItemSuggestion]
|
|
365
369
|
);
|
|
366
370
|
|
|
367
|
-
const
|
|
368
|
-
if (
|
|
369
|
-
|
|
370
|
-
idleTimerRef.current = null;
|
|
371
|
+
const onViewableItemsChanged = useRef(({ viewableItems }: any) => {
|
|
372
|
+
if (viewableItems && viewableItems.length > 0) {
|
|
373
|
+
firstVisibleItemRef.current = viewableItems[0].item;
|
|
371
374
|
}
|
|
372
|
-
};
|
|
375
|
+
}).current;
|
|
376
|
+
|
|
377
|
+
const logFirstVisibleItem = useCallback(() => {
|
|
378
|
+
if (!firstVisibleItemRef.current) return;
|
|
373
379
|
|
|
374
|
-
const onUserIdleAfterScroll = useCallback(() => {
|
|
375
380
|
logGA(GAEvents.chatDetailInConvPrmSuggScroll, {
|
|
376
381
|
group_id: lastMessage?.group_suggestion_id,
|
|
377
|
-
|
|
382
|
+
message_chat_id: lastMessage?.id,
|
|
383
|
+
suggestion_id: firstVisibleItemRef.current.suggestion_id,
|
|
378
384
|
});
|
|
379
|
-
}, [lastMessage, logGA]);
|
|
380
|
-
|
|
381
|
-
const resetIdleTimer = useCallback(() => {
|
|
382
|
-
clearIdleTimer();
|
|
383
|
-
|
|
384
|
-
hasScrolledRef.current = true;
|
|
385
385
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
const handleScroll = () => {
|
|
394
|
-
resetIdleTimer();
|
|
395
|
-
};
|
|
386
|
+
// Bắt đầu countdown
|
|
387
|
+
isInCountdownRef.current = true;
|
|
388
|
+
countdownRef.current = setTimeout(() => {
|
|
389
|
+
isInCountdownRef.current = false;
|
|
390
|
+
countdownRef.current = null;
|
|
391
|
+
}, COUNTDOWN_MS);
|
|
392
|
+
}, [lastMessage, logGA]);
|
|
396
393
|
|
|
397
|
-
const handleMomentumEnd = () => {
|
|
398
|
-
|
|
399
|
-
|
|
394
|
+
const handleMomentumEnd = useCallback(() => {
|
|
395
|
+
if (!isInCountdownRef.current) {
|
|
396
|
+
logFirstVisibleItem();
|
|
397
|
+
}
|
|
398
|
+
}, [logFirstVisibleItem]);
|
|
400
399
|
|
|
401
400
|
return (
|
|
402
401
|
<KContainer.View style={styles.container}>
|
|
@@ -413,9 +412,10 @@ const ChatFooter = ({ lastMessage }: IChatFooterProps) => {
|
|
|
413
412
|
horizontal
|
|
414
413
|
keyExtractor={(item: ISuggestionItem) => item.suggestion_id}
|
|
415
414
|
contentContainerStyle={styles.suggessionContainer}
|
|
416
|
-
|
|
415
|
+
onViewableItemsChanged={onViewableItemsChanged}
|
|
416
|
+
viewabilityConfig={viewabilityConfig}
|
|
417
|
+
scrollEventThrottle={16}
|
|
417
418
|
onMomentumScrollEnd={handleMomentumEnd}
|
|
418
|
-
scrollEventThrottle={200}
|
|
419
419
|
/>
|
|
420
420
|
</KContainer.VisibleView>
|
|
421
421
|
<KContainer.VisibleView visible={fileUpload.length > 0}>
|
|
@@ -503,7 +503,6 @@ const styles = StyleSheet.create({
|
|
|
503
503
|
container: {
|
|
504
504
|
paddingHorizontal: KSpacingValue['0.75rem'],
|
|
505
505
|
paddingVertical: KSpacingValue['0.5rem'],
|
|
506
|
-
gap: KSpacingValue['0.5rem'],
|
|
507
506
|
borderWidth: 1,
|
|
508
507
|
borderColor: KColors.hexToRgba(KColors.black, 0.15),
|
|
509
508
|
borderBottomWidth: 0,
|
|
@@ -521,6 +520,7 @@ const styles = StyleSheet.create({
|
|
|
521
520
|
},
|
|
522
521
|
input: {
|
|
523
522
|
maxHeight: 100,
|
|
523
|
+
marginBottom: 8,
|
|
524
524
|
},
|
|
525
525
|
popover: {
|
|
526
526
|
borderRadius: KRadiusValue['4x'],
|
|
@@ -540,9 +540,11 @@ const styles = StyleSheet.create({
|
|
|
540
540
|
listUploadItem: {
|
|
541
541
|
gap: KSpacingValue['0.75rem'],
|
|
542
542
|
paddingTop: 6,
|
|
543
|
+
paddingBottom: 8,
|
|
543
544
|
},
|
|
544
545
|
suggessionContainer: {
|
|
545
546
|
gap: KSpacingValue['0.25rem'],
|
|
547
|
+
paddingBottom: 8,
|
|
546
548
|
},
|
|
547
549
|
suggestionItem: {
|
|
548
550
|
backgroundColor: KColors.palette.gray.w25,
|
|
@@ -170,25 +170,30 @@ export function useStreamingMarkdownBlocks(text: string) {
|
|
|
170
170
|
class CustomRenderer extends Renderer implements RendererInterface {
|
|
171
171
|
constructor(
|
|
172
172
|
openImageViewer?: (images: { url: string }[], index: number) => void,
|
|
173
|
-
messageId?: string
|
|
173
|
+
messageId?: string,
|
|
174
|
+
productIds?: string[]
|
|
174
175
|
) {
|
|
175
176
|
super();
|
|
176
177
|
this.openImageViewer = openImageViewer;
|
|
177
178
|
this.messageId = messageId;
|
|
179
|
+
this.productIds = productIds;
|
|
178
180
|
}
|
|
179
181
|
|
|
180
182
|
openImageViewer?: (images: { url: string }[], index: number) => void;
|
|
181
183
|
messageId?: string;
|
|
184
|
+
productIds?: string[];
|
|
182
185
|
|
|
183
186
|
html(text: string): ReactNode {
|
|
184
187
|
const match = /^<!--\s*@component:(\w+)\(id:([\w-]+)\)\s*-->/.exec(text);
|
|
185
188
|
switch (match?.[1]) {
|
|
186
189
|
case 'product':
|
|
190
|
+
const productIndex = this.productIds?.indexOf(match?.[2] || '');
|
|
187
191
|
return (
|
|
188
192
|
<ProductHorizontalCard
|
|
189
193
|
productId={match?.[2]}
|
|
190
194
|
key={this.getKey()}
|
|
191
195
|
messageId={this.messageId}
|
|
196
|
+
index={productIndex}
|
|
192
197
|
/>
|
|
193
198
|
);
|
|
194
199
|
default:
|
|
@@ -300,12 +305,14 @@ class CustomRenderer extends Renderer implements RendererInterface {
|
|
|
300
305
|
|
|
301
306
|
hr(_styles?: any): ReactNode {
|
|
302
307
|
return (
|
|
303
|
-
<
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
308
|
+
<KContainer.View marginV={'0.5rem'}>
|
|
309
|
+
<KDivider
|
|
310
|
+
key={this.getKey()}
|
|
311
|
+
type="line"
|
|
312
|
+
size="sm"
|
|
313
|
+
background={KColors.hexToRgba(KColors.gray.dark, 0.2)}
|
|
314
|
+
/>
|
|
315
|
+
</KContainer.View>
|
|
309
316
|
);
|
|
310
317
|
}
|
|
311
318
|
|
|
@@ -356,18 +363,27 @@ class CustomRenderer extends Renderer implements RendererInterface {
|
|
|
356
363
|
/>
|
|
357
364
|
);
|
|
358
365
|
}
|
|
366
|
+
|
|
367
|
+
heading(text: string | ReactNode[]): ReactNode {
|
|
368
|
+
return (
|
|
369
|
+
<KLabel.Text key={this.getKey()} typo="TextMdBold">
|
|
370
|
+
{text}
|
|
371
|
+
</KLabel.Text>
|
|
372
|
+
);
|
|
373
|
+
}
|
|
359
374
|
}
|
|
360
375
|
|
|
361
376
|
const markedStyles: MarkedStyles = {
|
|
362
377
|
paragraph: {
|
|
363
|
-
marginVertical:
|
|
378
|
+
marginVertical: 4,
|
|
364
379
|
},
|
|
365
380
|
blockquote: {
|
|
366
|
-
marginVertical:
|
|
381
|
+
marginVertical: 4,
|
|
367
382
|
},
|
|
368
383
|
li: {
|
|
369
|
-
marginVertical:
|
|
384
|
+
marginVertical: 4,
|
|
370
385
|
justifyContent: 'center',
|
|
386
|
+
color: KColors.gray.dark,
|
|
371
387
|
},
|
|
372
388
|
};
|
|
373
389
|
|
|
@@ -408,13 +424,13 @@ const ChatAIAnswerMessageItem = ({
|
|
|
408
424
|
return ids;
|
|
409
425
|
}, [isStreaming, streamMessage, item]);
|
|
410
426
|
|
|
411
|
-
|
|
427
|
+
useSearchProduct({ productIds });
|
|
412
428
|
|
|
413
429
|
const products = useProductsStore((state) => state.products);
|
|
414
430
|
|
|
415
431
|
const renderer = useMemo(
|
|
416
|
-
() => new CustomRenderer(openImageViewer, item.id),
|
|
417
|
-
[openImageViewer, item.id]
|
|
432
|
+
() => new CustomRenderer(openImageViewer, item.id, productIds),
|
|
433
|
+
[openImageViewer, item.id, productIds]
|
|
418
434
|
);
|
|
419
435
|
const tokenizer = useMemo(() => new CustomTokenizer(), []);
|
|
420
436
|
|
|
@@ -63,7 +63,7 @@ const DeeplinkItem = ({ children, href, messageId }: DeeplinkItemProps) => {
|
|
|
63
63
|
if (data?.type === 'gift') {
|
|
64
64
|
logGA(GAEvents.chatDetailGiftDetailBtnTap, {
|
|
65
65
|
conversation_id: useSessionStore.getState().sessionId,
|
|
66
|
-
|
|
66
|
+
message_chat_id: messageId,
|
|
67
67
|
gift_id: data?.id,
|
|
68
68
|
});
|
|
69
69
|
return;
|
|
@@ -71,7 +71,7 @@ const DeeplinkItem = ({ children, href, messageId }: DeeplinkItemProps) => {
|
|
|
71
71
|
if (data?.type === 'faq') {
|
|
72
72
|
logGA(GAEvents.chatDetailFAQTap, {
|
|
73
73
|
conversation_id: useSessionStore.getState().sessionId,
|
|
74
|
-
|
|
74
|
+
message_chat_id: messageId,
|
|
75
75
|
deeplink_id: data?.id,
|
|
76
76
|
});
|
|
77
77
|
return;
|
|
@@ -79,7 +79,7 @@ const DeeplinkItem = ({ children, href, messageId }: DeeplinkItemProps) => {
|
|
|
79
79
|
if (data?.type === 'cx-support') {
|
|
80
80
|
logGA(GAEvents.chatDetailLivechatBtnTap, {
|
|
81
81
|
conversation_id: useSessionStore.getState().sessionId,
|
|
82
|
-
|
|
82
|
+
message_chat_id: messageId,
|
|
83
83
|
});
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
@@ -98,7 +98,7 @@ const MessageActionsBar = ({
|
|
|
98
98
|
// Handlers
|
|
99
99
|
const handleCopy = useCallback(() => {
|
|
100
100
|
logGA(GAEvents.chatDetailCopyBtnTap, {
|
|
101
|
-
|
|
101
|
+
message_chat_id: messageId,
|
|
102
102
|
});
|
|
103
103
|
copyToClipboard(messageContent);
|
|
104
104
|
}, [messageContent, copyToClipboard, logGA, messageId]);
|
|
@@ -159,8 +159,8 @@ const MessageActionsBar = ({
|
|
|
159
159
|
]}
|
|
160
160
|
>
|
|
161
161
|
<KImage.VectorIcons
|
|
162
|
-
name="like-
|
|
163
|
-
size={
|
|
162
|
+
name="thumb-like-o"
|
|
163
|
+
size={20}
|
|
164
164
|
color={
|
|
165
165
|
isLikeActive ? KColors.primary.normal : KColors.gray.light
|
|
166
166
|
}
|
|
@@ -215,8 +215,8 @@ const MessageActionsBar = ({
|
|
|
215
215
|
]}
|
|
216
216
|
>
|
|
217
217
|
<KImage.VectorIcons
|
|
218
|
-
name="
|
|
219
|
-
size={
|
|
218
|
+
name="thumb-dislike-o"
|
|
219
|
+
size={20}
|
|
220
220
|
color={
|
|
221
221
|
isDislikeActive
|
|
222
222
|
? KColors.primary.normal
|
|
@@ -253,7 +253,7 @@ const MessageActionsBar = ({
|
|
|
253
253
|
{/* Audio Button */}
|
|
254
254
|
<ActionButton
|
|
255
255
|
icon={audioButtonProps.icon}
|
|
256
|
-
iconSize={
|
|
256
|
+
iconSize={20}
|
|
257
257
|
iconColor={audioButtonProps.iconColor}
|
|
258
258
|
isActive={audioButtonProps.isActive}
|
|
259
259
|
isLoading={isAudioLoading}
|
|
@@ -264,7 +264,7 @@ const MessageActionsBar = ({
|
|
|
264
264
|
{/* Copy Button */}
|
|
265
265
|
<ActionButton
|
|
266
266
|
icon="copy-o"
|
|
267
|
-
iconSize={
|
|
267
|
+
iconSize={20}
|
|
268
268
|
isLoading={isCopying}
|
|
269
269
|
onPress={handleCopy}
|
|
270
270
|
testID="copy-button"
|
|
@@ -272,8 +272,8 @@ const MessageActionsBar = ({
|
|
|
272
272
|
|
|
273
273
|
{/* Share Button */}
|
|
274
274
|
<ActionButton
|
|
275
|
-
icon="share-o"
|
|
276
|
-
iconSize={
|
|
275
|
+
icon="text-share-o"
|
|
276
|
+
iconSize={20}
|
|
277
277
|
isLoading={isSharing}
|
|
278
278
|
onPress={shareMessage}
|
|
279
279
|
testID="share-button"
|
|
@@ -57,9 +57,13 @@ const PADDING_VERTICAL = KDims.isIphoneX ? UNIT * 3 : UNIT * 2.25;
|
|
|
57
57
|
const PADDING_HORIZONTAL = UNIT;
|
|
58
58
|
const CONTENT_MAX_HEIGHT = VIEWABLE_HEIGHT - 2 * PADDING_VERTICAL;
|
|
59
59
|
|
|
60
|
+
export type IPopupProps = KPopupProps & {
|
|
61
|
+
onPressClose?: () => void;
|
|
62
|
+
};
|
|
63
|
+
|
|
60
64
|
const Popup = forwardRef<WithPopupProps>((_, ref) => {
|
|
61
|
-
const queue = useRef<
|
|
62
|
-
const [data, setData] = useState<
|
|
65
|
+
const queue = useRef<IPopupProps[]>([]);
|
|
66
|
+
const [data, setData] = useState<IPopupProps | undefined>(undefined);
|
|
63
67
|
|
|
64
68
|
const scale = useSharedValue(1);
|
|
65
69
|
|
|
@@ -69,6 +73,7 @@ const Popup = forwardRef<WithPopupProps>((_, ref) => {
|
|
|
69
73
|
actions,
|
|
70
74
|
backgroundColor = KColors.white,
|
|
71
75
|
wrapperStyle = {},
|
|
76
|
+
onPressClose,
|
|
72
77
|
} = data || {};
|
|
73
78
|
|
|
74
79
|
const { showCloseButton, subTitle, title, alignment } = header || {};
|
|
@@ -84,6 +89,11 @@ const Popup = forwardRef<WithPopupProps>((_, ref) => {
|
|
|
84
89
|
setData(newPayload);
|
|
85
90
|
}, [scale]);
|
|
86
91
|
|
|
92
|
+
const handleDismiss = useCallback(() => {
|
|
93
|
+
dismiss();
|
|
94
|
+
onPressClose?.();
|
|
95
|
+
}, [dismiss, onPressClose]);
|
|
96
|
+
|
|
87
97
|
useImperativeHandle(
|
|
88
98
|
ref,
|
|
89
99
|
() => ({
|
|
@@ -177,12 +187,12 @@ const Popup = forwardRef<WithPopupProps>((_, ref) => {
|
|
|
177
187
|
</KContainer.View>
|
|
178
188
|
{showCloseButton && (
|
|
179
189
|
<KContainer.View marginL={'1rem'}>
|
|
180
|
-
<KButton.Close onPress={
|
|
190
|
+
<KButton.Close onPress={handleDismiss} />
|
|
181
191
|
</KContainer.View>
|
|
182
192
|
)}
|
|
183
193
|
</KContainer.View>
|
|
184
194
|
);
|
|
185
|
-
}, [alignment, data,
|
|
195
|
+
}, [alignment, data, handleDismiss, showCloseButton, subTitle, title]);
|
|
186
196
|
|
|
187
197
|
const renderActions = useMemo(() => {
|
|
188
198
|
if (!actions?.buttons) {
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
KButton,
|
|
3
3
|
KColors,
|
|
4
4
|
KContainer,
|
|
5
|
-
KDims,
|
|
5
|
+
// KDims,
|
|
6
6
|
KImage,
|
|
7
7
|
KLabel,
|
|
8
8
|
KRadiusValue,
|
|
@@ -16,17 +16,18 @@ import { StyleSheet } from 'react-native';
|
|
|
16
16
|
import useProductsStore from '../../store/products';
|
|
17
17
|
import { PRODUCT_STATUSES } from '../../types';
|
|
18
18
|
import { useChatContext } from '../../context/ChatContext';
|
|
19
|
-
import SkeletonPlaceholder from 'react-native-skeleton-placeholder';
|
|
19
|
+
// import SkeletonPlaceholder from 'react-native-skeleton-placeholder';
|
|
20
20
|
import { GAEvents } from '../../constants/events';
|
|
21
21
|
import useSessionStore from '../../store/session';
|
|
22
22
|
|
|
23
23
|
interface IProductHorizontalCardProps {
|
|
24
24
|
productId?: string;
|
|
25
25
|
messageId?: string;
|
|
26
|
+
index?: number;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
const ProductHorizontalCard = (props: IProductHorizontalCardProps) => {
|
|
29
|
-
const { productId, messageId } = props;
|
|
30
|
+
const { productId, messageId, index } = props;
|
|
30
31
|
const item = useProductsStore((state) =>
|
|
31
32
|
state.products.find((p) => p.id === productId)
|
|
32
33
|
);
|
|
@@ -142,9 +143,9 @@ const ProductHorizontalCard = (props: IProductHorizontalCardProps) => {
|
|
|
142
143
|
logGA(GAEvents.chatDetailProductCardTap, {
|
|
143
144
|
conversation_id: useSessionStore.getState().sessionId,
|
|
144
145
|
product_id: item.id,
|
|
145
|
-
position_in_list:
|
|
146
|
+
position_in_list: index,
|
|
146
147
|
});
|
|
147
|
-
}, [onNavigateToProduct, logGA, item]);
|
|
148
|
+
}, [onNavigateToProduct, logGA, item, index]);
|
|
148
149
|
|
|
149
150
|
const onPressAddToCart = useCallback(() => {
|
|
150
151
|
if (!item) return;
|
|
@@ -152,11 +153,11 @@ const ProductHorizontalCard = (props: IProductHorizontalCardProps) => {
|
|
|
152
153
|
logGA(GAEvents.chatDetailAddToCartBtnTap, {
|
|
153
154
|
conversation_id: useSessionStore.getState().sessionId,
|
|
154
155
|
product_id: item.id,
|
|
155
|
-
position_in_list:
|
|
156
|
+
position_in_list: index,
|
|
156
157
|
pdp_id: item.pdpId,
|
|
157
|
-
|
|
158
|
+
message_chat_id: messageId,
|
|
158
159
|
});
|
|
159
|
-
}, [onAddToCart, logGA, item, messageId]);
|
|
160
|
+
}, [onAddToCart, logGA, item, messageId, index]);
|
|
160
161
|
|
|
161
162
|
const onPressBuyNow = useCallback(() => {
|
|
162
163
|
if (!item) return;
|
|
@@ -166,46 +167,46 @@ const ProductHorizontalCard = (props: IProductHorizontalCardProps) => {
|
|
|
166
167
|
product_id: item.id,
|
|
167
168
|
position_in_list: -1, //TODO: fix
|
|
168
169
|
pdp_id: item.pdpId,
|
|
169
|
-
|
|
170
|
+
message_chat_id: messageId,
|
|
170
171
|
});
|
|
171
172
|
}, [onBuyNow, logGA, item, messageId]);
|
|
172
173
|
|
|
173
|
-
if (!item) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
174
|
+
// if (!item) {
|
|
175
|
+
// return (
|
|
176
|
+
// <KContainer.View style={styles.container}>
|
|
177
|
+
// <SkeletonPlaceholder borderRadius={4} speed={2000} direction="right">
|
|
178
|
+
// <SkeletonPlaceholder.Item flexDirection="row" gap={12}>
|
|
179
|
+
// <SkeletonPlaceholder.Item
|
|
180
|
+
// width={72}
|
|
181
|
+
// height={72}
|
|
182
|
+
// borderRadius={12}
|
|
183
|
+
// />
|
|
184
|
+
// <SkeletonPlaceholder.Item
|
|
185
|
+
// gap={12}
|
|
186
|
+
// width={KDims.width - 160}
|
|
187
|
+
// justifyContent="space-between"
|
|
188
|
+
// >
|
|
189
|
+
// <SkeletonPlaceholder.Item
|
|
190
|
+
// height={16}
|
|
191
|
+
// width={KDims.width / 2}
|
|
192
|
+
// borderRadius={4}
|
|
193
|
+
// />
|
|
194
|
+
// <SkeletonPlaceholder.Item
|
|
195
|
+
// height={16}
|
|
196
|
+
// width={160}
|
|
197
|
+
// borderRadius={4}
|
|
198
|
+
// />
|
|
199
|
+
// <SkeletonPlaceholder.Item
|
|
200
|
+
// height={16}
|
|
201
|
+
// width={80}
|
|
202
|
+
// borderRadius={4}
|
|
203
|
+
// />
|
|
204
|
+
// </SkeletonPlaceholder.Item>
|
|
205
|
+
// </SkeletonPlaceholder.Item>
|
|
206
|
+
// </SkeletonPlaceholder>
|
|
207
|
+
// </KContainer.View>
|
|
208
|
+
// );
|
|
209
|
+
// }
|
|
209
210
|
|
|
210
211
|
return (
|
|
211
212
|
<KContainer.Touchable style={styles.container} onPress={onPress}>
|
|
@@ -2,6 +2,7 @@ import { useEffect, useRef, useCallback } from 'react';
|
|
|
2
2
|
import { useChatContext } from '../../context/ChatContext';
|
|
3
3
|
import { ENDPOINTS } from '../../services/endpoints';
|
|
4
4
|
import {
|
|
5
|
+
ISuggestionItem,
|
|
5
6
|
SendActionLogType,
|
|
6
7
|
type IMessageItem,
|
|
7
8
|
type StreamMessageRequest,
|
|
@@ -91,10 +92,21 @@ export const useStreamMessage = () => {
|
|
|
91
92
|
},
|
|
92
93
|
]);
|
|
93
94
|
} else {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
const arrMessages = Object.values(buffers);
|
|
96
|
+
DeviceEventEmitter.emit(events.forceUpdateMessages, arrMessages);
|
|
97
|
+
arrMessages.forEach((m) => {
|
|
98
|
+
if (m?.metadata?.suggestion?.length > 0) {
|
|
99
|
+
logGA?.(GAEvents.chatDetailInConvPrmSuggReturn, {
|
|
100
|
+
conversation_id: sessionId,
|
|
101
|
+
message_chat_id: m?.id,
|
|
102
|
+
group_id: m?.group_suggestion_id,
|
|
103
|
+
suggestion_id:
|
|
104
|
+
m?.suggestions
|
|
105
|
+
?.map((s: ISuggestionItem) => s?.suggestion_id)
|
|
106
|
+
?.join(',') || '',
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
});
|
|
98
110
|
}
|
|
99
111
|
es.close();
|
|
100
112
|
buffers = {};
|
|
@@ -144,7 +156,7 @@ export const useStreamMessage = () => {
|
|
|
144
156
|
|
|
145
157
|
esRef.current = es;
|
|
146
158
|
},
|
|
147
|
-
[apiAddress, setIsStreaming, setStreamMessage]
|
|
159
|
+
[apiAddress, setIsStreaming, setStreamMessage, logGA, sessionId]
|
|
148
160
|
);
|
|
149
161
|
|
|
150
162
|
const stopStream = useCallback(() => {
|