vdb-ai-chat 1.0.6 → 1.0.8

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 (71) hide show
  1. package/dist/chat-widget.js +1 -1
  2. package/lib/commonjs/api.js +51 -12
  3. package/lib/commonjs/api.js.map +1 -1
  4. package/lib/commonjs/components/BetaNotice.js +13 -12
  5. package/lib/commonjs/components/BetaNotice.js.map +1 -1
  6. package/lib/commonjs/components/ChatInput.js +59 -49
  7. package/lib/commonjs/components/ChatInput.js.map +1 -1
  8. package/lib/commonjs/components/ChatWidget.js +74 -61
  9. package/lib/commonjs/components/ChatWidget.js.map +1 -1
  10. package/lib/commonjs/components/MessageBubble.js +67 -52
  11. package/lib/commonjs/components/MessageBubble.js.map +1 -1
  12. package/lib/commonjs/components/MessageMetaRow.js +50 -31
  13. package/lib/commonjs/components/MessageMetaRow.js.map +1 -1
  14. package/lib/commonjs/components/ProductsListView.js +232 -153
  15. package/lib/commonjs/components/ProductsListView.js.map +1 -1
  16. package/lib/commonjs/components/SuggestionsRow.js +27 -24
  17. package/lib/commonjs/components/SuggestionsRow.js.map +1 -1
  18. package/lib/commonjs/components/utils.js +15 -4
  19. package/lib/commonjs/components/utils.js.map +1 -1
  20. package/lib/commonjs/contexts/ThemeProvider.js +80 -0
  21. package/lib/commonjs/contexts/ThemeProvider.js.map +1 -0
  22. package/lib/commonjs/contexts/utils.js +142 -0
  23. package/lib/commonjs/contexts/utils.js.map +1 -0
  24. package/lib/module/api.js +51 -12
  25. package/lib/module/api.js.map +1 -1
  26. package/lib/module/components/BetaNotice.js +14 -13
  27. package/lib/module/components/BetaNotice.js.map +1 -1
  28. package/lib/module/components/ChatInput.js +61 -50
  29. package/lib/module/components/ChatInput.js.map +1 -1
  30. package/lib/module/components/ChatWidget.js +78 -63
  31. package/lib/module/components/ChatWidget.js.map +1 -1
  32. package/lib/module/components/MessageBubble.js +69 -52
  33. package/lib/module/components/MessageBubble.js.map +1 -1
  34. package/lib/module/components/MessageMetaRow.js +52 -32
  35. package/lib/module/components/MessageMetaRow.js.map +1 -1
  36. package/lib/module/components/ProductsListView.js +234 -154
  37. package/lib/module/components/ProductsListView.js.map +1 -1
  38. package/lib/module/components/SuggestionsRow.js +29 -25
  39. package/lib/module/components/SuggestionsRow.js.map +1 -1
  40. package/lib/module/components/utils.js +17 -3
  41. package/lib/module/components/utils.js.map +1 -1
  42. package/lib/module/contexts/ThemeProvider.js +75 -0
  43. package/lib/module/contexts/ThemeProvider.js.map +1 -0
  44. package/lib/module/contexts/utils.js +136 -0
  45. package/lib/module/contexts/utils.js.map +1 -0
  46. package/lib/typescript/api.d.ts.map +1 -1
  47. package/lib/typescript/components/BetaNotice.d.ts.map +1 -1
  48. package/lib/typescript/components/ChatInput.d.ts.map +1 -1
  49. package/lib/typescript/components/ChatWidget.d.ts.map +1 -1
  50. package/lib/typescript/components/MessageBubble.d.ts +1 -1
  51. package/lib/typescript/components/MessageBubble.d.ts.map +1 -1
  52. package/lib/typescript/components/MessageMetaRow.d.ts.map +1 -1
  53. package/lib/typescript/components/ProductsListView.d.ts.map +1 -1
  54. package/lib/typescript/components/SuggestionsRow.d.ts.map +1 -1
  55. package/lib/typescript/components/utils.d.ts.map +1 -1
  56. package/lib/typescript/contexts/ThemeProvider.d.ts +7 -0
  57. package/lib/typescript/contexts/ThemeProvider.d.ts.map +1 -0
  58. package/lib/typescript/contexts/utils.d.ts +136 -0
  59. package/lib/typescript/contexts/utils.d.ts.map +1 -0
  60. package/package.json +6 -2
  61. package/src/api.ts +58 -21
  62. package/src/components/BetaNotice.tsx +15 -13
  63. package/src/components/ChatInput.tsx +63 -62
  64. package/src/components/ChatWidget.tsx +238 -206
  65. package/src/components/MessageBubble.tsx +113 -74
  66. package/src/components/MessageMetaRow.tsx +80 -50
  67. package/src/components/ProductsListView.tsx +243 -184
  68. package/src/components/SuggestionsRow.tsx +40 -25
  69. package/src/components/utils.ts +24 -8
  70. package/src/contexts/ThemeProvider.tsx +87 -0
  71. package/src/contexts/utils.ts +135 -0
@@ -2,10 +2,14 @@ import React, { memo } from "react";
2
2
  import { View, Text, StyleSheet } from "react-native";
3
3
  import SuggestionsRow from "./SuggestionsRow";
4
4
  import type { ChatMessage, ChatTheme } from "../types";
5
+ import { useTheme } from "styled-components/native";
6
+ import styled from "styled-components/native";
7
+ import { DefaultTheme } from "styled-components/native";
8
+ import { css } from "styled-components/native";
5
9
 
6
10
  interface Props {
7
11
  message: ChatMessage;
8
- theme: ChatTheme;
12
+ userTheme: ChatTheme;
9
13
  priceMode?: string;
10
14
  handleFeedbackAction?: (...args: any[]) => void;
11
15
  onReloadResults?: (message: ChatMessage) => void;
@@ -20,11 +24,7 @@ interface Props {
20
24
 
21
25
  const MessageBubbleComponent: React.FC<Props> = ({
22
26
  message,
23
- theme,
24
- priceMode,
25
- handleFeedbackAction,
26
- onReloadResults,
27
- reloading,
27
+ userTheme,
28
28
  hasResults,
29
29
  totalResults,
30
30
  shownResults,
@@ -33,89 +33,128 @@ const MessageBubbleComponent: React.FC<Props> = ({
33
33
  isTyping,
34
34
  }) => {
35
35
  const isUser = message.role === "user";
36
-
36
+ const theme = useTheme();
37
37
  return (
38
- <View
39
- style={[styles.container, isUser ? styles.alignRight : styles.alignLeft]}
40
- >
41
- <View
42
- style={[
43
- styles.bubble,
44
- {
45
- backgroundColor: isUser
46
- ? theme.userBubbleColor
47
- : theme.botBubbleColor,
48
- borderRadius: theme.borderRadius || 8,
49
- borderBottomRightRadius: isUser ? 0 : theme.borderRadius,
50
- borderBottomLeftRadius: isUser ? theme.borderRadius : 0,
51
- },
52
- ]}
53
- >
54
- <Text
55
- style={[
56
- styles.text,
57
- {
58
- color: isUser ? theme.userTextColor : theme.botTextColor,
59
- fontFamily: theme.fontFamily,
60
- fontSize: theme.fontSize,
61
- },
62
- ]}
63
- >
38
+ <Container theme={theme} userTheme={userTheme} isUser={isUser}>
39
+ <BubbleContainer theme={theme} userTheme={userTheme} isUser={isUser}>
40
+ <MessageText isUser={isUser} userTheme={userTheme} theme={theme}>
64
41
  {message.text || ""}
65
- {message.role === "assistant" && hasResults && typeof totalResults === "number" ? (
66
- ` Found ${Number(totalResults).toLocaleString()} diamonds (showing first ${shownResults})`
67
- ) : null}
68
- </Text>
42
+ {message.role === "assistant" &&
43
+ hasResults &&
44
+ typeof totalResults === "number"
45
+ ? ` Found ${Number(
46
+ totalResults
47
+ ).toLocaleString()} diamonds (showing first ${shownResults})`
48
+ : null}
49
+ </MessageText>
69
50
  {message.role === "assistant" &&
70
51
  Array.isArray(message.suggestions) &&
71
52
  message.suggestions.length > 0 &&
72
53
  isLatest &&
73
54
  !isTyping &&
74
- !(message.search_payload &&
55
+ !(
56
+ message.search_payload &&
75
57
  typeof message.search_payload === "object" &&
76
- Object.keys(message.search_payload).length > 0) && (
77
- <View style={styles.suggestionsWrapper}>
58
+ Object.keys(message.search_payload).length > 0
59
+ ) && (
60
+ <SuggestionsWrapper theme={theme}>
78
61
  <SuggestionsRow
79
62
  suggestions={message.suggestions}
80
63
  onSelect={(v) => onSuggestionSelect?.(v)}
81
64
  variant="inline"
82
65
  />
83
- </View>
66
+ </SuggestionsWrapper>
84
67
  )}
85
- </View>
86
- </View>
87
- )};
68
+ </BubbleContainer>
69
+ </Container>
70
+ );
71
+ };
88
72
 
89
73
  // Memoize to prevent re-renders when parent re-renders
90
74
  export const MessageBubble = memo(MessageBubbleComponent);
91
75
 
92
- const styles = StyleSheet.create({
93
- container: {
94
- paddingHorizontal: 8,
95
- marginVertical: 0,
96
- width: "100%",
97
- },
98
-
99
- alignRight: {
100
- alignItems: "flex-end",
101
- },
102
- alignLeft: {
103
- alignItems: "flex-start",
104
- },
105
- bubble: {
106
- maxWidth: "80%",
107
- paddingHorizontal: 12,
108
- paddingVertical: 8,
109
- },
110
- text: {
111
- lineHeight: 20,
112
- },
113
- resultsInfo: {
114
- marginTop: 4,
115
- fontSize: 12,
116
- color: "#666",
117
- },
118
- suggestionsWrapper: {
119
- marginTop: 8,
120
- },
121
- });
76
+ const Container = styled.View<{
77
+ theme: DefaultTheme;
78
+ userTheme: ChatTheme;
79
+ isUser: Boolean;
80
+ }>`
81
+ padding-horizontal: 8px;
82
+ margin-vertical: 0;
83
+ width: 100%;
84
+ ${({ isUser }: { isUser: Boolean }) =>
85
+ isUser
86
+ ? css`
87
+ align-items: flex-end;
88
+ `
89
+ : css`
90
+ align-items: flex-start;
91
+ `}
92
+ `;
93
+
94
+ const BubbleContainer = styled.View<{
95
+ theme: DefaultTheme;
96
+ userTheme: ChatTheme;
97
+ isUser: Boolean;
98
+ }>`
99
+ max-width: 80%;
100
+ padding-horizontal: 12px;
101
+ padding-vertical: 8px;
102
+ background-color: ${({
103
+ userTheme,
104
+ theme,
105
+ isUser,
106
+ }: {
107
+ userTheme: ChatTheme;
108
+ theme: DefaultTheme;
109
+ isUser: Boolean;
110
+ }) =>
111
+ isUser
112
+ ? theme["core-06"] || userTheme.userBubbleColor || "#EDEDF2"
113
+ : theme["core-02"] || userTheme.botBubbleColor || "#EDEDF2"};
114
+ border-radius: ${({ userTheme }: { userTheme: ChatTheme }) =>
115
+ userTheme.borderRadius || 8}px;
116
+ border-bottom-right-radius: ${({
117
+ isUser,
118
+ userTheme,
119
+ }: {
120
+ isUser: Boolean;
121
+ userTheme: ChatTheme;
122
+ }) => (isUser ? 0 : userTheme.borderRadius)}px;
123
+ border-bottom-left-radius: ${({
124
+ isUser,
125
+ userTheme,
126
+ }: {
127
+ isUser: Boolean;
128
+ userTheme: ChatTheme;
129
+ }) => (isUser ? userTheme.borderRadius : 0)}px;
130
+ `;
131
+
132
+ const MessageText = styled.Text<{
133
+ theme: DefaultTheme;
134
+ userTheme: ChatTheme;
135
+ isUser: Boolean;
136
+ }>`
137
+ color: ${({
138
+ userTheme,
139
+ theme,
140
+ isUser,
141
+ }: {
142
+ userTheme: ChatTheme;
143
+ theme: DefaultTheme;
144
+ isUser: Boolean;
145
+ }) =>
146
+ isUser
147
+ ? theme["core-01"] || userTheme.userTextColor || "#FFFFFF"
148
+ : theme["core-05"] || userTheme.botTextColor || "#000000"};
149
+ font-family: ${({ userTheme }: { userTheme: ChatTheme }) =>
150
+ userTheme.fontFamily || "Roboto"};
151
+ font-size: ${({ userTheme }: { userTheme: ChatTheme }) =>
152
+ userTheme.fontSize || 16}px;
153
+ line-height: 20px;
154
+ `;
155
+
156
+ const SuggestionsWrapper = styled.View<{
157
+ theme: DefaultTheme;
158
+ }>`
159
+ margin-top: 8px;
160
+ `;
@@ -1,15 +1,11 @@
1
1
  import React from "react";
2
- import {
3
- View,
4
- Text,
5
- StyleSheet,
6
- Image,
7
- Platform,
8
- ActivityIndicator,
9
- Pressable,
10
- } from "react-native";
2
+ import { View, StyleSheet, Image, Platform } from "react-native";
11
3
  import type { ChatMessage } from "../types";
12
4
  import { FeedbackAction, fetchConversationId, formatToTime } from "./utils";
5
+ import { useTheme } from "styled-components/native";
6
+ import styled from "styled-components/native";
7
+ import { DefaultTheme } from "styled-components/native";
8
+ import { css } from "styled-components/native";
13
9
 
14
10
  let ImageComponent: typeof Image = Image;
15
11
  if (Platform.OS !== "web") {
@@ -36,10 +32,8 @@ export const MessageMetaRow: React.FC<Props> = ({
36
32
  message,
37
33
  priceMode,
38
34
  handleFeedbackAction,
39
- onReloadResults,
40
- reloading,
41
- hasResults,
42
35
  }) => {
36
+ const theme = useTheme();
43
37
  const isUser = message.role === "user";
44
38
  const [conversationId, setConversationId] = React.useState<string | null>(
45
39
  null
@@ -71,16 +65,14 @@ export const MessageMetaRow: React.FC<Props> = ({
71
65
  ]}
72
66
  >
73
67
  <View style={styles.timeContainer}>
74
- <Text style={styles.timeText}>{formatToTime(message.createdAt)}</Text>
68
+ <TimeText theme={theme}>{formatToTime(message.createdAt)}</TimeText>
75
69
  </View>
76
70
  {canFeedback ? (
77
71
  <View style={styles.likeDislikeContainer}>
78
- <Pressable
79
- style={(state: any) => [
80
- styles.borderButton,
81
- state?.hovered && styles.borderButtonHover,
82
- message.reaction === FeedbackAction.LIKE && styles.borderButtonLike,
83
- ]}
72
+ <LikeButton
73
+ type="like"
74
+ style={(state: any) => [state?.hovered && styles.borderButtonHover]}
75
+ reaction={message.reaction}
84
76
  onPress={() =>
85
77
  handleFeedbackAction(
86
78
  FeedbackAction.LIKE,
@@ -91,17 +83,24 @@ export const MessageMetaRow: React.FC<Props> = ({
91
83
  disabled={!canFeedback}
92
84
  >
93
85
  <ImageComponent
94
- source={{ uri: "https://cdn.vdbapp.com/ai/chat-widget/assets/img/like.svg" }}
86
+ source={{
87
+ uri: "https://cdn.vdbapp.com/ai/chat-widget/assets/img/like.svg",
88
+ }}
95
89
  resizeMode="contain"
96
- style={{ width: 20, height: 20, tintColor: message.reaction === FeedbackAction.LIKE ?"#00B140" : "#020001" }}
90
+ style={{
91
+ width: 20,
92
+ height: 20,
93
+ tintColor:
94
+ message.reaction === FeedbackAction.LIKE
95
+ ? theme["success-01"] || "#00B140"
96
+ : theme["core-05"] || "#020001",
97
+ }}
97
98
  />
98
- </Pressable>
99
- <Pressable
100
- style={(state: any) => [
101
- styles.borderButton,
102
- state?.hovered && styles.borderButtonHover,
103
- message.reaction === FeedbackAction.DISLIKE && styles.borderButtonDislike,
104
- ]}
99
+ </LikeButton>
100
+ <LikeButton
101
+ type="dislike"
102
+ style={(state: any) => [state?.hovered && styles.borderButtonHover]}
103
+ reaction={message.reaction}
105
104
  onPress={() =>
106
105
  handleFeedbackAction(
107
106
  FeedbackAction.DISLIKE,
@@ -112,11 +111,20 @@ export const MessageMetaRow: React.FC<Props> = ({
112
111
  disabled={!canFeedback}
113
112
  >
114
113
  <ImageComponent
115
- source={{ uri: "https://cdn.vdbapp.com/ai/chat-widget/assets/img/dislike.svg" }}
114
+ source={{
115
+ uri: "https://cdn.vdbapp.com/ai/chat-widget/assets/img/dislike.svg",
116
+ }}
116
117
  resizeMode="contain"
117
- style={{ width: 20, height: 20, tintColor: message.reaction === FeedbackAction.DISLIKE ? "#D0021B" : "#020001" }}
118
+ style={{
119
+ width: 20,
120
+ height: 20,
121
+ tintColor:
122
+ message.reaction === FeedbackAction.DISLIKE
123
+ ? theme["error-01"] || "#D0021B"
124
+ : theme["core-05"] || "#020001",
125
+ }}
118
126
  />
119
- </Pressable>
127
+ </LikeButton>
120
128
  </View>
121
129
  ) : null}
122
130
  {/* {message.search_payload &&
@@ -149,6 +157,47 @@ export const MessageMetaRow: React.FC<Props> = ({
149
157
  );
150
158
  };
151
159
 
160
+ const LikeButton = styled.Pressable<{
161
+ theme: DefaultTheme;
162
+ reaction: FeedbackAction;
163
+ type: "like" | "dislike";
164
+ }>`
165
+ border-width: 1;
166
+ border-radius: 8px;
167
+ padding-horizontal: 4px;
168
+ padding-vertical: 4px;
169
+ ${({
170
+ reaction,
171
+ type,
172
+ }: {
173
+ reaction: FeedbackAction;
174
+ type: "like" | "dislike";
175
+ }) =>
176
+ reaction === FeedbackAction.LIKE && type === "like"
177
+ ? css`
178
+ background-color: ${({ theme }: { theme: DefaultTheme }) =>
179
+ theme["success-02"] || "#DBFFE4"};
180
+ border-color: ${({ theme }: { theme: DefaultTheme }) =>
181
+ theme["success-01"] || "#00B140"};
182
+ `
183
+ : reaction === FeedbackAction.DISLIKE && type === "dislike"
184
+ ? css`
185
+ background-color: ${({ theme }: { theme: DefaultTheme }) =>
186
+ theme["error-02"] || "#FFE2E0"};
187
+ border-color: ${({ theme }: { theme: DefaultTheme }) =>
188
+ theme["error-01"] || "#D0021B"};
189
+ `
190
+ : css`
191
+ border-color: ${({ theme }: { theme: DefaultTheme }) =>
192
+ theme["core-03"] || "#D5D5DC"};
193
+ `}
194
+ `;
195
+
196
+ const TimeText = styled.Text<{ theme: DefaultTheme }>`
197
+ font-size: 12px;
198
+ color: ${({ theme }: { theme: DefaultTheme }) => theme["core-06"] || "#666"};
199
+ `;
200
+
152
201
  const styles = StyleSheet.create({
153
202
  rowContainer: {
154
203
  flexDirection: "row",
@@ -172,28 +221,9 @@ const styles = StyleSheet.create({
172
221
  timeContainer: {
173
222
  margin: 0,
174
223
  },
175
- borderButton: {
176
- borderWidth: 1,
177
- borderColor: "#D5D5DC",
178
- borderRadius: 8,
179
- paddingHorizontal: 4,
180
- paddingVertical: 4,
181
- },
182
224
  borderButtonHover: {
183
225
  backgroundColor: "#EDEDF2",
184
226
  },
185
- borderButtonLike: {
186
- backgroundColor: "#DBFFE4",
187
- borderColor: "#00B140",
188
- },
189
- borderButtonDislike: {
190
- backgroundColor: "#FFE2E0",
191
- borderColor: "#D0021B",
192
- },
193
- timeText: {
194
- fontSize: 12,
195
- color: "#666",
196
- },
197
227
  });
198
228
 
199
229
  export default MessageMetaRow;