@sagepilot-ai/react-native-sdk 0.2.2 → 0.2.4

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.js CHANGED
@@ -1,3 +1,44 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ SagepilotChat: () => SagepilotChat,
34
+ SagepilotChatError: () => SagepilotChatError,
35
+ SagepilotChatProvider: () => SagepilotChatProvider,
36
+ createAsyncStorageCacheStorage: () => createAsyncStorageCacheStorage,
37
+ createKeychainTokenStorage: () => createKeychainTokenStorage,
38
+ useSagepilotChat: () => useSagepilotChat
39
+ });
40
+ module.exports = __toCommonJS(index_exports);
41
+
1
42
  // src/core/errors/SagepilotChatError.ts
2
43
  var SagepilotChatError = class extends Error {
3
44
  constructor(code, message, options = {}) {
@@ -15,7 +56,7 @@ var SagepilotChatError = class extends Error {
15
56
 
16
57
  // src/core/config/constants.ts
17
58
  var SDK_NAME = "@sagepilot-ai/react-native-sdk";
18
- var SDK_VERSION = "0.2.0";
59
+ var SDK_VERSION = "0.2.4";
19
60
  var DEFAULT_HOST = "https://app.sagepilot.ai";
20
61
  var DEFAULT_WIDGET_HOST = "https://app.sagepilot.ai";
21
62
  var CUSTOMER_API_PREFIX = "/customer-api/v1";
@@ -464,6 +505,18 @@ function normalizeIdentity(identity) {
464
505
  user_hash: identity.userHash ?? identity.user_hash
465
506
  };
466
507
  }
508
+ function readStringField(input, key) {
509
+ const value = input[key];
510
+ return typeof value === "string" && value.trim() ? value : void 0;
511
+ }
512
+ function normalizeOptionalString(value) {
513
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
514
+ }
515
+ function readRecordField(input, key) {
516
+ const value = input[key];
517
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
518
+ return value;
519
+ }
467
520
  function toPublicSessionState(session) {
468
521
  return {
469
522
  session_id: session.session_id,
@@ -497,6 +550,7 @@ var SagepilotReactNativeChat = class {
497
550
  this.unreadPollTimer = null;
498
551
  this.stateCallbacks = /* @__PURE__ */ new Set();
499
552
  this.identifyCallbacks = /* @__PURE__ */ new Set();
553
+ this.conversationCreatedCallbacks = /* @__PURE__ */ new Set();
500
554
  this.unreadCallbacks = /* @__PURE__ */ new Set();
501
555
  this.readyCallbacks = /* @__PURE__ */ new Set();
502
556
  this.presentCallbacks = /* @__PURE__ */ new Set();
@@ -701,9 +755,17 @@ var SagepilotReactNativeChat = class {
701
755
  this.hostedChatView = { screen: "messages" };
702
756
  return this.showHostedChat();
703
757
  }
704
- presentMessageComposer(message) {
758
+ presentMessageComposer(message, options) {
705
759
  this.requireConfigured();
706
- this.hostedChatView = { screen: "composer", message };
760
+ const chatId = normalizeOptionalString(options?.chatId);
761
+ this.hostedChatView = {
762
+ screen: "composer",
763
+ message,
764
+ mode: options?.mode ?? "auto",
765
+ chatId,
766
+ metadata: options?.metadata,
767
+ onConversationCreated: options?.onConversationCreated
768
+ };
707
769
  return this.showHostedChat();
708
770
  }
709
771
  dismiss() {
@@ -752,6 +814,13 @@ var SagepilotReactNativeChat = class {
752
814
  this.dismissCallbacks.delete(callback);
753
815
  };
754
816
  }
817
+ onConversationCreated(callback) {
818
+ if (typeof callback !== "function") return () => void 0;
819
+ this.conversationCreatedCallbacks.add(callback);
820
+ return () => {
821
+ this.conversationCreatedCallbacks.delete(callback);
822
+ };
823
+ }
755
824
  onError(callback) {
756
825
  if (typeof callback !== "function") return () => void 0;
757
826
  this.errorCallbacks.add(callback);
@@ -803,7 +872,12 @@ var SagepilotReactNativeChat = class {
803
872
  url.searchParams.set("jwt", this.legacyWidgetJwt);
804
873
  }
805
874
  if (this.hostedChatView.screen === "composer") {
806
- url.searchParams.set("new", "true");
875
+ if (this.hostedChatView.chatId) {
876
+ url.searchParams.set("chat_id", this.hostedChatView.chatId);
877
+ }
878
+ if (this.hostedChatView.mode === "new" && !this.hostedChatView.chatId) {
879
+ url.searchParams.set("new", "true");
880
+ }
807
881
  if (this.hostedChatView.message) {
808
882
  url.searchParams.set("topic", this.hostedChatView.message);
809
883
  }
@@ -829,13 +903,19 @@ var SagepilotReactNativeChat = class {
829
903
  "})();"
830
904
  ].join("\n");
831
905
  }
906
+ getActiveHostedChatId() {
907
+ if (this.hostedChatView.screen === "composer" && this.hostedChatView.chatId) {
908
+ return this.hostedChatView.chatId;
909
+ }
910
+ return this.session?.conversation_id ?? void 0;
911
+ }
832
912
  getHostedIdentityMessage() {
833
913
  if (!this.legacyWidgetJwt) return null;
834
914
  return {
835
915
  type: "identity_update",
836
916
  data: {
837
917
  jwt: this.legacyWidgetJwt,
838
- chat_id: this.session?.conversation_id ?? void 0
918
+ chat_id: this.getActiveHostedChatId()
839
919
  }
840
920
  };
841
921
  }
@@ -854,17 +934,62 @@ var SagepilotReactNativeChat = class {
854
934
  }
855
935
  return true;
856
936
  }
937
+ if (message.type === "sagepilot:conversation_created") {
938
+ this.handleConversationCreated(message);
939
+ return true;
940
+ }
857
941
  if (message.type === "sagepilot:error") {
858
942
  this.emitError(message);
859
943
  return true;
860
944
  }
861
945
  return true;
862
946
  }
947
+ handleConversationCreated(message) {
948
+ const chatId = readStringField(message, "chat_id") ?? readStringField(message, "conversation_id");
949
+ if (!chatId) return;
950
+ void this.persistConversationId(chatId).catch((error) => this.emitError(error));
951
+ const bridgeMetadata = readRecordField(message, "metadata");
952
+ const composerMetadata = this.hostedChatView.screen === "composer" ? this.hostedChatView.metadata : void 0;
953
+ const metadata = {
954
+ ...composerMetadata ?? {},
955
+ ...bridgeMetadata ?? {}
956
+ };
957
+ const workspaceId = readStringField(message, "workspace_id") ?? this.workspaceId;
958
+ const channelId = readStringField(message, "channel_id") ?? this.channelId;
959
+ const sessionId = readStringField(message, "session_id") ?? this.session?.session_id;
960
+ const customerId = readStringField(message, "customer_id");
961
+ const messageId = readStringField(message, "message_id");
962
+ const createdAt = readStringField(message, "created_at");
963
+ const event = {
964
+ chat_id: chatId,
965
+ ...workspaceId ? { workspace_id: workspaceId } : {},
966
+ ...channelId ? { channel_id: channelId } : {},
967
+ ...sessionId ? { session_id: sessionId } : {},
968
+ ...customerId ? { customer_id: customerId } : {},
969
+ ...messageId ? { message_id: messageId } : {},
970
+ ...createdAt ? { created_at: createdAt } : {},
971
+ ...Object.keys(metadata).length > 0 ? { metadata } : {}
972
+ };
973
+ if (this.hostedChatView.screen === "composer") {
974
+ this.hostedChatView.onConversationCreated?.(event);
975
+ }
976
+ this.conversationCreatedCallbacks.forEach((callback) => callback(event));
977
+ }
978
+ async persistConversationId(conversationId) {
979
+ if (!this.session || !this.sessionManager) return;
980
+ if (this.session.conversation_id === conversationId) return;
981
+ this.session = await this.sessionManager.setSession({
982
+ ...this.session,
983
+ conversation_id: conversationId
984
+ });
985
+ this.emitState();
986
+ }
863
987
  destroy() {
864
988
  this.stopUnreadPolling();
865
989
  this.resetRuntimeState();
866
990
  this.emitState();
867
991
  this.identifyCallbacks.clear();
992
+ this.conversationCreatedCallbacks.clear();
868
993
  this.unreadCallbacks.clear();
869
994
  this.readyCallbacks.clear();
870
995
  this.presentCallbacks.clear();
@@ -1027,13 +1152,18 @@ var SagepilotChat = {
1027
1152
  logout: () => internalSagepilotChat.logout(),
1028
1153
  getIdentityState: () => internalSagepilotChat.getIdentityState(),
1029
1154
  onIdentify: (callback) => internalSagepilotChat.onIdentify(callback),
1155
+ onConversationCreated: (callback) => {
1156
+ return internalSagepilotChat.onConversationCreated(callback);
1157
+ },
1030
1158
  getUnreadCount: () => internalSagepilotChat.getUnreadCount(),
1031
1159
  onUnreadChange: (callback) => internalSagepilotChat.onUnreadChange(callback),
1032
1160
  startUnreadPolling: (intervalMs) => internalSagepilotChat.startUnreadPolling(intervalMs),
1033
1161
  stopUnreadPolling: () => internalSagepilotChat.stopUnreadPolling(),
1034
1162
  present: () => internalSagepilotChat.present(),
1035
1163
  presentMessages: () => internalSagepilotChat.presentMessages(),
1036
- presentMessageComposer: (message) => internalSagepilotChat.presentMessageComposer(message),
1164
+ presentMessageComposer: (message, options) => {
1165
+ return internalSagepilotChat.presentMessageComposer(message, options);
1166
+ },
1037
1167
  dismiss: () => internalSagepilotChat.dismiss(),
1038
1168
  hide: () => internalSagepilotChat.hide(),
1039
1169
  toggle: () => internalSagepilotChat.toggle(),
@@ -1059,18 +1189,9 @@ function createAsyncStorageCacheStorage(asyncStorage) {
1059
1189
  }
1060
1190
 
1061
1191
  // src/ui/SagepilotChatProvider.ts
1062
- import { createElement, useEffect, useRef, useState } from "react";
1063
- import {
1064
- ActivityIndicator,
1065
- Modal,
1066
- Platform,
1067
- Pressable,
1068
- SafeAreaView,
1069
- StyleSheet,
1070
- Text,
1071
- View
1072
- } from "react-native";
1073
- import { WebView } from "react-native-webview";
1192
+ var import_react = require("react");
1193
+ var import_react_native = require("react-native");
1194
+ var import_react_native_webview = require("react-native-webview");
1074
1195
 
1075
1196
  // src/core/webview/mobileBridge.ts
1076
1197
  function isHostedBridgeMessage(value) {
@@ -1151,6 +1272,28 @@ var mobileWebViewBridgeScript = `
1151
1272
  } catch (error) {}
1152
1273
  }, true);
1153
1274
 
1275
+ document.addEventListener("focusin", function (event) {
1276
+ try {
1277
+ var target = event.target && event.target.closest
1278
+ ? event.target
1279
+ : event.target && event.target.parentElement;
1280
+ if (target && target.closest && target.closest("input, textarea, [contenteditable='true']")) {
1281
+ sendToReactNative({ type: "sagepilot:keyboard_focus" });
1282
+ }
1283
+ } catch (error) {}
1284
+ }, true);
1285
+
1286
+ document.addEventListener("focusout", function (event) {
1287
+ try {
1288
+ var target = event.target && event.target.closest
1289
+ ? event.target
1290
+ : event.target && event.target.parentElement;
1291
+ if (target && target.closest && target.closest("input, textarea, [contenteditable='true']")) {
1292
+ sendToReactNative({ type: "sagepilot:keyboard_blur" });
1293
+ }
1294
+ } catch (error) {}
1295
+ }, true);
1296
+
1154
1297
  ensureViewport();
1155
1298
  injectMobileStyles();
1156
1299
  sendToReactNative({ type: "sagepilot:ready" });
@@ -1158,6 +1301,10 @@ var mobileWebViewBridgeScript = `
1158
1301
  })();
1159
1302
  `;
1160
1303
 
1304
+ // src/specs/SagepilotInsetsViewNativeComponent.ts
1305
+ var import_codegenNativeComponent = __toESM(require("react-native/Libraries/Utilities/codegenNativeComponent"));
1306
+ var SagepilotInsetsViewNativeComponent_default = (0, import_codegenNativeComponent.default)("SagepilotInsetsView");
1307
+
1161
1308
  // src/ui/SagepilotChatProvider.ts
1162
1309
  function readPresentationState() {
1163
1310
  return {
@@ -1200,30 +1347,68 @@ function readUrlOrigin(url) {
1200
1347
  var hostedChatWebViewProps = {
1201
1348
  allowFileAccess: true,
1202
1349
  allowFileAccessFromFileURLs: true,
1350
+ ...import_react_native.Platform.OS === "ios" ? {
1351
+ automaticallyAdjustContentInsets: false,
1352
+ contentInsetAdjustmentBehavior: "never",
1353
+ hideKeyboardAccessoryView: true
1354
+ } : null,
1355
+ bounces: false,
1203
1356
  domStorageEnabled: true,
1204
1357
  javaScriptEnabled: true,
1358
+ overScrollMode: "never",
1359
+ // The hosted widget owns feed scrolling internally; outer WebView scrolling lets iOS focus-scroll the page over the keyboard.
1360
+ scrollEnabled: false,
1205
1361
  setSupportMultipleWindows: false,
1206
1362
  sharedCookiesEnabled: true,
1207
1363
  thirdPartyCookiesEnabled: true
1208
1364
  };
1365
+ var AndroidInsetsView = import_react_native.Platform.OS === "android" ? SagepilotInsetsViewNativeComponent_default : import_react_native.View;
1366
+ var emptyAndroidInsets = { top: 0, bottom: 0 };
1209
1367
  function SagepilotChatProvider({
1210
1368
  children,
1211
1369
  closeLabel = "Close",
1212
1370
  loadingLabel = "Loading chat"
1213
1371
  }) {
1214
- const [state, setState] = useState(readPresentationState);
1215
- const webFrameRef = useRef(null);
1216
- const nativeWebViewRef = useRef(null);
1217
- useEffect(() => {
1372
+ const [state, setState] = (0, import_react.useState)(readPresentationState);
1373
+ const [androidModalInsets, setAndroidModalInsets] = (0, import_react.useState)(emptyAndroidInsets);
1374
+ const webFrameRef = (0, import_react.useRef)(null);
1375
+ const nativeWebViewRef = (0, import_react.useRef)(null);
1376
+ (0, import_react.useEffect)(() => {
1218
1377
  return internalSagepilotChat.onStateChange(() => {
1219
1378
  setState(readPresentationState());
1220
1379
  });
1221
1380
  }, []);
1381
+ const handleAndroidInsetsChange = (0, import_react.useCallback)((event) => {
1382
+ const nextBottomInset = event.nativeEvent?.bottom;
1383
+ const nextTopInset = event.nativeEvent?.top;
1384
+ if (typeof nextBottomInset !== "number" || typeof nextTopInset !== "number" || !Number.isFinite(nextBottomInset) || !Number.isFinite(nextTopInset)) return;
1385
+ setAndroidModalInsets({
1386
+ top: Math.max(0, nextTopInset),
1387
+ bottom: Math.max(0, nextBottomInset)
1388
+ });
1389
+ }, []);
1222
1390
  const showCloseButton = state.presentation?.showCloseButton ?? false;
1223
1391
  const presentationStyle = state.presentation?.style ?? "sheet";
1224
1392
  const isFullScreenModal = presentationStyle === "fullScreen";
1225
1393
  const animationType = presentationStyle === "fullScreen" || presentationStyle === "push" ? "slide" : "fade";
1226
- const ModalContainer = Platform.OS === "ios" && isFullScreenModal ? SafeAreaView : View;
1394
+ const ModalContainer = import_react_native.Platform.OS === "ios" && isFullScreenModal ? import_react_native.SafeAreaView : import_react_native.View;
1395
+ const NativeModalContainer = import_react_native.Platform.OS === "android" ? AndroidInsetsView : ModalContainer;
1396
+ const ChatContentContainer = import_react_native.Platform.OS === "ios" ? import_react_native.KeyboardAvoidingView : import_react_native.View;
1397
+ const nativeModalContainerProps = import_react_native.Platform.OS === "android" ? { style: styles.container, onInsetsChange: handleAndroidInsetsChange } : { style: styles.container };
1398
+ const chatContentContainerProps = import_react_native.Platform.OS === "ios" ? {
1399
+ behavior: "padding",
1400
+ enabled: true,
1401
+ keyboardVerticalOffset: 0,
1402
+ style: styles.modalContent
1403
+ } : {
1404
+ style: [
1405
+ styles.modalContent,
1406
+ import_react_native.Platform.OS === "android" ? {
1407
+ paddingTop: androidModalInsets.top,
1408
+ paddingBottom: androidModalInsets.bottom
1409
+ } : null
1410
+ ].filter(Boolean)
1411
+ };
1227
1412
  const handleWebViewMessage = (event) => {
1228
1413
  internalSagepilotChat.handleHostedBridgeMessage(parseHostedBridgeMessage(event.nativeEvent?.data));
1229
1414
  };
@@ -1238,8 +1423,8 @@ function SagepilotChatProvider({
1238
1423
  if (!script || !nativeWebViewRef.current) return;
1239
1424
  nativeWebViewRef.current.injectJavaScript(script);
1240
1425
  };
1241
- useEffect(() => {
1242
- if (Platform.OS !== "web" || typeof window === "undefined") return;
1426
+ (0, import_react.useEffect)(() => {
1427
+ if (import_react_native.Platform.OS !== "web" || typeof window === "undefined") return;
1243
1428
  const trustedWidgetOrigin = readUrlOrigin(state.conversationUrl);
1244
1429
  if (!trustedWidgetOrigin) return;
1245
1430
  const handleWindowMessage = (event) => {
@@ -1249,41 +1434,41 @@ function SagepilotChatProvider({
1249
1434
  window.addEventListener("message", handleWindowMessage);
1250
1435
  return () => window.removeEventListener("message", handleWindowMessage);
1251
1436
  }, [state.conversationUrl]);
1252
- useEffect(() => {
1253
- if (Platform.OS !== "web" || !state.isPresented) return;
1437
+ (0, import_react.useEffect)(() => {
1438
+ if (import_react_native.Platform.OS !== "web" || !state.isPresented) return;
1254
1439
  postIdentityToWebFrame();
1255
1440
  }, [state.isPresented, state.conversationUrl, state.configured]);
1256
- useEffect(() => {
1257
- if (Platform.OS === "web" || !state.isPresented) return;
1441
+ (0, import_react.useEffect)(() => {
1442
+ if (import_react_native.Platform.OS === "web" || !state.isPresented) return;
1258
1443
  postIdentityToNativeWebView();
1259
1444
  }, [state.isPresented, state.conversationUrl, state.configured]);
1260
- if (Platform.OS === "web") {
1261
- return createElement(
1262
- View,
1445
+ if (import_react_native.Platform.OS === "web") {
1446
+ return (0, import_react.createElement)(
1447
+ import_react_native.View,
1263
1448
  { style: styles.root },
1264
1449
  children,
1265
- state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ? createElement("iframe", {
1450
+ state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ? (0, import_react.createElement)("iframe", {
1266
1451
  src: state.preloadUrl,
1267
1452
  style: styles.webPreloadFrame,
1268
1453
  title: "Sagepilot chat preload"
1269
1454
  }) : null,
1270
- state.configured && state.isPresented && state.conversationUrl ? createElement(
1271
- View,
1455
+ state.configured && state.isPresented && state.conversationUrl ? (0, import_react.createElement)(
1456
+ import_react_native.View,
1272
1457
  { style: styles.webOverlay },
1273
- createElement(
1274
- View,
1458
+ (0, import_react.createElement)(
1459
+ import_react_native.View,
1275
1460
  { style: styles.webPanel },
1276
- showCloseButton ? createElement(
1277
- Pressable,
1461
+ showCloseButton ? (0, import_react.createElement)(
1462
+ import_react_native.Pressable,
1278
1463
  {
1279
1464
  accessibilityRole: "button",
1280
1465
  accessibilityLabel: closeLabel,
1281
1466
  onPress: () => internalSagepilotChat.dismiss(),
1282
1467
  style: styles.webCloseButton
1283
1468
  },
1284
- createElement(Text, { style: styles.closeText }, closeLabel)
1469
+ (0, import_react.createElement)(import_react_native.Text, { style: styles.closeText }, closeLabel)
1285
1470
  ) : null,
1286
- createElement("iframe", {
1471
+ (0, import_react.createElement)("iframe", {
1287
1472
  ref: webFrameRef,
1288
1473
  src: state.conversationUrl,
1289
1474
  style: styles.webFrame,
@@ -1294,63 +1479,69 @@ function SagepilotChatProvider({
1294
1479
  ) : null
1295
1480
  );
1296
1481
  }
1297
- return createElement(
1298
- View,
1482
+ return (0, import_react.createElement)(
1483
+ import_react_native.View,
1299
1484
  { style: styles.root },
1300
1485
  children,
1301
- state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ? createElement(WebView, {
1486
+ state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ? (0, import_react.createElement)(import_react_native_webview.WebView, {
1302
1487
  ...hostedChatWebViewProps,
1303
1488
  source: { uri: state.preloadUrl },
1304
1489
  style: styles.preloadWebview,
1305
1490
  injectedJavaScriptBeforeContentLoaded: getInjectedWebViewScript(),
1306
1491
  onMessage: handleWebViewMessage
1307
1492
  }) : null,
1308
- createElement(
1309
- Modal,
1493
+ (0, import_react.createElement)(
1494
+ import_react_native.Modal,
1310
1495
  {
1311
1496
  visible: state.configured && state.isPresented,
1312
1497
  animationType,
1313
1498
  presentationStyle: isFullScreenModal ? "fullScreen" : "pageSheet",
1499
+ statusBarTranslucent: import_react_native.Platform.OS === "android",
1500
+ navigationBarTranslucent: import_react_native.Platform.OS === "android",
1314
1501
  onRequestClose: () => internalSagepilotChat.dismiss()
1315
1502
  },
1316
- createElement(
1317
- ModalContainer,
1318
- { style: styles.container },
1319
- showCloseButton ? createElement(
1320
- View,
1321
- { style: styles.header },
1322
- createElement(
1323
- Pressable,
1324
- {
1325
- accessibilityRole: "button",
1326
- accessibilityLabel: closeLabel,
1327
- onPress: () => internalSagepilotChat.dismiss(),
1328
- style: styles.closeButton
1329
- },
1330
- createElement(Text, { style: styles.closeText }, closeLabel)
1331
- )
1332
- ) : null,
1333
- state.conversationUrl ? createElement(WebView, {
1334
- ...hostedChatWebViewProps,
1335
- ref: nativeWebViewRef,
1336
- source: { uri: state.conversationUrl },
1337
- style: styles.webview,
1338
- startInLoadingState: true,
1339
- injectedJavaScriptBeforeContentLoaded: getInjectedWebViewScript(),
1340
- onMessage: handleWebViewMessage,
1341
- onLoadEnd: postIdentityToNativeWebView,
1342
- renderLoading: () => createElement(
1343
- View,
1344
- { style: styles.loading },
1345
- createElement(ActivityIndicator, null),
1346
- createElement(Text, { style: styles.loadingText }, loadingLabel)
1347
- )
1348
- }) : null
1503
+ (0, import_react.createElement)(
1504
+ NativeModalContainer,
1505
+ nativeModalContainerProps,
1506
+ (0, import_react.createElement)(
1507
+ ChatContentContainer,
1508
+ chatContentContainerProps,
1509
+ showCloseButton ? (0, import_react.createElement)(
1510
+ import_react_native.View,
1511
+ { style: styles.header },
1512
+ (0, import_react.createElement)(
1513
+ import_react_native.Pressable,
1514
+ {
1515
+ accessibilityRole: "button",
1516
+ accessibilityLabel: closeLabel,
1517
+ onPress: () => internalSagepilotChat.dismiss(),
1518
+ style: styles.closeButton
1519
+ },
1520
+ (0, import_react.createElement)(import_react_native.Text, { style: styles.closeText }, closeLabel)
1521
+ )
1522
+ ) : null,
1523
+ state.conversationUrl ? (0, import_react.createElement)(import_react_native_webview.WebView, {
1524
+ ...hostedChatWebViewProps,
1525
+ ref: nativeWebViewRef,
1526
+ source: { uri: state.conversationUrl },
1527
+ style: styles.webview,
1528
+ startInLoadingState: true,
1529
+ injectedJavaScriptBeforeContentLoaded: getInjectedWebViewScript(),
1530
+ onMessage: handleWebViewMessage,
1531
+ onLoadEnd: postIdentityToNativeWebView,
1532
+ renderLoading: () => (0, import_react.createElement)(
1533
+ import_react_native.View,
1534
+ { style: styles.loading },
1535
+ (0, import_react.createElement)(import_react_native.ActivityIndicator, null),
1536
+ (0, import_react.createElement)(import_react_native.Text, { style: styles.loadingText }, loadingLabel)
1537
+ )
1538
+ }) : null
1539
+ )
1349
1540
  )
1350
1541
  )
1351
1542
  );
1352
1543
  }
1353
- var styles = StyleSheet.create({
1544
+ var styles = import_react_native.StyleSheet.create({
1354
1545
  root: {
1355
1546
  flex: 1
1356
1547
  },
@@ -1358,6 +1549,11 @@ var styles = StyleSheet.create({
1358
1549
  flex: 1,
1359
1550
  backgroundColor: "#ffffff"
1360
1551
  },
1552
+ modalContent: {
1553
+ flex: 1,
1554
+ width: "100%",
1555
+ backgroundColor: "#ffffff"
1556
+ },
1361
1557
  header: {
1362
1558
  minHeight: 48,
1363
1559
  alignItems: "flex-end",
@@ -1431,7 +1627,7 @@ var styles = StyleSheet.create({
1431
1627
  borderStyle: "none"
1432
1628
  },
1433
1629
  loading: {
1434
- ...StyleSheet.absoluteFillObject,
1630
+ ...import_react_native.StyleSheet.absoluteFillObject,
1435
1631
  alignItems: "center",
1436
1632
  justifyContent: "center",
1437
1633
  backgroundColor: "#ffffff"
@@ -1444,7 +1640,7 @@ var styles = StyleSheet.create({
1444
1640
  });
1445
1641
 
1446
1642
  // src/hooks/useSagepilotChat.ts
1447
- import { useCallback, useEffect as useEffect2, useState as useState2 } from "react";
1643
+ var import_react2 = require("react");
1448
1644
  function readState() {
1449
1645
  const state = SagepilotChat.getState();
1450
1646
  return {
@@ -1456,23 +1652,28 @@ function readState() {
1456
1652
  };
1457
1653
  }
1458
1654
  function useSagepilotChat() {
1459
- const [state, setState] = useState2(readState);
1460
- useEffect2(() => {
1655
+ const [state, setState] = (0, import_react2.useState)(readState);
1656
+ (0, import_react2.useEffect)(() => {
1461
1657
  return SagepilotChat.onStateChange(() => {
1462
1658
  setState(readState());
1463
1659
  });
1464
1660
  }, []);
1465
- const present = useCallback(() => SagepilotChat.present(), []);
1466
- const presentMessages = useCallback(() => SagepilotChat.presentMessages(), []);
1467
- const presentMessageComposer = useCallback((message) => SagepilotChat.presentMessageComposer(message), []);
1468
- const dismiss = useCallback(() => SagepilotChat.dismiss(), []);
1469
- const hide = useCallback(() => SagepilotChat.hide(), []);
1470
- const toggle = useCallback(() => SagepilotChat.toggle(), []);
1471
- const identify = useCallback((identity) => {
1661
+ const present = (0, import_react2.useCallback)(() => SagepilotChat.present(), []);
1662
+ const presentMessages = (0, import_react2.useCallback)(() => SagepilotChat.presentMessages(), []);
1663
+ const presentMessageComposer = (0, import_react2.useCallback)((message, options) => {
1664
+ return SagepilotChat.presentMessageComposer(message, options);
1665
+ }, []);
1666
+ const dismiss = (0, import_react2.useCallback)(() => SagepilotChat.dismiss(), []);
1667
+ const hide = (0, import_react2.useCallback)(() => SagepilotChat.hide(), []);
1668
+ const toggle = (0, import_react2.useCallback)(() => SagepilotChat.toggle(), []);
1669
+ const identify = (0, import_react2.useCallback)((identity) => {
1472
1670
  return SagepilotChat.identify(identity);
1473
1671
  }, []);
1474
- const logout = useCallback(() => SagepilotChat.logout(), []);
1475
- const getUnreadCount = useCallback(() => SagepilotChat.getUnreadCount(), []);
1672
+ const logout = (0, import_react2.useCallback)(() => SagepilotChat.logout(), []);
1673
+ const getUnreadCount = (0, import_react2.useCallback)(() => SagepilotChat.getUnreadCount(), []);
1674
+ const onConversationCreated = (0, import_react2.useCallback)((callback) => {
1675
+ return SagepilotChat.onConversationCreated(callback);
1676
+ }, []);
1476
1677
  return {
1477
1678
  ...state,
1478
1679
  present,
@@ -1483,14 +1684,16 @@ function useSagepilotChat() {
1483
1684
  toggle,
1484
1685
  identify,
1485
1686
  logout,
1486
- getUnreadCount
1687
+ getUnreadCount,
1688
+ onConversationCreated
1487
1689
  };
1488
1690
  }
1489
- export {
1691
+ // Annotate the CommonJS export names for ESM import in node:
1692
+ 0 && (module.exports = {
1490
1693
  SagepilotChat,
1491
1694
  SagepilotChatError,
1492
1695
  SagepilotChatProvider,
1493
1696
  createAsyncStorageCacheStorage,
1494
1697
  createKeychainTokenStorage,
1495
1698
  useSagepilotChat
1496
- };
1699
+ });