react-native-srschat 0.1.14 → 0.1.15
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/commonjs/components/email.js +243 -0
- package/lib/commonjs/components/email.js.map +1 -0
- package/lib/commonjs/components/feedback.js +115 -0
- package/lib/commonjs/components/feedback.js.map +1 -0
- package/lib/commonjs/components/header.js +33 -17
- package/lib/commonjs/components/header.js.map +1 -1
- package/lib/commonjs/components/input.js +106 -0
- package/lib/commonjs/components/input.js.map +1 -0
- package/lib/commonjs/components/productCard.js +234 -0
- package/lib/commonjs/components/productCard.js.map +1 -0
- package/lib/commonjs/components/testing.js +19 -6
- package/lib/commonjs/components/testing.js.map +1 -1
- package/lib/commonjs/{layout/chatIcon.js → components/welcomeButton.js} +40 -37
- package/lib/commonjs/components/welcomeButton.js.map +1 -0
- package/lib/commonjs/components/welcomeInput.js +87 -0
- package/lib/commonjs/components/welcomeInput.js.map +1 -0
- package/lib/commonjs/contexts/AppContext.js +269 -55
- package/lib/commonjs/contexts/AppContext.js.map +1 -1
- package/lib/commonjs/hooks/{Stream.js → stream.js} +107 -39
- package/lib/commonjs/hooks/stream.js.map +1 -0
- package/lib/commonjs/hooks/useAsyncStorage.js +36 -0
- package/lib/commonjs/hooks/useAsyncStorage.js.map +1 -0
- package/lib/commonjs/index.js +13 -6
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/layout/disclaimer.js +200 -0
- package/lib/commonjs/layout/disclaimer.js.map +1 -0
- package/lib/commonjs/layout/ex.js +272 -0
- package/lib/commonjs/layout/ex.js.map +1 -0
- package/lib/commonjs/layout/icon.js +114 -0
- package/lib/commonjs/layout/icon.js.map +1 -0
- package/lib/commonjs/layout/layout.js +148 -14
- package/lib/commonjs/layout/layout.js.map +1 -1
- package/lib/commonjs/layout/welcome.js +135 -0
- package/lib/commonjs/layout/welcome.js.map +1 -0
- package/lib/commonjs/layout/window.js +205 -0
- package/lib/commonjs/layout/window.js.map +1 -0
- package/lib/module/components/email.js +233 -0
- package/lib/module/components/email.js.map +1 -0
- package/lib/module/components/feedback.js +105 -0
- package/lib/module/components/feedback.js.map +1 -0
- package/lib/module/components/header.js +33 -17
- package/lib/module/components/header.js.map +1 -1
- package/lib/module/components/input.js +96 -0
- package/lib/module/components/input.js.map +1 -0
- package/lib/module/components/productCard.js +225 -0
- package/lib/module/components/productCard.js.map +1 -0
- package/lib/module/components/testing.js +20 -7
- package/lib/module/components/testing.js.map +1 -1
- package/lib/module/components/welcomeButton.js +48 -0
- package/lib/module/components/welcomeButton.js.map +1 -0
- package/lib/module/components/welcomeInput.js +77 -0
- package/lib/module/components/welcomeInput.js.map +1 -0
- package/lib/module/contexts/AppContext.js +269 -56
- package/lib/module/contexts/AppContext.js.map +1 -1
- package/lib/module/hooks/{Stream.js → stream.js} +107 -39
- package/lib/module/hooks/stream.js.map +1 -0
- package/lib/module/hooks/useAsyncStorage.js +29 -0
- package/lib/module/hooks/useAsyncStorage.js.map +1 -0
- package/lib/module/index.js +13 -6
- package/lib/module/index.js.map +1 -1
- package/lib/module/layout/disclaimer.js +190 -0
- package/lib/module/layout/disclaimer.js.map +1 -0
- package/lib/module/layout/ex.js +262 -0
- package/lib/module/layout/ex.js.map +1 -0
- package/lib/module/layout/icon.js +104 -0
- package/lib/module/layout/icon.js.map +1 -0
- package/lib/module/layout/layout.js +150 -16
- package/lib/module/layout/layout.js.map +1 -1
- package/lib/module/layout/welcome.js +126 -0
- package/lib/module/layout/welcome.js.map +1 -0
- package/lib/module/layout/window.js +195 -0
- package/lib/module/layout/window.js.map +1 -0
- package/lib/typescript/components/email.d.ts +5 -0
- package/lib/typescript/components/email.d.ts.map +1 -0
- package/lib/typescript/components/feedback.d.ts +6 -0
- package/lib/typescript/components/feedback.d.ts.map +1 -0
- package/lib/typescript/components/header.d.ts.map +1 -1
- package/lib/typescript/components/input.d.ts +6 -0
- package/lib/typescript/components/input.d.ts.map +1 -0
- package/lib/typescript/components/productCard.d.ts +5 -0
- package/lib/typescript/components/productCard.d.ts.map +1 -0
- package/lib/typescript/components/testing.d.ts.map +1 -1
- package/lib/typescript/components/welcomeButton.d.ts +4 -0
- package/lib/typescript/components/welcomeButton.d.ts.map +1 -0
- package/lib/typescript/components/welcomeInput.d.ts +6 -0
- package/lib/typescript/components/welcomeInput.d.ts.map +1 -0
- package/lib/typescript/contexts/AppContext.d.ts +5 -1
- package/lib/typescript/contexts/AppContext.d.ts.map +1 -1
- package/lib/typescript/hooks/{Stream.d.ts → stream.d.ts} +1 -1
- package/lib/typescript/hooks/stream.d.ts.map +1 -0
- package/lib/typescript/hooks/useAsyncStorage.d.ts +2 -0
- package/lib/typescript/hooks/useAsyncStorage.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +2 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/layout/disclaimer.d.ts +5 -0
- package/lib/typescript/layout/disclaimer.d.ts.map +1 -0
- package/lib/typescript/layout/ex.d.ts +3 -0
- package/lib/typescript/layout/ex.d.ts.map +1 -0
- package/lib/typescript/layout/{chatIcon.d.ts → icon.d.ts} +1 -1
- package/lib/typescript/layout/icon.d.ts.map +1 -0
- package/lib/typescript/layout/layout.d.ts +1 -4
- package/lib/typescript/layout/layout.d.ts.map +1 -1
- package/lib/typescript/layout/welcome.d.ts +5 -0
- package/lib/typescript/layout/welcome.d.ts.map +1 -0
- package/lib/typescript/layout/window.d.ts +5 -0
- package/lib/typescript/layout/window.d.ts.map +1 -0
- package/package.json +6 -1
- package/src/components/email.js +210 -0
- package/src/components/feedback.js +114 -0
- package/src/components/header.js +32 -17
- package/src/components/input.js +95 -0
- package/src/components/productCard.js +240 -0
- package/src/components/testing.js +17 -4
- package/src/components/welcomeButton.js +51 -0
- package/src/components/welcomeInput.js +81 -0
- package/src/contexts/AppContext.js +235 -52
- package/src/hooks/{Stream.js → stream.js} +123 -41
- package/src/hooks/useAsyncStorage.js +33 -0
- package/src/index.js +7 -3
- package/src/layout/disclaimer.js +187 -0
- package/src/layout/ex.js +251 -0
- package/src/layout/icon.js +96 -0
- package/src/layout/layout.js +137 -10
- package/src/layout/welcome.js +124 -0
- package/src/layout/window.js +194 -0
- package/lib/commonjs/hooks/Stream.js.map +0 -1
- package/lib/commonjs/layout/chatIcon.js.map +0 -1
- package/lib/commonjs/layout/chatWindow.js +0 -199
- package/lib/commonjs/layout/chatWindow.js.map +0 -1
- package/lib/module/hooks/Stream.js.map +0 -1
- package/lib/module/layout/chatIcon.js +0 -44
- package/lib/module/layout/chatIcon.js.map +0 -1
- package/lib/module/layout/chatWindow.js +0 -189
- package/lib/module/layout/chatWindow.js.map +0 -1
- package/lib/typescript/hooks/Stream.d.ts.map +0 -1
- package/lib/typescript/layout/chatIcon.d.ts.map +0 -1
- package/lib/typescript/layout/chatWindow.d.ts +0 -6
- package/lib/typescript/layout/chatWindow.d.ts.map +0 -1
- package/src/layout/chatIcon.js +0 -38
- package/src/layout/chatWindow.js +0 -211
|
@@ -1,82 +1,265 @@
|
|
|
1
|
-
import React, {createContext, useContext, useState, useEffect } from "react";
|
|
1
|
+
import React, {createContext, useContext, useState, useEffect, useMemo } from "react";
|
|
2
|
+
import uuid from 'react-native-uuid';
|
|
3
|
+
import axios from "axios";
|
|
4
|
+
import useAsyncStorage from '../hooks/useAsyncStorage';
|
|
2
5
|
|
|
3
6
|
export const AppContext = createContext();
|
|
4
7
|
|
|
5
|
-
export const AppProvider = ({ children }) => {
|
|
8
|
+
export const AppProvider = ({ data, onProductCardClick, onAddToCartClick, uiConfig = {}, children }) => {
|
|
6
9
|
|
|
7
|
-
const
|
|
10
|
+
const theme = {
|
|
11
|
+
userMessage: '#003764',
|
|
12
|
+
botMessage: '#003764',
|
|
13
|
+
backgroundColor: '#f6f6f6',
|
|
14
|
+
textColor: '#161616',
|
|
15
|
+
textColorSecondary: '#FFFFFF',
|
|
16
|
+
inlineButtonColor: '#dbd4c8'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Backend URLs
|
|
20
|
+
const BASE_URL = "srs-external-agent-backend-586731320826.us-central1.run.app";
|
|
21
|
+
const LOGGING_URL = "srs-external-agent-logging-ve7hwyltsq-uc.a.run.app";
|
|
22
|
+
const API_PREFIX = "https://";
|
|
8
23
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
{type: "
|
|
12
|
-
{type: "ai", text: "Could you provide more details on the specific model or horsepower you are interested in for the Hayward Super Pump? We have various models with different features, such as variable speed settings and different horsepower ratings. Alternatively, I can offer you some recommendations right away to help you decide."},
|
|
24
|
+
// Default Messages
|
|
25
|
+
const defaultMessage = [
|
|
26
|
+
{type: "ai", text: "Hi there 👋 I’m Poseidon, your Heritage Pool+ AI Agent. I can help you during your online visit with Product and Account information. How can I help you today?"}
|
|
13
27
|
]
|
|
14
28
|
|
|
29
|
+
const maintenanceMessage = [
|
|
30
|
+
{ type: "ai", text: "Hi there 👋 I’m Poseidon, your Heritage Pool+ AI Agent. I'm currently undergoing maintenance to improve my services. Thank you for your patience and understanding!",},
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
// Base Variables
|
|
34
|
+
const [showModal, setShowModal] = useState("Icon");
|
|
15
35
|
const [input, setInput] = useState('');
|
|
16
|
-
const [messages, setMessages] = useState(
|
|
36
|
+
const [messages, setMessages] = useState(defaultMessage);
|
|
37
|
+
const [conversationStartTime, setConversationStartTime] = useState(null);
|
|
38
|
+
const [lastUserMessage, setLastUserMessage] = useState("");
|
|
39
|
+
const [lastMessageId, setLastMessageId] = useState("");
|
|
40
|
+
const [sessionId, setSessionId] = useState(null);
|
|
17
41
|
|
|
18
|
-
|
|
19
|
-
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
const newSessionId = uuid.v4(); // Generate UUID v4
|
|
44
|
+
setSessionId(newSessionId);
|
|
45
|
+
}, []);
|
|
20
46
|
|
|
21
|
-
|
|
22
|
-
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (showModal == "Off") {
|
|
49
|
+
setShowModal("Icon")
|
|
50
|
+
}
|
|
51
|
+
}, [uiConfig.showIcon]);
|
|
23
52
|
|
|
24
|
-
|
|
25
|
-
|
|
53
|
+
// Message UI
|
|
54
|
+
const [typingIndicator, setTypingIndicator] = useState(false);
|
|
55
|
+
const [ghostMessage, setGhostMessage] = useState(false);
|
|
56
|
+
const [ghostCard, setGhostCard] = useState(false);
|
|
57
|
+
const [stopActivated, setStopActivated] = useState(false);
|
|
58
|
+
const [disclaimer, setDisclaimer] = useState(false);
|
|
59
|
+
const [startStreaming, setStartStreaming] = useState(false);
|
|
26
60
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
61
|
+
const stopGenerating = () => {
|
|
62
|
+
setTypingIndicator(false);
|
|
63
|
+
setStopActivated(true);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
function handleSend(input) {
|
|
67
|
+
if (maintenance) {
|
|
68
|
+
setMessages([ ...messages, { type: "user", text: input },
|
|
69
|
+
{ type: "ai", text: "The chat is currently unavailable, please come back later!",},]);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (input.trim() !== "") {
|
|
73
|
+
if (messages.length <= 1) {
|
|
74
|
+
const startTime = new Date().toISOString();
|
|
75
|
+
setConversationStartTime(startTime);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Initiate streaming
|
|
79
|
+
setShowModal("ChatWindow");
|
|
80
|
+
setLastUserMessage(input);
|
|
81
|
+
setMessages([...messages, { type: "user", text: input }]);
|
|
82
|
+
setTypingIndicator(true);
|
|
83
|
+
setGhostMessage(true);
|
|
84
|
+
setStartStreaming(true);
|
|
85
|
+
setInput("")
|
|
86
|
+
}
|
|
87
|
+
}
|
|
42
88
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
|
|
89
|
+
// After form submission
|
|
90
|
+
function setNextMessage(name) {
|
|
91
|
+
setMessages((prevMessages) => {
|
|
92
|
+
const updatedMessages = prevMessages.map((message, index) => {
|
|
93
|
+
if (index === prevMessages.length - 1 && message.form) {
|
|
94
|
+
return { ...message, form: false };
|
|
49
95
|
}
|
|
50
|
-
return
|
|
96
|
+
return message;
|
|
51
97
|
});
|
|
98
|
+
|
|
99
|
+
const nextMessage = {
|
|
100
|
+
type: "ai",
|
|
101
|
+
text: [`Nice to meet you ${name}. How can I help you today?`],
|
|
102
|
+
};
|
|
103
|
+
return [...updatedMessages, nextMessage];
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Confirm Disclaimer
|
|
108
|
+
async function confirmDisclaimer() {
|
|
109
|
+
setDisclaimer(true);
|
|
110
|
+
if (!maintenance) {
|
|
111
|
+
setShowModal("Welcome");
|
|
112
|
+
setMessages(defaultMessage);
|
|
113
|
+
} else {
|
|
114
|
+
setShowModal("ChatWindow");
|
|
115
|
+
setMessages(maintenanceMessage);
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
const response = await axios.post(
|
|
119
|
+
API_PREFIX + LOGGING_URL + "/log-disclaimer",
|
|
120
|
+
{ email: "cristin@instalily.ai" },
|
|
121
|
+
);
|
|
52
122
|
} catch (error) {
|
|
53
|
-
console.error(
|
|
123
|
+
console.error("Error in Log disclaimer:", error);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function handleButtonClick(buttonText) {
|
|
128
|
+
handleSend(buttonText);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const [maintenance, setMaintenance] = useState(false);
|
|
132
|
+
|
|
133
|
+
const handleClearState = async () => {
|
|
134
|
+
if (!maintenance) {
|
|
135
|
+
setShowModal("Welcome");
|
|
136
|
+
}
|
|
137
|
+
if (messages.length > 1) {
|
|
138
|
+
if (maintenance) {
|
|
139
|
+
setMessages(maintenanceMessage);
|
|
140
|
+
} else {
|
|
141
|
+
setMessages(defaultMessage);
|
|
142
|
+
}
|
|
143
|
+
const newSessionId = uuid.v4();
|
|
144
|
+
setSessionId(newSessionId);
|
|
145
|
+
setTypingIndicator(false);
|
|
146
|
+
setGhostMessage(false);
|
|
147
|
+
/* try {
|
|
148
|
+
const response = await axios.post(API_PREFIX + BASE_URL + "/clear", {
|
|
149
|
+
customer_code: data.customer_code,
|
|
150
|
+
session_id: data.session_id,
|
|
151
|
+
message_id: lastMessageId,
|
|
152
|
+
user_UUID: data.user_UUID,
|
|
153
|
+
});
|
|
154
|
+
console.log(response);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error("Error in Clear:", error);
|
|
157
|
+
} */
|
|
54
158
|
}
|
|
55
159
|
};
|
|
56
160
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
161
|
+
const [feedback, setFeedback] = useState({});
|
|
162
|
+
|
|
163
|
+
async function handleFeedback(feedbackValue, messageId) {
|
|
164
|
+
switchFeedbackOpen(true, messageId, true);
|
|
165
|
+
setFeedback((prevFeedback) => {
|
|
166
|
+
const updatedFeedback = { ...prevFeedback };
|
|
167
|
+
|
|
168
|
+
if (!updatedFeedback[messageId]) {
|
|
169
|
+
updatedFeedback[messageId] = 0;
|
|
66
170
|
}
|
|
67
171
|
|
|
68
|
-
|
|
69
|
-
|
|
172
|
+
updatedFeedback[messageId] = feedbackValue;
|
|
173
|
+
|
|
174
|
+
return updatedFeedback;
|
|
175
|
+
});
|
|
176
|
+
try {
|
|
177
|
+
const response = await axios.post(
|
|
178
|
+
API_PREFIX + LOGGING_URL + "/feedback",
|
|
179
|
+
{
|
|
180
|
+
message_id: messageId,
|
|
181
|
+
feedback: feedbackValue,
|
|
182
|
+
},
|
|
183
|
+
);
|
|
184
|
+
//console.log(response)
|
|
70
185
|
} catch (error) {
|
|
71
|
-
console.error(
|
|
72
|
-
return 'Error processing message';
|
|
186
|
+
console.error("Error in feedback post:", error);
|
|
73
187
|
}
|
|
74
|
-
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const [feedbackOpen, setFeedbackOpen] = useState({});
|
|
191
|
+
const [writeFeedback, setWriteFeedback] = useState("");
|
|
192
|
+
const [writeAnswer, setWriteAnswer] = useState("");
|
|
75
193
|
|
|
194
|
+
// Written Feedback ----------------------------
|
|
195
|
+
|
|
196
|
+
function switchFeedbackOpen(newVal, messageId, resetvalue) {
|
|
197
|
+
console.log(newVal,feedbackOpen[messageId], messageId, resetvalue)
|
|
198
|
+
console.log(feedbackOpen)
|
|
199
|
+
if (newVal != feedbackOpen[messageId]) {
|
|
200
|
+
setWriteFeedback("");
|
|
201
|
+
setWriteAnswer("");
|
|
202
|
+
}
|
|
203
|
+
if (resetvalue) {
|
|
204
|
+
setWriteFeedback("");
|
|
205
|
+
setWriteAnswer("");
|
|
206
|
+
}
|
|
207
|
+
if (feedbackOpen[messageId] == "done") {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
setFeedbackOpen((prevFeedback) => {
|
|
211
|
+
const updatedFeedback = { ...prevFeedback };
|
|
212
|
+
updatedFeedback[messageId] = newVal;
|
|
213
|
+
return updatedFeedback;
|
|
214
|
+
});
|
|
215
|
+
console.log(feedbackOpen)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async function handleWrittenFeedback(messageId) {
|
|
219
|
+
if (writeFeedback.trim() !== "" || writeAnswer.trim() !== "") {
|
|
220
|
+
//console.log(messageId, writeFeedback)
|
|
221
|
+
switchFeedbackOpen(-1, messageId, true);
|
|
222
|
+
try {
|
|
223
|
+
const response = await axios.post(
|
|
224
|
+
API_PREFIX + LOGGING_URL + "/feedback-message",
|
|
225
|
+
{
|
|
226
|
+
message_id: messageId,
|
|
227
|
+
feedback_message: writeFeedback,
|
|
228
|
+
correct_answer: writeAnswer,
|
|
229
|
+
},
|
|
230
|
+
);
|
|
231
|
+
//console.log(response)
|
|
232
|
+
} catch (error) {
|
|
233
|
+
console.error("Error in feedback_message:", error);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const formatChatHistory = () => {
|
|
239
|
+
// Skip the first message (index 0) which is the welcome message
|
|
240
|
+
return messages.slice(1).map((message) => {
|
|
241
|
+
if (Array.isArray(message.text)) {
|
|
242
|
+
return {
|
|
243
|
+
type: message.type,
|
|
244
|
+
content: message.text.join("\n"),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
type: message.type,
|
|
249
|
+
content: message.text,
|
|
250
|
+
};
|
|
251
|
+
});
|
|
252
|
+
};
|
|
76
253
|
|
|
77
254
|
return (
|
|
78
255
|
<AppContext.Provider
|
|
79
|
-
value={{ showModal, setShowModal, messages, setMessages, handleSend,
|
|
256
|
+
value={{ showModal, setShowModal, messages, setMessages, handleSend, input, setInput, defaultMessage, typingIndicator, setTypingIndicator,
|
|
257
|
+
handleClearState, theme, handleButtonClick, conversationStartTime, setConversationStartTime, lastUserMessage, setLastUserMessage,
|
|
258
|
+
ghostMessage, setGhostMessage, ghostCard, setGhostCard, stopActivated, setStopActivated, disclaimer, setDisclaimer,
|
|
259
|
+
startStreaming, setStartStreaming, maintenance, setMaintenance, feedback, setFeedback, handleFeedback, feedbackOpen, setFeedbackOpen,
|
|
260
|
+
writeFeedback, setWriteFeedback, writeAnswer, setWriteAnswer, BASE_URL, lastMessageId, setLastMessageId,
|
|
261
|
+
onProductCardClick, onAddToCartClick, data, sessionId, setSessionId, handleWrittenFeedback, switchFeedbackOpen, confirmDisclaimer,
|
|
262
|
+
formatChatHistory, uiConfig
|
|
80
263
|
}}
|
|
81
264
|
>
|
|
82
265
|
{children}
|
|
@@ -2,26 +2,70 @@ import React, { useState, useEffect, useRef, useContext } from 'react';
|
|
|
2
2
|
import { AppContext } from "../contexts/AppContext";
|
|
3
3
|
|
|
4
4
|
export function useWebSocketMessage() {
|
|
5
|
-
const { setIsComplete, startStreaming, setMessages, messages, setGhostMessage,
|
|
6
|
-
setTypingIndicator, setStartStreaming, lastUserMessage, stopActivated,
|
|
7
|
-
setGhostCard, BASE_URL, setStopActivated, setLastMessageId } = useContext(AppContext);
|
|
5
|
+
const { setIsComplete, startStreaming, setMessages, messages, setGhostMessage,data,
|
|
6
|
+
setTypingIndicator, setStartStreaming, lastUserMessage, stopActivated,sessionId,
|
|
7
|
+
setGhostCard, BASE_URL, setStopActivated, setLastMessageId, conversationStartTime } = useContext(AppContext);
|
|
8
8
|
|
|
9
|
-
const wsProtocol =
|
|
9
|
+
const wsProtocol = 'wss://'
|
|
10
10
|
const wsUrl = BASE_URL.replace(/^http(s)?:\/\//, '');
|
|
11
11
|
const ENDPOINT = '/send/event';
|
|
12
12
|
|
|
13
13
|
const payload = {
|
|
14
|
-
|
|
14
|
+
"customer_code": data.customer_code,
|
|
15
|
+
"branch_code": "NBPISLA" /* data.branch_code */,
|
|
16
|
+
"branch_full_name": data.branch_full_name,
|
|
17
|
+
"customer_token": data.customer_token,
|
|
18
|
+
active_ship_to_information: {
|
|
19
|
+
shipToId: data.active_ship_to,
|
|
20
|
+
"customerId": 0,
|
|
21
|
+
"customerCode": "HPTA",
|
|
22
|
+
"shipToSequenceId": 1,
|
|
23
|
+
"customerShipToName": "HERITAGE PLUS TEST ACCOUNT",
|
|
24
|
+
"addressLine1": "7440 STATE HIGHWAY 121",
|
|
25
|
+
"addressLine2": "",
|
|
26
|
+
"addressLine3": "",
|
|
27
|
+
"city": "MCKINNEY",
|
|
28
|
+
"state": "TX",
|
|
29
|
+
"zipCode": "750702196",
|
|
30
|
+
"phone": "2144914149",
|
|
31
|
+
"fax": " ",
|
|
32
|
+
"orderAckEmail": "",
|
|
33
|
+
"customerPORequiredInd": "N",
|
|
34
|
+
"termsCode": "NET30",
|
|
35
|
+
"shipVia": "",
|
|
36
|
+
"salesPerson": "AS201585",
|
|
37
|
+
"salesPersonName": "",
|
|
38
|
+
"salesPersonCellPhone": "405-226-5844",
|
|
39
|
+
"salesPersonEmail": "Aaron.Spitz@heritagepsg.com",
|
|
40
|
+
"insideSalesPerson": "",
|
|
41
|
+
"secondarySalesPersonName": "",
|
|
42
|
+
"secondarySalesPersonEmail": null
|
|
43
|
+
},
|
|
44
|
+
branch_details: {
|
|
45
|
+
"active_branch_business_hours": "8:00 AM - 4:30 PM",
|
|
46
|
+
"active_branch_email": "OrdersHarrisburg@bel-aqua.com",
|
|
47
|
+
"active_branch_location": "Elizabethtown,PA",
|
|
48
|
+
"active_branch_name": "BEL-AQUA HARRISBURG",
|
|
49
|
+
"active_branch_phone": "(717)-689-3314",
|
|
50
|
+
"active_brand_name": "BEL-AQUA"
|
|
51
|
+
},
|
|
15
52
|
user_query: lastUserMessage,
|
|
16
|
-
|
|
53
|
+
session_id: String(sessionId),
|
|
54
|
+
conversation_start_time: conversationStartTime,
|
|
55
|
+
customer_name: "Cristin Connerney",
|
|
56
|
+
device: "mobile",
|
|
57
|
+
user_UUID: "cristin.connerney@srsdistribution.com",
|
|
58
|
+
window_location: "mobile"
|
|
17
59
|
};
|
|
18
60
|
|
|
19
61
|
const wsRef = useRef(null);
|
|
20
62
|
|
|
21
63
|
useEffect(() => {
|
|
22
64
|
if (startStreaming) {
|
|
23
|
-
console.log(payload)
|
|
65
|
+
console.log(payload, BASE_URL)
|
|
24
66
|
const socketUrl = `${wsProtocol}${wsUrl}${ENDPOINT}`;
|
|
67
|
+
console.log(socketUrl)
|
|
68
|
+
|
|
25
69
|
const ws = new WebSocket(socketUrl);
|
|
26
70
|
wsRef.current = ws;
|
|
27
71
|
|
|
@@ -32,9 +76,11 @@ export function useWebSocketMessage() {
|
|
|
32
76
|
|
|
33
77
|
ws.onmessage = (event) => {
|
|
34
78
|
const response = JSON.parse(event.data);
|
|
35
|
-
|
|
79
|
+
if (response.type != "chunk") {
|
|
80
|
+
console.log(response)
|
|
81
|
+
}
|
|
36
82
|
switch (response.type) {
|
|
37
|
-
case 'middle_message':
|
|
83
|
+
/* case 'middle_message':
|
|
38
84
|
const middleMessage = {
|
|
39
85
|
type: "middle",
|
|
40
86
|
text: response.message,
|
|
@@ -42,7 +88,7 @@ export function useWebSocketMessage() {
|
|
|
42
88
|
product_cards: "False",
|
|
43
89
|
}
|
|
44
90
|
setMessages([...messages, middleMessage])
|
|
45
|
-
break;
|
|
91
|
+
break; */
|
|
46
92
|
case 'message':
|
|
47
93
|
if (response.product_cards == "False" || response.product_cards == false ) {
|
|
48
94
|
setGhostMessage(false);
|
|
@@ -54,7 +100,7 @@ export function useWebSocketMessage() {
|
|
|
54
100
|
const newMessage = {
|
|
55
101
|
type: "ai",
|
|
56
102
|
message_id: response.message_id || '',
|
|
57
|
-
text:
|
|
103
|
+
text: response.message,
|
|
58
104
|
feedback: "True",
|
|
59
105
|
products: [],
|
|
60
106
|
product_cards: response.product_cards || "False",
|
|
@@ -67,51 +113,94 @@ export function useWebSocketMessage() {
|
|
|
67
113
|
case 'chunk':
|
|
68
114
|
const newContent = response.chunk;
|
|
69
115
|
const newMessageId = response.message_id;
|
|
116
|
+
|
|
70
117
|
setMessages(prevMessages => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
118
|
+
if (prevMessages.length > 0 && prevMessages[prevMessages.length - 1].type === "ai") {
|
|
119
|
+
return prevMessages.map((message, index) =>
|
|
120
|
+
index === prevMessages.length - 1
|
|
121
|
+
? {
|
|
122
|
+
...message,
|
|
123
|
+
text: message.text + newContent,
|
|
124
|
+
message_id: newMessageId || message.message_id,
|
|
125
|
+
feedback: "True"
|
|
126
|
+
}
|
|
127
|
+
: message
|
|
128
|
+
);
|
|
129
|
+
} else {
|
|
79
130
|
return [
|
|
80
|
-
...prevMessages
|
|
81
|
-
|
|
131
|
+
...prevMessages,
|
|
132
|
+
{
|
|
133
|
+
type: "ai",
|
|
134
|
+
text: newContent,
|
|
135
|
+
message_id: newMessageId,
|
|
136
|
+
feedback: "True"
|
|
137
|
+
}
|
|
82
138
|
];
|
|
83
|
-
} else {
|
|
84
|
-
setGhostMessage(false);
|
|
85
|
-
return [...prevMessages, {
|
|
86
|
-
type: "ai",
|
|
87
|
-
text: [newContent],
|
|
88
|
-
message_id: newMessageId,
|
|
89
|
-
feedback: "True"
|
|
90
|
-
}];
|
|
91
139
|
}
|
|
92
140
|
});
|
|
141
|
+
setGhostMessage(false);
|
|
93
142
|
if (newMessageId) {
|
|
94
143
|
setLastMessageId(newMessageId);
|
|
95
144
|
}
|
|
96
|
-
break;
|
|
145
|
+
break;
|
|
97
146
|
case 'product_cards':
|
|
98
147
|
setMessages(prevMessages => {
|
|
99
148
|
const lastMessageIndex = prevMessages.length - 1;
|
|
149
|
+
|
|
100
150
|
if (prevMessages[lastMessageIndex] && prevMessages[lastMessageIndex].type === "ai") {
|
|
151
|
+
const expandedProducts = response.products.map(prod => ({
|
|
152
|
+
part_number: prod.part_number || "",
|
|
153
|
+
inventory_info: prod.inventory_info ? {
|
|
154
|
+
default_uom: prod.inventory_info.default_uom || "",
|
|
155
|
+
is_valid: prod.inventory_info.is_valid || false,
|
|
156
|
+
info_by_uom: prod.inventory_info.info_by_uom
|
|
157
|
+
? Object.keys(prod.inventory_info.info_by_uom).reduce((acc, key) => {
|
|
158
|
+
const value = prod.inventory_info.info_by_uom[key] || {};
|
|
159
|
+
acc[key] = {
|
|
160
|
+
gross_price: value.gross_price ?? 0,
|
|
161
|
+
net_price: value.net_price ?? 0,
|
|
162
|
+
is_on_sale: value.is_on_sale ?? false,
|
|
163
|
+
quantity_available: value.quantity_available ?? 0,
|
|
164
|
+
discounts: value.discounts ?? null,
|
|
165
|
+
};
|
|
166
|
+
return acc;
|
|
167
|
+
}, {})
|
|
168
|
+
: {}
|
|
169
|
+
} : {},
|
|
170
|
+
product_details: prod.product_details ? {
|
|
171
|
+
brand: prod.product_details.brand || "",
|
|
172
|
+
flow: prod.product_details.flow || "",
|
|
173
|
+
heritage_link: prod.product_details.heritage_link || "",
|
|
174
|
+
image_url: prod.product_details.image_url || "",
|
|
175
|
+
is_pump: prod.product_details.is_pump || "",
|
|
176
|
+
manufacturer_id: prod.product_details.manufacturer_id || "",
|
|
177
|
+
mfg_number: prod.product_details.mfg_number || "",
|
|
178
|
+
part_number: prod.product_details.part_number || "",
|
|
179
|
+
product_description: prod.product_details.product_description || "",
|
|
180
|
+
product_name: prod.product_details.product_name || "",
|
|
181
|
+
type: prod.product_details.type || "",
|
|
182
|
+
vertical: prod.product_details.vertical || ""
|
|
183
|
+
} : {}
|
|
184
|
+
}));
|
|
185
|
+
|
|
101
186
|
const updatedLastMessage = {
|
|
102
187
|
...prevMessages[lastMessageIndex],
|
|
103
|
-
products:
|
|
188
|
+
products: expandedProducts,
|
|
104
189
|
product_cards: "True"
|
|
105
190
|
};
|
|
191
|
+
|
|
106
192
|
return [
|
|
107
193
|
...prevMessages.slice(0, lastMessageIndex),
|
|
108
194
|
updatedLastMessage
|
|
109
195
|
];
|
|
110
|
-
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return prevMessages;
|
|
111
199
|
});
|
|
200
|
+
|
|
112
201
|
setGhostMessage(false);
|
|
113
|
-
setTypingIndicator(false)
|
|
114
|
-
setGhostCard(false)
|
|
202
|
+
setTypingIndicator(false);
|
|
203
|
+
setGhostCard(false);
|
|
115
204
|
break;
|
|
116
205
|
case 'product_document':
|
|
117
206
|
setMessages(prevMessages => {
|
|
@@ -133,11 +222,6 @@ export function useWebSocketMessage() {
|
|
|
133
222
|
setGhostCard(false)
|
|
134
223
|
break;
|
|
135
224
|
case 'suggested_questions':
|
|
136
|
-
/* const questions = {
|
|
137
|
-
type: "questions",
|
|
138
|
-
message_id: response.message_id || '',
|
|
139
|
-
suggested_questions: response.suggested_questions || [],
|
|
140
|
-
}; */
|
|
141
225
|
setMessages(prevMessages => {
|
|
142
226
|
const lastMessageIndex = prevMessages.length - 1;
|
|
143
227
|
if (prevMessages[lastMessageIndex] && prevMessages[lastMessageIndex].type === "ai") {
|
|
@@ -152,10 +236,8 @@ export function useWebSocketMessage() {
|
|
|
152
236
|
];
|
|
153
237
|
}
|
|
154
238
|
});
|
|
155
|
-
//setMessages((prevMessages) => [...prevMessages, questions]);
|
|
156
239
|
break;
|
|
157
240
|
case 'setComplete':
|
|
158
|
-
setIsComplete(true);
|
|
159
241
|
setTypingIndicator(false);
|
|
160
242
|
setStartStreaming(false)
|
|
161
243
|
setGhostCard(false)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
3
|
+
|
|
4
|
+
export default function useAsyncStorage(key, defaultValue) {
|
|
5
|
+
const [value, setValue] = useState(defaultValue);
|
|
6
|
+
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
const loadValue = async () => {
|
|
9
|
+
try {
|
|
10
|
+
const storedValue = await AsyncStorage.getItem(key);
|
|
11
|
+
if (storedValue !== null) {
|
|
12
|
+
setValue(JSON.parse(storedValue));
|
|
13
|
+
}
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error(`Error loading data for key "${key}":`, error);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
loadValue();
|
|
20
|
+
}, [key]);
|
|
21
|
+
|
|
22
|
+
const setValueInAsyncStorage = async (newValue) => {
|
|
23
|
+
try {
|
|
24
|
+
const result = typeof newValue === 'function' ? newValue(value) : newValue;
|
|
25
|
+
setValue(result);
|
|
26
|
+
await AsyncStorage.setItem(key, JSON.stringify(result));
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error(`Error saving data for key "${key}":`, error);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return [value, setValueInAsyncStorage];
|
|
33
|
+
}
|
package/src/index.js
CHANGED
|
@@ -3,11 +3,11 @@ import { View, StyleSheet } from 'react-native';
|
|
|
3
3
|
import { AppProvider } from './contexts/AppContext';
|
|
4
4
|
import { Layout } from './layout/layout';
|
|
5
5
|
|
|
6
|
-
export const Chat = ({ data, onProductCardClick, onAddToCartClick }) => {
|
|
6
|
+
export const Chat = ({ data, onProductCardClick, onAddToCartClick, uiConfig }) => {
|
|
7
7
|
return (
|
|
8
|
-
<AppProvider>
|
|
8
|
+
<AppProvider data={data} onProductCardClick={onProductCardClick} onAddToCartClick={onAddToCartClick} uiConfig={uiConfig}>
|
|
9
9
|
<View style={styles.container} pointerEvents='box-none'>
|
|
10
|
-
<Layout
|
|
10
|
+
<Layout/>
|
|
11
11
|
</View>
|
|
12
12
|
</AppProvider>
|
|
13
13
|
);
|
|
@@ -23,4 +23,8 @@ const styles = StyleSheet.create({
|
|
|
23
23
|
bottom: 0,
|
|
24
24
|
zIndex: 1000,
|
|
25
25
|
},
|
|
26
|
+
text: {
|
|
27
|
+
fontFamily: "Helvetica Neue" || "sans-serif",
|
|
28
|
+
fontSize: 16,
|
|
29
|
+
},
|
|
26
30
|
});
|