@sagepilot-ai/react-native-sdk 0.2.1 → 0.2.3
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/README.md +11 -6
- package/android/build.gradle +53 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/ai/sagepilot/reactnativesdk/SagepilotInsetsChangeEvent.java +26 -0
- package/android/src/main/java/ai/sagepilot/reactnativesdk/SagepilotInsetsView.java +78 -0
- package/android/src/main/java/ai/sagepilot/reactnativesdk/SagepilotInsetsViewManager.java +59 -0
- package/android/src/main/java/ai/sagepilot/reactnativesdk/SagepilotReactNativeSdkPackage.java +20 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/SagepilotInsetsViewManagerDelegate.java +25 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/SagepilotInsetsViewManagerInterface.java +10 -0
- package/dist/{index.d.cts → index.d.mts} +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +247 -87
- package/dist/{index.cjs → index.mjs} +215 -110
- package/package.json +18 -8
- package/react-native.config.js +5 -1
- package/src/specs/SagepilotInsetsViewNativeComponent.ts +17 -0
- package/android/.gitkeep +0 -1
|
@@ -1,34 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
SagepilotChat: () => SagepilotChat,
|
|
24
|
-
SagepilotChatError: () => SagepilotChatError,
|
|
25
|
-
SagepilotChatProvider: () => SagepilotChatProvider,
|
|
26
|
-
createAsyncStorageCacheStorage: () => createAsyncStorageCacheStorage,
|
|
27
|
-
createKeychainTokenStorage: () => createKeychainTokenStorage,
|
|
28
|
-
useSagepilotChat: () => useSagepilotChat
|
|
29
|
-
});
|
|
30
|
-
module.exports = __toCommonJS(index_exports);
|
|
31
|
-
|
|
32
1
|
// src/core/errors/SagepilotChatError.ts
|
|
33
2
|
var SagepilotChatError = class extends Error {
|
|
34
3
|
constructor(code, message, options = {}) {
|
|
@@ -46,7 +15,7 @@ var SagepilotChatError = class extends Error {
|
|
|
46
15
|
|
|
47
16
|
// src/core/config/constants.ts
|
|
48
17
|
var SDK_NAME = "@sagepilot-ai/react-native-sdk";
|
|
49
|
-
var SDK_VERSION = "0.2.
|
|
18
|
+
var SDK_VERSION = "0.2.3";
|
|
50
19
|
var DEFAULT_HOST = "https://app.sagepilot.ai";
|
|
51
20
|
var DEFAULT_WIDGET_HOST = "https://app.sagepilot.ai";
|
|
52
21
|
var CUSTOMER_API_PREFIX = "/customer-api/v1";
|
|
@@ -732,9 +701,9 @@ var SagepilotReactNativeChat = class {
|
|
|
732
701
|
this.hostedChatView = { screen: "messages" };
|
|
733
702
|
return this.showHostedChat();
|
|
734
703
|
}
|
|
735
|
-
presentMessageComposer(message) {
|
|
704
|
+
presentMessageComposer(message, options) {
|
|
736
705
|
this.requireConfigured();
|
|
737
|
-
this.hostedChatView = { screen: "composer", message };
|
|
706
|
+
this.hostedChatView = { screen: "composer", message, mode: options?.mode ?? "auto" };
|
|
738
707
|
return this.showHostedChat();
|
|
739
708
|
}
|
|
740
709
|
dismiss() {
|
|
@@ -830,8 +799,13 @@ var SagepilotReactNativeChat = class {
|
|
|
830
799
|
}
|
|
831
800
|
url.searchParams.set("session_id", session.session_id);
|
|
832
801
|
url.searchParams.set("wid", this.workspaceId);
|
|
802
|
+
if (this.legacyWidgetJwt) {
|
|
803
|
+
url.searchParams.set("jwt", this.legacyWidgetJwt);
|
|
804
|
+
}
|
|
833
805
|
if (this.hostedChatView.screen === "composer") {
|
|
834
|
-
|
|
806
|
+
if (this.hostedChatView.mode === "new") {
|
|
807
|
+
url.searchParams.set("new", "true");
|
|
808
|
+
}
|
|
835
809
|
if (this.hostedChatView.message) {
|
|
836
810
|
url.searchParams.set("topic", this.hostedChatView.message);
|
|
837
811
|
}
|
|
@@ -857,6 +831,16 @@ var SagepilotReactNativeChat = class {
|
|
|
857
831
|
"})();"
|
|
858
832
|
].join("\n");
|
|
859
833
|
}
|
|
834
|
+
getHostedIdentityMessage() {
|
|
835
|
+
if (!this.legacyWidgetJwt) return null;
|
|
836
|
+
return {
|
|
837
|
+
type: "identity_update",
|
|
838
|
+
data: {
|
|
839
|
+
jwt: this.legacyWidgetJwt,
|
|
840
|
+
chat_id: this.session?.conversation_id ?? void 0
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
}
|
|
860
844
|
handleHostedBridgeMessage(message) {
|
|
861
845
|
if (!message) return false;
|
|
862
846
|
if (message.type === "close_widget") {
|
|
@@ -1051,7 +1035,9 @@ var SagepilotChat = {
|
|
|
1051
1035
|
stopUnreadPolling: () => internalSagepilotChat.stopUnreadPolling(),
|
|
1052
1036
|
present: () => internalSagepilotChat.present(),
|
|
1053
1037
|
presentMessages: () => internalSagepilotChat.presentMessages(),
|
|
1054
|
-
presentMessageComposer: (message) =>
|
|
1038
|
+
presentMessageComposer: (message, options) => {
|
|
1039
|
+
return internalSagepilotChat.presentMessageComposer(message, options);
|
|
1040
|
+
},
|
|
1055
1041
|
dismiss: () => internalSagepilotChat.dismiss(),
|
|
1056
1042
|
hide: () => internalSagepilotChat.hide(),
|
|
1057
1043
|
toggle: () => internalSagepilotChat.toggle(),
|
|
@@ -1077,9 +1063,19 @@ function createAsyncStorageCacheStorage(asyncStorage) {
|
|
|
1077
1063
|
}
|
|
1078
1064
|
|
|
1079
1065
|
// src/ui/SagepilotChatProvider.ts
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1066
|
+
import { createElement, useCallback, useEffect, useRef, useState } from "react";
|
|
1067
|
+
import {
|
|
1068
|
+
ActivityIndicator,
|
|
1069
|
+
KeyboardAvoidingView,
|
|
1070
|
+
Modal,
|
|
1071
|
+
Platform,
|
|
1072
|
+
Pressable,
|
|
1073
|
+
SafeAreaView,
|
|
1074
|
+
StyleSheet,
|
|
1075
|
+
Text,
|
|
1076
|
+
View
|
|
1077
|
+
} from "react-native";
|
|
1078
|
+
import { WebView } from "react-native-webview";
|
|
1083
1079
|
|
|
1084
1080
|
// src/core/webview/mobileBridge.ts
|
|
1085
1081
|
function isHostedBridgeMessage(value) {
|
|
@@ -1160,6 +1156,28 @@ var mobileWebViewBridgeScript = `
|
|
|
1160
1156
|
} catch (error) {}
|
|
1161
1157
|
}, true);
|
|
1162
1158
|
|
|
1159
|
+
document.addEventListener("focusin", function (event) {
|
|
1160
|
+
try {
|
|
1161
|
+
var target = event.target && event.target.closest
|
|
1162
|
+
? event.target
|
|
1163
|
+
: event.target && event.target.parentElement;
|
|
1164
|
+
if (target && target.closest && target.closest("input, textarea, [contenteditable='true']")) {
|
|
1165
|
+
sendToReactNative({ type: "sagepilot:keyboard_focus" });
|
|
1166
|
+
}
|
|
1167
|
+
} catch (error) {}
|
|
1168
|
+
}, true);
|
|
1169
|
+
|
|
1170
|
+
document.addEventListener("focusout", function (event) {
|
|
1171
|
+
try {
|
|
1172
|
+
var target = event.target && event.target.closest
|
|
1173
|
+
? event.target
|
|
1174
|
+
: event.target && event.target.parentElement;
|
|
1175
|
+
if (target && target.closest && target.closest("input, textarea, [contenteditable='true']")) {
|
|
1176
|
+
sendToReactNative({ type: "sagepilot:keyboard_blur" });
|
|
1177
|
+
}
|
|
1178
|
+
} catch (error) {}
|
|
1179
|
+
}, true);
|
|
1180
|
+
|
|
1163
1181
|
ensureViewport();
|
|
1164
1182
|
injectMobileStyles();
|
|
1165
1183
|
sendToReactNative({ type: "sagepilot:ready" });
|
|
@@ -1167,6 +1185,10 @@ var mobileWebViewBridgeScript = `
|
|
|
1167
1185
|
})();
|
|
1168
1186
|
`;
|
|
1169
1187
|
|
|
1188
|
+
// src/specs/SagepilotInsetsViewNativeComponent.ts
|
|
1189
|
+
import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
|
|
1190
|
+
var SagepilotInsetsViewNativeComponent_default = codegenNativeComponent("SagepilotInsetsView");
|
|
1191
|
+
|
|
1170
1192
|
// src/ui/SagepilotChatProvider.ts
|
|
1171
1193
|
function readPresentationState() {
|
|
1172
1194
|
return {
|
|
@@ -1184,6 +1206,20 @@ function getInjectedWebViewScript() {
|
|
|
1184
1206
|
mobileWebViewBridgeScript
|
|
1185
1207
|
].filter(Boolean).join("\n");
|
|
1186
1208
|
}
|
|
1209
|
+
function getHostedIdentityDispatchScript() {
|
|
1210
|
+
const message = internalSagepilotChat.getHostedIdentityMessage();
|
|
1211
|
+
if (!message) return "";
|
|
1212
|
+
return [
|
|
1213
|
+
internalSagepilotChat.getHostedAuthScript(),
|
|
1214
|
+
"(function(){",
|
|
1215
|
+
"try {",
|
|
1216
|
+
`var message = ${JSON.stringify(message)};`,
|
|
1217
|
+
"window.dispatchEvent(new MessageEvent('message', { data: message, origin: window.location.origin, source: window.parent || window }));",
|
|
1218
|
+
"} catch (_) {}",
|
|
1219
|
+
"true;",
|
|
1220
|
+
"})();"
|
|
1221
|
+
].filter(Boolean).join("\n");
|
|
1222
|
+
}
|
|
1187
1223
|
function readUrlOrigin(url) {
|
|
1188
1224
|
if (!url) return null;
|
|
1189
1225
|
try {
|
|
@@ -1195,33 +1231,78 @@ function readUrlOrigin(url) {
|
|
|
1195
1231
|
var hostedChatWebViewProps = {
|
|
1196
1232
|
allowFileAccess: true,
|
|
1197
1233
|
allowFileAccessFromFileURLs: true,
|
|
1234
|
+
bounces: false,
|
|
1198
1235
|
domStorageEnabled: true,
|
|
1199
1236
|
javaScriptEnabled: true,
|
|
1237
|
+
overScrollMode: "never",
|
|
1238
|
+
scrollEnabled: Platform.OS !== "android",
|
|
1200
1239
|
setSupportMultipleWindows: false,
|
|
1201
1240
|
sharedCookiesEnabled: true,
|
|
1202
1241
|
thirdPartyCookiesEnabled: true
|
|
1203
1242
|
};
|
|
1243
|
+
var AndroidInsetsView = Platform.OS === "android" ? SagepilotInsetsViewNativeComponent_default : View;
|
|
1244
|
+
var emptyAndroidInsets = { top: 0, bottom: 0 };
|
|
1204
1245
|
function SagepilotChatProvider({
|
|
1205
1246
|
children,
|
|
1206
1247
|
closeLabel = "Close",
|
|
1207
1248
|
loadingLabel = "Loading chat"
|
|
1208
1249
|
}) {
|
|
1209
|
-
const [state, setState] =
|
|
1210
|
-
|
|
1250
|
+
const [state, setState] = useState(readPresentationState);
|
|
1251
|
+
const [androidModalInsets, setAndroidModalInsets] = useState(emptyAndroidInsets);
|
|
1252
|
+
const webFrameRef = useRef(null);
|
|
1253
|
+
const nativeWebViewRef = useRef(null);
|
|
1254
|
+
useEffect(() => {
|
|
1211
1255
|
return internalSagepilotChat.onStateChange(() => {
|
|
1212
1256
|
setState(readPresentationState());
|
|
1213
1257
|
});
|
|
1214
1258
|
}, []);
|
|
1259
|
+
const handleAndroidInsetsChange = useCallback((event) => {
|
|
1260
|
+
const nextBottomInset = event.nativeEvent?.bottom;
|
|
1261
|
+
const nextTopInset = event.nativeEvent?.top;
|
|
1262
|
+
if (typeof nextBottomInset !== "number" || typeof nextTopInset !== "number" || !Number.isFinite(nextBottomInset) || !Number.isFinite(nextTopInset)) return;
|
|
1263
|
+
setAndroidModalInsets({
|
|
1264
|
+
top: Math.max(0, nextTopInset),
|
|
1265
|
+
bottom: Math.max(0, nextBottomInset)
|
|
1266
|
+
});
|
|
1267
|
+
}, []);
|
|
1215
1268
|
const showCloseButton = state.presentation?.showCloseButton ?? false;
|
|
1216
1269
|
const presentationStyle = state.presentation?.style ?? "sheet";
|
|
1217
1270
|
const isFullScreenModal = presentationStyle === "fullScreen";
|
|
1218
1271
|
const animationType = presentationStyle === "fullScreen" || presentationStyle === "push" ? "slide" : "fade";
|
|
1219
|
-
const ModalContainer =
|
|
1272
|
+
const ModalContainer = Platform.OS === "ios" && isFullScreenModal ? SafeAreaView : View;
|
|
1273
|
+
const NativeModalContainer = Platform.OS === "android" ? AndroidInsetsView : ModalContainer;
|
|
1274
|
+
const ChatContentContainer = Platform.OS === "ios" ? KeyboardAvoidingView : View;
|
|
1275
|
+
const nativeModalContainerProps = Platform.OS === "android" ? { style: styles.container, onInsetsChange: handleAndroidInsetsChange } : { style: styles.container };
|
|
1276
|
+
const chatContentContainerProps = Platform.OS === "ios" ? {
|
|
1277
|
+
behavior: "padding",
|
|
1278
|
+
enabled: true,
|
|
1279
|
+
keyboardVerticalOffset: 0,
|
|
1280
|
+
style: styles.modalContent
|
|
1281
|
+
} : {
|
|
1282
|
+
style: [
|
|
1283
|
+
styles.modalContent,
|
|
1284
|
+
Platform.OS === "android" ? {
|
|
1285
|
+
paddingTop: androidModalInsets.top,
|
|
1286
|
+
paddingBottom: androidModalInsets.bottom
|
|
1287
|
+
} : null
|
|
1288
|
+
].filter(Boolean)
|
|
1289
|
+
};
|
|
1220
1290
|
const handleWebViewMessage = (event) => {
|
|
1221
1291
|
internalSagepilotChat.handleHostedBridgeMessage(parseHostedBridgeMessage(event.nativeEvent?.data));
|
|
1222
1292
|
};
|
|
1223
|
-
|
|
1224
|
-
|
|
1293
|
+
const postIdentityToWebFrame = () => {
|
|
1294
|
+
const message = internalSagepilotChat.getHostedIdentityMessage();
|
|
1295
|
+
const targetOrigin = readUrlOrigin(state.conversationUrl);
|
|
1296
|
+
if (!message || !targetOrigin) return;
|
|
1297
|
+
webFrameRef.current?.contentWindow?.postMessage(message, targetOrigin);
|
|
1298
|
+
};
|
|
1299
|
+
const postIdentityToNativeWebView = () => {
|
|
1300
|
+
const script = getHostedIdentityDispatchScript();
|
|
1301
|
+
if (!script || !nativeWebViewRef.current) return;
|
|
1302
|
+
nativeWebViewRef.current.injectJavaScript(script);
|
|
1303
|
+
};
|
|
1304
|
+
useEffect(() => {
|
|
1305
|
+
if (Platform.OS !== "web" || typeof window === "undefined") return;
|
|
1225
1306
|
const trustedWidgetOrigin = readUrlOrigin(state.conversationUrl);
|
|
1226
1307
|
if (!trustedWidgetOrigin) return;
|
|
1227
1308
|
const handleWindowMessage = (event) => {
|
|
@@ -1231,96 +1312,114 @@ function SagepilotChatProvider({
|
|
|
1231
1312
|
window.addEventListener("message", handleWindowMessage);
|
|
1232
1313
|
return () => window.removeEventListener("message", handleWindowMessage);
|
|
1233
1314
|
}, [state.conversationUrl]);
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1315
|
+
useEffect(() => {
|
|
1316
|
+
if (Platform.OS !== "web" || !state.isPresented) return;
|
|
1317
|
+
postIdentityToWebFrame();
|
|
1318
|
+
}, [state.isPresented, state.conversationUrl, state.configured]);
|
|
1319
|
+
useEffect(() => {
|
|
1320
|
+
if (Platform.OS === "web" || !state.isPresented) return;
|
|
1321
|
+
postIdentityToNativeWebView();
|
|
1322
|
+
}, [state.isPresented, state.conversationUrl, state.configured]);
|
|
1323
|
+
if (Platform.OS === "web") {
|
|
1324
|
+
return createElement(
|
|
1325
|
+
View,
|
|
1237
1326
|
{ style: styles.root },
|
|
1238
1327
|
children,
|
|
1239
|
-
state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ?
|
|
1328
|
+
state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ? createElement("iframe", {
|
|
1240
1329
|
src: state.preloadUrl,
|
|
1241
1330
|
style: styles.webPreloadFrame,
|
|
1242
1331
|
title: "Sagepilot chat preload"
|
|
1243
1332
|
}) : null,
|
|
1244
|
-
state.configured && state.isPresented && state.conversationUrl ?
|
|
1245
|
-
|
|
1333
|
+
state.configured && state.isPresented && state.conversationUrl ? createElement(
|
|
1334
|
+
View,
|
|
1246
1335
|
{ style: styles.webOverlay },
|
|
1247
|
-
|
|
1248
|
-
|
|
1336
|
+
createElement(
|
|
1337
|
+
View,
|
|
1249
1338
|
{ style: styles.webPanel },
|
|
1250
|
-
showCloseButton ?
|
|
1251
|
-
|
|
1339
|
+
showCloseButton ? createElement(
|
|
1340
|
+
Pressable,
|
|
1252
1341
|
{
|
|
1253
1342
|
accessibilityRole: "button",
|
|
1254
1343
|
accessibilityLabel: closeLabel,
|
|
1255
1344
|
onPress: () => internalSagepilotChat.dismiss(),
|
|
1256
1345
|
style: styles.webCloseButton
|
|
1257
1346
|
},
|
|
1258
|
-
|
|
1347
|
+
createElement(Text, { style: styles.closeText }, closeLabel)
|
|
1259
1348
|
) : null,
|
|
1260
|
-
|
|
1349
|
+
createElement("iframe", {
|
|
1350
|
+
ref: webFrameRef,
|
|
1261
1351
|
src: state.conversationUrl,
|
|
1262
1352
|
style: styles.webFrame,
|
|
1263
|
-
title: "Sagepilot chat"
|
|
1353
|
+
title: "Sagepilot chat",
|
|
1354
|
+
onLoad: postIdentityToWebFrame
|
|
1264
1355
|
})
|
|
1265
1356
|
)
|
|
1266
1357
|
) : null
|
|
1267
1358
|
);
|
|
1268
1359
|
}
|
|
1269
|
-
return
|
|
1270
|
-
|
|
1360
|
+
return createElement(
|
|
1361
|
+
View,
|
|
1271
1362
|
{ style: styles.root },
|
|
1272
1363
|
children,
|
|
1273
|
-
state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ?
|
|
1364
|
+
state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ? createElement(WebView, {
|
|
1274
1365
|
...hostedChatWebViewProps,
|
|
1275
1366
|
source: { uri: state.preloadUrl },
|
|
1276
1367
|
style: styles.preloadWebview,
|
|
1277
1368
|
injectedJavaScriptBeforeContentLoaded: getInjectedWebViewScript(),
|
|
1278
1369
|
onMessage: handleWebViewMessage
|
|
1279
1370
|
}) : null,
|
|
1280
|
-
|
|
1281
|
-
|
|
1371
|
+
createElement(
|
|
1372
|
+
Modal,
|
|
1282
1373
|
{
|
|
1283
1374
|
visible: state.configured && state.isPresented,
|
|
1284
1375
|
animationType,
|
|
1285
1376
|
presentationStyle: isFullScreenModal ? "fullScreen" : "pageSheet",
|
|
1377
|
+
statusBarTranslucent: Platform.OS === "android",
|
|
1378
|
+
navigationBarTranslucent: Platform.OS === "android",
|
|
1286
1379
|
onRequestClose: () => internalSagepilotChat.dismiss()
|
|
1287
1380
|
},
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
{
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1381
|
+
createElement(
|
|
1382
|
+
NativeModalContainer,
|
|
1383
|
+
nativeModalContainerProps,
|
|
1384
|
+
createElement(
|
|
1385
|
+
ChatContentContainer,
|
|
1386
|
+
chatContentContainerProps,
|
|
1387
|
+
showCloseButton ? createElement(
|
|
1388
|
+
View,
|
|
1389
|
+
{ style: styles.header },
|
|
1390
|
+
createElement(
|
|
1391
|
+
Pressable,
|
|
1392
|
+
{
|
|
1393
|
+
accessibilityRole: "button",
|
|
1394
|
+
accessibilityLabel: closeLabel,
|
|
1395
|
+
onPress: () => internalSagepilotChat.dismiss(),
|
|
1396
|
+
style: styles.closeButton
|
|
1397
|
+
},
|
|
1398
|
+
createElement(Text, { style: styles.closeText }, closeLabel)
|
|
1399
|
+
)
|
|
1400
|
+
) : null,
|
|
1401
|
+
state.conversationUrl ? createElement(WebView, {
|
|
1402
|
+
...hostedChatWebViewProps,
|
|
1403
|
+
ref: nativeWebViewRef,
|
|
1404
|
+
source: { uri: state.conversationUrl },
|
|
1405
|
+
style: styles.webview,
|
|
1406
|
+
startInLoadingState: true,
|
|
1407
|
+
injectedJavaScriptBeforeContentLoaded: getInjectedWebViewScript(),
|
|
1408
|
+
onMessage: handleWebViewMessage,
|
|
1409
|
+
onLoadEnd: postIdentityToNativeWebView,
|
|
1410
|
+
renderLoading: () => createElement(
|
|
1411
|
+
View,
|
|
1412
|
+
{ style: styles.loading },
|
|
1413
|
+
createElement(ActivityIndicator, null),
|
|
1414
|
+
createElement(Text, { style: styles.loadingText }, loadingLabel)
|
|
1415
|
+
)
|
|
1416
|
+
}) : null
|
|
1417
|
+
)
|
|
1319
1418
|
)
|
|
1320
1419
|
)
|
|
1321
1420
|
);
|
|
1322
1421
|
}
|
|
1323
|
-
var styles =
|
|
1422
|
+
var styles = StyleSheet.create({
|
|
1324
1423
|
root: {
|
|
1325
1424
|
flex: 1
|
|
1326
1425
|
},
|
|
@@ -1328,6 +1427,11 @@ var styles = import_react_native.StyleSheet.create({
|
|
|
1328
1427
|
flex: 1,
|
|
1329
1428
|
backgroundColor: "#ffffff"
|
|
1330
1429
|
},
|
|
1430
|
+
modalContent: {
|
|
1431
|
+
flex: 1,
|
|
1432
|
+
width: "100%",
|
|
1433
|
+
backgroundColor: "#ffffff"
|
|
1434
|
+
},
|
|
1331
1435
|
header: {
|
|
1332
1436
|
minHeight: 48,
|
|
1333
1437
|
alignItems: "flex-end",
|
|
@@ -1401,7 +1505,7 @@ var styles = import_react_native.StyleSheet.create({
|
|
|
1401
1505
|
borderStyle: "none"
|
|
1402
1506
|
},
|
|
1403
1507
|
loading: {
|
|
1404
|
-
...
|
|
1508
|
+
...StyleSheet.absoluteFillObject,
|
|
1405
1509
|
alignItems: "center",
|
|
1406
1510
|
justifyContent: "center",
|
|
1407
1511
|
backgroundColor: "#ffffff"
|
|
@@ -1414,7 +1518,7 @@ var styles = import_react_native.StyleSheet.create({
|
|
|
1414
1518
|
});
|
|
1415
1519
|
|
|
1416
1520
|
// src/hooks/useSagepilotChat.ts
|
|
1417
|
-
|
|
1521
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useState as useState2 } from "react";
|
|
1418
1522
|
function readState() {
|
|
1419
1523
|
const state = SagepilotChat.getState();
|
|
1420
1524
|
return {
|
|
@@ -1426,23 +1530,25 @@ function readState() {
|
|
|
1426
1530
|
};
|
|
1427
1531
|
}
|
|
1428
1532
|
function useSagepilotChat() {
|
|
1429
|
-
const [state, setState] = (
|
|
1430
|
-
(
|
|
1533
|
+
const [state, setState] = useState2(readState);
|
|
1534
|
+
useEffect2(() => {
|
|
1431
1535
|
return SagepilotChat.onStateChange(() => {
|
|
1432
1536
|
setState(readState());
|
|
1433
1537
|
});
|
|
1434
1538
|
}, []);
|
|
1435
|
-
const present = (
|
|
1436
|
-
const presentMessages = (
|
|
1437
|
-
const presentMessageComposer = (
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
const
|
|
1441
|
-
const
|
|
1539
|
+
const present = useCallback2(() => SagepilotChat.present(), []);
|
|
1540
|
+
const presentMessages = useCallback2(() => SagepilotChat.presentMessages(), []);
|
|
1541
|
+
const presentMessageComposer = useCallback2((message, options) => {
|
|
1542
|
+
return SagepilotChat.presentMessageComposer(message, options);
|
|
1543
|
+
}, []);
|
|
1544
|
+
const dismiss = useCallback2(() => SagepilotChat.dismiss(), []);
|
|
1545
|
+
const hide = useCallback2(() => SagepilotChat.hide(), []);
|
|
1546
|
+
const toggle = useCallback2(() => SagepilotChat.toggle(), []);
|
|
1547
|
+
const identify = useCallback2((identity) => {
|
|
1442
1548
|
return SagepilotChat.identify(identity);
|
|
1443
1549
|
}, []);
|
|
1444
|
-
const logout = (
|
|
1445
|
-
const getUnreadCount = (
|
|
1550
|
+
const logout = useCallback2(() => SagepilotChat.logout(), []);
|
|
1551
|
+
const getUnreadCount = useCallback2(() => SagepilotChat.getUnreadCount(), []);
|
|
1446
1552
|
return {
|
|
1447
1553
|
...state,
|
|
1448
1554
|
present,
|
|
@@ -1456,12 +1562,11 @@ function useSagepilotChat() {
|
|
|
1456
1562
|
getUnreadCount
|
|
1457
1563
|
};
|
|
1458
1564
|
}
|
|
1459
|
-
|
|
1460
|
-
0 && (module.exports = {
|
|
1565
|
+
export {
|
|
1461
1566
|
SagepilotChat,
|
|
1462
1567
|
SagepilotChatError,
|
|
1463
1568
|
SagepilotChatProvider,
|
|
1464
1569
|
createAsyncStorageCacheStorage,
|
|
1465
1570
|
createKeychainTokenStorage,
|
|
1466
1571
|
useSagepilotChat
|
|
1467
|
-
}
|
|
1572
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sagepilot-ai/react-native-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Sagepilot AI React Native chat SDK",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sagepilot",
|
|
@@ -11,28 +11,38 @@
|
|
|
11
11
|
"sdk"
|
|
12
12
|
],
|
|
13
13
|
"license": "MIT",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"module": "./dist/index.mjs",
|
|
16
|
+
"react-native": "./dist/index.js",
|
|
17
17
|
"types": "./dist/index.d.ts",
|
|
18
18
|
"exports": {
|
|
19
19
|
".": {
|
|
20
20
|
"types": "./dist/index.d.ts",
|
|
21
|
-
"import": "./dist/index.
|
|
22
|
-
"require": "./dist/index.
|
|
21
|
+
"import": "./dist/index.mjs",
|
|
22
|
+
"require": "./dist/index.js"
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
"LICENSE.md",
|
|
27
|
-
"android",
|
|
27
|
+
"android/build.gradle",
|
|
28
|
+
"android/src",
|
|
28
29
|
"dist",
|
|
29
30
|
"ios",
|
|
30
31
|
"react-native.config.js",
|
|
32
|
+
"src/specs",
|
|
31
33
|
"README.md"
|
|
32
34
|
],
|
|
35
|
+
"codegenConfig": {
|
|
36
|
+
"name": "SagepilotReactNativeSdkSpec",
|
|
37
|
+
"type": "components",
|
|
38
|
+
"jsSrcsDir": "./src/specs",
|
|
39
|
+
"android": {
|
|
40
|
+
"javaPackageName": "ai.sagepilot.reactnativesdk"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
33
43
|
"sideEffects": false,
|
|
34
44
|
"scripts": {
|
|
35
|
-
"build": "tsup
|
|
45
|
+
"build": "tsup",
|
|
36
46
|
"typecheck": "tsc --noEmit",
|
|
37
47
|
"prepublishOnly": "npm run typecheck && npm run build"
|
|
38
48
|
},
|
package/react-native.config.js
CHANGED
|
@@ -2,7 +2,11 @@ module.exports = {
|
|
|
2
2
|
dependency: {
|
|
3
3
|
platforms: {
|
|
4
4
|
ios: {},
|
|
5
|
-
android: {
|
|
5
|
+
android: {
|
|
6
|
+
sourceDir: "./android",
|
|
7
|
+
packageImportPath: "import ai.sagepilot.reactnativesdk.SagepilotReactNativeSdkPackage;",
|
|
8
|
+
packageInstance: "new SagepilotReactNativeSdkPackage()"
|
|
9
|
+
}
|
|
6
10
|
}
|
|
7
11
|
}
|
|
8
12
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { HostComponent, ViewProps } from "react-native";
|
|
2
|
+
import type { DirectEventHandler, Double } from "react-native/Libraries/Types/CodegenTypes";
|
|
3
|
+
import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
|
|
4
|
+
|
|
5
|
+
export type SagepilotInsetsChangeEvent = Readonly<{
|
|
6
|
+
top: Double;
|
|
7
|
+
bottom: Double;
|
|
8
|
+
imeBottom: Double;
|
|
9
|
+
systemBarsBottom: Double;
|
|
10
|
+
keyboardVisible: boolean;
|
|
11
|
+
}>;
|
|
12
|
+
|
|
13
|
+
export interface NativeProps extends ViewProps {
|
|
14
|
+
onInsetsChange?: DirectEventHandler<SagepilotInsetsChangeEvent>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default codegenNativeComponent<NativeProps>("SagepilotInsetsView") as HostComponent<NativeProps>;
|
package/android/.gitkeep
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|