react-native-chatbot-ai 0.1.51 → 0.1.53
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/DrawerContent.js +6 -4
- package/lib/module/components/Drawer/DrawerContent.js.map +1 -1
- package/lib/module/components/chat/item/ChatAIAnswerMessageItem.js +39 -13
- package/lib/module/components/chat/item/ChatAIAnswerMessageItem.js.map +1 -1
- package/lib/module/components/chat/item/ChatTable.js +45 -7
- package/lib/module/components/chat/item/ChatTable.js.map +1 -1
- package/lib/module/components/product/Card.js +426 -0
- package/lib/module/components/product/Card.js.map +1 -0
- package/lib/module/components/product/CardHorizontal.js +2 -40
- package/lib/module/components/product/CardHorizontal.js.map +1 -1
- package/lib/module/translation/resources/i18n.js +4 -1
- package/lib/module/translation/resources/i18n.js.map +1 -1
- package/lib/module/utils/common.js +10 -0
- package/lib/module/utils/common.js.map +1 -1
- package/lib/typescript/src/components/Drawer/DrawerContent.d.ts.map +1 -1
- package/lib/typescript/src/components/chat/item/ChatAIAnswerMessageItem.d.ts.map +1 -1
- package/lib/typescript/src/components/chat/item/ChatTable.d.ts.map +1 -1
- package/lib/typescript/src/components/product/Card.d.ts +9 -0
- package/lib/typescript/src/components/product/Card.d.ts.map +1 -0
- package/lib/typescript/src/components/product/CardHorizontal.d.ts.map +1 -1
- package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
- package/lib/typescript/src/utils/common.d.ts +3 -0
- package/lib/typescript/src/utils/common.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Drawer/DrawerContent.tsx +6 -4
- package/src/components/chat/item/ChatAIAnswerMessageItem.tsx +50 -18
- package/src/components/chat/item/ChatTable.tsx +51 -5
- package/src/components/product/Card.tsx +484 -0
- package/src/components/product/CardHorizontal.tsx +2 -39
- package/src/ignore.d.ts +1 -1
- package/src/translation/resources/i18n.ts +4 -0
- package/src/utils/common.ts +17 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DrawerContent.d.ts","sourceRoot":"","sources":["../../../../../src/components/Drawer/DrawerContent.tsx"],"names":[],"mappings":"AAcA,QAAA,MAAM,aAAa,+
|
|
1
|
+
{"version":3,"file":"DrawerContent.d.ts","sourceRoot":"","sources":["../../../../../src/components/Drawer/DrawerContent.tsx"],"names":[],"mappings":"AAcA,QAAA,MAAM,aAAa,+CAuFlB,CAAC;AAUF,eAAe,aAAa,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatAIAnswerMessageItem.d.ts","sourceRoot":"","sources":["../../../../../../src/components/chat/item/ChatAIAnswerMessageItem.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatAIAnswerMessageItem.d.ts","sourceRoot":"","sources":["../../../../../../src/components/chat/item/ChatAIAnswerMessageItem.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AA2B9C,UAAU,4BAA4B;IACpC,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA4QD,QAAA,MAAM,uBAAuB,GAAI,mBAG9B,4BAA4B,4CA0G9B,CAAC;AACF,eAAe,uBAAuB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatTable.d.ts","sourceRoot":"","sources":["../../../../../../src/components/chat/item/ChatTable.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChatTable.d.ts","sourceRoot":"","sources":["../../../../../../src/components/chat/item/ChatTable.tsx"],"names":[],"mappings":"AAMA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,UAAU,UAAU;IAClB,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;IAC5B,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,SAAS,CAAC,EAAE,GAAG,CAAC;CACjB;AASD,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CA6GnC,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface IProductCardProps {
|
|
2
|
+
productId?: string;
|
|
3
|
+
messageId?: string;
|
|
4
|
+
index?: number;
|
|
5
|
+
showSensitiveInfo?: boolean;
|
|
6
|
+
}
|
|
7
|
+
declare const ProductCardWrapper: import("react").MemoExoticComponent<(props: IProductCardProps) => import("react/jsx-runtime").JSX.Element | null>;
|
|
8
|
+
export default ProductCardWrapper;
|
|
9
|
+
//# sourceMappingURL=Card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../../../src/components/product/Card.tsx"],"names":[],"mappings":"AAwBA,UAAU,iBAAiB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,QAAA,MAAM,kBAAkB,8CAAgB,iBAAiB,oDASvD,CAAC;AAkXH,eAAe,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CardHorizontal.d.ts","sourceRoot":"","sources":["../../../../../src/components/product/CardHorizontal.tsx"],"names":[],"mappings":"AAsBA,UAAU,2BAA2B;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,QAAA,MAAM,4BAA4B,8CACxB,2BAA2B,oDAUpC,CAAC;
|
|
1
|
+
{"version":3,"file":"CardHorizontal.d.ts","sourceRoot":"","sources":["../../../../../src/components/product/CardHorizontal.tsx"],"names":[],"mappings":"AAsBA,UAAU,2BAA2B;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,QAAA,MAAM,4BAA4B,8CACxB,2BAA2B,oDAUpC,CAAC;AAySF,eAAe,4BAA4B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../../../../src/translation/resources/i18n.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../../../../src/translation/resources/i18n.ts"],"names":[],"mappings":";;;AA4DA,wBAEE"}
|
|
@@ -6,5 +6,8 @@ interface ShortenOptions {
|
|
|
6
6
|
keepEnd?: number;
|
|
7
7
|
}
|
|
8
8
|
export declare const shortenFileName: (name: string, options?: ShortenOptions) => string;
|
|
9
|
+
export declare const COMPONENT_REGEX: RegExp;
|
|
10
|
+
export declare const COMPONENT_GLOBAL_REGEX: RegExp;
|
|
11
|
+
export declare const parseProductParams: (raw?: string) => Record<string, string>;
|
|
9
12
|
export {};
|
|
10
13
|
//# sourceMappingURL=common.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/utils/common.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,GAAI,GAAG,GAAG,EAAE,GAAG,GAAG,YAC4B,CAAC;AAEtE,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAU9C,CAAC;AAEF,UAAU,cAAc;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,UAAS,cAAmB,WAkBzE,CAAC"}
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/utils/common.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,GAAI,GAAG,GAAG,EAAE,GAAG,GAAG,YAC4B,CAAC;AAEtE,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAU9C,CAAC;AAEF,UAAU,cAAc;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,UAAS,cAAmB,WAkBzE,CAAC;AAEF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,sBAAsB,QACU,CAAC;AAE9C,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAWtE,CAAC"}
|
package/package.json
CHANGED
|
@@ -34,10 +34,12 @@ const DrawerContent = () => {
|
|
|
34
34
|
|
|
35
35
|
const onSearchCallback = useCallback(
|
|
36
36
|
(isSuccess?: boolean) => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
if (debouncedSearchTerm?.trim?.().length > 0) {
|
|
38
|
+
logGA(GAEvents.sidebarSearchConversationSend, {
|
|
39
|
+
content: debouncedSearchTerm,
|
|
40
|
+
search_result: isSuccess ? 'yes' : null,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
41
43
|
},
|
|
42
44
|
[logGA, debouncedSearchTerm]
|
|
43
45
|
);
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from 'react-native-marked';
|
|
20
20
|
import { useSearchProduct } from '../../../hooks/product/useSearchProduct';
|
|
21
21
|
import ProductHorizontalCard from '../../product/CardHorizontal';
|
|
22
|
+
import ProductCard from '../../product/Card';
|
|
22
23
|
import ChatTable from './ChatTable';
|
|
23
24
|
import DeeplinkItem from './DeeplinkItem';
|
|
24
25
|
import { useChatContext } from '../../../context/ChatContext';
|
|
@@ -26,6 +27,11 @@ import { trans } from '../../../translation';
|
|
|
26
27
|
import MessageActionsBar from './MessageActionsBar';
|
|
27
28
|
import useProductsStore from '../../../store/products';
|
|
28
29
|
import ShimmerBlock from './ShimmerBlock';
|
|
30
|
+
import {
|
|
31
|
+
COMPONENT_GLOBAL_REGEX,
|
|
32
|
+
COMPONENT_REGEX,
|
|
33
|
+
parseProductParams,
|
|
34
|
+
} from '../../../utils/common';
|
|
29
35
|
|
|
30
36
|
interface ChatAIAnswerMessageItemProps {
|
|
31
37
|
item: IMessageItem;
|
|
@@ -51,22 +57,47 @@ class CustomRenderer extends Renderer implements RendererInterface {
|
|
|
51
57
|
productIds?: string[];
|
|
52
58
|
|
|
53
59
|
html(text: string): ReactNode {
|
|
54
|
-
const
|
|
55
|
-
|
|
60
|
+
const normalized = text?.trim?.();
|
|
61
|
+
const match = COMPONENT_REGEX.exec(normalized);
|
|
62
|
+
console.log('match:', match);
|
|
63
|
+
if (!match) {
|
|
64
|
+
return (
|
|
65
|
+
<KLabel.Text typo="TextMdNormal" key={this.getKey()}>
|
|
66
|
+
{text}
|
|
67
|
+
</KLabel.Text>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
const component = match?.[1];
|
|
71
|
+
const params = parseProductParams(match?.[2]);
|
|
72
|
+
switch (component) {
|
|
56
73
|
case 'product':
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
74
|
+
const productId = params?.id;
|
|
75
|
+
const type = params?.type ?? 'horizontal';
|
|
76
|
+
const productIndex = this.productIds?.indexOf(productId || '');
|
|
77
|
+
console.log('product params:', params, 'type:', type);
|
|
78
|
+
if (type === 'vertical') {
|
|
79
|
+
return (
|
|
80
|
+
<ProductCard
|
|
81
|
+
productId={productId}
|
|
82
|
+
key={this.getKey()}
|
|
83
|
+
messageId={this.messageId}
|
|
84
|
+
index={productIndex}
|
|
85
|
+
/>
|
|
86
|
+
);
|
|
87
|
+
} else {
|
|
88
|
+
return (
|
|
89
|
+
<ProductHorizontalCard
|
|
90
|
+
productId={productId}
|
|
91
|
+
key={this.getKey()}
|
|
92
|
+
messageId={this.messageId}
|
|
93
|
+
index={productIndex}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
66
97
|
default:
|
|
67
98
|
return (
|
|
68
99
|
<KLabel.Text typo="TextMdNormal" key={this.getKey()}>
|
|
69
|
-
{
|
|
100
|
+
{text}
|
|
70
101
|
</KLabel.Text>
|
|
71
102
|
);
|
|
72
103
|
}
|
|
@@ -293,14 +324,15 @@ const ChatAIAnswerMessageItem = ({
|
|
|
293
324
|
}
|
|
294
325
|
|
|
295
326
|
if (typeof content !== 'string') return [];
|
|
296
|
-
|
|
297
|
-
const regex =
|
|
298
|
-
/<!--\s*@component:product\([^)]*id:\s*['"]?([\w-]+)['"]?[^)]*\)\s*-->/g;
|
|
299
327
|
const ids: string[] = [];
|
|
300
328
|
let match;
|
|
301
|
-
while ((match =
|
|
302
|
-
|
|
303
|
-
|
|
329
|
+
while ((match = COMPONENT_GLOBAL_REGEX.exec(content)) !== null) {
|
|
330
|
+
const componentName = match?.[1];
|
|
331
|
+
if (componentName !== 'product') continue;
|
|
332
|
+
const params = parseProductParams(match?.[2]);
|
|
333
|
+
const productId = params?.id;
|
|
334
|
+
if (productId) {
|
|
335
|
+
ids.push(productId);
|
|
304
336
|
}
|
|
305
337
|
}
|
|
306
338
|
return ids;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
KColors,
|
|
3
3
|
KContainer,
|
|
4
|
-
KDims,
|
|
5
4
|
KRadiusValue,
|
|
6
5
|
KSpacingValue,
|
|
7
6
|
} from '@droppii/libs';
|
|
8
|
-
import React from 'react';
|
|
7
|
+
import React, { useEffect, useState } from 'react';
|
|
9
8
|
import { ScrollView, StyleSheet } from 'react-native';
|
|
10
9
|
|
|
11
10
|
interface TableProps {
|
|
@@ -20,6 +19,9 @@ const toArray = (
|
|
|
20
19
|
node: React.ReactNode | React.ReactNode[]
|
|
21
20
|
): React.ReactNode[] => (Array.isArray(node) ? node : [node]);
|
|
22
21
|
|
|
22
|
+
const HEADER_CELL_MAX_WIDTH = 165;
|
|
23
|
+
const COLUMN_CELL_MAX_WIDTH = 220;
|
|
24
|
+
|
|
23
25
|
const ChatTable: React.FC<TableProps> = ({
|
|
24
26
|
header,
|
|
25
27
|
rows,
|
|
@@ -27,6 +29,42 @@ const ChatTable: React.FC<TableProps> = ({
|
|
|
27
29
|
rowStyle,
|
|
28
30
|
cellStyle,
|
|
29
31
|
}) => {
|
|
32
|
+
const columnWidthRef = React.useRef<Record<number, number>>({});
|
|
33
|
+
const [columnWidths, setColumnWidths] = useState<Record<number, number>>({});
|
|
34
|
+
|
|
35
|
+
const layoutCountRef = React.useRef(0);
|
|
36
|
+
const expectedLayoutCountRef = React.useRef(0);
|
|
37
|
+
|
|
38
|
+
const onCellLayout = (colIndex: number, width: number) => {
|
|
39
|
+
const prev = columnWidthRef.current[colIndex] ?? 0;
|
|
40
|
+
|
|
41
|
+
if (width > prev) {
|
|
42
|
+
columnWidthRef.current[colIndex] = width;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
layoutCountRef.current += 1;
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
layoutCountRef.current >= expectedLayoutCountRef.current &&
|
|
49
|
+
expectedLayoutCountRef.current > 0
|
|
50
|
+
) {
|
|
51
|
+
setColumnWidths({ ...columnWidthRef.current });
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
const headerCount = header?.length ?? 0;
|
|
57
|
+
const rowCount =
|
|
58
|
+
rows?.reduce((sum, row) => sum + (row?.length ?? 0), 0) ?? 0;
|
|
59
|
+
|
|
60
|
+
expectedLayoutCountRef.current = headerCount + rowCount;
|
|
61
|
+
|
|
62
|
+
// reset trước mỗi lần render mới
|
|
63
|
+
layoutCountRef.current = 0;
|
|
64
|
+
columnWidthRef.current = {};
|
|
65
|
+
setColumnWidths({});
|
|
66
|
+
}, [header, rows]);
|
|
67
|
+
|
|
30
68
|
return (
|
|
31
69
|
<ScrollView
|
|
32
70
|
horizontal
|
|
@@ -44,7 +82,11 @@ const ChatTable: React.FC<TableProps> = ({
|
|
|
44
82
|
styles.headerCell,
|
|
45
83
|
j < header.length - 1 && styles.borderRight,
|
|
46
84
|
j === 0 && styles.firstCell,
|
|
85
|
+
columnWidths?.[j] && { width: columnWidths[j] },
|
|
47
86
|
]}
|
|
87
|
+
onLayout={(e: any) => {
|
|
88
|
+
onCellLayout(j, e?.nativeEvent?.layout?.width);
|
|
89
|
+
}}
|
|
48
90
|
>
|
|
49
91
|
{toArray(cell).map((child, k) => (
|
|
50
92
|
<React.Fragment key={`header-cell-${j}-${k}`}>
|
|
@@ -71,7 +113,11 @@ const ChatTable: React.FC<TableProps> = ({
|
|
|
71
113
|
styles.cell,
|
|
72
114
|
j < (row?.length || 0) - 1 && styles.borderRight,
|
|
73
115
|
j === 0 && styles.firstCell,
|
|
116
|
+
columnWidths?.[j] && { width: columnWidths[j] },
|
|
74
117
|
]}
|
|
118
|
+
onLayout={(e: any) => {
|
|
119
|
+
onCellLayout(j, e?.nativeEvent?.layout?.width);
|
|
120
|
+
}}
|
|
75
121
|
>
|
|
76
122
|
{toArray(cell).map((child, k) => (
|
|
77
123
|
<React.Fragment key={`cell-${i}-${j}-${k}`}>
|
|
@@ -110,20 +156,20 @@ const styles = StyleSheet.create({
|
|
|
110
156
|
padding: 8,
|
|
111
157
|
borderBottomWidth: 1,
|
|
112
158
|
borderColor: KColors.hexToRgba(KColors.gray.dark, 0.2),
|
|
113
|
-
|
|
159
|
+
maxWidth: COLUMN_CELL_MAX_WIDTH,
|
|
114
160
|
},
|
|
115
161
|
cell: {
|
|
116
162
|
padding: 8,
|
|
117
163
|
borderBottomWidth: 1,
|
|
118
164
|
borderColor: KColors.hexToRgba(KColors.gray.dark, 0.2),
|
|
119
|
-
|
|
165
|
+
maxWidth: COLUMN_CELL_MAX_WIDTH,
|
|
120
166
|
},
|
|
121
167
|
borderRight: {
|
|
122
168
|
borderRightWidth: 1,
|
|
123
169
|
borderColor: KColors.hexToRgba(KColors.gray.dark, 0.2),
|
|
124
170
|
},
|
|
125
171
|
firstCell: {
|
|
126
|
-
|
|
172
|
+
maxWidth: HEADER_CELL_MAX_WIDTH,
|
|
127
173
|
},
|
|
128
174
|
headerText: {
|
|
129
175
|
fontWeight: 'bold',
|