@lorikeetai/react-native-sdk 2.0.0-alpha.1 → 2.0.0-alpha.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 +97 -5
- package/dist/index.cjs +228 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +441 -15
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +441 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +229 -46
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
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.
|
|
25
|
+
pnpm add @lorikeetai/react-native-sdk@2.0.0-alpha.3 \
|
|
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
|
|
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
|
-
- `
|
|
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
|
|
125
|
-
|
|
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
|
|
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,18 @@ 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
|
+
* `LorikeetWidgetView` applies this to its own `logout()`. Exported because a
|
|
317
|
+
* composed host has to run the timer itself and nothing else will report
|
|
318
|
+
* `logout_failed` for it, and two hosts choosing their own budgets is how one
|
|
319
|
+
* app calls a clear failed that the other never does.
|
|
320
|
+
*/
|
|
321
|
+
const LOGOUT_CONFIRMATION_TIMEOUT_MS = 1e4;
|
|
322
|
+
/**
|
|
287
323
|
* Elapsed time is the only signal available: the bridge reports `ready`,
|
|
288
324
|
* `error` and the persistence messages, but never stream health, so the SDK
|
|
289
325
|
* cannot ask whether the connection actually survived.
|
|
@@ -410,6 +446,7 @@ const stylesheet = react_native.StyleSheet.create({
|
|
|
410
446
|
textAlign: "center",
|
|
411
447
|
fontSize: 16
|
|
412
448
|
},
|
|
449
|
+
closedControl: { padding: 16 },
|
|
413
450
|
webView: { flex: 1 },
|
|
414
451
|
closed: {
|
|
415
452
|
flex: 1,
|
|
@@ -488,8 +525,8 @@ const LorikeetWidgetHeader = ({ title, style, icon = /* @__PURE__ */ (0, react_j
|
|
|
488
525
|
]
|
|
489
526
|
});
|
|
490
527
|
};
|
|
491
|
-
function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, styles, onEvent, onWebViewMessage, ticketId, session, metadata, webviewProps }) {
|
|
492
|
-
var _customisations$title;
|
|
528
|
+
const LorikeetWidgetView = (0, react.forwardRef)(function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, styles, onEvent, onWebViewMessage, ticketId, session, metadata, webviewProps }, ref) {
|
|
529
|
+
var _customisations$hideH, _customisations$title;
|
|
493
530
|
const [lorikeetClient, setLorikeetClient] = (0, react.useState)(null);
|
|
494
531
|
const [loaded, setLoaded] = (0, react.useState)(null);
|
|
495
532
|
const [generation, setGeneration] = (0, react.useState)(0);
|
|
@@ -514,7 +551,12 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
|
|
|
514
551
|
});
|
|
515
552
|
const resumingTicketId = ticketId !== void 0 && ticketId !== refusedTicketId ? ticketId : void 0;
|
|
516
553
|
const [attemptedTicketId, setAttemptedTicketId] = (0, react.useState)(void 0);
|
|
517
|
-
const [closed, setClosed] = (0, react.useState)(
|
|
554
|
+
const [closed, setClosed] = (0, react.useState)(null);
|
|
555
|
+
const [clearing, setClearing] = (0, react.useState)(null);
|
|
556
|
+
const [loggedOutIdentity, setLoggedOutIdentity] = (0, react.useState)(null);
|
|
557
|
+
const onEventRef = (0, react.useRef)(onEvent);
|
|
558
|
+
onEventRef.current = onEvent;
|
|
559
|
+
const hideHeader = (_customisations$hideH = customisations === null || customisations === void 0 ? void 0 : customisations.hideHeader) !== null && _customisations$hideH !== void 0 ? _customisations$hideH : true;
|
|
518
560
|
const load = (0, react.useCallback)((client, forIdentity, intendedTicketId, resume, force = false) => {
|
|
519
561
|
const next = client.getWebviewUrl({
|
|
520
562
|
token: authToken,
|
|
@@ -522,7 +564,7 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
|
|
|
522
564
|
session: resume === null || resume === void 0 ? void 0 : resume.session
|
|
523
565
|
});
|
|
524
566
|
const unchanged = uriRef.current === next;
|
|
525
|
-
if (loadedForRef.current.identity !== forIdentity || loadedForRef.current.intendedTicketId !== intendedTicketId) setClosed(
|
|
567
|
+
if (loadedForRef.current.identity !== forIdentity || loadedForRef.current.intendedTicketId !== intendedTicketId) setClosed(null);
|
|
526
568
|
uriRef.current = next;
|
|
527
569
|
loadedForRef.current = {
|
|
528
570
|
identity: forIdentity,
|
|
@@ -551,10 +593,12 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
|
|
|
551
593
|
metadata,
|
|
552
594
|
customisations: {
|
|
553
595
|
...customisations,
|
|
554
|
-
hideHeader
|
|
596
|
+
hideHeader
|
|
555
597
|
}
|
|
556
598
|
});
|
|
557
599
|
setLorikeetClient(lorikeetClient);
|
|
600
|
+
if (clearing !== null || loggedOutIdentity === identity) return;
|
|
601
|
+
if (loggedOutIdentity !== null) setLoggedOutIdentity(null);
|
|
558
602
|
const resume = resumingTicketId !== void 0 ? {
|
|
559
603
|
session,
|
|
560
604
|
ticketId: resumingTicketId
|
|
@@ -564,13 +608,108 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
|
|
|
564
608
|
publicKey,
|
|
565
609
|
baseUrl,
|
|
566
610
|
authToken,
|
|
611
|
+
clearing,
|
|
567
612
|
customisations,
|
|
613
|
+
hideHeader,
|
|
614
|
+
loggedOutIdentity,
|
|
568
615
|
metadata,
|
|
569
616
|
session,
|
|
570
617
|
resumingTicketId,
|
|
571
618
|
identity,
|
|
572
619
|
load
|
|
573
620
|
]);
|
|
621
|
+
/**
|
|
622
|
+
* Clear this customer's chat from the device. Loads the page's own `/logout`,
|
|
623
|
+
* the only thing that can drop the chat's cookies and the storage the page
|
|
624
|
+
* keeps; a host clearing its stored `ticketId` and `session` leaves both
|
|
625
|
+
* behind.
|
|
626
|
+
*
|
|
627
|
+
* Nothing else loads until the page confirms with `logged_out`, and nothing
|
|
628
|
+
* loads for these credentials after it, so pass the next customer's in to
|
|
629
|
+
* start their chat. Clear your own stored `ticketId` and `session` too.
|
|
630
|
+
*/
|
|
631
|
+
const logout = (0, react.useCallback)(() => {
|
|
632
|
+
observedRef.current = null;
|
|
633
|
+
setClosed(null);
|
|
634
|
+
setClearing((previous) => {
|
|
635
|
+
if (previous !== null) return {
|
|
636
|
+
...previous,
|
|
637
|
+
attempt: previous.attempt + 1
|
|
638
|
+
};
|
|
639
|
+
setLoggedOutIdentity(identity);
|
|
640
|
+
return {
|
|
641
|
+
attempt: 1,
|
|
642
|
+
baseUrl,
|
|
643
|
+
identity,
|
|
644
|
+
uri: new LorikeetClient({
|
|
645
|
+
api_base: baseUrl,
|
|
646
|
+
public_key: publicKey
|
|
647
|
+
}).getLogoutUrl(),
|
|
648
|
+
webviewProps: {
|
|
649
|
+
...webviewProps,
|
|
650
|
+
injectedJavaScript: void 0,
|
|
651
|
+
injectedJavaScriptBeforeContentLoaded: void 0,
|
|
652
|
+
onMessage: void 0,
|
|
653
|
+
onShouldStartLoadWithRequest: void 0
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
});
|
|
657
|
+
}, [
|
|
658
|
+
baseUrl,
|
|
659
|
+
identity,
|
|
660
|
+
publicKey,
|
|
661
|
+
webviewProps
|
|
662
|
+
]);
|
|
663
|
+
/**
|
|
664
|
+
* Show a minimised conversation again, exactly as the customer left it.
|
|
665
|
+
*
|
|
666
|
+
* A no-op unless something is minimised, so a host with its own launcher can
|
|
667
|
+
* call it without first asking.
|
|
668
|
+
*/
|
|
669
|
+
const reopen = (0, react.useCallback)(() => {
|
|
670
|
+
setClosed((previous) => previous === "minimised" ? null : previous);
|
|
671
|
+
}, []);
|
|
672
|
+
/**
|
|
673
|
+
* What the widget is actually on, for a host that has to store it or draw its
|
|
674
|
+
* own launcher around it.
|
|
675
|
+
*/
|
|
676
|
+
const getConversation = (0, react.useCallback)(() => {
|
|
677
|
+
const resumable = resumableConversation(observedRef.current, identity, resumingTicketId);
|
|
678
|
+
if (resumable === null) return null;
|
|
679
|
+
return {
|
|
680
|
+
minimised: closed === "minimised",
|
|
681
|
+
session: resumable.session,
|
|
682
|
+
ticketId: resumable.ticketId
|
|
683
|
+
};
|
|
684
|
+
}, [
|
|
685
|
+
closed,
|
|
686
|
+
identity,
|
|
687
|
+
resumingTicketId
|
|
688
|
+
]);
|
|
689
|
+
(0, react.useImperativeHandle)(ref, () => ({
|
|
690
|
+
getConversation,
|
|
691
|
+
logout,
|
|
692
|
+
reopen
|
|
693
|
+
}), [
|
|
694
|
+
getConversation,
|
|
695
|
+
logout,
|
|
696
|
+
reopen
|
|
697
|
+
]);
|
|
698
|
+
const clearingAttempt = clearing === null || clearing === void 0 ? void 0 : clearing.attempt;
|
|
699
|
+
(0, react.useEffect)(() => {
|
|
700
|
+
if (clearingAttempt === void 0) return;
|
|
701
|
+
const timer = setTimeout(() => {
|
|
702
|
+
var _onEventRef$current;
|
|
703
|
+
(_onEventRef$current = onEventRef.current) === null || _onEventRef$current === void 0 || _onEventRef$current.call(onEventRef, { type: "logout_failed" });
|
|
704
|
+
}, LOGOUT_CONFIRMATION_TIMEOUT_MS);
|
|
705
|
+
return () => {
|
|
706
|
+
clearTimeout(timer);
|
|
707
|
+
};
|
|
708
|
+
}, [clearingAttempt]);
|
|
709
|
+
const handleClearingEvent = (0, react.useCallback)((event) => {
|
|
710
|
+
if (event.type === "logged_out") setClearing((previous) => (previous === null || previous === void 0 ? void 0 : previous.attempt) === clearingAttempt ? null : previous);
|
|
711
|
+
onEvent === null || onEvent === void 0 || onEvent(event);
|
|
712
|
+
}, [clearingAttempt, onEvent]);
|
|
574
713
|
const reload = (0, react.useCallback)(() => {
|
|
575
714
|
const resume = resumableConversation(observedRef.current, identity, resumingTicketId);
|
|
576
715
|
if (lorikeetClient !== null && resume !== null) {
|
|
@@ -602,7 +741,7 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
|
|
|
602
741
|
};
|
|
603
742
|
}, [reload]);
|
|
604
743
|
const startNewChat = (0, react.useCallback)(() => {
|
|
605
|
-
setClosed(
|
|
744
|
+
setClosed(null);
|
|
606
745
|
if (lorikeetClient !== null && resumingTicketId === void 0) {
|
|
607
746
|
observedRef.current = null;
|
|
608
747
|
load(lorikeetClient, identity, void 0, null, true);
|
|
@@ -628,7 +767,7 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
|
|
|
628
767
|
intendedTicketId: resumingTicketId
|
|
629
768
|
};
|
|
630
769
|
}
|
|
631
|
-
if (event.type === "close") setClosed(
|
|
770
|
+
if (event.type === "close") setClosed(event.reason === "minimised" ? "minimised" : "ended");
|
|
632
771
|
if (event.type === "new_chat") startNewChat();
|
|
633
772
|
if (event.type === "error" && attemptedTicketId !== void 0 && isUnusableConversationCode(event.error)) {
|
|
634
773
|
observedRef.current = null;
|
|
@@ -652,7 +791,31 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
|
|
|
652
791
|
onWebViewMessage === null || onWebViewMessage === void 0 || onWebViewMessage(event);
|
|
653
792
|
webviewProps === null || webviewProps === void 0 || (_webviewProps$onMessa2 = webviewProps.onMessage) === null || _webviewProps$onMessa2 === void 0 || _webviewProps$onMessa2.call(webviewProps, event);
|
|
654
793
|
}, [onWebViewMessage, webviewProps]);
|
|
655
|
-
if (
|
|
794
|
+
if (clearing !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native_safe_area_context.SafeAreaView, {
|
|
795
|
+
edges: [
|
|
796
|
+
"top",
|
|
797
|
+
"left",
|
|
798
|
+
"right"
|
|
799
|
+
],
|
|
800
|
+
style: stylesheet.root,
|
|
801
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
802
|
+
accessibilityElementsHidden: true,
|
|
803
|
+
importantForAccessibility: "no-hide-descendants",
|
|
804
|
+
pointerEvents: "none",
|
|
805
|
+
style: stylesheet.closed,
|
|
806
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetWebView, {
|
|
807
|
+
baseUrl: clearing.baseUrl,
|
|
808
|
+
onEvent: handleClearingEvent,
|
|
809
|
+
uri: clearing.uri,
|
|
810
|
+
webviewProps: {
|
|
811
|
+
...clearing.webviewProps,
|
|
812
|
+
style: stylesheet.webView
|
|
813
|
+
}
|
|
814
|
+
}, `logout|${clearing.attempt}`)
|
|
815
|
+
})
|
|
816
|
+
});
|
|
817
|
+
if (lorikeetClient === null || loaded === null || loaded.identity !== identity || loaded.intendedTicketId !== resumingTicketId || loggedOutIdentity === identity) return null;
|
|
818
|
+
const isClosed = closed !== null;
|
|
656
819
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native_safe_area_context.SafeAreaView, {
|
|
657
820
|
edges: [
|
|
658
821
|
"top",
|
|
@@ -662,46 +825,67 @@ function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, sty
|
|
|
662
825
|
style: stylesheet.root,
|
|
663
826
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
|
|
664
827
|
style: stylesheet.container,
|
|
665
|
-
children: [
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
828
|
+
children: [
|
|
829
|
+
hideHeader && closed !== "minimised" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetHeader, {
|
|
830
|
+
onIconPress: startNewChat,
|
|
831
|
+
style: styles === null || styles === void 0 ? void 0 : styles.header,
|
|
832
|
+
title: (_customisations$title = customisations === null || customisations === void 0 ? void 0 : customisations.title) !== null && _customisations$title !== void 0 ? _customisations$title : "Lorikeet AI Agent"
|
|
833
|
+
}) : null,
|
|
834
|
+
closed === "minimised" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableOpacity, {
|
|
835
|
+
onPress: reopen,
|
|
836
|
+
style: stylesheet.closedControl,
|
|
837
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
|
|
838
|
+
style: stylesheet.headerText,
|
|
839
|
+
children: "Reopen chat"
|
|
840
|
+
})
|
|
841
|
+
}) : null,
|
|
842
|
+
!hideHeader && closed === "ended" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableOpacity, {
|
|
843
|
+
onPress: startNewChat,
|
|
844
|
+
style: stylesheet.closedControl,
|
|
845
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
|
|
846
|
+
style: stylesheet.headerText,
|
|
847
|
+
children: "Start new chat"
|
|
848
|
+
})
|
|
849
|
+
}) : null,
|
|
850
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
851
|
+
accessibilityElementsHidden: isClosed,
|
|
852
|
+
importantForAccessibility: isClosed ? "no-hide-descendants" : "auto",
|
|
853
|
+
pointerEvents: isClosed ? "none" : "auto",
|
|
854
|
+
style: isClosed ? stylesheet.closed : stylesheet.webView,
|
|
855
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetWebView, {
|
|
856
|
+
baseUrl: lorikeetClient.baseUrl,
|
|
857
|
+
onEvent: handleEvent,
|
|
858
|
+
ref: webViewRef,
|
|
859
|
+
uri: loaded.uri,
|
|
860
|
+
webviewProps: {
|
|
861
|
+
allowsInlineMediaPlayback: true,
|
|
862
|
+
mediaPlaybackRequiresUserAction: false,
|
|
863
|
+
scalesPageToFit: true,
|
|
864
|
+
startInLoadingState: true,
|
|
865
|
+
style: stylesheet.webView,
|
|
866
|
+
...webviewProps,
|
|
867
|
+
onMessage: handleMessage,
|
|
868
|
+
onRenderProcessGone: (event) => {
|
|
869
|
+
var _webviewProps$onRende;
|
|
870
|
+
if (generation === generationRef.current) reload();
|
|
871
|
+
webviewProps === null || webviewProps === void 0 || (_webviewProps$onRende = webviewProps.onRenderProcessGone) === null || _webviewProps$onRende === void 0 || _webviewProps$onRende.call(webviewProps, event);
|
|
872
|
+
},
|
|
873
|
+
onContentProcessDidTerminate: (event) => {
|
|
874
|
+
var _webviewProps$onConte;
|
|
875
|
+
if (generation === generationRef.current) reload();
|
|
876
|
+
webviewProps === null || webviewProps === void 0 || (_webviewProps$onConte = webviewProps.onContentProcessDidTerminate) === null || _webviewProps$onConte === void 0 || _webviewProps$onConte.call(webviewProps, event);
|
|
877
|
+
}
|
|
696
878
|
}
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
|
|
879
|
+
}, `${identity}|${resumingTicketId !== null && resumingTicketId !== void 0 ? resumingTicketId : ""}|${generation}`)
|
|
880
|
+
})
|
|
881
|
+
]
|
|
700
882
|
})
|
|
701
883
|
});
|
|
702
|
-
}
|
|
884
|
+
});
|
|
885
|
+
LorikeetWidgetView.displayName = "LorikeetWidgetView";
|
|
703
886
|
|
|
704
887
|
//#endregion
|
|
888
|
+
exports.LOGOUT_CONFIRMATION_TIMEOUT_MS = LOGOUT_CONFIRMATION_TIMEOUT_MS;
|
|
705
889
|
exports.LORIKEET_ERROR_CODES = LORIKEET_ERROR_CODES;
|
|
706
890
|
exports.LorikeetClient = LorikeetClient;
|
|
707
891
|
exports.LorikeetWidgetHeader = LorikeetWidgetHeader;
|