rn-erxes-sdk 0.3.3 → 0.4.0
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 +140 -2
- package/docs/native-ios.md +5 -0
- package/ios/RnErxesSdk.swift +20 -1
- package/lib/commonjs/ErxesMessenger.js +234 -0
- package/lib/commonjs/ErxesMessenger.js.map +1 -0
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/nativeIos.js +13 -0
- package/lib/commonjs/nativeIos.js.map +1 -1
- package/lib/module/ErxesMessenger.js +229 -0
- package/lib/module/ErxesMessenger.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/nativeIos.js +13 -0
- package/lib/module/nativeIos.js.map +1 -1
- package/lib/typescript/ErxesMessenger.d.ts +95 -0
- package/lib/typescript/ErxesMessenger.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/nativeIos.d.ts +7 -0
- package/lib/typescript/nativeIos.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ErxesMessenger.tsx +323 -0
- package/src/index.tsx +8 -0
- package/src/nativeIos.ts +15 -0
package/README.md
CHANGED
|
@@ -127,9 +127,15 @@ Supports the classic widget and the full-screen **chat mode** (with voice
|
|
|
127
127
|
messages and header/drawer actions).
|
|
128
128
|
|
|
129
129
|
```tsx
|
|
130
|
-
import {
|
|
130
|
+
import { ErxesMessenger } from 'rn-erxes-sdk';
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
+
Two APIs are exported:
|
|
134
|
+
|
|
135
|
+
- **`<ErxesMessenger />`** — a declarative React component that handles configure,
|
|
136
|
+
user identity, action taps, and the show/hide lifecycle. Recommended for most apps.
|
|
137
|
+
- **`ErxesNativeIOS`** — the low-level native bridge for advanced/imperative control.
|
|
138
|
+
|
|
133
139
|
## Requirements
|
|
134
140
|
|
|
135
141
|
| | |
|
|
@@ -174,7 +180,129 @@ cd ios && pod install
|
|
|
174
180
|
npx expo run:ios
|
|
175
181
|
```
|
|
176
182
|
|
|
177
|
-
## Usage
|
|
183
|
+
## Usage — `<ErxesMessenger />` (recommended)
|
|
184
|
+
|
|
185
|
+
Render the component where the messenger should be active. It configures the SDK on
|
|
186
|
+
mount, dispatches action taps to your `onPress` handlers, and hides the messenger on
|
|
187
|
+
unmount. It renders nothing — the messenger UI is presented natively over your app.
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
import { ErxesMessenger } from 'rn-erxes-sdk';
|
|
191
|
+
|
|
192
|
+
<ErxesMessenger
|
|
193
|
+
integrationId="YOUR_INTEGRATION_ID"
|
|
194
|
+
subDomain="yourcompany.erxes.io"
|
|
195
|
+
user={{ name: 'Jane Doe', email: 'user@example.com' }}
|
|
196
|
+
/>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Example 1 — Classic floating launcher
|
|
200
|
+
|
|
201
|
+
Shows a draggable button over your app. Tapping it opens the messenger.
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
<ErxesMessenger
|
|
205
|
+
integrationId={INTEGRATION_ID}
|
|
206
|
+
endpoint={ENDPOINT}
|
|
207
|
+
displayMode="classic"
|
|
208
|
+
launcherVisible
|
|
209
|
+
user={CURRENT_USER}
|
|
210
|
+
/>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Example 2 — Home screen full-screen chat
|
|
214
|
+
|
|
215
|
+
Chat mode opens full-screen and auto-opens when connected. Bind `visible` to screen
|
|
216
|
+
focus so the messenger shows/hides as the user navigates, and add a header action to
|
|
217
|
+
jump to another screen.
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
import { ActivityIndicator, View } from 'react-native';
|
|
221
|
+
|
|
222
|
+
const isFocused = useIsFocused();
|
|
223
|
+
|
|
224
|
+
<ErxesMessenger
|
|
225
|
+
visible={isFocused}
|
|
226
|
+
integrationId={INTEGRATION_ID}
|
|
227
|
+
endpoint={ENDPOINT}
|
|
228
|
+
displayMode="chat"
|
|
229
|
+
user={CURRENT_USER}
|
|
230
|
+
renderLoading={() => (
|
|
231
|
+
<View style={{ flex: 1, justifyContent: 'center' }}>
|
|
232
|
+
<ActivityIndicator />
|
|
233
|
+
</View>
|
|
234
|
+
)}
|
|
235
|
+
homeActions={[
|
|
236
|
+
{
|
|
237
|
+
id: 'profile',
|
|
238
|
+
title: 'Profile',
|
|
239
|
+
systemIcon: 'person.crop.circle',
|
|
240
|
+
onPress: async ({ hide }) => {
|
|
241
|
+
await hide();
|
|
242
|
+
navigation.navigate('Profile', { user: CURRENT_USER });
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
]}
|
|
246
|
+
/>
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
`renderLoading` shows your own UI until the connection handshake completes
|
|
250
|
+
(`onReady`). Note that chat mode also shows its own loading indicator inside the
|
|
251
|
+
full-screen native view, so `renderLoading` is most useful in classic mode.
|
|
252
|
+
|
|
253
|
+
### Example 3 — Settings → Support screen with a close button
|
|
254
|
+
|
|
255
|
+
Open chat on mount, hide it on unmount, and add an `X` action that closes the
|
|
256
|
+
messenger and pops the screen.
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
<ErxesMessenger
|
|
260
|
+
integrationId={INTEGRATION_ID}
|
|
261
|
+
endpoint={ENDPOINT}
|
|
262
|
+
displayMode="chat"
|
|
263
|
+
autoOpen
|
|
264
|
+
autoHideOnUnmount
|
|
265
|
+
user={CURRENT_USER}
|
|
266
|
+
homeActions={[
|
|
267
|
+
{
|
|
268
|
+
id: 'close',
|
|
269
|
+
title: 'Close',
|
|
270
|
+
systemIcon: 'xmark',
|
|
271
|
+
onPress: async ({ hide }) => {
|
|
272
|
+
await hide();
|
|
273
|
+
navigation.goBack();
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
]}
|
|
277
|
+
onReady={() => console.log('erxes messenger ready')}
|
|
278
|
+
onError={(error) => console.log('erxes messenger error', error)}
|
|
279
|
+
/>
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Props
|
|
283
|
+
|
|
284
|
+
| Prop | Type | Notes |
|
|
285
|
+
|---|---|---|
|
|
286
|
+
| `integrationId` | `string` | Required. |
|
|
287
|
+
| `endpoint` / `serverUrl` / `subDomain` | `string` | Provide one. `subDomain` accepts `'company.erxes.io'`. |
|
|
288
|
+
| `displayMode` | `'classic' \| 'chat'` | Defaults to `'classic'`. |
|
|
289
|
+
| `user` | `ErxesUser` | `{ name?, email?, phone?, customData? }`. |
|
|
290
|
+
| `cachedCustomerId` | `string` | Reuse a cached customer. |
|
|
291
|
+
| `primaryColor` | `string` | Hex accent, e.g. `'#3f78d9'`. |
|
|
292
|
+
| `visible` | `boolean` | Controlled show/hide on change. |
|
|
293
|
+
| `autoOpen` | `boolean` | Open after configure. Defaults to `true` in chat mode. |
|
|
294
|
+
| `autoHideOnUnmount` | `boolean` | Hide on unmount. Defaults to `true`. |
|
|
295
|
+
| `launcherVisible` | `boolean` | Show/hide the floating launcher after configure. |
|
|
296
|
+
| `homeActions` / `drawerActions` | `ErxesAction[]` | `{ id, title, systemIcon, onPress? }`. Chat mode only. |
|
|
297
|
+
| `renderLoading` | `() => ReactNode` | Rendered while configuring (between `onLoad` and `onReady`/`onError`), e.g. a spinner. Defaults to nothing. |
|
|
298
|
+
| `onLoad` / `onReady` / `onOpen` / `onClose` / `onError` | callbacks | Lifecycle events. |
|
|
299
|
+
| `onLoadingChange` | `(loading: boolean) => void` | Fired when the loading state changes (`true` while configuring). |
|
|
300
|
+
| `onAction` | `(id, helpers) => void` | Fallback for tapped actions with no `onPress`. |
|
|
301
|
+
|
|
302
|
+
Action `onPress` (and `onAction`) receive `ErxesMessengerHelpers`:
|
|
303
|
+
`show`, `hide`, `showLauncher`, `hideLauncher`, `setUser`, `clearUser`.
|
|
304
|
+
|
|
305
|
+
## Advanced — `ErxesNativeIOS` (low-level)
|
|
178
306
|
|
|
179
307
|
Call `configure` once at startup. It connects in the background so the messenger opens instantly.
|
|
180
308
|
|
|
@@ -235,6 +363,16 @@ const sub = ErxesNativeIOS.addActionListener((id) => {
|
|
|
235
363
|
// sub.remove() on cleanup
|
|
236
364
|
```
|
|
237
365
|
|
|
366
|
+
To know when the messenger has finished connecting (e.g. to hide your own
|
|
367
|
+
spinner), listen for the ready event:
|
|
368
|
+
|
|
369
|
+
```tsx
|
|
370
|
+
const readySub = ErxesNativeIOS.addReadyListener(() => {
|
|
371
|
+
// connection handshake complete — messenger is ready
|
|
372
|
+
});
|
|
373
|
+
// readySub.remove() on cleanup
|
|
374
|
+
```
|
|
375
|
+
|
|
238
376
|
Chat mode also supports voice messages — see the [Native iOS guide](docs/native-ios.md) for the required `Info.plist` permissions.
|
|
239
377
|
|
|
240
378
|
On logout:
|
package/docs/native-ios.md
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
([`erxes/erxes-ios-sdk`](https://github.com/erxes/erxes-ios-sdk) `0.30.7`)
|
|
5
5
|
into your React Native app.
|
|
6
6
|
|
|
7
|
+
> **Most apps should use the `<ErxesMessenger />` component instead** — it wraps
|
|
8
|
+
> this bridge and manages configure, user identity, action taps, and the show/hide
|
|
9
|
+
> lifecycle declaratively. See the [README](../README.md#usage--erxesmessenger-recommended).
|
|
10
|
+
> This guide documents the low-level `ErxesNativeIOS` API for advanced/imperative use.
|
|
11
|
+
|
|
7
12
|
## Requirements
|
|
8
13
|
|
|
9
14
|
| | |
|
package/ios/RnErxesSdk.swift
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Combine
|
|
1
2
|
import Foundation
|
|
2
3
|
import MessengerSDK
|
|
3
4
|
import UIKit
|
|
@@ -8,15 +9,21 @@ final class RnErxesSdk: RCTEventEmitter {
|
|
|
8
9
|
/// JS event fired when a chat-mode action (homeActions/drawerActions) is tapped.
|
|
9
10
|
private static let actionEvent = "onErxesAction"
|
|
10
11
|
|
|
12
|
+
/// JS event fired when the connect handshake completes (`MessengerSDK.isReady`).
|
|
13
|
+
private static let readyEvent = "onErxesReady"
|
|
14
|
+
|
|
11
15
|
/// True while JS has at least one listener attached, so we don't emit into the void.
|
|
12
16
|
private var hasListeners = false
|
|
13
17
|
|
|
18
|
+
/// Observes `MessengerSDK.shared.isReady` so we can forward readiness to JS.
|
|
19
|
+
private var readyCancellable: AnyCancellable?
|
|
20
|
+
|
|
14
21
|
override static func requiresMainQueueSetup() -> Bool {
|
|
15
22
|
true
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
override func supportedEvents() -> [String] {
|
|
19
|
-
[Self.actionEvent]
|
|
26
|
+
[Self.actionEvent, Self.readyEvent]
|
|
20
27
|
}
|
|
21
28
|
|
|
22
29
|
override func startObserving() {
|
|
@@ -62,6 +69,18 @@ final class RnErxesSdk: RCTEventEmitter {
|
|
|
62
69
|
self.sendEvent(withName: Self.actionEvent, body: ["id": id])
|
|
63
70
|
}
|
|
64
71
|
|
|
72
|
+
// Forward the connect handshake to JS as `onErxesReady`. `$isReady`
|
|
73
|
+
// emits its current value on subscribe, so a `configure()` after the
|
|
74
|
+
// SDK is already connected still notifies JS. `removeDuplicates`
|
|
75
|
+
// collapses repeated `true`s into a single emission per connection.
|
|
76
|
+
self.readyCancellable = MessengerSDK.shared.$isReady
|
|
77
|
+
.removeDuplicates()
|
|
78
|
+
.filter { $0 }
|
|
79
|
+
.sink { [weak self] _ in
|
|
80
|
+
guard let self, self.hasListeners else { return }
|
|
81
|
+
self.sendEvent(withName: Self.readyEvent, body: nil)
|
|
82
|
+
}
|
|
83
|
+
|
|
65
84
|
MessengerSDK.configure(
|
|
66
85
|
MessengerConfig(
|
|
67
86
|
endpoint: endpoint,
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ErxesMessenger = ErxesMessenger;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _nativeIos = require("./nativeIos");
|
|
10
|
+
/**
|
|
11
|
+
* The identified end user. Same shape the native bridge expects — passing
|
|
12
|
+
* `undefined` leaves the visitor anonymous until you call `setUser` later.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Helpers handed to action `onPress` callbacks (and `onAction`) so you can drive
|
|
17
|
+
* the messenger imperatively from inside a tap handler — show/hide it, toggle the
|
|
18
|
+
* launcher, or swap the user.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A chat-mode action rendered in the header (`homeActions`) or drawer
|
|
23
|
+
* (`drawerActions`). Only `id`/`title`/`systemIcon` cross the native bridge; the
|
|
24
|
+
* `onPress` callback stays in JS and runs when the matching action is tapped.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Drop `onPress` so only the data-only fields the native bridge understands
|
|
29
|
+
* (`id`/`title`/`systemIcon`) cross over. React Native cannot send JS functions
|
|
30
|
+
* to native, so `onPress` is dispatched on the JS side via the action listener.
|
|
31
|
+
*/
|
|
32
|
+
function stripActions(actions) {
|
|
33
|
+
return actions.map(_ref => {
|
|
34
|
+
let {
|
|
35
|
+
onPress: _onPress,
|
|
36
|
+
...nativeAction
|
|
37
|
+
} = _ref;
|
|
38
|
+
return nativeAction;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Declarative wrapper around {@link ErxesNativeIOS}. Configures the native erxes
|
|
44
|
+
* messenger, wires up action taps, and manages the show/hide lifecycle so app
|
|
45
|
+
* code stays a single component. Renders nothing — the messenger UI is presented
|
|
46
|
+
* natively over your app.
|
|
47
|
+
*
|
|
48
|
+
* For advanced/imperative control, use `ErxesNativeIOS` directly.
|
|
49
|
+
*/
|
|
50
|
+
function ErxesMessenger(_ref2) {
|
|
51
|
+
let {
|
|
52
|
+
integrationId,
|
|
53
|
+
endpoint,
|
|
54
|
+
serverUrl,
|
|
55
|
+
subDomain,
|
|
56
|
+
displayMode = 'classic',
|
|
57
|
+
user,
|
|
58
|
+
cachedCustomerId,
|
|
59
|
+
primaryColor,
|
|
60
|
+
visible,
|
|
61
|
+
autoOpen = displayMode === 'chat',
|
|
62
|
+
autoHideOnUnmount = true,
|
|
63
|
+
launcherVisible,
|
|
64
|
+
homeActions = [],
|
|
65
|
+
drawerActions = [],
|
|
66
|
+
renderLoading,
|
|
67
|
+
onLoad,
|
|
68
|
+
onReady,
|
|
69
|
+
onOpen,
|
|
70
|
+
onClose,
|
|
71
|
+
onError,
|
|
72
|
+
onAction,
|
|
73
|
+
onLoadingChange
|
|
74
|
+
} = _ref2;
|
|
75
|
+
// Keep the latest actions/callback in refs so the action listener (registered
|
|
76
|
+
// once below) always dispatches against current props without re-subscribing.
|
|
77
|
+
const actionsRef = (0, _react.useRef)([]);
|
|
78
|
+
const onActionRef = (0, _react.useRef)(onAction);
|
|
79
|
+
const onLoadingChangeRef = (0, _react.useRef)(onLoadingChange);
|
|
80
|
+
// Tracks whether we believe the messenger is currently presented, so we never
|
|
81
|
+
// double-present (chat mode auto-presents inside `configure()`) or fire a
|
|
82
|
+
// redundant show/hide. Native gives us no presentation callback, so this is our
|
|
83
|
+
// best-effort intent mirror.
|
|
84
|
+
const shownRef = (0, _react.useRef)(false);
|
|
85
|
+
|
|
86
|
+
// Flips true only after native `configure()` resolves. The controlled-`visible`
|
|
87
|
+
// effect gates on this so it never calls `showMessenger()` before `configure()`
|
|
88
|
+
// (the native SDK asserts on that ordering).
|
|
89
|
+
const [configured, setConfigured] = (0, _react.useState)(false);
|
|
90
|
+
// True while configuring (between `onLoad` and `onReady`/`onError`); drives
|
|
91
|
+
// `renderLoading`.
|
|
92
|
+
const [loading, setLoading] = (0, _react.useState)(false);
|
|
93
|
+
(0, _react.useEffect)(() => {
|
|
94
|
+
onLoadingChangeRef.current = onLoadingChange;
|
|
95
|
+
}, [onLoadingChange]);
|
|
96
|
+
(0, _react.useEffect)(() => {
|
|
97
|
+
var _onLoadingChangeRef$c;
|
|
98
|
+
(_onLoadingChangeRef$c = onLoadingChangeRef.current) === null || _onLoadingChangeRef$c === void 0 ? void 0 : _onLoadingChangeRef$c.call(onLoadingChangeRef, loading);
|
|
99
|
+
}, [loading]);
|
|
100
|
+
(0, _react.useEffect)(() => {
|
|
101
|
+
actionsRef.current = [...homeActions, ...drawerActions];
|
|
102
|
+
onActionRef.current = onAction;
|
|
103
|
+
}, [homeActions, drawerActions, onAction]);
|
|
104
|
+
(0, _react.useEffect)(() => {
|
|
105
|
+
if (_reactNative.Platform.OS !== 'ios') {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
setConfigured(false);
|
|
109
|
+
const helpers = {
|
|
110
|
+
show: async () => {
|
|
111
|
+
await _nativeIos.ErxesNativeIOS.showMessenger();
|
|
112
|
+
shownRef.current = true;
|
|
113
|
+
},
|
|
114
|
+
hide: async () => {
|
|
115
|
+
await _nativeIos.ErxesNativeIOS.hideMessenger();
|
|
116
|
+
shownRef.current = false;
|
|
117
|
+
},
|
|
118
|
+
showLauncher: () => _nativeIos.ErxesNativeIOS.showLauncher(),
|
|
119
|
+
hideLauncher: () => _nativeIos.ErxesNativeIOS.hideLauncher(),
|
|
120
|
+
setUser: nextUser => _nativeIos.ErxesNativeIOS.setUser(nextUser),
|
|
121
|
+
clearUser: () => _nativeIos.ErxesNativeIOS.clearUser()
|
|
122
|
+
};
|
|
123
|
+
const sub = _nativeIos.ErxesNativeIOS.addActionListener(async id => {
|
|
124
|
+
var _onActionRef$current;
|
|
125
|
+
const action = actionsRef.current.find(item => item.id === id);
|
|
126
|
+
if (action !== null && action !== void 0 && action.onPress) {
|
|
127
|
+
await action.onPress(helpers);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
await ((_onActionRef$current = onActionRef.current) === null || _onActionRef$current === void 0 ? void 0 : _onActionRef$current.call(onActionRef, id, helpers));
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Connection complete (native `MessengerSDK.isReady`): the messenger is
|
|
134
|
+
// truly ready, so end the loading state and notify the host.
|
|
135
|
+
const readySub = _nativeIos.ErxesNativeIOS.addReadyListener(() => {
|
|
136
|
+
setLoading(false);
|
|
137
|
+
onReady === null || onReady === void 0 ? void 0 : onReady();
|
|
138
|
+
});
|
|
139
|
+
async function setup() {
|
|
140
|
+
try {
|
|
141
|
+
setLoading(true);
|
|
142
|
+
onLoad === null || onLoad === void 0 ? void 0 : onLoad();
|
|
143
|
+
if (user) {
|
|
144
|
+
await _nativeIos.ErxesNativeIOS.setUser(user);
|
|
145
|
+
}
|
|
146
|
+
await _nativeIos.ErxesNativeIOS.configure({
|
|
147
|
+
integrationId,
|
|
148
|
+
endpoint,
|
|
149
|
+
serverUrl,
|
|
150
|
+
subDomain,
|
|
151
|
+
cachedCustomerId,
|
|
152
|
+
displayMode,
|
|
153
|
+
primaryColor,
|
|
154
|
+
homeActions: stripActions(homeActions),
|
|
155
|
+
drawerActions: stripActions(drawerActions)
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// `configure()` only kicks off the async connect; `onReady` and the end
|
|
159
|
+
// of `loading` are driven by the ready listener above, not here.
|
|
160
|
+
|
|
161
|
+
// Decide the initial open state. If `visible` is controlled it wins;
|
|
162
|
+
// otherwise fall back to `autoOpen` (defaults to true in chat mode).
|
|
163
|
+
const shouldOpen = visible ?? autoOpen;
|
|
164
|
+
if (displayMode === 'chat') {
|
|
165
|
+
// Chat mode auto-presents itself inside `configure()` — never call
|
|
166
|
+
// `showMessenger()` for the initial open or we'd present a second one.
|
|
167
|
+
if (shouldOpen) {
|
|
168
|
+
shownRef.current = true;
|
|
169
|
+
onOpen === null || onOpen === void 0 ? void 0 : onOpen();
|
|
170
|
+
} else {
|
|
171
|
+
// Caller wants it closed: undo the native auto-present.
|
|
172
|
+
await _nativeIos.ErxesNativeIOS.hideMessenger();
|
|
173
|
+
shownRef.current = false;
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
// Classic mode: configure does not open anything. Show the launcher
|
|
177
|
+
// and/or present the sheet explicitly.
|
|
178
|
+
if (launcherVisible === true) {
|
|
179
|
+
await _nativeIos.ErxesNativeIOS.showLauncher();
|
|
180
|
+
} else if (launcherVisible === false) {
|
|
181
|
+
await _nativeIos.ErxesNativeIOS.hideLauncher();
|
|
182
|
+
}
|
|
183
|
+
if (shouldOpen) {
|
|
184
|
+
await _nativeIos.ErxesNativeIOS.showMessenger();
|
|
185
|
+
shownRef.current = true;
|
|
186
|
+
onOpen === null || onOpen === void 0 ? void 0 : onOpen();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
setConfigured(true);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
// Setup failed before the connection could complete — end loading here
|
|
192
|
+
// since the ready listener will never fire.
|
|
193
|
+
setLoading(false);
|
|
194
|
+
onError === null || onError === void 0 ? void 0 : onError(error);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
setup();
|
|
198
|
+
return () => {
|
|
199
|
+
sub.remove();
|
|
200
|
+
readySub.remove();
|
|
201
|
+
if (autoHideOnUnmount && shownRef.current) {
|
|
202
|
+
_nativeIos.ErxesNativeIOS.hideMessenger();
|
|
203
|
+
shownRef.current = false;
|
|
204
|
+
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
// Re-run setup only when the native config identity changes; callbacks and
|
|
208
|
+
// actions are read through refs so they don't need to be deps here.
|
|
209
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
210
|
+
}, [integrationId, endpoint, serverUrl, subDomain, displayMode]);
|
|
211
|
+
(0, _react.useEffect)(() => {
|
|
212
|
+
// Wait until `configure()` has resolved — otherwise `showMessenger()` would
|
|
213
|
+
// race ahead of it and trip the native configure-before-show assertion. The
|
|
214
|
+
// initial open is handled in `setup()`; this only reacts to later changes.
|
|
215
|
+
if (_reactNative.Platform.OS !== 'ios' || visible === undefined || !configured) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (visible && !shownRef.current) {
|
|
219
|
+
_nativeIos.ErxesNativeIOS.showMessenger();
|
|
220
|
+
shownRef.current = true;
|
|
221
|
+
onOpen === null || onOpen === void 0 ? void 0 : onOpen();
|
|
222
|
+
} else if (!visible && shownRef.current) {
|
|
223
|
+
_nativeIos.ErxesNativeIOS.hideMessenger();
|
|
224
|
+
shownRef.current = false;
|
|
225
|
+
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
226
|
+
}
|
|
227
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
228
|
+
}, [visible, configured]);
|
|
229
|
+
if (loading && renderLoading) {
|
|
230
|
+
return renderLoading();
|
|
231
|
+
}
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=ErxesMessenger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNative","_nativeIos","stripActions","actions","map","_ref","onPress","_onPress","nativeAction","ErxesMessenger","_ref2","integrationId","endpoint","serverUrl","subDomain","displayMode","user","cachedCustomerId","primaryColor","visible","autoOpen","autoHideOnUnmount","launcherVisible","homeActions","drawerActions","renderLoading","onLoad","onReady","onOpen","onClose","onError","onAction","onLoadingChange","actionsRef","useRef","onActionRef","onLoadingChangeRef","shownRef","configured","setConfigured","useState","loading","setLoading","useEffect","current","_onLoadingChangeRef$c","call","Platform","OS","helpers","show","ErxesNativeIOS","showMessenger","hide","hideMessenger","showLauncher","hideLauncher","setUser","nextUser","clearUser","sub","addActionListener","id","_onActionRef$current","action","find","item","readySub","addReadyListener","setup","configure","shouldOpen","error","remove","undefined"],"sourceRoot":"../../src","sources":["ErxesMessenger.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAEA,IAAAE,UAAA,GAAAF,OAAA;AAEA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAUA;AACA;AACA;AACA;AACA;;AA0EA;AACA;AACA;AACA;AACA;AACA,SAASG,YAAYA,CAACC,OAAsB,EAAE;EAC5C,OAAOA,OAAO,CAACC,GAAG,CAACC,IAAA;IAAA,IAAC;MAAEC,OAAO,EAAEC,QAAQ;MAAE,GAAGC;IAAa,CAAC,GAAAH,IAAA;IAAA,OAAKG,YAAY;EAAA,EAAC;AAC9E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,cAAcA,CAAAC,KAAA,EAuBN;EAAA,IAvBO;IAC7BC,aAAa;IACbC,QAAQ;IACRC,SAAS;IACTC,SAAS;IACTC,WAAW,GAAG,SAAS;IACvBC,IAAI;IACJC,gBAAgB;IAChBC,YAAY;IACZC,OAAO;IACPC,QAAQ,GAAGL,WAAW,KAAK,MAAM;IACjCM,iBAAiB,GAAG,IAAI;IACxBC,eAAe;IACfC,WAAW,GAAG,EAAE;IAChBC,aAAa,GAAG,EAAE;IAClBC,aAAa;IACbC,MAAM;IACNC,OAAO;IACPC,MAAM;IACNC,OAAO;IACPC,OAAO;IACPC,QAAQ;IACRC;EACmB,CAAC,GAAAtB,KAAA;EACpB;EACA;EACA,MAAMuB,UAAU,GAAG,IAAAC,aAAM,EAAgB,EAAE,CAAC;EAC5C,MAAMC,WAAW,GAAG,IAAAD,aAAM,EAACH,QAAQ,CAAC;EACpC,MAAMK,kBAAkB,GAAG,IAAAF,aAAM,EAACF,eAAe,CAAC;EAClD;EACA;EACA;EACA;EACA,MAAMK,QAAQ,GAAG,IAAAH,aAAM,EAAC,KAAK,CAAC;;EAE9B;EACA;EACA;EACA,MAAM,CAACI,UAAU,EAAEC,aAAa,CAAC,GAAG,IAAAC,eAAQ,EAAC,KAAK,CAAC;EACnD;EACA;EACA,MAAM,CAACC,OAAO,EAAEC,UAAU,CAAC,GAAG,IAAAF,eAAQ,EAAC,KAAK,CAAC;EAE7C,IAAAG,gBAAS,EAAC,MAAM;IACdP,kBAAkB,CAACQ,OAAO,GAAGZ,eAAe;EAC9C,CAAC,EAAE,CAACA,eAAe,CAAC,CAAC;EAErB,IAAAW,gBAAS,EAAC,MAAM;IAAA,IAAAE,qBAAA;IACd,CAAAA,qBAAA,GAAAT,kBAAkB,CAACQ,OAAO,cAAAC,qBAAA,uBAA1BA,qBAAA,CAAAC,IAAA,CAAAV,kBAAkB,EAAWK,OAAO,CAAC;EACvC,CAAC,EAAE,CAACA,OAAO,CAAC,CAAC;EAEb,IAAAE,gBAAS,EAAC,MAAM;IACdV,UAAU,CAACW,OAAO,GAAG,CAAC,GAAGrB,WAAW,EAAE,GAAGC,aAAa,CAAC;IACvDW,WAAW,CAACS,OAAO,GAAGb,QAAQ;EAChC,CAAC,EAAE,CAACR,WAAW,EAAEC,aAAa,EAAEO,QAAQ,CAAC,CAAC;EAE1C,IAAAY,gBAAS,EAAC,MAAM;IACd,IAAII,qBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;MACzB;IACF;IAEAT,aAAa,CAAC,KAAK,CAAC;IAEpB,MAAMU,OAA8B,GAAG;MACrCC,IAAI,EAAE,MAAAA,CAAA,KAAY;QAChB,MAAMC,yBAAc,CAACC,aAAa,CAAC,CAAC;QACpCf,QAAQ,CAACO,OAAO,GAAG,IAAI;MACzB,CAAC;MACDS,IAAI,EAAE,MAAAA,CAAA,KAAY;QAChB,MAAMF,yBAAc,CAACG,aAAa,CAAC,CAAC;QACpCjB,QAAQ,CAACO,OAAO,GAAG,KAAK;MAC1B,CAAC;MACDW,YAAY,EAAEA,CAAA,KAAMJ,yBAAc,CAACI,YAAY,CAAC,CAAC;MACjDC,YAAY,EAAEA,CAAA,KAAML,yBAAc,CAACK,YAAY,CAAC,CAAC;MACjDC,OAAO,EAAGC,QAAQ,IAAKP,yBAAc,CAACM,OAAO,CAACC,QAAQ,CAAC;MACvDC,SAAS,EAAEA,CAAA,KAAMR,yBAAc,CAACQ,SAAS,CAAC;IAC5C,CAAC;IAED,MAAMC,GAAG,GAAGT,yBAAc,CAACU,iBAAiB,CAAC,MAAOC,EAAE,IAAK;MAAA,IAAAC,oBAAA;MACzD,MAAMC,MAAM,GAAG/B,UAAU,CAACW,OAAO,CAACqB,IAAI,CAAEC,IAAI,IAAKA,IAAI,CAACJ,EAAE,KAAKA,EAAE,CAAC;MAEhE,IAAIE,MAAM,aAANA,MAAM,eAANA,MAAM,CAAE1D,OAAO,EAAE;QACnB,MAAM0D,MAAM,CAAC1D,OAAO,CAAC2C,OAAO,CAAC;QAC7B;MACF;MAEA,QAAAc,oBAAA,GAAM5B,WAAW,CAACS,OAAO,cAAAmB,oBAAA,uBAAnBA,oBAAA,CAAAjB,IAAA,CAAAX,WAAW,EAAW2B,EAAE,EAAEb,OAAO,CAAC;IAC1C,CAAC,CAAC;;IAEF;IACA;IACA,MAAMkB,QAAQ,GAAGhB,yBAAc,CAACiB,gBAAgB,CAAC,MAAM;MACrD1B,UAAU,CAAC,KAAK,CAAC;MACjBf,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAG,CAAC;IACb,CAAC,CAAC;IAEF,eAAe0C,KAAKA,CAAA,EAAG;MACrB,IAAI;QACF3B,UAAU,CAAC,IAAI,CAAC;QAChBhB,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAG,CAAC;QAEV,IAAIV,IAAI,EAAE;UACR,MAAMmC,yBAAc,CAACM,OAAO,CAACzC,IAAI,CAAC;QACpC;QAEA,MAAMmC,yBAAc,CAACmB,SAAS,CAAC;UAC7B3D,aAAa;UACbC,QAAQ;UACRC,SAAS;UACTC,SAAS;UACTG,gBAAgB;UAChBF,WAAW;UACXG,YAAY;UACZK,WAAW,EAAErB,YAAY,CAACqB,WAAW,CAAC;UACtCC,aAAa,EAAEtB,YAAY,CAACsB,aAAa;QAC3C,CAAC,CAAC;;QAEF;QACA;;QAEA;QACA;QACA,MAAM+C,UAAU,GAAGpD,OAAO,IAAIC,QAAQ;QAEtC,IAAIL,WAAW,KAAK,MAAM,EAAE;UAC1B;UACA;UACA,IAAIwD,UAAU,EAAE;YACdlC,QAAQ,CAACO,OAAO,GAAG,IAAI;YACvBhB,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAG,CAAC;UACZ,CAAC,MAAM;YACL;YACA,MAAMuB,yBAAc,CAACG,aAAa,CAAC,CAAC;YACpCjB,QAAQ,CAACO,OAAO,GAAG,KAAK;UAC1B;QACF,CAAC,MAAM;UACL;UACA;UACA,IAAItB,eAAe,KAAK,IAAI,EAAE;YAC5B,MAAM6B,yBAAc,CAACI,YAAY,CAAC,CAAC;UACrC,CAAC,MAAM,IAAIjC,eAAe,KAAK,KAAK,EAAE;YACpC,MAAM6B,yBAAc,CAACK,YAAY,CAAC,CAAC;UACrC;UAEA,IAAIe,UAAU,EAAE;YACd,MAAMpB,yBAAc,CAACC,aAAa,CAAC,CAAC;YACpCf,QAAQ,CAACO,OAAO,GAAG,IAAI;YACvBhB,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAG,CAAC;UACZ;QACF;QAEAW,aAAa,CAAC,IAAI,CAAC;MACrB,CAAC,CAAC,OAAOiC,KAAK,EAAE;QACd;QACA;QACA9B,UAAU,CAAC,KAAK,CAAC;QACjBZ,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAG0C,KAAK,CAAC;MAClB;IACF;IAEAH,KAAK,CAAC,CAAC;IAEP,OAAO,MAAM;MACXT,GAAG,CAACa,MAAM,CAAC,CAAC;MACZN,QAAQ,CAACM,MAAM,CAAC,CAAC;MAEjB,IAAIpD,iBAAiB,IAAIgB,QAAQ,CAACO,OAAO,EAAE;QACzCO,yBAAc,CAACG,aAAa,CAAC,CAAC;QAC9BjB,QAAQ,CAACO,OAAO,GAAG,KAAK;QACxBf,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAG,CAAC;MACb;IACF,CAAC;IACD;IACA;IACA;EACF,CAAC,EAAE,CAAClB,aAAa,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,SAAS,EAAEC,WAAW,CAAC,CAAC;EAEhE,IAAA4B,gBAAS,EAAC,MAAM;IACd;IACA;IACA;IACA,IAAII,qBAAQ,CAACC,EAAE,KAAK,KAAK,IAAI7B,OAAO,KAAKuD,SAAS,IAAI,CAACpC,UAAU,EAAE;MACjE;IACF;IAEA,IAAInB,OAAO,IAAI,CAACkB,QAAQ,CAACO,OAAO,EAAE;MAChCO,yBAAc,CAACC,aAAa,CAAC,CAAC;MAC9Bf,QAAQ,CAACO,OAAO,GAAG,IAAI;MACvBhB,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAG,CAAC;IACZ,CAAC,MAAM,IAAI,CAACT,OAAO,IAAIkB,QAAQ,CAACO,OAAO,EAAE;MACvCO,yBAAc,CAACG,aAAa,CAAC,CAAC;MAC9BjB,QAAQ,CAACO,OAAO,GAAG,KAAK;MACxBf,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAG,CAAC;IACb;IACA;EACF,CAAC,EAAE,CAACV,OAAO,EAAEmB,UAAU,CAAC,CAAC;EAEzB,IAAIG,OAAO,IAAIhB,aAAa,EAAE;IAC5B,OAAOA,aAAa,CAAC,CAAC;EACxB;EAEA,OAAO,IAAI;AACb"}
|
package/lib/commonjs/index.js
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
Object.defineProperty(exports, "ErxesMessenger", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _ErxesMessenger.ErxesMessenger;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
6
12
|
Object.defineProperty(exports, "ErxesNativeIOS", {
|
|
7
13
|
enumerable: true,
|
|
8
14
|
get: function () {
|
|
@@ -10,4 +16,5 @@ Object.defineProperty(exports, "ErxesNativeIOS", {
|
|
|
10
16
|
}
|
|
11
17
|
});
|
|
12
18
|
var _nativeIos = require("./nativeIos");
|
|
19
|
+
var _ErxesMessenger = require("./ErxesMessenger");
|
|
13
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_nativeIos","require"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_nativeIos","require","_ErxesMessenger"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;;;;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA;AAOA,IAAAC,eAAA,GAAAD,OAAA"}
|
|
@@ -13,6 +13,9 @@ var _reactNative = require("react-native");
|
|
|
13
13
|
|
|
14
14
|
/** Native event name emitted when a chat-mode action is tapped. */
|
|
15
15
|
const ACTION_EVENT = 'onErxesAction';
|
|
16
|
+
|
|
17
|
+
/** Native event name emitted when the connect handshake completes. */
|
|
18
|
+
const READY_EVENT = 'onErxesReady';
|
|
16
19
|
const LINKING_ERROR = "The rn-erxes-sdk native iOS module is not linked. Run `pod install` in your app's ios directory and rebuild the app.";
|
|
17
20
|
const nativeModule = _reactNative.NativeModules.RnErxesSdk;
|
|
18
21
|
function getNativeModule() {
|
|
@@ -65,6 +68,16 @@ const ErxesNativeIOS = {
|
|
|
65
68
|
addActionListener(handler) {
|
|
66
69
|
const emitter = new _reactNative.NativeEventEmitter(getNativeModule());
|
|
67
70
|
return emitter.addListener(ACTION_EVENT, event => handler(event.id));
|
|
71
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* Listen for the connect handshake completing — i.e. the messenger is ready
|
|
74
|
+
* (`MessengerSDK.isReady`). Fires once per connection; if already connected
|
|
75
|
+
* when you subscribe via a fresh `configure`, it fires again. Returns a
|
|
76
|
+
* subscription — call `.remove()` to stop listening.
|
|
77
|
+
*/
|
|
78
|
+
addReadyListener(handler) {
|
|
79
|
+
const emitter = new _reactNative.NativeEventEmitter(getNativeModule());
|
|
80
|
+
return emitter.addListener(READY_EVENT, () => handler());
|
|
68
81
|
}
|
|
69
82
|
};
|
|
70
83
|
exports.ErxesNativeIOS = ErxesNativeIOS;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","ACTION_EVENT","LINKING_ERROR","nativeModule","NativeModules","RnErxesSdk","getNativeModule","Platform","OS","Error","ErxesNativeIOS","configure","options","setUser","customData","Object","fromEntries","entries","filter","_ref","value","undefined","map","_ref2","key","String","clearUser","showMessenger","showLauncher","hideLauncher","hideMessenger","addActionListener","handler","emitter","NativeEventEmitter","addListener","event","id","exports"],"sourceRoot":"../../src","sources":["nativeIos.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAQA;AACA;AACA;AACA;AACA;;AA2CA;AACA,MAAMC,YAAY,GAAG,eAAe;
|
|
1
|
+
{"version":3,"names":["_reactNative","require","ACTION_EVENT","READY_EVENT","LINKING_ERROR","nativeModule","NativeModules","RnErxesSdk","getNativeModule","Platform","OS","Error","ErxesNativeIOS","configure","options","setUser","customData","Object","fromEntries","entries","filter","_ref","value","undefined","map","_ref2","key","String","clearUser","showMessenger","showLauncher","hideLauncher","hideMessenger","addActionListener","handler","emitter","NativeEventEmitter","addListener","event","id","addReadyListener","exports"],"sourceRoot":"../../src","sources":["nativeIos.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAQA;AACA;AACA;AACA;AACA;;AA2CA;AACA,MAAMC,YAAY,GAAG,eAAe;;AAEpC;AACA,MAAMC,WAAW,GAAG,cAAc;AAElC,MAAMC,aAAa,GACjB,sHAAsH;AAExH,MAAMC,YAAY,GAAGC,0BAAa,CAACC,UAAyC;AAE5E,SAASC,eAAeA,CAAA,EAAoB;EAC1C,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;IACzB,MAAM,IAAIC,KAAK,CAAC,kDAAkD,CAAC;EACrE;EAEA,IAAI,CAACN,YAAY,EAAE;IACjB,MAAM,IAAIM,KAAK,CAACP,aAAa,CAAC;EAChC;EAEA,OAAOC,YAAY;AACrB;AAEO,MAAMO,cAAc,GAAG;EAC5BC,SAASA,CAACC,OAAwB,EAAE;IAClC,OAAON,eAAe,CAAC,CAAC,CAACK,SAAS,CAACC,OAAO,CAAC;EAC7C,CAAC;EACDC,OAAOA,CAACD,OAAsB,EAAE;IAC9B,MAAME,UAAU,GAAGC,MAAM,CAACC,WAAW,CACnCD,MAAM,CAACE,OAAO,CAACL,OAAO,CAACE,UAAU,IAAI,CAAC,CAAC,CAAC,CACrCI,MAAM,CAACC,IAAA;MAAA,IAAC,GAAGC,KAAK,CAAC,GAAAD,IAAA;MAAA,OAAKC,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAKC,SAAS;IAAA,EAAC,CAC5DC,GAAG,CAACC,KAAA;MAAA,IAAC,CAACC,GAAG,EAAEJ,KAAK,CAAC,GAAAG,KAAA;MAAA,OAAK,CAACC,GAAG,EAAEC,MAAM,CAACL,KAAK,CAAC,CAAC;IAAA,EAC/C,CAAC;IAED,OAAOd,eAAe,CAAC,CAAC,CAACO,OAAO,CAAC;MAC/B,GAAGD,OAAO;MACVE;IACF,CAAC,CAAC;EACJ,CAAC;EACDY,SAASA,CAAA,EAAG;IACV,OAAOpB,eAAe,CAAC,CAAC,CAACoB,SAAS,CAAC,CAAC;EACtC,CAAC;EACDC,aAAaA,CAAA,EAAG;IACd,OAAOrB,eAAe,CAAC,CAAC,CAACqB,aAAa,CAAC,CAAC;EAC1C,CAAC;EACDC,YAAYA,CAAA,EAAG;IACb,OAAOtB,eAAe,CAAC,CAAC,CAACsB,YAAY,CAAC,CAAC;EACzC,CAAC;EACDC,YAAYA,CAAA,EAAG;IACb,OAAOvB,eAAe,CAAC,CAAC,CAACuB,YAAY,CAAC,CAAC;EACzC,CAAC;EACDC,aAAaA,CAAA,EAAG;IACd,OAAOxB,eAAe,CAAC,CAAC,CAACwB,aAAa,CAAC,CAAC;EAC1C,CAAC;EACD;AACF;AACA;AACA;AACA;AACA;EACEC,iBAAiBA,CAACC,OAA6B,EAAuB;IACpE,MAAMC,OAAO,GAAG,IAAIC,+BAAkB,CACpC5B,eAAe,CAAC,CAClB,CAAC;IACD,OAAO2B,OAAO,CAACE,WAAW,CAACnC,YAAY,EAAGoC,KAAqB,IAC7DJ,OAAO,CAACI,KAAK,CAACC,EAAE,CAClB,CAAC;EACH,CAAC;EACD;AACF;AACA;AACA;AACA;AACA;EACEC,gBAAgBA,CAACN,OAAmB,EAAuB;IACzD,MAAMC,OAAO,GAAG,IAAIC,+BAAkB,CACpC5B,eAAe,CAAC,CAClB,CAAC;IACD,OAAO2B,OAAO,CAACE,WAAW,CAAClC,WAAW,EAAE,MAAM+B,OAAO,CAAC,CAAC,CAAC;EAC1D;AACF,CAAC;AAACO,OAAA,CAAA7B,cAAA,GAAAA,cAAA"}
|