@lorikeetai/react-native-sdk 2.0.0-alpha.1 → 2.0.0-alpha.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/README.md CHANGED
@@ -22,7 +22,7 @@ bare `pnpm add @lorikeetai/react-native-sdk` installs the 1.x line, and no
22
22
  semver range reaches a prerelease either.
23
23
 
24
24
  ```bash
25
- pnpm add @lorikeetai/react-native-sdk@2.0.0-alpha.1 \
25
+ pnpm add @lorikeetai/react-native-sdk@2.0.0-alpha.2 \
26
26
  react-native-webview@^13.15.0 \
27
27
  react-native-safe-area-context@^5.6.0 \
28
28
  react-native-svg@^15.13.0
@@ -67,9 +67,12 @@ export default function Screen() {
67
67
  - `publicKey` (required): The public key for your Lorikeet account
68
68
  - `authToken` (required): Authentication token for the user
69
69
  - `baseUrl` (optional): Base URL for the Lorikeet API (defaults to `https://chat.lorikeetcx.ai`)
70
- - `customisations` (optional): Widget customization options from `@lorikeetai/web-sdk`
70
+ - `customisations` (optional): Widget customisation options. Exported as
71
+ `Customisations` from this package, so there is nothing else to install
71
72
  - `styles` (optional): Style overrides for the header text
72
- - `onWebViewMessage` (optional): Handler for messages from the webview
73
+ - `onEvent` (optional): What the page reported, as typed events. See [Events](#events)
74
+ - `onWebViewMessage` (optional): Handler for raw messages from the webview.
75
+ Deprecated in favour of `onEvent`, and still called
73
76
  - `ticketId` (optional): Resume this conversation instead of starting a new one
74
77
  - `session` (optional): The session token that authorises `ticketId`
75
78
  - `metadata` (optional): Arbitrary context attached to the conversation, for
@@ -121,13 +124,102 @@ Pass both or neither. `session` authorises exactly the ticket it was issued
121
124
  for, and a resume without it fails with `CUSTOMER_ID_MISSING`.
122
125
 
123
126
  The SDK does not store these for you, and it does not clear them. On logout,
124
- clear your own copy, or the next customer on that device resumes the previous
125
- one's conversation.
127
+ clear your own copy and call the widget's `logout()`; see
128
+ [Logging out](#logging-out).
126
129
 
127
130
  While `ticketId` is set, the header's new-chat icon reloads that conversation
128
131
  rather than starting a new one. To start a new one, clear your stored
129
132
  `ticketId` and `session` and let the next mount fall back to `/widget`.
130
133
 
134
+ ## Events
135
+
136
+ `onEvent` reports what the page said, as a `LorikeetWidgetEvent`:
137
+
138
+ | Event | Means |
139
+ | --------------------------------- | --------------------------------------------------------------- |
140
+ | `ready` | The conversation is usable |
141
+ | `ticket_created` | A ticket this page load created. Once per ticket, never a resume |
142
+ | `customer_message` | The customer sent something |
143
+ | `agent_message` | The agent replied. `markUnread` is the page asking for an unread indicator |
144
+ | `close` | The page hid itself, with a `reason` of `ended_by_customer` or `minimised` |
145
+ | `conversation_ended` | It ended without the customer ending it |
146
+ | `new_chat` | The page is asking for a replacement conversation |
147
+ | `persist_ticket_id` | Store this, with the session, to resume later |
148
+ | `persist_session` | The other half of that pair |
149
+ | `logged_out` | `/logout` cleared this frame. See [Logging out](#logging-out) |
150
+ | `logout_failed` | `/logout` did not confirm. The widget stays unavailable |
151
+ | `error` | A page-level failure. `LORIKEET_ERROR_CODES` lists the codes |
152
+
153
+ Names match the web SDK's wherever it has one, so a host integrating both does
154
+ not learn two vocabularies.
155
+
156
+ `preload_complete` is in the union but cannot reach React Native: the preload
157
+ page posts it to a web parent only. Do not wait on it.
158
+
159
+ ## Logging out
160
+
161
+ Clearing your own stored `ticketId` and `session` is not enough. The chat keeps
162
+ cookies and its own storage inside the WebView, which native code cannot reach,
163
+ so the next person on the device can reopen the previous customer's
164
+ conversation. Only the chat's `/logout` page can clear those, and only if the
165
+ WebView is navigated to it.
166
+
167
+ With the drop-in, call `logout()` on its ref:
168
+
169
+ ```tsx
170
+ const widget = useRef<LorikeetWidgetHandle>(null)
171
+
172
+ return (
173
+ <>
174
+ <LorikeetWidgetView {...props} ref={widget} />
175
+ <Button
176
+ onPress={() => {
177
+ widget.current?.logout()
178
+ void clearResumeForCustomer(customerId)
179
+ }}
180
+ title="Sign out"
181
+ />
182
+ </>
183
+ )
184
+ ```
185
+
186
+ The widget stays on that page until the chat confirms, and nothing you pass it
187
+ in the meantime changes that: handing it the next customer's credentials while
188
+ the clear is still running would unmount the page mid-clear and leave the last
189
+ customer's cookies on the device. Pass them once `logged_out` has arrived and
190
+ the next chat starts normally.
191
+
192
+ A logout that does not confirm within ten seconds reports `logout_failed` and
193
+ leaves the widget unavailable rather than opening a chat on a device the
194
+ previous customer's credentials still unlock. Call `logout()` again to retry.
195
+
196
+ That obligation outlives the component. The SDK stores nothing, so a widget
197
+ unmounted before the clear confirmed, by a screen change or an app restart,
198
+ comes back with no memory of it and opens a chat normally, on a device whose
199
+ cookies were never cleared. Record the failure alongside the conversation you
200
+ already store, and call `logout()` again before mounting a chat for anyone
201
+ else. We would rather own this than ask you to, and
202
+ [ADP-3160](https://linear.app/lorikeet/issue/ADP-3160) is where that storage
203
+ layer belongs.
204
+
205
+ If you compose the parts yourself, build the URL and navigate to it:
206
+
207
+ ```tsx
208
+ const client = new LorikeetClient({ public_key: publicKey, api_base: baseUrl })
209
+
210
+ setUri(client.getLogoutUrl())
211
+ ```
212
+
213
+ Either way, wait for `logged_out` before treating the device as clean. The
214
+ WebView's load event does not prove anything: an error page fires it too.
215
+
216
+ The anonymous customer's long-lived token is deliberately not among these
217
+ events. It identifies the same anonymous customer for a year, this SDK offers
218
+ no way to hand one back, and the web SDK keeps the same message inside the
219
+ frame. A host that genuinely needs it can read the raw bridge, but storing it
220
+ is storing a credential, and [ADP-3160](https://linear.app/lorikeet/issue/ADP-3160)
221
+ is the work that should remove the need.
222
+
131
223
  ## Identity
132
224
 
133
225
  The public key, base URL and auth token are one unit, and a conversation belongs
package/dist/index.cjs CHANGED
@@ -144,6 +144,26 @@ var LorikeetClient = class {
144
144
  if (this.metadata) url.searchParams.append("metadata", JSON.stringify(this.metadata));
145
145
  return url.toString();
146
146
  });
147
+ _defineProperty(
148
+ this,
149
+ /**
150
+ * The page that clears this key's credentials from the WebView: its cookies,
151
+ * server-side, and the storage the frame keeps. Navigating a WebView here is
152
+ * the only way to reach either, so a host that only drops its own copy of
153
+ * `ticketId` and `session` leaves the next person on the device able to
154
+ * reopen the conversation.
155
+ *
156
+ * The page confirms with a `loggedOut` message, which the SDK reports as
157
+ * `logged_out`. The load event does not: an error page fires that too.
158
+ */
159
+ "getLogoutUrl",
160
+ () => {
161
+ const url = new URL(this.baseUrl);
162
+ url.pathname = "/logout";
163
+ url.searchParams.append("public_key", this.publicKey);
164
+ return url.toString();
165
+ }
166
+ );
147
167
  if (api_base) this.baseUrl = api_base;
148
168
  this.publicKey = public_key;
149
169
  if (customisations) this.customisations = customisations;
@@ -210,7 +230,10 @@ const eventFromMessage = (message) => {
210
230
  switch (record.type) {
211
231
  case "ready": return { type: "ready" };
212
232
  case "customerMessage": return { type: "customer_message" };
213
- case "agentMessage": return { type: "agent_message" };
233
+ case "agentMessage": return typeof record.markUnread === "boolean" ? {
234
+ type: "agent_message",
235
+ markUnread: record.markUnread
236
+ } : { type: "agent_message" };
214
237
  case "closeChat": {
215
238
  const reason = asNonEmptyString(record.reason);
216
239
  return reason === "ended_by_customer" || reason === "minimised" ? {
@@ -234,6 +257,7 @@ const eventFromMessage = (message) => {
234
257
  session
235
258
  };
236
259
  }
260
+ case "loggedOut": return { type: "logged_out" };
237
261
  case "error": {
238
262
  const error = asNonEmptyString(record.error);
239
263
  return error === null ? null : {
@@ -284,6 +308,13 @@ const resumedTicketIdFromUri = (uri) => {
284
308
  */
285
309
  const BACKGROUND_RELOAD_THRESHOLD_MS = 18e4;
286
310
  /**
311
+ * How long `/logout` gets to confirm it cleared the frame before the host is
312
+ * told it did not. Matches the web SDK's own budget, and like it, a logout that
313
+ * misses the deadline leaves the widget unavailable rather than letting the next
314
+ * customer start a chat on a device the previous one's credentials still open.
315
+ */
316
+ const LOGOUT_CONFIRMATION_TIMEOUT_MS = 1e4;
317
+ /**
287
318
  * Elapsed time is the only signal available: the bridge reports `ready`,
288
319
  * `error` and the persistence messages, but never stream health, so the SDK
289
320
  * cannot ask whether the connection actually survived.
@@ -410,6 +441,7 @@ const stylesheet = react_native.StyleSheet.create({
410
441
  textAlign: "center",
411
442
  fontSize: 16
412
443
  },
444
+ closedControl: { padding: 16 },
413
445
  webView: { flex: 1 },
414
446
  closed: {
415
447
  flex: 1,
@@ -488,8 +520,8 @@ const LorikeetWidgetHeader = ({ title, style, icon = /* @__PURE__ */ (0, react_j
488
520
  ]
489
521
  });
490
522
  };
491
- function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, styles, onEvent, onWebViewMessage, ticketId, session, metadata, webviewProps }) {
492
- var _customisations$title;
523
+ const LorikeetWidgetView = (0, react.forwardRef)(function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, styles, onEvent, onWebViewMessage, ticketId, session, metadata, webviewProps }, ref) {
524
+ var _customisations$hideH, _customisations$title;
493
525
  const [lorikeetClient, setLorikeetClient] = (0, react.useState)(null);
494
526
  const [loaded, setLoaded] = (0, react.useState)(null);
495
527
  const [generation, setGeneration] = (0, react.useState)(0);
@@ -514,7 +546,12 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
514
546
  });
515
547
  const resumingTicketId = ticketId !== void 0 && ticketId !== refusedTicketId ? ticketId : void 0;
516
548
  const [attemptedTicketId, setAttemptedTicketId] = (0, react.useState)(void 0);
517
- const [closed, setClosed] = (0, react.useState)(false);
549
+ const [closed, setClosed] = (0, react.useState)(null);
550
+ const [clearing, setClearing] = (0, react.useState)(null);
551
+ const [loggedOutIdentity, setLoggedOutIdentity] = (0, react.useState)(null);
552
+ const onEventRef = (0, react.useRef)(onEvent);
553
+ onEventRef.current = onEvent;
554
+ const hideHeader = (_customisations$hideH = customisations === null || customisations === void 0 ? void 0 : customisations.hideHeader) !== null && _customisations$hideH !== void 0 ? _customisations$hideH : true;
518
555
  const load = (0, react.useCallback)((client, forIdentity, intendedTicketId, resume, force = false) => {
519
556
  const next = client.getWebviewUrl({
520
557
  token: authToken,
@@ -522,7 +559,7 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
522
559
  session: resume === null || resume === void 0 ? void 0 : resume.session
523
560
  });
524
561
  const unchanged = uriRef.current === next;
525
- if (loadedForRef.current.identity !== forIdentity || loadedForRef.current.intendedTicketId !== intendedTicketId) setClosed(false);
562
+ if (loadedForRef.current.identity !== forIdentity || loadedForRef.current.intendedTicketId !== intendedTicketId) setClosed(null);
526
563
  uriRef.current = next;
527
564
  loadedForRef.current = {
528
565
  identity: forIdentity,
@@ -551,10 +588,12 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
551
588
  metadata,
552
589
  customisations: {
553
590
  ...customisations,
554
- hideHeader: (customisations === null || customisations === void 0 ? void 0 : customisations.hideHeader) === void 0 ? true : customisations.hideHeader
591
+ hideHeader
555
592
  }
556
593
  });
557
594
  setLorikeetClient(lorikeetClient);
595
+ if (clearing !== null || loggedOutIdentity === identity) return;
596
+ if (loggedOutIdentity !== null) setLoggedOutIdentity(null);
558
597
  const resume = resumingTicketId !== void 0 ? {
559
598
  session,
560
599
  ticketId: resumingTicketId
@@ -564,13 +603,108 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
564
603
  publicKey,
565
604
  baseUrl,
566
605
  authToken,
606
+ clearing,
567
607
  customisations,
608
+ hideHeader,
609
+ loggedOutIdentity,
568
610
  metadata,
569
611
  session,
570
612
  resumingTicketId,
571
613
  identity,
572
614
  load
573
615
  ]);
616
+ /**
617
+ * Clear this customer's chat from the device. Loads the page's own `/logout`,
618
+ * the only thing that can drop the chat's cookies and the storage the page
619
+ * keeps; a host clearing its stored `ticketId` and `session` leaves both
620
+ * behind.
621
+ *
622
+ * Nothing else loads until the page confirms with `logged_out`, and nothing
623
+ * loads for these credentials after it, so pass the next customer's in to
624
+ * start their chat. Clear your own stored `ticketId` and `session` too.
625
+ */
626
+ const logout = (0, react.useCallback)(() => {
627
+ observedRef.current = null;
628
+ setClosed(null);
629
+ setClearing((previous) => {
630
+ if (previous !== null) return {
631
+ ...previous,
632
+ attempt: previous.attempt + 1
633
+ };
634
+ setLoggedOutIdentity(identity);
635
+ return {
636
+ attempt: 1,
637
+ baseUrl,
638
+ identity,
639
+ uri: new LorikeetClient({
640
+ api_base: baseUrl,
641
+ public_key: publicKey
642
+ }).getLogoutUrl(),
643
+ webviewProps: {
644
+ ...webviewProps,
645
+ injectedJavaScript: void 0,
646
+ injectedJavaScriptBeforeContentLoaded: void 0,
647
+ onMessage: void 0,
648
+ onShouldStartLoadWithRequest: void 0
649
+ }
650
+ };
651
+ });
652
+ }, [
653
+ baseUrl,
654
+ identity,
655
+ publicKey,
656
+ webviewProps
657
+ ]);
658
+ /**
659
+ * Show a minimised conversation again, exactly as the customer left it.
660
+ *
661
+ * A no-op unless something is minimised, so a host with its own launcher can
662
+ * call it without first asking.
663
+ */
664
+ const reopen = (0, react.useCallback)(() => {
665
+ setClosed((previous) => previous === "minimised" ? null : previous);
666
+ }, []);
667
+ /**
668
+ * What the widget is actually on, for a host that has to store it or draw its
669
+ * own launcher around it.
670
+ */
671
+ const getConversation = (0, react.useCallback)(() => {
672
+ const resumable = resumableConversation(observedRef.current, identity, resumingTicketId);
673
+ if (resumable === null) return null;
674
+ return {
675
+ minimised: closed === "minimised",
676
+ session: resumable.session,
677
+ ticketId: resumable.ticketId
678
+ };
679
+ }, [
680
+ closed,
681
+ identity,
682
+ resumingTicketId
683
+ ]);
684
+ (0, react.useImperativeHandle)(ref, () => ({
685
+ getConversation,
686
+ logout,
687
+ reopen
688
+ }), [
689
+ getConversation,
690
+ logout,
691
+ reopen
692
+ ]);
693
+ const clearingAttempt = clearing === null || clearing === void 0 ? void 0 : clearing.attempt;
694
+ (0, react.useEffect)(() => {
695
+ if (clearingAttempt === void 0) return;
696
+ const timer = setTimeout(() => {
697
+ var _onEventRef$current;
698
+ (_onEventRef$current = onEventRef.current) === null || _onEventRef$current === void 0 || _onEventRef$current.call(onEventRef, { type: "logout_failed" });
699
+ }, LOGOUT_CONFIRMATION_TIMEOUT_MS);
700
+ return () => {
701
+ clearTimeout(timer);
702
+ };
703
+ }, [clearingAttempt]);
704
+ const handleClearingEvent = (0, react.useCallback)((event) => {
705
+ if (event.type === "logged_out") setClearing((previous) => (previous === null || previous === void 0 ? void 0 : previous.attempt) === clearingAttempt ? null : previous);
706
+ onEvent === null || onEvent === void 0 || onEvent(event);
707
+ }, [clearingAttempt, onEvent]);
574
708
  const reload = (0, react.useCallback)(() => {
575
709
  const resume = resumableConversation(observedRef.current, identity, resumingTicketId);
576
710
  if (lorikeetClient !== null && resume !== null) {
@@ -602,7 +736,7 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
602
736
  };
603
737
  }, [reload]);
604
738
  const startNewChat = (0, react.useCallback)(() => {
605
- setClosed(false);
739
+ setClosed(null);
606
740
  if (lorikeetClient !== null && resumingTicketId === void 0) {
607
741
  observedRef.current = null;
608
742
  load(lorikeetClient, identity, void 0, null, true);
@@ -628,7 +762,7 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
628
762
  intendedTicketId: resumingTicketId
629
763
  };
630
764
  }
631
- if (event.type === "close") setClosed(true);
765
+ if (event.type === "close") setClosed(event.reason === "minimised" ? "minimised" : "ended");
632
766
  if (event.type === "new_chat") startNewChat();
633
767
  if (event.type === "error" && attemptedTicketId !== void 0 && isUnusableConversationCode(event.error)) {
634
768
  observedRef.current = null;
@@ -652,7 +786,31 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
652
786
  onWebViewMessage === null || onWebViewMessage === void 0 || onWebViewMessage(event);
653
787
  webviewProps === null || webviewProps === void 0 || (_webviewProps$onMessa2 = webviewProps.onMessage) === null || _webviewProps$onMessa2 === void 0 || _webviewProps$onMessa2.call(webviewProps, event);
654
788
  }, [onWebViewMessage, webviewProps]);
655
- if (lorikeetClient === null || loaded === null || loaded.identity !== identity || loaded.intendedTicketId !== resumingTicketId) return null;
789
+ if (clearing !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native_safe_area_context.SafeAreaView, {
790
+ edges: [
791
+ "top",
792
+ "left",
793
+ "right"
794
+ ],
795
+ style: stylesheet.root,
796
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
797
+ accessibilityElementsHidden: true,
798
+ importantForAccessibility: "no-hide-descendants",
799
+ pointerEvents: "none",
800
+ style: stylesheet.closed,
801
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetWebView, {
802
+ baseUrl: clearing.baseUrl,
803
+ onEvent: handleClearingEvent,
804
+ uri: clearing.uri,
805
+ webviewProps: {
806
+ ...clearing.webviewProps,
807
+ style: stylesheet.webView
808
+ }
809
+ }, `logout|${clearing.attempt}`)
810
+ })
811
+ });
812
+ if (lorikeetClient === null || loaded === null || loaded.identity !== identity || loaded.intendedTicketId !== resumingTicketId || loggedOutIdentity === identity) return null;
813
+ const isClosed = closed !== null;
656
814
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native_safe_area_context.SafeAreaView, {
657
815
  edges: [
658
816
  "top",
@@ -662,44 +820,64 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
662
820
  style: stylesheet.root,
663
821
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
664
822
  style: stylesheet.container,
665
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetHeader, {
666
- onIconPress: startNewChat,
667
- style: styles === null || styles === void 0 ? void 0 : styles.header,
668
- title: (_customisations$title = customisations === null || customisations === void 0 ? void 0 : customisations.title) !== null && _customisations$title !== void 0 ? _customisations$title : "Lorikeet AI Agent"
669
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
670
- accessibilityElementsHidden: closed,
671
- importantForAccessibility: closed ? "no-hide-descendants" : "auto",
672
- pointerEvents: closed ? "none" : "auto",
673
- style: closed ? stylesheet.closed : stylesheet.webView,
674
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetWebView, {
675
- baseUrl: lorikeetClient.baseUrl,
676
- onEvent: handleEvent,
677
- ref: webViewRef,
678
- uri: loaded.uri,
679
- webviewProps: {
680
- allowsInlineMediaPlayback: true,
681
- mediaPlaybackRequiresUserAction: false,
682
- scalesPageToFit: true,
683
- startInLoadingState: true,
684
- style: stylesheet.webView,
685
- ...webviewProps,
686
- onMessage: handleMessage,
687
- onRenderProcessGone: (event) => {
688
- var _webviewProps$onRende;
689
- if (generation === generationRef.current) reload();
690
- webviewProps === null || webviewProps === void 0 || (_webviewProps$onRende = webviewProps.onRenderProcessGone) === null || _webviewProps$onRende === void 0 || _webviewProps$onRende.call(webviewProps, event);
691
- },
692
- onContentProcessDidTerminate: (event) => {
693
- var _webviewProps$onConte;
694
- if (generation === generationRef.current) reload();
695
- webviewProps === null || webviewProps === void 0 || (_webviewProps$onConte = webviewProps.onContentProcessDidTerminate) === null || _webviewProps$onConte === void 0 || _webviewProps$onConte.call(webviewProps, event);
823
+ children: [
824
+ hideHeader && closed !== "minimised" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetHeader, {
825
+ onIconPress: startNewChat,
826
+ style: styles === null || styles === void 0 ? void 0 : styles.header,
827
+ title: (_customisations$title = customisations === null || customisations === void 0 ? void 0 : customisations.title) !== null && _customisations$title !== void 0 ? _customisations$title : "Lorikeet AI Agent"
828
+ }) : null,
829
+ closed === "minimised" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableOpacity, {
830
+ onPress: reopen,
831
+ style: stylesheet.closedControl,
832
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
833
+ style: stylesheet.headerText,
834
+ children: "Reopen chat"
835
+ })
836
+ }) : null,
837
+ !hideHeader && closed === "ended" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableOpacity, {
838
+ onPress: startNewChat,
839
+ style: stylesheet.closedControl,
840
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
841
+ style: stylesheet.headerText,
842
+ children: "Start new chat"
843
+ })
844
+ }) : null,
845
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
846
+ accessibilityElementsHidden: isClosed,
847
+ importantForAccessibility: isClosed ? "no-hide-descendants" : "auto",
848
+ pointerEvents: isClosed ? "none" : "auto",
849
+ style: isClosed ? stylesheet.closed : stylesheet.webView,
850
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetWebView, {
851
+ baseUrl: lorikeetClient.baseUrl,
852
+ onEvent: handleEvent,
853
+ ref: webViewRef,
854
+ uri: loaded.uri,
855
+ webviewProps: {
856
+ allowsInlineMediaPlayback: true,
857
+ mediaPlaybackRequiresUserAction: false,
858
+ scalesPageToFit: true,
859
+ startInLoadingState: true,
860
+ style: stylesheet.webView,
861
+ ...webviewProps,
862
+ onMessage: handleMessage,
863
+ onRenderProcessGone: (event) => {
864
+ var _webviewProps$onRende;
865
+ if (generation === generationRef.current) reload();
866
+ webviewProps === null || webviewProps === void 0 || (_webviewProps$onRende = webviewProps.onRenderProcessGone) === null || _webviewProps$onRende === void 0 || _webviewProps$onRende.call(webviewProps, event);
867
+ },
868
+ onContentProcessDidTerminate: (event) => {
869
+ var _webviewProps$onConte;
870
+ if (generation === generationRef.current) reload();
871
+ webviewProps === null || webviewProps === void 0 || (_webviewProps$onConte = webviewProps.onContentProcessDidTerminate) === null || _webviewProps$onConte === void 0 || _webviewProps$onConte.call(webviewProps, event);
872
+ }
696
873
  }
697
- }
698
- }, `${identity}|${resumingTicketId !== null && resumingTicketId !== void 0 ? resumingTicketId : ""}|${generation}`)
699
- })]
874
+ }, `${identity}|${resumingTicketId !== null && resumingTicketId !== void 0 ? resumingTicketId : ""}|${generation}`)
875
+ })
876
+ ]
700
877
  })
701
878
  });
702
- }
879
+ });
880
+ LorikeetWidgetView.displayName = "LorikeetWidgetView";
703
881
 
704
882
  //#endregion
705
883
  exports.LORIKEET_ERROR_CODES = LORIKEET_ERROR_CODES;