@robylon/react-native-sdk 2.0.19-staging.9 → 2.0.20
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 +68 -1
- package/lib/commonjs/Chatbotsdk.js.map +1 -1
- package/lib/commonjs/FloatingButton.js +1 -1
- package/lib/commonjs/FloatingButton.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/versions/version.staging.js +1 -1
- package/lib/commonjs/versions/version.staging.js.map +1 -1
- package/lib/module/Chatbotsdk.js +68 -1
- package/lib/module/Chatbotsdk.js.map +1 -1
- package/lib/module/FloatingButton.js +1 -1
- package/lib/module/FloatingButton.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/module/versions/version.staging.js.map +1 -1
- package/lib/typescript/Chatbotsdk.d.ts.map +1 -1
- package/lib/typescript/FloatingButton.d.ts +1 -0
- package/lib/typescript/FloatingButton.d.ts.map +1 -1
- package/lib/typescript/versions/version.staging.d.ts +1 -1
- package/lib/typescript/versions/version.staging.d.ts.map +1 -1
- package/package.json +2 -2
- package/scripts/create-branch.js +39 -22
- package/scripts/validate-publish.js +30 -53
- package/src/ChatbotWebview.tsx +0 -44
- package/src/Chatbotsdk.tsx +0 -679
- package/src/FloatingButton.tsx +0 -74
- package/src/LoadingIndicator.tsx +0 -11
- package/src/Toast.tsx +0 -65
- package/src/components/DebugButton.tsx +0 -46
- package/src/components/ErrorBoundary.tsx +0 -38
- package/src/config.ts +0 -4
- package/src/constants/errorConstants.ts +0 -21
- package/src/constants.ts +0 -4
- package/src/global.d.ts +0 -11
- package/src/hooks/useChatbotEvents.ts +0 -93
- package/src/index.tsx +0 -10
- package/src/openChatbot.ts +0 -11
- package/src/openChatbot.tsx +0 -0
- package/src/services/ErrorTrackingService.ts +0 -217
- package/src/types/events.ts +0 -25
- package/src/types/react-native-flipper-performance-plugin.d.ts +0 -3
- package/src/types/react-native-globals.d.ts +0 -10
- package/src/utils/cookieUtils.ts +0 -7
- package/src/utils/debugConfig.ts +0 -56
- package/src/utils/debugMenu.ts +0 -14
- package/src/utils/errorHandler.ts +0 -58
- package/src/utils/logger.ts +0 -14
- package/src/utils/systemInfo.ts +0 -84
- package/src/utils/webViewStorage.ts +0 -62
- package/src/version.ts +0 -2
- package/src/versions/version.dev.ts +0 -2
- package/src/versions/version.production.ts +0 -2
- package/src/versions/version.staging.ts +0 -2
package/src/Chatbotsdk.tsx
DELETED
|
@@ -1,679 +0,0 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
useState,
|
|
3
|
-
useEffect,
|
|
4
|
-
useRef,
|
|
5
|
-
useMemo,
|
|
6
|
-
useCallback,
|
|
7
|
-
} from "react";
|
|
8
|
-
import {
|
|
9
|
-
View,
|
|
10
|
-
StyleSheet,
|
|
11
|
-
Animated,
|
|
12
|
-
Dimensions,
|
|
13
|
-
Platform,
|
|
14
|
-
StatusBar,
|
|
15
|
-
PixelRatio,
|
|
16
|
-
} from "react-native";
|
|
17
|
-
import { WebView, WebViewMessageEvent } from "react-native-webview";
|
|
18
|
-
import FloatingButton from "./FloatingButton";
|
|
19
|
-
import { API_URL, BASE_CHATBOT_URL } from "./constants";
|
|
20
|
-
import { SDK_VERSION } from "./version";
|
|
21
|
-
import { getSystemInfo, getBrowserAndOSInfoScript } from "./utils/systemInfo";
|
|
22
|
-
import { useChatbotEvents } from "./hooks/useChatbotEvents";
|
|
23
|
-
import { ChatbotEventType, ChatbotEventHandler } from "./types/events";
|
|
24
|
-
import { logger } from "./utils/logger";
|
|
25
|
-
import { enableNetworkDebug, enableWebViewDebug } from "./utils/debugConfig";
|
|
26
|
-
import DebugButton from "./components/DebugButton";
|
|
27
|
-
import { ErrorBoundary } from "./components/ErrorBoundary";
|
|
28
|
-
import {
|
|
29
|
-
ErrorCodes,
|
|
30
|
-
ErrorTypes,
|
|
31
|
-
ErrorMessages,
|
|
32
|
-
} from "./constants/errorConstants";
|
|
33
|
-
import { setupGlobalErrorHandlers } from "./utils/errorHandler";
|
|
34
|
-
import { errorTracker } from "./services/ErrorTrackingService";
|
|
35
|
-
import { generateUUID } from "./utils/cookieUtils";
|
|
36
|
-
import {
|
|
37
|
-
StorageMessageType,
|
|
38
|
-
StorageMessage,
|
|
39
|
-
getStorageScript,
|
|
40
|
-
createStorageMessage,
|
|
41
|
-
} from "./utils/webViewStorage";
|
|
42
|
-
|
|
43
|
-
export interface ChatbotProps {
|
|
44
|
-
api_key: string;
|
|
45
|
-
user_id?: string | null | number;
|
|
46
|
-
user_token?: string;
|
|
47
|
-
user_profile?: {
|
|
48
|
-
email?: string;
|
|
49
|
-
name?: string;
|
|
50
|
-
mobile?: string;
|
|
51
|
-
is_test_user?: boolean;
|
|
52
|
-
};
|
|
53
|
-
onEvent?: ChatbotEventHandler;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
interface InternalChatbotProps extends ChatbotProps {
|
|
57
|
-
show_floating_button?: boolean;
|
|
58
|
-
onMessage?: (message: any) => void;
|
|
59
|
-
isFullScreen?: boolean;
|
|
60
|
-
enableAnimation?: boolean;
|
|
61
|
-
onOpen?: () => void;
|
|
62
|
-
onClose?: () => void;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
interface ChatbotMessage {
|
|
66
|
-
type: string;
|
|
67
|
-
data?: any;
|
|
68
|
-
level?: string;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface ChatbotConfig {
|
|
72
|
-
brand_color: string;
|
|
73
|
-
image_url: string;
|
|
74
|
-
welcome_message: string;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const Chatbot: React.FC<InternalChatbotProps> = ({
|
|
78
|
-
api_key,
|
|
79
|
-
user_id,
|
|
80
|
-
user_token,
|
|
81
|
-
show_floating_button = true,
|
|
82
|
-
onEvent,
|
|
83
|
-
onMessage,
|
|
84
|
-
isFullScreen = true,
|
|
85
|
-
enableAnimation = true,
|
|
86
|
-
onOpen,
|
|
87
|
-
onClose,
|
|
88
|
-
user_profile,
|
|
89
|
-
}) => {
|
|
90
|
-
const [isWebViewVisible, setIsWebViewVisible] = useState(false);
|
|
91
|
-
const [chatbotConfig, setChatbotConfig] = useState<ChatbotConfig | null>(
|
|
92
|
-
null
|
|
93
|
-
);
|
|
94
|
-
const [loading, setLoading] = useState(true);
|
|
95
|
-
const webViewRef = useRef<WebView>(null);
|
|
96
|
-
const fadeAnim = useRef(new Animated.Value(0)).current;
|
|
97
|
-
const isFirstLoadRef = useRef(true);
|
|
98
|
-
const [toastVisible, setToastVisible] = useState(false);
|
|
99
|
-
const [toastMessage, setToastMessage] = useState("");
|
|
100
|
-
const [effectiveUserId, setEffectiveUserId] = useState<string>();
|
|
101
|
-
const [isStorageReady, setIsStorageReady] = useState(false);
|
|
102
|
-
const pendingStorageOps = useRef<Array<() => void>>([]);
|
|
103
|
-
const memoryCache = useRef<Record<string, string>>({});
|
|
104
|
-
|
|
105
|
-
const [systemInfo, setSystemInfo] = useState({ os: "", browser: "" });
|
|
106
|
-
|
|
107
|
-
// Create chatbotConfig object for events
|
|
108
|
-
const chatbotConfigForEvents = useMemo(
|
|
109
|
-
() => ({
|
|
110
|
-
userId: effectiveUserId,
|
|
111
|
-
isAnonymous: !user_id && user_id !== 0,
|
|
112
|
-
// Add other config properties as needed
|
|
113
|
-
}),
|
|
114
|
-
[effectiveUserId, user_id]
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
// Initialize event handling
|
|
118
|
-
const { emitEvent, onInternalEvent } = useChatbotEvents({
|
|
119
|
-
api_key,
|
|
120
|
-
chatbotConfig: chatbotConfigForEvents ?? {},
|
|
121
|
-
user_profile: user_profile,
|
|
122
|
-
onEvent: onEvent,
|
|
123
|
-
systemInfo: systemInfo ?? { os: "", browser: "" },
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
const triggerAppInit = () => {
|
|
127
|
-
if (webViewRef.current) {
|
|
128
|
-
webViewRef.current.injectJavaScript(`
|
|
129
|
-
// Trigger APP_READY equivalent
|
|
130
|
-
window.ReactNativeWebView.postMessage(JSON.stringify({ type: 'APP_READY' }));
|
|
131
|
-
true;
|
|
132
|
-
`);
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const executeStorageOp = useCallback(
|
|
137
|
-
(operation: () => void) => {
|
|
138
|
-
if (isStorageReady) {
|
|
139
|
-
operation();
|
|
140
|
-
} else {
|
|
141
|
-
pendingStorageOps.current.push(operation);
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
[isStorageReady]
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
// Handle WebView messages
|
|
148
|
-
const handleMessage = useCallback(
|
|
149
|
-
(event: WebViewMessageEvent) => {
|
|
150
|
-
const { data } = event.nativeEvent;
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
const parsedData: ChatbotMessage = JSON.parse(data);
|
|
154
|
-
|
|
155
|
-
// Handle storage messages
|
|
156
|
-
if (
|
|
157
|
-
Object.values(StorageMessageType).includes(
|
|
158
|
-
parsedData.type as StorageMessageType
|
|
159
|
-
)
|
|
160
|
-
) {
|
|
161
|
-
const storageMessage = parsedData as StorageMessage;
|
|
162
|
-
switch (storageMessage.type) {
|
|
163
|
-
case StorageMessageType.STORAGE_READY:
|
|
164
|
-
setIsStorageReady(true);
|
|
165
|
-
pendingStorageOps.current.forEach((op) => op());
|
|
166
|
-
pendingStorageOps.current = [];
|
|
167
|
-
// Try to get stored ID immediately after storage is ready
|
|
168
|
-
webViewRef.current?.injectJavaScript(
|
|
169
|
-
createStorageMessage(
|
|
170
|
-
StorageMessageType.GET_STORAGE,
|
|
171
|
-
"rblyn_anon"
|
|
172
|
-
)
|
|
173
|
-
);
|
|
174
|
-
break;
|
|
175
|
-
case StorageMessageType.STORAGE_RESPONSE:
|
|
176
|
-
if (storageMessage.key && storageMessage.value) {
|
|
177
|
-
memoryCache.current[storageMessage.key] = storageMessage.value;
|
|
178
|
-
if (storageMessage.key === "rblyn_anon") {
|
|
179
|
-
setEffectiveUserId(storageMessage.value);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
break;
|
|
183
|
-
case StorageMessageType.STORAGE_ERROR:
|
|
184
|
-
logger.error("WebView storage error:", storageMessage.error);
|
|
185
|
-
break;
|
|
186
|
-
}
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Add debug logging
|
|
191
|
-
if (__DEV__) {
|
|
192
|
-
if (parsedData?.type === "CONSOLE") {
|
|
193
|
-
console.log(`WebView ${parsedData?.level}:`, parsedData?.data);
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
if (parsedData?.type === "ERROR") {
|
|
197
|
-
console.error("WebView Error:", parsedData?.data);
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (parsedData?.type === "SYSTEM_INFO") {
|
|
203
|
-
setSystemInfo(parsedData?.data ?? { os: "", browser: "" });
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (parsedData?.type === "APP_READY") {
|
|
208
|
-
emitEvent(ChatbotEventType.CHATBOT_APP_READY);
|
|
209
|
-
if (webViewRef.current && isWebViewVisible) {
|
|
210
|
-
webViewRef.current?.injectJavaScript(getBrowserAndOSInfoScript());
|
|
211
|
-
|
|
212
|
-
const messageData = {
|
|
213
|
-
name: "registerUserId",
|
|
214
|
-
action: "registerUserId",
|
|
215
|
-
data: {
|
|
216
|
-
userId: effectiveUserId,
|
|
217
|
-
token: user_token ? `${user_token}` : undefined,
|
|
218
|
-
userProfile: {
|
|
219
|
-
...user_profile,
|
|
220
|
-
...getSystemInfo(systemInfo),
|
|
221
|
-
},
|
|
222
|
-
},
|
|
223
|
-
};
|
|
224
|
-
logger.debug("messageData====>", JSON.stringify(messageData));
|
|
225
|
-
webViewRef.current?.injectJavaScript(`
|
|
226
|
-
window.postMessage(${JSON.stringify({
|
|
227
|
-
name: "openFrame",
|
|
228
|
-
domain: "app-domain.com",
|
|
229
|
-
})}, '*');
|
|
230
|
-
window.postMessage(${JSON.stringify(messageData)}, '*');
|
|
231
|
-
`);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// Handle other message types
|
|
236
|
-
switch (parsedData?.type) {
|
|
237
|
-
case "close_chatbot":
|
|
238
|
-
closeWebView();
|
|
239
|
-
break;
|
|
240
|
-
case "CHATBOT_LOADED":
|
|
241
|
-
emitEvent(ChatbotEventType.CHATBOT_LOADED, parsedData?.data);
|
|
242
|
-
break;
|
|
243
|
-
case "CHAT_INITIALIZED":
|
|
244
|
-
emitEvent(ChatbotEventType.CHAT_INITIALIZED, parsedData?.data);
|
|
245
|
-
break;
|
|
246
|
-
case "SESSION_REFRESHED":
|
|
247
|
-
emitEvent(ChatbotEventType.SESSION_REFRESHED, parsedData?.data);
|
|
248
|
-
break;
|
|
249
|
-
case "CHAT_INITIALIZATION_FAILED":
|
|
250
|
-
emitEvent(
|
|
251
|
-
ChatbotEventType.CHAT_INITIALIZATION_FAILED,
|
|
252
|
-
parsedData?.data
|
|
253
|
-
);
|
|
254
|
-
break;
|
|
255
|
-
default:
|
|
256
|
-
if (onMessage) onMessage(parsedData ?? {});
|
|
257
|
-
}
|
|
258
|
-
} catch (error) {
|
|
259
|
-
errorTracker.trackError(
|
|
260
|
-
error instanceof Error
|
|
261
|
-
? error
|
|
262
|
-
: new Error("Failed to parse WebView message"),
|
|
263
|
-
"ChatbotSDK",
|
|
264
|
-
{
|
|
265
|
-
type: ErrorTypes.RUNTIME_ERROR,
|
|
266
|
-
context: { messageData: data },
|
|
267
|
-
}
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
},
|
|
271
|
-
[
|
|
272
|
-
emitEvent,
|
|
273
|
-
isWebViewVisible,
|
|
274
|
-
onMessage,
|
|
275
|
-
systemInfo,
|
|
276
|
-
effectiveUserId,
|
|
277
|
-
user_token,
|
|
278
|
-
user_profile,
|
|
279
|
-
]
|
|
280
|
-
);
|
|
281
|
-
|
|
282
|
-
// Initialize user ID
|
|
283
|
-
useEffect(() => {
|
|
284
|
-
const initializeUserId = async () => {
|
|
285
|
-
let userId = user_id ? String(user_id) : undefined;
|
|
286
|
-
|
|
287
|
-
if (!userId) {
|
|
288
|
-
// Try memory cache first
|
|
289
|
-
userId = memoryCache.current["rblyn_anon"];
|
|
290
|
-
|
|
291
|
-
if (!userId) {
|
|
292
|
-
userId = generateUUID();
|
|
293
|
-
executeStorageOp(() => {
|
|
294
|
-
webViewRef.current?.injectJavaScript(
|
|
295
|
-
createStorageMessage(
|
|
296
|
-
StorageMessageType.SET_STORAGE,
|
|
297
|
-
"rblyn_anon",
|
|
298
|
-
userId!
|
|
299
|
-
)
|
|
300
|
-
);
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
setEffectiveUserId(userId);
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
initializeUserId();
|
|
309
|
-
}, [user_id, executeStorageOp]);
|
|
310
|
-
|
|
311
|
-
// Initialize WebView storage
|
|
312
|
-
useEffect(() => {
|
|
313
|
-
if (webViewRef.current) {
|
|
314
|
-
webViewRef.current.injectJavaScript(getStorageScript());
|
|
315
|
-
// Try to get stored ID once storage is ready
|
|
316
|
-
executeStorageOp(() => {
|
|
317
|
-
webViewRef.current?.injectJavaScript(
|
|
318
|
-
createStorageMessage(StorageMessageType.GET_STORAGE, "rblyn_anon")
|
|
319
|
-
);
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
}, []);
|
|
323
|
-
|
|
324
|
-
useEffect(() => {
|
|
325
|
-
const fetchChatbotConfig = async () => {
|
|
326
|
-
try {
|
|
327
|
-
const endpointUrl = `${API_URL}/chat/chatbot/get/`;
|
|
328
|
-
const payload = {
|
|
329
|
-
client_user_id: effectiveUserId,
|
|
330
|
-
org_id: api_key,
|
|
331
|
-
token: user_token,
|
|
332
|
-
extra_info: {},
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
// setToastMessage(endpointUrl + " : " + BASE_CHATBOT_URL);
|
|
336
|
-
// setToastVisible(true);
|
|
337
|
-
|
|
338
|
-
const response = await fetch(endpointUrl, {
|
|
339
|
-
method: "POST",
|
|
340
|
-
headers: {
|
|
341
|
-
"Content-Type": "application/json",
|
|
342
|
-
},
|
|
343
|
-
body: JSON.stringify(payload),
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
if (!response.ok) {
|
|
347
|
-
throw new Error("Failed to fetch chatbot configuration");
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
const data = await response.json();
|
|
351
|
-
const orgInfo = data?.user?.org_info;
|
|
352
|
-
|
|
353
|
-
if (orgInfo) {
|
|
354
|
-
setChatbotConfig({
|
|
355
|
-
brand_color: orgInfo?.config?.brand_colour || "#007AFF",
|
|
356
|
-
image_url: orgInfo?.brand_config?.launcher_logo_url || "",
|
|
357
|
-
welcome_message: orgInfo?.config?.welcome_message || "",
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
} catch (error) {
|
|
361
|
-
errorTracker.trackError(
|
|
362
|
-
error instanceof Error
|
|
363
|
-
? error
|
|
364
|
-
: new Error("Failed to fetch chatbot configuration"),
|
|
365
|
-
"ChatbotSDK",
|
|
366
|
-
{
|
|
367
|
-
type: ErrorTypes.NETWORK_ERROR,
|
|
368
|
-
context: { api_key, user_id },
|
|
369
|
-
}
|
|
370
|
-
);
|
|
371
|
-
} finally {
|
|
372
|
-
setLoading(false);
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
if (api_key && effectiveUserId) {
|
|
377
|
-
fetchChatbotConfig();
|
|
378
|
-
}
|
|
379
|
-
}, [api_key, effectiveUserId, user_token]);
|
|
380
|
-
|
|
381
|
-
function constructUrl(): string {
|
|
382
|
-
if (!effectiveUserId) return "";
|
|
383
|
-
const params = new URLSearchParams({
|
|
384
|
-
id: api_key,
|
|
385
|
-
});
|
|
386
|
-
console.log("BASE_CHATBOT_URL SDK_VERSION", BASE_CHATBOT_URL, SDK_VERSION);
|
|
387
|
-
return `${BASE_CHATBOT_URL}?${params.toString()}`;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// Handle opening the chatbot
|
|
391
|
-
const openWebView = useCallback(() => {
|
|
392
|
-
setIsWebViewVisible(true);
|
|
393
|
-
if (enableAnimation) {
|
|
394
|
-
Animated.timing(fadeAnim, {
|
|
395
|
-
toValue: 1,
|
|
396
|
-
duration: 250,
|
|
397
|
-
useNativeDriver: true,
|
|
398
|
-
}).start(() => {
|
|
399
|
-
onOpen?.();
|
|
400
|
-
emitEvent(ChatbotEventType.CHATBOT_OPENED);
|
|
401
|
-
if (!isFirstLoadRef.current) {
|
|
402
|
-
setTimeout(triggerAppInit, 100);
|
|
403
|
-
}
|
|
404
|
-
});
|
|
405
|
-
} else {
|
|
406
|
-
fadeAnim.setValue(1);
|
|
407
|
-
requestAnimationFrame(() => {
|
|
408
|
-
onOpen?.();
|
|
409
|
-
emitEvent(ChatbotEventType.CHATBOT_OPENED);
|
|
410
|
-
if (!isFirstLoadRef.current) {
|
|
411
|
-
setTimeout(triggerAppInit, 100);
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
}, [enableAnimation, fadeAnim, onOpen, emitEvent]);
|
|
416
|
-
|
|
417
|
-
// Handle closing the chatbot
|
|
418
|
-
const closeWebView = useCallback(() => {
|
|
419
|
-
if (webViewRef.current) {
|
|
420
|
-
webViewRef.current.postMessage(
|
|
421
|
-
JSON.stringify({
|
|
422
|
-
name: "closeFrame",
|
|
423
|
-
domain: "app-domain.com",
|
|
424
|
-
})
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
const complete = () => {
|
|
429
|
-
setIsWebViewVisible(false);
|
|
430
|
-
onClose?.();
|
|
431
|
-
emitEvent(ChatbotEventType.CHATBOT_CLOSED);
|
|
432
|
-
};
|
|
433
|
-
|
|
434
|
-
if (enableAnimation) {
|
|
435
|
-
Animated.timing(fadeAnim, {
|
|
436
|
-
toValue: 0,
|
|
437
|
-
duration: 200,
|
|
438
|
-
useNativeDriver: true,
|
|
439
|
-
}).start(complete);
|
|
440
|
-
} else {
|
|
441
|
-
fadeAnim.setValue(0);
|
|
442
|
-
requestAnimationFrame(complete);
|
|
443
|
-
}
|
|
444
|
-
}, [enableAnimation, fadeAnim, onClose, emitEvent]);
|
|
445
|
-
|
|
446
|
-
// Emit button loaded event when component mounts
|
|
447
|
-
useEffect(() => {
|
|
448
|
-
if (show_floating_button && chatbotConfig) {
|
|
449
|
-
emitEvent(ChatbotEventType.CHATBOT_BUTTON_LOADED);
|
|
450
|
-
}
|
|
451
|
-
}, [show_floating_button, chatbotConfig, emitEvent]);
|
|
452
|
-
|
|
453
|
-
const getScreenDimensions = () => {
|
|
454
|
-
const windowHeight = Dimensions.get("window").height;
|
|
455
|
-
const windowWidth = Dimensions.get("window").width;
|
|
456
|
-
const statusBarHeight =
|
|
457
|
-
Platform.OS === "ios" ? 0 : StatusBar.currentHeight || 0;
|
|
458
|
-
|
|
459
|
-
return {
|
|
460
|
-
height: windowHeight - statusBarHeight,
|
|
461
|
-
width: windowWidth,
|
|
462
|
-
};
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
const screenDimensions = getScreenDimensions();
|
|
466
|
-
|
|
467
|
-
useEffect(() => {
|
|
468
|
-
if (__DEV__) {
|
|
469
|
-
enableNetworkDebug();
|
|
470
|
-
}
|
|
471
|
-
}, []);
|
|
472
|
-
|
|
473
|
-
// Deliberate error for testing error boundary
|
|
474
|
-
// useEffect(() => {
|
|
475
|
-
// if (__DEV__) {
|
|
476
|
-
// // Set up global error handlers
|
|
477
|
-
// setupGlobalErrorHandlers();
|
|
478
|
-
|
|
479
|
-
// // Test async error
|
|
480
|
-
// setTimeout(() => {
|
|
481
|
-
// Promise.reject(new Error("Test async error"));
|
|
482
|
-
// }, 1000);
|
|
483
|
-
|
|
484
|
-
// // Test sync error
|
|
485
|
-
// setTimeout(() => {
|
|
486
|
-
// throw new Error("Test sync error");
|
|
487
|
-
// }, 2000);
|
|
488
|
-
// }
|
|
489
|
-
// }, []);
|
|
490
|
-
|
|
491
|
-
return (
|
|
492
|
-
<ErrorBoundary componentName="ChatbotSDK">
|
|
493
|
-
<View style={styles.mainContainer}>
|
|
494
|
-
{!loading && (
|
|
495
|
-
<>
|
|
496
|
-
<ErrorBoundary componentName="FloatingButton">
|
|
497
|
-
{show_floating_button && api_key && chatbotConfig && (
|
|
498
|
-
<FloatingButton
|
|
499
|
-
onPress={() => {
|
|
500
|
-
emitEvent(ChatbotEventType.CHATBOT_BUTTON_CLICKED);
|
|
501
|
-
openWebView();
|
|
502
|
-
}}
|
|
503
|
-
brandColor={chatbotConfig.brand_color}
|
|
504
|
-
imageUrl={chatbotConfig.image_url}
|
|
505
|
-
/>
|
|
506
|
-
)}
|
|
507
|
-
</ErrorBoundary>
|
|
508
|
-
<View
|
|
509
|
-
style={[
|
|
510
|
-
styles.webViewWrapper,
|
|
511
|
-
{ height: isWebViewVisible ? "100%" : 0 },
|
|
512
|
-
]}
|
|
513
|
-
pointerEvents={isWebViewVisible ? "auto" : "none"}
|
|
514
|
-
>
|
|
515
|
-
<Animated.View
|
|
516
|
-
style={[styles.fullScreenContainer, { opacity: fadeAnim }]}
|
|
517
|
-
>
|
|
518
|
-
<ErrorBoundary componentName="ChatbotWebView">
|
|
519
|
-
<WebView
|
|
520
|
-
ref={webViewRef}
|
|
521
|
-
source={{ uri: constructUrl() }}
|
|
522
|
-
onMessage={handleMessage}
|
|
523
|
-
style={styles.webview}
|
|
524
|
-
containerStyle={
|
|
525
|
-
isFullScreen
|
|
526
|
-
? {
|
|
527
|
-
width: screenDimensions.width,
|
|
528
|
-
height: screenDimensions.height,
|
|
529
|
-
}
|
|
530
|
-
: undefined
|
|
531
|
-
}
|
|
532
|
-
allowsInlineMediaPlayback={true}
|
|
533
|
-
mediaPlaybackRequiresUserAction={false}
|
|
534
|
-
allowFileAccess={false}
|
|
535
|
-
geolocationEnabled={false}
|
|
536
|
-
javaScriptEnabled={true}
|
|
537
|
-
domStorageEnabled={true}
|
|
538
|
-
cacheEnabled={true}
|
|
539
|
-
scrollEnabled={true}
|
|
540
|
-
bounces={false}
|
|
541
|
-
onShouldStartLoadWithRequest={(request) => {
|
|
542
|
-
return request.url.startsWith(BASE_CHATBOT_URL);
|
|
543
|
-
}}
|
|
544
|
-
startInLoadingState={isFirstLoadRef.current}
|
|
545
|
-
// onLoadEnd={() => {
|
|
546
|
-
// if (__DEV__) {
|
|
547
|
-
// enableWebViewDebug(webViewRef);
|
|
548
|
-
// }
|
|
549
|
-
// webViewRef.current?.injectJavaScript(`
|
|
550
|
-
// if (!document.querySelector('meta[name="viewport"]')) {
|
|
551
|
-
// var meta = document.createElement('meta');
|
|
552
|
-
// meta.name = 'viewport';
|
|
553
|
-
// meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no';
|
|
554
|
-
// document.getElementsByTagName('head')[0].appendChild(meta);
|
|
555
|
-
// }
|
|
556
|
-
|
|
557
|
-
// if (!document.querySelector('#injectedStyle')) {
|
|
558
|
-
// const style = document.createElement('style');
|
|
559
|
-
// style.id = 'injectedStyle';
|
|
560
|
-
// style.textContent = \`
|
|
561
|
-
// html, body, #root, #__next {
|
|
562
|
-
// height: 100% !important;
|
|
563
|
-
// min-height: 100% !important;
|
|
564
|
-
// overflow: hidden !important;
|
|
565
|
-
// }
|
|
566
|
-
// \`;
|
|
567
|
-
// document.head.appendChild(style);
|
|
568
|
-
// }
|
|
569
|
-
|
|
570
|
-
// window.sendToChatbot = function(message) {
|
|
571
|
-
// window.ReactNativeWebView.postMessage(JSON.stringify(message));
|
|
572
|
-
// };
|
|
573
|
-
|
|
574
|
-
// // Only create observer if it doesn't exist
|
|
575
|
-
// if (!window.closeButtonObserver) {
|
|
576
|
-
// // Setup mutation observer to watch for close button
|
|
577
|
-
// window.closeButtonObserver = new MutationObserver(function(mutations) {
|
|
578
|
-
// const closeButton = document.querySelector('.chatbot-close-button');
|
|
579
|
-
// if (closeButton && !closeButton.hasAttribute('listener-attached')) {
|
|
580
|
-
// closeButton.setAttribute('listener-attached', 'true');
|
|
581
|
-
// closeButton.addEventListener('click', () => {
|
|
582
|
-
// try {
|
|
583
|
-
// const message = { type: 'close_chatbot' };
|
|
584
|
-
// window.ReactNativeWebView.postMessage(JSON.stringify(message));
|
|
585
|
-
// } catch (error) {
|
|
586
|
-
// console.error('Error sending close message:', error);
|
|
587
|
-
// }
|
|
588
|
-
// });
|
|
589
|
-
// console.log('Close button listener attached');
|
|
590
|
-
// }
|
|
591
|
-
// });
|
|
592
|
-
|
|
593
|
-
// // Start observing
|
|
594
|
-
// window.closeButtonObserver.observe(document.body, {
|
|
595
|
-
// childList: true,
|
|
596
|
-
// subtree: true
|
|
597
|
-
// });
|
|
598
|
-
|
|
599
|
-
// // Initial check for existing button
|
|
600
|
-
// const existingButton = document.querySelector('.chatbot-close-button');
|
|
601
|
-
// if (existingButton && !existingButton.hasAttribute('listener-attached')) {
|
|
602
|
-
// existingButton.setAttribute('listener-attached', 'true');
|
|
603
|
-
// existingButton.addEventListener('click', () => {
|
|
604
|
-
// try {
|
|
605
|
-
// const message = { type: 'close_chatbot' };
|
|
606
|
-
// window.ReactNativeWebView.postMessage(JSON.stringify(message));
|
|
607
|
-
// } catch (error) {
|
|
608
|
-
// console.error('Error sending close message:', error);
|
|
609
|
-
// }
|
|
610
|
-
// });
|
|
611
|
-
// console.log('Close button listener attached to existing button');
|
|
612
|
-
// }
|
|
613
|
-
// }
|
|
614
|
-
|
|
615
|
-
// true;
|
|
616
|
-
// `);
|
|
617
|
-
// isFirstLoadRef.current = false;
|
|
618
|
-
// }}
|
|
619
|
-
onError={(syntheticEvent) => {
|
|
620
|
-
const { nativeEvent } = syntheticEvent;
|
|
621
|
-
errorTracker.trackError(
|
|
622
|
-
new Error(nativeEvent.description),
|
|
623
|
-
"ChatbotWebView",
|
|
624
|
-
{
|
|
625
|
-
type: ErrorTypes.RUNTIME_ERROR,
|
|
626
|
-
context: {
|
|
627
|
-
url: nativeEvent.url,
|
|
628
|
-
code: nativeEvent.code,
|
|
629
|
-
},
|
|
630
|
-
}
|
|
631
|
-
);
|
|
632
|
-
}}
|
|
633
|
-
/>
|
|
634
|
-
</ErrorBoundary>
|
|
635
|
-
</Animated.View>
|
|
636
|
-
</View>
|
|
637
|
-
</>
|
|
638
|
-
)}
|
|
639
|
-
{/* <Toast message={toastMessage} visible={toastVisible} duration={10000} /> */}
|
|
640
|
-
{__DEV__ && <DebugButton />}
|
|
641
|
-
</View>
|
|
642
|
-
</ErrorBoundary>
|
|
643
|
-
);
|
|
644
|
-
};
|
|
645
|
-
|
|
646
|
-
const styles = StyleSheet.create({
|
|
647
|
-
mainContainer: {
|
|
648
|
-
flex: 1,
|
|
649
|
-
position: "relative",
|
|
650
|
-
},
|
|
651
|
-
webViewWrapper: {
|
|
652
|
-
position: "absolute",
|
|
653
|
-
top: 0,
|
|
654
|
-
left: 0,
|
|
655
|
-
right: 0,
|
|
656
|
-
bottom: 0,
|
|
657
|
-
overflow: "hidden",
|
|
658
|
-
zIndex: 1000,
|
|
659
|
-
},
|
|
660
|
-
fullScreenContainer: {
|
|
661
|
-
position: "absolute",
|
|
662
|
-
top: 0,
|
|
663
|
-
left: 0,
|
|
664
|
-
right: 0,
|
|
665
|
-
bottom: 0,
|
|
666
|
-
backgroundColor: "white",
|
|
667
|
-
zIndex: 1000,
|
|
668
|
-
},
|
|
669
|
-
inlineContainer: {
|
|
670
|
-
flex: 1,
|
|
671
|
-
backgroundColor: "white",
|
|
672
|
-
},
|
|
673
|
-
webview: {
|
|
674
|
-
flex: 1,
|
|
675
|
-
backgroundColor: "white",
|
|
676
|
-
},
|
|
677
|
-
});
|
|
678
|
-
|
|
679
|
-
export default Chatbot;
|