@robylon/react-native-sdk 2.0.22-staging.1 → 2.0.23-staging.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.
- package/lib/commonjs/Chatbotsdk.js +4 -4
- package/lib/commonjs/Chatbotsdk.js.map +1 -1
- package/lib/commonjs/config.js +1 -1
- package/lib/commonjs/config.js.map +1 -1
- package/lib/commonjs/constants.js +1 -1
- package/lib/commonjs/constants.js.map +1 -1
- package/lib/commonjs/openChatbot.js +2 -1
- package/lib/commonjs/versions/version.staging.js +1 -1
- package/lib/module/Chatbotsdk.js +4 -4
- package/lib/module/Chatbotsdk.js.map +1 -1
- package/lib/module/config.js +1 -1
- package/lib/module/config.js.map +1 -1
- package/lib/module/constants.js +1 -1
- package/lib/module/constants.js.map +1 -1
- package/lib/module/versions/version.staging.js +1 -1
- package/lib/typescript/Chatbotsdk.d.ts +11 -3
- package/lib/typescript/Chatbotsdk.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/versions/version.staging.d.ts +1 -1
- package/package.json +2 -2
- package/src/Chatbotsdk.tsx +582 -511
- package/src/index.tsx +1 -1
- package/src/versions/version.staging.ts +1 -1
package/src/Chatbotsdk.tsx
CHANGED
|
@@ -4,6 +4,8 @@ import React, {
|
|
|
4
4
|
useRef,
|
|
5
5
|
useMemo,
|
|
6
6
|
useCallback,
|
|
7
|
+
useImperativeHandle,
|
|
8
|
+
forwardRef,
|
|
7
9
|
} from "react";
|
|
8
10
|
import {
|
|
9
11
|
View,
|
|
@@ -52,6 +54,18 @@ export interface ChatbotProps {
|
|
|
52
54
|
is_test_user?: boolean;
|
|
53
55
|
};
|
|
54
56
|
onEvent?: ChatbotEventHandler;
|
|
57
|
+
// Controlled component props
|
|
58
|
+
isOpen?: boolean;
|
|
59
|
+
onOpen?: () => void;
|
|
60
|
+
onClose?: () => void;
|
|
61
|
+
onReady?: () => void;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface ChatbotRef {
|
|
65
|
+
open: () => void;
|
|
66
|
+
close: () => void;
|
|
67
|
+
toggle: () => void;
|
|
68
|
+
isReady: () => boolean;
|
|
55
69
|
}
|
|
56
70
|
|
|
57
71
|
interface InternalChatbotProps extends ChatbotProps {
|
|
@@ -59,8 +73,6 @@ interface InternalChatbotProps extends ChatbotProps {
|
|
|
59
73
|
onMessage?: (message: any) => void;
|
|
60
74
|
isFullScreen?: boolean;
|
|
61
75
|
enableAnimation?: boolean;
|
|
62
|
-
onOpen?: () => void;
|
|
63
|
-
onClose?: () => void;
|
|
64
76
|
}
|
|
65
77
|
|
|
66
78
|
interface ChatbotMessage {
|
|
@@ -114,537 +126,593 @@ export interface ChatbotConfig {
|
|
|
114
126
|
};
|
|
115
127
|
}
|
|
116
128
|
|
|
117
|
-
const Chatbot
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
129
|
+
const Chatbot = forwardRef<ChatbotRef, InternalChatbotProps>(
|
|
130
|
+
(
|
|
131
|
+
{
|
|
132
|
+
api_key,
|
|
133
|
+
user_id,
|
|
134
|
+
user_token,
|
|
135
|
+
show_floating_button = true,
|
|
136
|
+
onEvent,
|
|
137
|
+
onMessage,
|
|
138
|
+
isFullScreen = true,
|
|
139
|
+
enableAnimation = true,
|
|
140
|
+
isOpen: externalIsOpen,
|
|
141
|
+
onOpen: externalOnOpen,
|
|
142
|
+
onClose: externalOnClose,
|
|
143
|
+
onReady,
|
|
144
|
+
user_profile,
|
|
145
|
+
},
|
|
146
|
+
ref
|
|
147
|
+
) => {
|
|
148
|
+
const [isWebViewVisible, setIsWebViewVisible] = useState(false);
|
|
149
|
+
const [chatbotConfig, setChatbotConfig] = useState<ChatbotConfig | null>(
|
|
150
|
+
null
|
|
151
|
+
);
|
|
152
|
+
const [loading, setLoading] = useState(true);
|
|
153
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
154
|
+
const webViewRef = useRef<WebView>(null);
|
|
155
|
+
const isFirstLoadRef = useRef(true);
|
|
156
|
+
const [toastVisible, setToastVisible] = useState(false);
|
|
157
|
+
const [toastMessage, setToastMessage] = useState("");
|
|
158
|
+
const [effectiveUserId, setEffectiveUserId] = useState<string>();
|
|
159
|
+
const [isStorageReady, setIsStorageReady] = useState(false);
|
|
160
|
+
const pendingStorageOps = useRef<Array<() => void>>([]);
|
|
161
|
+
const memoryCache = useRef<Record<string, string>>({});
|
|
162
|
+
const [systemInfo, setSystemInfo] = useState({ os: "", browser: "" });
|
|
163
|
+
|
|
164
|
+
// Initialize animated values
|
|
165
|
+
const animatedValues = useRef({
|
|
166
|
+
scale: new Animated.Value(1),
|
|
167
|
+
translateY: new Animated.Value(0),
|
|
168
|
+
opacity: new Animated.Value(1),
|
|
169
|
+
}).current;
|
|
170
|
+
|
|
171
|
+
// Create chatbotConfig object for events
|
|
172
|
+
const chatbotConfigForEvents = useMemo(
|
|
173
|
+
() => ({
|
|
174
|
+
userId: effectiveUserId,
|
|
175
|
+
isAnonymous: !user_id && user_id !== 0,
|
|
176
|
+
// Add other config properties as needed
|
|
177
|
+
}),
|
|
178
|
+
[effectiveUserId, user_id]
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
// Initialize event handling
|
|
182
|
+
const { emitEvent, onInternalEvent } = useChatbotEvents({
|
|
183
|
+
api_key,
|
|
184
|
+
chatbotConfig: chatbotConfigForEvents ?? {},
|
|
185
|
+
user_profile: user_profile,
|
|
186
|
+
onEvent: onEvent,
|
|
187
|
+
systemInfo: systemInfo ?? { os: "", browser: "" },
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Expose ref methods
|
|
191
|
+
useImperativeHandle(
|
|
192
|
+
ref,
|
|
193
|
+
() => ({
|
|
194
|
+
open: () => {
|
|
195
|
+
if (isInitialized) {
|
|
196
|
+
openWebView();
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
close: () => {
|
|
200
|
+
if (isInitialized) {
|
|
201
|
+
closeWebView();
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
toggle: () => {
|
|
205
|
+
if (isInitialized) {
|
|
206
|
+
if (isWebViewVisible) {
|
|
207
|
+
closeWebView();
|
|
208
|
+
} else {
|
|
209
|
+
openWebView();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
isReady: () => isInitialized,
|
|
214
|
+
}),
|
|
215
|
+
[isInitialized, isWebViewVisible]
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
const triggerAppInit = () => {
|
|
219
|
+
if (webViewRef.current) {
|
|
220
|
+
webViewRef.current.injectJavaScript(`
|
|
174
221
|
// Trigger APP_READY equivalent
|
|
175
222
|
window.ReactNativeWebView.postMessage(JSON.stringify({ type: 'APP_READY' }));
|
|
176
223
|
true;
|
|
177
224
|
`);
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
const executeStorageOp = useCallback(
|
|
182
|
-
(operation: () => void) => {
|
|
183
|
-
if (isStorageReady) {
|
|
184
|
-
operation();
|
|
185
|
-
} else {
|
|
186
|
-
pendingStorageOps.current.push(operation);
|
|
187
225
|
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
try {
|
|
198
|
-
const parsedData: ChatbotMessage = JSON.parse(data);
|
|
199
|
-
|
|
200
|
-
// Handle storage messages
|
|
201
|
-
if (
|
|
202
|
-
Object.values(StorageMessageType).includes(
|
|
203
|
-
parsedData.type as StorageMessageType
|
|
204
|
-
)
|
|
205
|
-
) {
|
|
206
|
-
const storageMessage = parsedData as StorageMessage;
|
|
207
|
-
switch (storageMessage.type) {
|
|
208
|
-
case StorageMessageType.STORAGE_READY:
|
|
209
|
-
setIsStorageReady(true);
|
|
210
|
-
pendingStorageOps.current.forEach((op) => op());
|
|
211
|
-
pendingStorageOps.current = [];
|
|
212
|
-
// Try to get stored ID immediately after storage is ready
|
|
213
|
-
webViewRef.current?.injectJavaScript(
|
|
214
|
-
createStorageMessage(
|
|
215
|
-
StorageMessageType.GET_STORAGE,
|
|
216
|
-
"rblyn_anon"
|
|
217
|
-
)
|
|
218
|
-
);
|
|
219
|
-
break;
|
|
220
|
-
case StorageMessageType.STORAGE_RESPONSE:
|
|
221
|
-
if (storageMessage.key && storageMessage.value) {
|
|
222
|
-
memoryCache.current[storageMessage.key] = storageMessage.value;
|
|
223
|
-
if (storageMessage.key === "rblyn_anon") {
|
|
224
|
-
setEffectiveUserId(storageMessage.value);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
break;
|
|
228
|
-
case StorageMessageType.STORAGE_ERROR:
|
|
229
|
-
logger.error("WebView storage error:", storageMessage.error);
|
|
230
|
-
break;
|
|
231
|
-
}
|
|
232
|
-
return;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const executeStorageOp = useCallback(
|
|
229
|
+
(operation: () => void) => {
|
|
230
|
+
if (isStorageReady) {
|
|
231
|
+
operation();
|
|
232
|
+
} else {
|
|
233
|
+
pendingStorageOps.current.push(operation);
|
|
233
234
|
}
|
|
235
|
+
},
|
|
236
|
+
[isStorageReady]
|
|
237
|
+
);
|
|
234
238
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
+
// Handle WebView messages
|
|
240
|
+
const handleMessage = useCallback(
|
|
241
|
+
(event: WebViewMessageEvent) => {
|
|
242
|
+
const { data } = event.nativeEvent;
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
const parsedData: ChatbotMessage = JSON.parse(data);
|
|
246
|
+
|
|
247
|
+
// Handle storage messages
|
|
248
|
+
if (
|
|
249
|
+
Object.values(StorageMessageType).includes(
|
|
250
|
+
parsedData.type as StorageMessageType
|
|
251
|
+
)
|
|
252
|
+
) {
|
|
253
|
+
const storageMessage = parsedData as StorageMessage;
|
|
254
|
+
switch (storageMessage.type) {
|
|
255
|
+
case StorageMessageType.STORAGE_READY:
|
|
256
|
+
setIsStorageReady(true);
|
|
257
|
+
pendingStorageOps.current.forEach((op) => op());
|
|
258
|
+
pendingStorageOps.current = [];
|
|
259
|
+
// Try to get stored ID immediately after storage is ready
|
|
260
|
+
webViewRef.current?.injectJavaScript(
|
|
261
|
+
createStorageMessage(
|
|
262
|
+
StorageMessageType.GET_STORAGE,
|
|
263
|
+
"rblyn_anon"
|
|
264
|
+
)
|
|
265
|
+
);
|
|
266
|
+
break;
|
|
267
|
+
case StorageMessageType.STORAGE_RESPONSE:
|
|
268
|
+
if (storageMessage.key && storageMessage.value) {
|
|
269
|
+
memoryCache.current[storageMessage.key] =
|
|
270
|
+
storageMessage.value;
|
|
271
|
+
if (storageMessage.key === "rblyn_anon") {
|
|
272
|
+
setEffectiveUserId(storageMessage.value);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
break;
|
|
276
|
+
case StorageMessageType.STORAGE_ERROR:
|
|
277
|
+
logger.error("WebView storage error:", storageMessage.error);
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
239
280
|
return;
|
|
240
281
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
282
|
+
|
|
283
|
+
// Add debug logging
|
|
284
|
+
if (__DEV__) {
|
|
285
|
+
if (parsedData?.type === "CONSOLE") {
|
|
286
|
+
console.log(`WebView ${parsedData?.level}:`, parsedData?.data);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (parsedData?.type === "ERROR") {
|
|
290
|
+
console.error("WebView Error:", parsedData?.data);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
244
293
|
}
|
|
245
|
-
}
|
|
246
294
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
295
|
+
if (parsedData?.type === "SYSTEM_INFO") {
|
|
296
|
+
setSystemInfo(parsedData?.data ?? { os: "", browser: "" });
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
251
299
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
300
|
+
if (parsedData?.type === "APP_READY") {
|
|
301
|
+
emitEvent(ChatbotEventType.CHATBOT_APP_READY);
|
|
302
|
+
if (webViewRef.current && isWebViewVisible) {
|
|
303
|
+
webViewRef.current?.injectJavaScript(getBrowserAndOSInfoScript());
|
|
304
|
+
|
|
305
|
+
const messageData = {
|
|
306
|
+
name: "registerUserId",
|
|
307
|
+
action: "registerUserId",
|
|
308
|
+
data: {
|
|
309
|
+
userId: effectiveUserId,
|
|
310
|
+
token: user_token ? `${user_token}` : undefined,
|
|
311
|
+
userProfile: {
|
|
312
|
+
...user_profile,
|
|
313
|
+
...getSystemInfo(systemInfo),
|
|
314
|
+
},
|
|
265
315
|
},
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
webViewRef.current?.injectJavaScript(`
|
|
316
|
+
};
|
|
317
|
+
logger.debug("messageData====>", JSON.stringify(messageData));
|
|
318
|
+
webViewRef.current?.injectJavaScript(`
|
|
270
319
|
window.postMessage(${JSON.stringify({
|
|
271
320
|
name: "openFrame",
|
|
272
321
|
domain: "app-domain.com",
|
|
273
322
|
})}, '*');
|
|
274
323
|
window.postMessage(${JSON.stringify(messageData)}, '*');
|
|
275
324
|
`);
|
|
325
|
+
}
|
|
276
326
|
}
|
|
277
|
-
}
|
|
278
327
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
328
|
+
// Handle other message types
|
|
329
|
+
switch (parsedData?.type) {
|
|
330
|
+
case "close_chatbot":
|
|
331
|
+
closeWebView();
|
|
332
|
+
break;
|
|
333
|
+
case "CHATBOT_LOADED":
|
|
334
|
+
emitEvent(ChatbotEventType.CHATBOT_LOADED, parsedData?.data);
|
|
335
|
+
break;
|
|
336
|
+
case "CHAT_INITIALIZED":
|
|
337
|
+
emitEvent(ChatbotEventType.CHAT_INITIALIZED, parsedData?.data);
|
|
338
|
+
break;
|
|
339
|
+
case "SESSION_REFRESHED":
|
|
340
|
+
emitEvent(ChatbotEventType.SESSION_REFRESHED, parsedData?.data);
|
|
341
|
+
break;
|
|
342
|
+
case "CHAT_INITIALIZATION_FAILED":
|
|
343
|
+
emitEvent(
|
|
344
|
+
ChatbotEventType.CHAT_INITIALIZATION_FAILED,
|
|
345
|
+
parsedData?.data
|
|
346
|
+
);
|
|
347
|
+
break;
|
|
348
|
+
default:
|
|
349
|
+
if (onMessage) onMessage(parsedData ?? {});
|
|
350
|
+
}
|
|
351
|
+
} catch (error) {
|
|
352
|
+
errorTracker.trackError(
|
|
353
|
+
error instanceof Error
|
|
354
|
+
? error
|
|
355
|
+
: new Error("Failed to parse WebView message"),
|
|
356
|
+
"ChatbotSDK",
|
|
357
|
+
{
|
|
358
|
+
type: ErrorTypes.RUNTIME_ERROR,
|
|
359
|
+
context: { messageData: data },
|
|
360
|
+
}
|
|
361
|
+
);
|
|
301
362
|
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
363
|
+
},
|
|
364
|
+
[
|
|
365
|
+
emitEvent,
|
|
366
|
+
isWebViewVisible,
|
|
367
|
+
onMessage,
|
|
368
|
+
systemInfo,
|
|
369
|
+
effectiveUserId,
|
|
370
|
+
user_token,
|
|
371
|
+
user_profile,
|
|
372
|
+
]
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
// Initialize user ID
|
|
376
|
+
useEffect(() => {
|
|
377
|
+
const initializeUserId = async () => {
|
|
378
|
+
let userId = user_id ? String(user_id) : undefined;
|
|
379
|
+
|
|
380
|
+
if (!userId) {
|
|
381
|
+
// Try memory cache first
|
|
382
|
+
userId = memoryCache.current["rblyn_anon"];
|
|
383
|
+
|
|
384
|
+
if (!userId) {
|
|
385
|
+
userId = generateUUID();
|
|
386
|
+
executeStorageOp(() => {
|
|
387
|
+
webViewRef.current?.injectJavaScript(
|
|
388
|
+
createStorageMessage(
|
|
389
|
+
StorageMessageType.SET_STORAGE,
|
|
390
|
+
"rblyn_anon",
|
|
391
|
+
userId!
|
|
392
|
+
)
|
|
393
|
+
);
|
|
394
|
+
});
|
|
311
395
|
}
|
|
312
|
-
|
|
313
|
-
}
|
|
314
|
-
},
|
|
315
|
-
[
|
|
316
|
-
emitEvent,
|
|
317
|
-
isWebViewVisible,
|
|
318
|
-
onMessage,
|
|
319
|
-
systemInfo,
|
|
320
|
-
effectiveUserId,
|
|
321
|
-
user_token,
|
|
322
|
-
user_profile,
|
|
323
|
-
]
|
|
324
|
-
);
|
|
396
|
+
}
|
|
325
397
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
const initializeUserId = async () => {
|
|
329
|
-
let userId = user_id ? String(user_id) : undefined;
|
|
398
|
+
setEffectiveUserId(userId);
|
|
399
|
+
};
|
|
330
400
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
userId = memoryCache.current["rblyn_anon"];
|
|
401
|
+
initializeUserId();
|
|
402
|
+
}, [user_id, executeStorageOp]);
|
|
334
403
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
userId!
|
|
343
|
-
)
|
|
344
|
-
);
|
|
345
|
-
});
|
|
404
|
+
// Handle external isOpen prop changes
|
|
405
|
+
useEffect(() => {
|
|
406
|
+
if (externalIsOpen !== undefined && isInitialized) {
|
|
407
|
+
if (externalIsOpen && !isWebViewVisible) {
|
|
408
|
+
openWebView();
|
|
409
|
+
} else if (!externalIsOpen && isWebViewVisible) {
|
|
410
|
+
closeWebView();
|
|
346
411
|
}
|
|
347
412
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
// Try to get stored ID once storage is ready
|
|
360
|
-
executeStorageOp(() => {
|
|
361
|
-
webViewRef.current?.injectJavaScript(
|
|
362
|
-
createStorageMessage(StorageMessageType.GET_STORAGE, "rblyn_anon")
|
|
363
|
-
);
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
}, []);
|
|
367
|
-
|
|
368
|
-
useEffect(() => {
|
|
369
|
-
const fetchChatbotConfig = async () => {
|
|
370
|
-
try {
|
|
371
|
-
const endpointUrl = `${API_URL}/chat/chatbot/get/`;
|
|
372
|
-
const payload = {
|
|
373
|
-
client_user_id: effectiveUserId,
|
|
374
|
-
org_id: api_key,
|
|
375
|
-
token: user_token,
|
|
376
|
-
extra_info: {},
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
// setToastMessage(endpointUrl + " : " + BASE_CHATBOT_URL);
|
|
380
|
-
// setToastVisible(true);
|
|
381
|
-
|
|
382
|
-
const response = await fetch(endpointUrl, {
|
|
383
|
-
method: "POST",
|
|
384
|
-
headers: {
|
|
385
|
-
"Content-Type": "application/json",
|
|
386
|
-
},
|
|
387
|
-
body: JSON.stringify(payload),
|
|
413
|
+
}, [externalIsOpen, isInitialized, isWebViewVisible]);
|
|
414
|
+
|
|
415
|
+
// Initialize WebView storage
|
|
416
|
+
useEffect(() => {
|
|
417
|
+
if (webViewRef.current) {
|
|
418
|
+
webViewRef.current.injectJavaScript(getStorageScript());
|
|
419
|
+
// Try to get stored ID once storage is ready
|
|
420
|
+
executeStorageOp(() => {
|
|
421
|
+
webViewRef.current?.injectJavaScript(
|
|
422
|
+
createStorageMessage(StorageMessageType.GET_STORAGE, "rblyn_anon")
|
|
423
|
+
);
|
|
388
424
|
});
|
|
425
|
+
}
|
|
426
|
+
}, []);
|
|
389
427
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
428
|
+
useEffect(() => {
|
|
429
|
+
const fetchChatbotConfig = async () => {
|
|
430
|
+
try {
|
|
431
|
+
const endpointUrl = `${API_URL}/chat/chatbot/get/`;
|
|
432
|
+
const payload = {
|
|
433
|
+
client_user_id: effectiveUserId,
|
|
434
|
+
org_id: api_key,
|
|
435
|
+
token: user_token,
|
|
436
|
+
extra_info: {},
|
|
437
|
+
};
|
|
393
438
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
chat_interface_config: {
|
|
402
|
-
chat_bubble_prompts: [],
|
|
403
|
-
display_name: orgInfo.brand_config?.display_name || "",
|
|
404
|
-
welcome_message:
|
|
405
|
-
orgInfo.brand_config?.welcome_message ||
|
|
406
|
-
"Hey! What can we help you with today?",
|
|
407
|
-
redirect_url: orgInfo.brand_config?.redirect_url || "",
|
|
408
|
-
},
|
|
409
|
-
interface_properties: {
|
|
410
|
-
position:
|
|
411
|
-
orgInfo.brand_config?.interface_properties?.position ||
|
|
412
|
-
WidgetPositionEnums.RIGHT,
|
|
413
|
-
side_spacing:
|
|
414
|
-
orgInfo.brand_config?.interface_properties?.side_spacing ?? 20,
|
|
415
|
-
bottom_spacing:
|
|
416
|
-
orgInfo.brand_config?.interface_properties?.bottom_spacing ??
|
|
417
|
-
20,
|
|
418
|
-
},
|
|
419
|
-
interface_type:
|
|
420
|
-
orgInfo.brand_config?.interface_type ||
|
|
421
|
-
ChatbotInterfaceType.WIDGET,
|
|
422
|
-
launcher_type:
|
|
423
|
-
orgInfo.brand_config?.launcher_type || LauncherType.IMAGE,
|
|
424
|
-
launcher_properties: {
|
|
425
|
-
text: orgInfo.brand_config?.launcher_properties?.text || "",
|
|
426
|
-
},
|
|
427
|
-
images: {
|
|
428
|
-
launcher_image_url: {
|
|
429
|
-
url:
|
|
430
|
-
orgInfo.brand_config?.images?.launcher_image_url?.url || "",
|
|
431
|
-
},
|
|
439
|
+
// setToastMessage(endpointUrl + " : " + BASE_CHATBOT_URL);
|
|
440
|
+
// setToastVisible(true);
|
|
441
|
+
|
|
442
|
+
const response = await fetch(endpointUrl, {
|
|
443
|
+
method: "POST",
|
|
444
|
+
headers: {
|
|
445
|
+
"Content-Type": "application/json",
|
|
432
446
|
},
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
error instanceof Error
|
|
439
|
-
? error
|
|
440
|
-
: new Error("Failed to fetch chatbot configuration"),
|
|
441
|
-
"ChatbotSDK",
|
|
442
|
-
{
|
|
443
|
-
type: ErrorTypes.NETWORK_ERROR,
|
|
444
|
-
context: { api_key, user_id },
|
|
447
|
+
body: JSON.stringify(payload),
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
if (!response.ok) {
|
|
451
|
+
throw new Error("Failed to fetch chatbot configuration");
|
|
445
452
|
}
|
|
446
|
-
);
|
|
447
|
-
} finally {
|
|
448
|
-
setLoading(false);
|
|
449
|
-
}
|
|
450
|
-
};
|
|
451
453
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
454
|
+
const data = await response.json();
|
|
455
|
+
const orgInfo = data?.user?.org_info;
|
|
456
|
+
|
|
457
|
+
if (orgInfo) {
|
|
458
|
+
const config: ChatbotConfig = {
|
|
459
|
+
brand_colour: orgInfo.brand_config?.colors?.brand_color || "",
|
|
460
|
+
image_url: orgInfo.brand_config?.launcher_logo_url || "",
|
|
461
|
+
chat_interface_config: {
|
|
462
|
+
chat_bubble_prompts: [],
|
|
463
|
+
display_name: orgInfo.brand_config?.display_name || "",
|
|
464
|
+
welcome_message:
|
|
465
|
+
orgInfo.brand_config?.welcome_message ||
|
|
466
|
+
"Hey! What can we help you with today?",
|
|
467
|
+
redirect_url: orgInfo.brand_config?.redirect_url || "",
|
|
468
|
+
},
|
|
469
|
+
interface_properties: {
|
|
470
|
+
position:
|
|
471
|
+
orgInfo.brand_config?.interface_properties?.position ||
|
|
472
|
+
WidgetPositionEnums.RIGHT,
|
|
473
|
+
side_spacing:
|
|
474
|
+
orgInfo.brand_config?.interface_properties?.side_spacing ??
|
|
475
|
+
20,
|
|
476
|
+
bottom_spacing:
|
|
477
|
+
orgInfo.brand_config?.interface_properties?.bottom_spacing ??
|
|
478
|
+
20,
|
|
479
|
+
},
|
|
480
|
+
interface_type:
|
|
481
|
+
orgInfo.brand_config?.interface_type ||
|
|
482
|
+
ChatbotInterfaceType.WIDGET,
|
|
483
|
+
launcher_type:
|
|
484
|
+
orgInfo.brand_config?.launcher_type || LauncherType.IMAGE,
|
|
485
|
+
launcher_properties: {
|
|
486
|
+
text: orgInfo.brand_config?.launcher_properties?.text || "",
|
|
487
|
+
},
|
|
488
|
+
images: {
|
|
489
|
+
launcher_image_url: {
|
|
490
|
+
url:
|
|
491
|
+
orgInfo.brand_config?.images?.launcher_image_url?.url || "",
|
|
492
|
+
},
|
|
493
|
+
},
|
|
494
|
+
};
|
|
495
|
+
setChatbotConfig(config);
|
|
496
|
+
}
|
|
497
|
+
} catch (error) {
|
|
498
|
+
errorTracker.trackError(
|
|
499
|
+
error instanceof Error
|
|
500
|
+
? error
|
|
501
|
+
: new Error("Failed to fetch chatbot configuration"),
|
|
502
|
+
"ChatbotSDK",
|
|
503
|
+
{
|
|
504
|
+
type: ErrorTypes.NETWORK_ERROR,
|
|
505
|
+
context: { api_key, user_id },
|
|
506
|
+
}
|
|
507
|
+
);
|
|
508
|
+
} finally {
|
|
509
|
+
setLoading(false);
|
|
510
|
+
}
|
|
511
|
+
};
|
|
456
512
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
});
|
|
462
|
-
console.log("BASE_CHATBOT_URL SDK_VERSION", BASE_CHATBOT_URL);
|
|
463
|
-
return `${BASE_CHATBOT_URL}?${params.toString()}`;
|
|
464
|
-
}
|
|
513
|
+
if (api_key && effectiveUserId) {
|
|
514
|
+
fetchChatbotConfig();
|
|
515
|
+
}
|
|
516
|
+
}, [api_key, effectiveUserId, user_token]);
|
|
465
517
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
animateWebViewOpen(animatedValues, () => {
|
|
471
|
-
onOpen?.();
|
|
472
|
-
emitEvent(ChatbotEventType.CHATBOT_OPENED);
|
|
473
|
-
if (!isFirstLoadRef.current) {
|
|
474
|
-
setTimeout(triggerAppInit, 100);
|
|
475
|
-
}
|
|
476
|
-
});
|
|
477
|
-
} else {
|
|
478
|
-
requestAnimationFrame(() => {
|
|
479
|
-
onOpen?.();
|
|
480
|
-
emitEvent(ChatbotEventType.CHATBOT_OPENED);
|
|
481
|
-
if (!isFirstLoadRef.current) {
|
|
482
|
-
setTimeout(triggerAppInit, 100);
|
|
483
|
-
}
|
|
518
|
+
function constructUrl(): string {
|
|
519
|
+
if (!effectiveUserId) return "";
|
|
520
|
+
const params = new URLSearchParams({
|
|
521
|
+
id: api_key,
|
|
484
522
|
});
|
|
523
|
+
console.log("BASE_CHATBOT_URL SDK_VERSION", BASE_CHATBOT_URL);
|
|
524
|
+
return `${BASE_CHATBOT_URL}?${params.toString()}`;
|
|
485
525
|
}
|
|
486
|
-
}, [enableAnimation, animatedValues, onOpen, emitEvent]);
|
|
487
|
-
|
|
488
|
-
// NOt Needed
|
|
489
|
-
// Handle closing the chatbot
|
|
490
|
-
const closeWebView = useCallback(() => {
|
|
491
|
-
if (webViewRef.current) {
|
|
492
|
-
webViewRef.current.postMessage(
|
|
493
|
-
JSON.stringify({
|
|
494
|
-
name: "closeFrame",
|
|
495
|
-
domain: "app-domain.com",
|
|
496
|
-
})
|
|
497
|
-
);
|
|
498
|
-
}
|
|
499
526
|
|
|
500
|
-
|
|
501
|
-
|
|
527
|
+
// Handle opening the chatbot
|
|
528
|
+
const openWebView = useCallback(() => {
|
|
529
|
+
setIsWebViewVisible(true);
|
|
530
|
+
if (enableAnimation) {
|
|
531
|
+
animateWebViewOpen(animatedValues, () => {
|
|
532
|
+
externalOnOpen?.();
|
|
533
|
+
emitEvent(ChatbotEventType.CHATBOT_OPENED);
|
|
534
|
+
if (!isFirstLoadRef.current) {
|
|
535
|
+
setTimeout(triggerAppInit, 100);
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
} else {
|
|
539
|
+
requestAnimationFrame(() => {
|
|
540
|
+
externalOnOpen?.();
|
|
541
|
+
emitEvent(ChatbotEventType.CHATBOT_OPENED);
|
|
542
|
+
if (!isFirstLoadRef.current) {
|
|
543
|
+
setTimeout(triggerAppInit, 100);
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
}, [enableAnimation, animatedValues, externalOnOpen, emitEvent]);
|
|
548
|
+
|
|
549
|
+
// Handle closing the chatbot
|
|
550
|
+
const closeWebView = useCallback(() => {
|
|
551
|
+
if (webViewRef.current) {
|
|
552
|
+
webViewRef.current.postMessage(
|
|
553
|
+
JSON.stringify({
|
|
554
|
+
name: "closeFrame",
|
|
555
|
+
domain: "app-domain.com",
|
|
556
|
+
})
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (enableAnimation) {
|
|
561
|
+
animateWebViewClose(animatedValues, () => {
|
|
562
|
+
setIsWebViewVisible(false);
|
|
563
|
+
externalOnClose?.();
|
|
564
|
+
emitEvent(ChatbotEventType.CHATBOT_CLOSED);
|
|
565
|
+
});
|
|
566
|
+
} else {
|
|
502
567
|
setIsWebViewVisible(false);
|
|
503
|
-
|
|
568
|
+
externalOnClose?.();
|
|
504
569
|
emitEvent(ChatbotEventType.CHATBOT_CLOSED);
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
setIsWebViewVisible(false);
|
|
508
|
-
onClose?.();
|
|
509
|
-
emitEvent(ChatbotEventType.CHATBOT_CLOSED);
|
|
510
|
-
}
|
|
511
|
-
}, [enableAnimation, animatedValues, onClose, emitEvent]);
|
|
512
|
-
|
|
513
|
-
// Emit button loaded event when component mounts
|
|
514
|
-
useEffect(() => {
|
|
515
|
-
if (show_floating_button && chatbotConfig) {
|
|
516
|
-
emitEvent(ChatbotEventType.CHATBOT_BUTTON_LOADED);
|
|
517
|
-
}
|
|
518
|
-
}, [show_floating_button, chatbotConfig, emitEvent]);
|
|
570
|
+
}
|
|
571
|
+
}, [enableAnimation, animatedValues, externalOnClose, emitEvent]);
|
|
519
572
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
573
|
+
// Emit button loaded event when component mounts
|
|
574
|
+
useEffect(() => {
|
|
575
|
+
if (show_floating_button && chatbotConfig) {
|
|
576
|
+
emitEvent(ChatbotEventType.CHATBOT_BUTTON_LOADED);
|
|
577
|
+
}
|
|
578
|
+
}, [show_floating_button, chatbotConfig, emitEvent]);
|
|
525
579
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
580
|
+
// Set initialization state when chatbot is ready
|
|
581
|
+
useEffect(() => {
|
|
582
|
+
if (!loading && chatbotConfig && effectiveUserId && !isInitialized) {
|
|
583
|
+
setIsInitialized(true);
|
|
584
|
+
onReady?.();
|
|
585
|
+
}
|
|
586
|
+
}, [loading, chatbotConfig, effectiveUserId, isInitialized, onReady]);
|
|
587
|
+
|
|
588
|
+
const getScreenDimensions = () => {
|
|
589
|
+
const windowHeight = Dimensions.get("window").height;
|
|
590
|
+
const windowWidth = Dimensions.get("window").width;
|
|
591
|
+
const statusBarHeight =
|
|
592
|
+
Platform.OS === "ios" ? 0 : StatusBar.currentHeight || 0;
|
|
593
|
+
|
|
594
|
+
return {
|
|
595
|
+
height: windowHeight - statusBarHeight,
|
|
596
|
+
width: windowWidth,
|
|
597
|
+
};
|
|
529
598
|
};
|
|
530
|
-
};
|
|
531
599
|
|
|
532
|
-
|
|
600
|
+
const screenDimensions = getScreenDimensions();
|
|
533
601
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
style={[
|
|
597
|
-
styles.webViewWrapper,
|
|
598
|
-
{ height: isWebViewVisible ? "100%" : 0 },
|
|
599
|
-
]}
|
|
600
|
-
pointerEvents={isWebViewVisible ? "auto" : "none"}
|
|
601
|
-
>
|
|
602
|
-
<Animated.View
|
|
602
|
+
useEffect(() => {
|
|
603
|
+
if (__DEV__) {
|
|
604
|
+
enableNetworkDebug();
|
|
605
|
+
}
|
|
606
|
+
}, []);
|
|
607
|
+
|
|
608
|
+
// Deliberate error for testing error boundary
|
|
609
|
+
// useEffect(() => {
|
|
610
|
+
// if (__DEV__) {
|
|
611
|
+
// // Set up global error handlers
|
|
612
|
+
// setupGlobalErrorHandlers();
|
|
613
|
+
|
|
614
|
+
// // Test async error
|
|
615
|
+
// setTimeout(() => {
|
|
616
|
+
// Promise.reject(new Error("Test async error"));
|
|
617
|
+
// }, 1000);
|
|
618
|
+
|
|
619
|
+
// // Test sync error
|
|
620
|
+
// setTimeout(() => {
|
|
621
|
+
// throw new Error("Test sync error");
|
|
622
|
+
// }, 2000);
|
|
623
|
+
// }
|
|
624
|
+
// }, []);
|
|
625
|
+
|
|
626
|
+
const position = chatbotConfig?.interface_properties?.position || "Right";
|
|
627
|
+
const sideSpacing = chatbotConfig?.interface_properties?.side_spacing ?? 20;
|
|
628
|
+
const bottomSpacing =
|
|
629
|
+
chatbotConfig?.interface_properties?.bottom_spacing ?? 20;
|
|
630
|
+
|
|
631
|
+
// const mainContainerStyle = useMemo(() => {
|
|
632
|
+
// return {
|
|
633
|
+
// ...styles.mainContainer,
|
|
634
|
+
// [position.toLowerCase()]: `${sideSpacing ?? 20}px`,
|
|
635
|
+
// alignItems:
|
|
636
|
+
// position === "Right" ? "flex-end" : ("flex-start" as FlexAlignType),
|
|
637
|
+
// // Explicitly clear mobile-specific styles
|
|
638
|
+
// top: undefined,
|
|
639
|
+
// [position === "Right" ? "left" : "right"]: undefined,
|
|
640
|
+
// backgroundColor: "green",
|
|
641
|
+
// };
|
|
642
|
+
// }, [position, sideSpacing, styles.mainContainer]);
|
|
643
|
+
|
|
644
|
+
return (
|
|
645
|
+
<ErrorBoundary componentName="ChatbotSDK">
|
|
646
|
+
<View style={styles?.mainContainer}>
|
|
647
|
+
{!loading && (
|
|
648
|
+
<>
|
|
649
|
+
<ErrorBoundary componentName="FloatingButton">
|
|
650
|
+
{show_floating_button && api_key && chatbotConfig && (
|
|
651
|
+
<FloatingButton
|
|
652
|
+
chatbotConfig={chatbotConfig}
|
|
653
|
+
isWebViewVisible={isWebViewVisible}
|
|
654
|
+
onPress={() => {
|
|
655
|
+
emitEvent(ChatbotEventType.CHATBOT_BUTTON_CLICKED);
|
|
656
|
+
openWebView();
|
|
657
|
+
}}
|
|
658
|
+
brandColor={chatbotConfig.brand_colour}
|
|
659
|
+
imageUrl={chatbotConfig.image_url}
|
|
660
|
+
/>
|
|
661
|
+
)}
|
|
662
|
+
</ErrorBoundary>
|
|
663
|
+
<View
|
|
603
664
|
style={[
|
|
604
|
-
styles.
|
|
605
|
-
{
|
|
606
|
-
opacity: animatedValues.opacity,
|
|
607
|
-
transform: [
|
|
608
|
-
{ scale: animatedValues.scale },
|
|
609
|
-
{ translateY: animatedValues.translateY },
|
|
610
|
-
],
|
|
611
|
-
},
|
|
665
|
+
styles.webViewWrapper,
|
|
666
|
+
{ height: isWebViewVisible ? "100%" : 0 },
|
|
612
667
|
]}
|
|
668
|
+
pointerEvents={isWebViewVisible ? "auto" : "none"}
|
|
613
669
|
>
|
|
614
|
-
<
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
}}
|
|
642
|
-
startInLoadingState={isFirstLoadRef.current}
|
|
643
|
-
onLoadEnd={() => {
|
|
644
|
-
if (__DEV__) {
|
|
645
|
-
enableWebViewDebug(webViewRef);
|
|
670
|
+
<Animated.View
|
|
671
|
+
style={[
|
|
672
|
+
styles.fullScreenContainer,
|
|
673
|
+
{
|
|
674
|
+
opacity: animatedValues.opacity,
|
|
675
|
+
transform: [
|
|
676
|
+
{ scale: animatedValues.scale },
|
|
677
|
+
{ translateY: animatedValues.translateY },
|
|
678
|
+
],
|
|
679
|
+
},
|
|
680
|
+
]}
|
|
681
|
+
>
|
|
682
|
+
<ErrorBoundary componentName="ChatbotWebView">
|
|
683
|
+
<WebView
|
|
684
|
+
ref={webViewRef}
|
|
685
|
+
source={{
|
|
686
|
+
uri: constructUrl(),
|
|
687
|
+
}}
|
|
688
|
+
onMessage={handleMessage}
|
|
689
|
+
style={styles.webview}
|
|
690
|
+
containerStyle={
|
|
691
|
+
isFullScreen
|
|
692
|
+
? {
|
|
693
|
+
width: screenDimensions.width,
|
|
694
|
+
height: screenDimensions.height - 40,
|
|
695
|
+
}
|
|
696
|
+
: undefined
|
|
646
697
|
}
|
|
647
|
-
|
|
698
|
+
allowsInlineMediaPlayback={true}
|
|
699
|
+
mediaPlaybackRequiresUserAction={false}
|
|
700
|
+
allowFileAccess={false}
|
|
701
|
+
geolocationEnabled={false}
|
|
702
|
+
javaScriptEnabled={true}
|
|
703
|
+
domStorageEnabled={true}
|
|
704
|
+
cacheEnabled={true}
|
|
705
|
+
scrollEnabled={true}
|
|
706
|
+
bounces={false}
|
|
707
|
+
onShouldStartLoadWithRequest={(request) => {
|
|
708
|
+
return request.url.startsWith(BASE_CHATBOT_URL);
|
|
709
|
+
}}
|
|
710
|
+
startInLoadingState={isFirstLoadRef.current}
|
|
711
|
+
onLoadEnd={() => {
|
|
712
|
+
if (__DEV__) {
|
|
713
|
+
enableWebViewDebug(webViewRef);
|
|
714
|
+
}
|
|
715
|
+
webViewRef.current?.injectJavaScript(`
|
|
648
716
|
if (!document.querySelector('meta[name="viewport"]')) {
|
|
649
717
|
var meta = document.createElement('meta');
|
|
650
718
|
meta.name = 'viewport';
|
|
@@ -712,34 +780,37 @@ const Chatbot: React.FC<InternalChatbotProps> = ({
|
|
|
712
780
|
|
|
713
781
|
true;
|
|
714
782
|
`);
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
}
|
|
783
|
+
isFirstLoadRef.current = false;
|
|
784
|
+
}}
|
|
785
|
+
onError={(syntheticEvent) => {
|
|
786
|
+
const { nativeEvent } = syntheticEvent;
|
|
787
|
+
errorTracker.trackError(
|
|
788
|
+
new Error(nativeEvent.description),
|
|
789
|
+
"ChatbotWebView",
|
|
790
|
+
{
|
|
791
|
+
type: ErrorTypes.RUNTIME_ERROR,
|
|
792
|
+
context: {
|
|
793
|
+
url: nativeEvent.url,
|
|
794
|
+
code: nativeEvent.code,
|
|
795
|
+
},
|
|
796
|
+
}
|
|
797
|
+
);
|
|
798
|
+
}}
|
|
799
|
+
/>
|
|
800
|
+
</ErrorBoundary>
|
|
801
|
+
</Animated.View>
|
|
802
|
+
</View>
|
|
803
|
+
</>
|
|
804
|
+
)}
|
|
805
|
+
{/* <Toast message={toastMessage} visible={toastVisible} duration={10000} /> */}
|
|
806
|
+
{__DEV__ && <DebugButton />}
|
|
807
|
+
</View>
|
|
808
|
+
</ErrorBoundary>
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
);
|
|
812
|
+
|
|
813
|
+
Chatbot.displayName = "Chatbot";
|
|
743
814
|
|
|
744
815
|
const styles = StyleSheet.create({
|
|
745
816
|
mainContainer: {
|