@sagepilot-ai/react-native-sdk 0.2.0 → 0.2.2
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/dist/index.cjs +57 -3
- package/dist/index.js +59 -4
- package/package.json +1 -1
- package/LICENSE.md +0 -21
package/dist/index.cjs
CHANGED
|
@@ -830,6 +830,9 @@ var SagepilotReactNativeChat = class {
|
|
|
830
830
|
}
|
|
831
831
|
url.searchParams.set("session_id", session.session_id);
|
|
832
832
|
url.searchParams.set("wid", this.workspaceId);
|
|
833
|
+
if (this.legacyWidgetJwt) {
|
|
834
|
+
url.searchParams.set("jwt", this.legacyWidgetJwt);
|
|
835
|
+
}
|
|
833
836
|
if (this.hostedChatView.screen === "composer") {
|
|
834
837
|
url.searchParams.set("new", "true");
|
|
835
838
|
if (this.hostedChatView.message) {
|
|
@@ -857,6 +860,16 @@ var SagepilotReactNativeChat = class {
|
|
|
857
860
|
"})();"
|
|
858
861
|
].join("\n");
|
|
859
862
|
}
|
|
863
|
+
getHostedIdentityMessage() {
|
|
864
|
+
if (!this.legacyWidgetJwt) return null;
|
|
865
|
+
return {
|
|
866
|
+
type: "identity_update",
|
|
867
|
+
data: {
|
|
868
|
+
jwt: this.legacyWidgetJwt,
|
|
869
|
+
chat_id: this.session?.conversation_id ?? void 0
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
}
|
|
860
873
|
handleHostedBridgeMessage(message) {
|
|
861
874
|
if (!message) return false;
|
|
862
875
|
if (message.type === "close_widget") {
|
|
@@ -1184,6 +1197,20 @@ function getInjectedWebViewScript() {
|
|
|
1184
1197
|
mobileWebViewBridgeScript
|
|
1185
1198
|
].filter(Boolean).join("\n");
|
|
1186
1199
|
}
|
|
1200
|
+
function getHostedIdentityDispatchScript() {
|
|
1201
|
+
const message = internalSagepilotChat.getHostedIdentityMessage();
|
|
1202
|
+
if (!message) return "";
|
|
1203
|
+
return [
|
|
1204
|
+
internalSagepilotChat.getHostedAuthScript(),
|
|
1205
|
+
"(function(){",
|
|
1206
|
+
"try {",
|
|
1207
|
+
`var message = ${JSON.stringify(message)};`,
|
|
1208
|
+
"window.dispatchEvent(new MessageEvent('message', { data: message, origin: window.location.origin, source: window.parent || window }));",
|
|
1209
|
+
"} catch (_) {}",
|
|
1210
|
+
"true;",
|
|
1211
|
+
"})();"
|
|
1212
|
+
].filter(Boolean).join("\n");
|
|
1213
|
+
}
|
|
1187
1214
|
function readUrlOrigin(url) {
|
|
1188
1215
|
if (!url) return null;
|
|
1189
1216
|
try {
|
|
@@ -1207,6 +1234,8 @@ function SagepilotChatProvider({
|
|
|
1207
1234
|
loadingLabel = "Loading chat"
|
|
1208
1235
|
}) {
|
|
1209
1236
|
const [state, setState] = (0, import_react.useState)(readPresentationState);
|
|
1237
|
+
const webFrameRef = (0, import_react.useRef)(null);
|
|
1238
|
+
const nativeWebViewRef = (0, import_react.useRef)(null);
|
|
1210
1239
|
(0, import_react.useEffect)(() => {
|
|
1211
1240
|
return internalSagepilotChat.onStateChange(() => {
|
|
1212
1241
|
setState(readPresentationState());
|
|
@@ -1214,10 +1243,23 @@ function SagepilotChatProvider({
|
|
|
1214
1243
|
}, []);
|
|
1215
1244
|
const showCloseButton = state.presentation?.showCloseButton ?? false;
|
|
1216
1245
|
const presentationStyle = state.presentation?.style ?? "sheet";
|
|
1246
|
+
const isFullScreenModal = presentationStyle === "fullScreen";
|
|
1217
1247
|
const animationType = presentationStyle === "fullScreen" || presentationStyle === "push" ? "slide" : "fade";
|
|
1248
|
+
const ModalContainer = import_react_native.Platform.OS === "ios" && isFullScreenModal ? import_react_native.SafeAreaView : import_react_native.View;
|
|
1218
1249
|
const handleWebViewMessage = (event) => {
|
|
1219
1250
|
internalSagepilotChat.handleHostedBridgeMessage(parseHostedBridgeMessage(event.nativeEvent?.data));
|
|
1220
1251
|
};
|
|
1252
|
+
const postIdentityToWebFrame = () => {
|
|
1253
|
+
const message = internalSagepilotChat.getHostedIdentityMessage();
|
|
1254
|
+
const targetOrigin = readUrlOrigin(state.conversationUrl);
|
|
1255
|
+
if (!message || !targetOrigin) return;
|
|
1256
|
+
webFrameRef.current?.contentWindow?.postMessage(message, targetOrigin);
|
|
1257
|
+
};
|
|
1258
|
+
const postIdentityToNativeWebView = () => {
|
|
1259
|
+
const script = getHostedIdentityDispatchScript();
|
|
1260
|
+
if (!script || !nativeWebViewRef.current) return;
|
|
1261
|
+
nativeWebViewRef.current.injectJavaScript(script);
|
|
1262
|
+
};
|
|
1221
1263
|
(0, import_react.useEffect)(() => {
|
|
1222
1264
|
if (import_react_native.Platform.OS !== "web" || typeof window === "undefined") return;
|
|
1223
1265
|
const trustedWidgetOrigin = readUrlOrigin(state.conversationUrl);
|
|
@@ -1229,6 +1271,14 @@ function SagepilotChatProvider({
|
|
|
1229
1271
|
window.addEventListener("message", handleWindowMessage);
|
|
1230
1272
|
return () => window.removeEventListener("message", handleWindowMessage);
|
|
1231
1273
|
}, [state.conversationUrl]);
|
|
1274
|
+
(0, import_react.useEffect)(() => {
|
|
1275
|
+
if (import_react_native.Platform.OS !== "web" || !state.isPresented) return;
|
|
1276
|
+
postIdentityToWebFrame();
|
|
1277
|
+
}, [state.isPresented, state.conversationUrl, state.configured]);
|
|
1278
|
+
(0, import_react.useEffect)(() => {
|
|
1279
|
+
if (import_react_native.Platform.OS === "web" || !state.isPresented) return;
|
|
1280
|
+
postIdentityToNativeWebView();
|
|
1281
|
+
}, [state.isPresented, state.conversationUrl, state.configured]);
|
|
1232
1282
|
if (import_react_native.Platform.OS === "web") {
|
|
1233
1283
|
return (0, import_react.createElement)(
|
|
1234
1284
|
import_react_native.View,
|
|
@@ -1256,9 +1306,11 @@ function SagepilotChatProvider({
|
|
|
1256
1306
|
(0, import_react.createElement)(import_react_native.Text, { style: styles.closeText }, closeLabel)
|
|
1257
1307
|
) : null,
|
|
1258
1308
|
(0, import_react.createElement)("iframe", {
|
|
1309
|
+
ref: webFrameRef,
|
|
1259
1310
|
src: state.conversationUrl,
|
|
1260
1311
|
style: styles.webFrame,
|
|
1261
|
-
title: "Sagepilot chat"
|
|
1312
|
+
title: "Sagepilot chat",
|
|
1313
|
+
onLoad: postIdentityToWebFrame
|
|
1262
1314
|
})
|
|
1263
1315
|
)
|
|
1264
1316
|
) : null
|
|
@@ -1280,11 +1332,11 @@ function SagepilotChatProvider({
|
|
|
1280
1332
|
{
|
|
1281
1333
|
visible: state.configured && state.isPresented,
|
|
1282
1334
|
animationType,
|
|
1283
|
-
presentationStyle:
|
|
1335
|
+
presentationStyle: isFullScreenModal ? "fullScreen" : "pageSheet",
|
|
1284
1336
|
onRequestClose: () => internalSagepilotChat.dismiss()
|
|
1285
1337
|
},
|
|
1286
1338
|
(0, import_react.createElement)(
|
|
1287
|
-
|
|
1339
|
+
ModalContainer,
|
|
1288
1340
|
{ style: styles.container },
|
|
1289
1341
|
showCloseButton ? (0, import_react.createElement)(
|
|
1290
1342
|
import_react_native.View,
|
|
@@ -1302,11 +1354,13 @@ function SagepilotChatProvider({
|
|
|
1302
1354
|
) : null,
|
|
1303
1355
|
state.conversationUrl ? (0, import_react.createElement)(import_react_native_webview.WebView, {
|
|
1304
1356
|
...hostedChatWebViewProps,
|
|
1357
|
+
ref: nativeWebViewRef,
|
|
1305
1358
|
source: { uri: state.conversationUrl },
|
|
1306
1359
|
style: styles.webview,
|
|
1307
1360
|
startInLoadingState: true,
|
|
1308
1361
|
injectedJavaScriptBeforeContentLoaded: getInjectedWebViewScript(),
|
|
1309
1362
|
onMessage: handleWebViewMessage,
|
|
1363
|
+
onLoadEnd: postIdentityToNativeWebView,
|
|
1310
1364
|
renderLoading: () => (0, import_react.createElement)(
|
|
1311
1365
|
import_react_native.View,
|
|
1312
1366
|
{ style: styles.loading },
|
package/dist/index.js
CHANGED
|
@@ -799,6 +799,9 @@ var SagepilotReactNativeChat = class {
|
|
|
799
799
|
}
|
|
800
800
|
url.searchParams.set("session_id", session.session_id);
|
|
801
801
|
url.searchParams.set("wid", this.workspaceId);
|
|
802
|
+
if (this.legacyWidgetJwt) {
|
|
803
|
+
url.searchParams.set("jwt", this.legacyWidgetJwt);
|
|
804
|
+
}
|
|
802
805
|
if (this.hostedChatView.screen === "composer") {
|
|
803
806
|
url.searchParams.set("new", "true");
|
|
804
807
|
if (this.hostedChatView.message) {
|
|
@@ -826,6 +829,16 @@ var SagepilotReactNativeChat = class {
|
|
|
826
829
|
"})();"
|
|
827
830
|
].join("\n");
|
|
828
831
|
}
|
|
832
|
+
getHostedIdentityMessage() {
|
|
833
|
+
if (!this.legacyWidgetJwt) return null;
|
|
834
|
+
return {
|
|
835
|
+
type: "identity_update",
|
|
836
|
+
data: {
|
|
837
|
+
jwt: this.legacyWidgetJwt,
|
|
838
|
+
chat_id: this.session?.conversation_id ?? void 0
|
|
839
|
+
}
|
|
840
|
+
};
|
|
841
|
+
}
|
|
829
842
|
handleHostedBridgeMessage(message) {
|
|
830
843
|
if (!message) return false;
|
|
831
844
|
if (message.type === "close_widget") {
|
|
@@ -1046,12 +1059,13 @@ function createAsyncStorageCacheStorage(asyncStorage) {
|
|
|
1046
1059
|
}
|
|
1047
1060
|
|
|
1048
1061
|
// src/ui/SagepilotChatProvider.ts
|
|
1049
|
-
import { createElement, useEffect, useState } from "react";
|
|
1062
|
+
import { createElement, useEffect, useRef, useState } from "react";
|
|
1050
1063
|
import {
|
|
1051
1064
|
ActivityIndicator,
|
|
1052
1065
|
Modal,
|
|
1053
1066
|
Platform,
|
|
1054
1067
|
Pressable,
|
|
1068
|
+
SafeAreaView,
|
|
1055
1069
|
StyleSheet,
|
|
1056
1070
|
Text,
|
|
1057
1071
|
View
|
|
@@ -1161,6 +1175,20 @@ function getInjectedWebViewScript() {
|
|
|
1161
1175
|
mobileWebViewBridgeScript
|
|
1162
1176
|
].filter(Boolean).join("\n");
|
|
1163
1177
|
}
|
|
1178
|
+
function getHostedIdentityDispatchScript() {
|
|
1179
|
+
const message = internalSagepilotChat.getHostedIdentityMessage();
|
|
1180
|
+
if (!message) return "";
|
|
1181
|
+
return [
|
|
1182
|
+
internalSagepilotChat.getHostedAuthScript(),
|
|
1183
|
+
"(function(){",
|
|
1184
|
+
"try {",
|
|
1185
|
+
`var message = ${JSON.stringify(message)};`,
|
|
1186
|
+
"window.dispatchEvent(new MessageEvent('message', { data: message, origin: window.location.origin, source: window.parent || window }));",
|
|
1187
|
+
"} catch (_) {}",
|
|
1188
|
+
"true;",
|
|
1189
|
+
"})();"
|
|
1190
|
+
].filter(Boolean).join("\n");
|
|
1191
|
+
}
|
|
1164
1192
|
function readUrlOrigin(url) {
|
|
1165
1193
|
if (!url) return null;
|
|
1166
1194
|
try {
|
|
@@ -1184,6 +1212,8 @@ function SagepilotChatProvider({
|
|
|
1184
1212
|
loadingLabel = "Loading chat"
|
|
1185
1213
|
}) {
|
|
1186
1214
|
const [state, setState] = useState(readPresentationState);
|
|
1215
|
+
const webFrameRef = useRef(null);
|
|
1216
|
+
const nativeWebViewRef = useRef(null);
|
|
1187
1217
|
useEffect(() => {
|
|
1188
1218
|
return internalSagepilotChat.onStateChange(() => {
|
|
1189
1219
|
setState(readPresentationState());
|
|
@@ -1191,10 +1221,23 @@ function SagepilotChatProvider({
|
|
|
1191
1221
|
}, []);
|
|
1192
1222
|
const showCloseButton = state.presentation?.showCloseButton ?? false;
|
|
1193
1223
|
const presentationStyle = state.presentation?.style ?? "sheet";
|
|
1224
|
+
const isFullScreenModal = presentationStyle === "fullScreen";
|
|
1194
1225
|
const animationType = presentationStyle === "fullScreen" || presentationStyle === "push" ? "slide" : "fade";
|
|
1226
|
+
const ModalContainer = Platform.OS === "ios" && isFullScreenModal ? SafeAreaView : View;
|
|
1195
1227
|
const handleWebViewMessage = (event) => {
|
|
1196
1228
|
internalSagepilotChat.handleHostedBridgeMessage(parseHostedBridgeMessage(event.nativeEvent?.data));
|
|
1197
1229
|
};
|
|
1230
|
+
const postIdentityToWebFrame = () => {
|
|
1231
|
+
const message = internalSagepilotChat.getHostedIdentityMessage();
|
|
1232
|
+
const targetOrigin = readUrlOrigin(state.conversationUrl);
|
|
1233
|
+
if (!message || !targetOrigin) return;
|
|
1234
|
+
webFrameRef.current?.contentWindow?.postMessage(message, targetOrigin);
|
|
1235
|
+
};
|
|
1236
|
+
const postIdentityToNativeWebView = () => {
|
|
1237
|
+
const script = getHostedIdentityDispatchScript();
|
|
1238
|
+
if (!script || !nativeWebViewRef.current) return;
|
|
1239
|
+
nativeWebViewRef.current.injectJavaScript(script);
|
|
1240
|
+
};
|
|
1198
1241
|
useEffect(() => {
|
|
1199
1242
|
if (Platform.OS !== "web" || typeof window === "undefined") return;
|
|
1200
1243
|
const trustedWidgetOrigin = readUrlOrigin(state.conversationUrl);
|
|
@@ -1206,6 +1249,14 @@ function SagepilotChatProvider({
|
|
|
1206
1249
|
window.addEventListener("message", handleWindowMessage);
|
|
1207
1250
|
return () => window.removeEventListener("message", handleWindowMessage);
|
|
1208
1251
|
}, [state.conversationUrl]);
|
|
1252
|
+
useEffect(() => {
|
|
1253
|
+
if (Platform.OS !== "web" || !state.isPresented) return;
|
|
1254
|
+
postIdentityToWebFrame();
|
|
1255
|
+
}, [state.isPresented, state.conversationUrl, state.configured]);
|
|
1256
|
+
useEffect(() => {
|
|
1257
|
+
if (Platform.OS === "web" || !state.isPresented) return;
|
|
1258
|
+
postIdentityToNativeWebView();
|
|
1259
|
+
}, [state.isPresented, state.conversationUrl, state.configured]);
|
|
1209
1260
|
if (Platform.OS === "web") {
|
|
1210
1261
|
return createElement(
|
|
1211
1262
|
View,
|
|
@@ -1233,9 +1284,11 @@ function SagepilotChatProvider({
|
|
|
1233
1284
|
createElement(Text, { style: styles.closeText }, closeLabel)
|
|
1234
1285
|
) : null,
|
|
1235
1286
|
createElement("iframe", {
|
|
1287
|
+
ref: webFrameRef,
|
|
1236
1288
|
src: state.conversationUrl,
|
|
1237
1289
|
style: styles.webFrame,
|
|
1238
|
-
title: "Sagepilot chat"
|
|
1290
|
+
title: "Sagepilot chat",
|
|
1291
|
+
onLoad: postIdentityToWebFrame
|
|
1239
1292
|
})
|
|
1240
1293
|
)
|
|
1241
1294
|
) : null
|
|
@@ -1257,11 +1310,11 @@ function SagepilotChatProvider({
|
|
|
1257
1310
|
{
|
|
1258
1311
|
visible: state.configured && state.isPresented,
|
|
1259
1312
|
animationType,
|
|
1260
|
-
presentationStyle:
|
|
1313
|
+
presentationStyle: isFullScreenModal ? "fullScreen" : "pageSheet",
|
|
1261
1314
|
onRequestClose: () => internalSagepilotChat.dismiss()
|
|
1262
1315
|
},
|
|
1263
1316
|
createElement(
|
|
1264
|
-
|
|
1317
|
+
ModalContainer,
|
|
1265
1318
|
{ style: styles.container },
|
|
1266
1319
|
showCloseButton ? createElement(
|
|
1267
1320
|
View,
|
|
@@ -1279,11 +1332,13 @@ function SagepilotChatProvider({
|
|
|
1279
1332
|
) : null,
|
|
1280
1333
|
state.conversationUrl ? createElement(WebView, {
|
|
1281
1334
|
...hostedChatWebViewProps,
|
|
1335
|
+
ref: nativeWebViewRef,
|
|
1282
1336
|
source: { uri: state.conversationUrl },
|
|
1283
1337
|
style: styles.webview,
|
|
1284
1338
|
startInLoadingState: true,
|
|
1285
1339
|
injectedJavaScriptBeforeContentLoaded: getInjectedWebViewScript(),
|
|
1286
1340
|
onMessage: handleWebViewMessage,
|
|
1341
|
+
onLoadEnd: postIdentityToNativeWebView,
|
|
1287
1342
|
renderLoading: () => createElement(
|
|
1288
1343
|
View,
|
|
1289
1344
|
{ style: styles.loading },
|
package/package.json
CHANGED
package/LICENSE.md
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Sagepilot AI
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|