@experiaapp/webchat-react-native 2.0.1
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 +254 -0
- package/app.plugin.js +6 -0
- package/lib/adapters/audio.d.ts +74 -0
- package/lib/adapters/audio.js +39 -0
- package/lib/adapters/audioRoute.d.ts +57 -0
- package/lib/adapters/audioRoute.js +77 -0
- package/lib/adapters/expoDefaults.d.ts +77 -0
- package/lib/adapters/expoDefaults.js +539 -0
- package/lib/adapters/picker.d.ts +67 -0
- package/lib/adapters/picker.js +37 -0
- package/lib/adapters/webrtc.d.ts +131 -0
- package/lib/adapters/webrtc.js +70 -0
- package/lib/core/VideoCallClient.d.ts +106 -0
- package/lib/core/VideoCallClient.js +302 -0
- package/lib/core/WebchatClient.d.ts +34 -0
- package/lib/core/WebchatClient.js +132 -0
- package/lib/core/configClient.d.ts +42 -0
- package/lib/core/configClient.js +302 -0
- package/lib/core/greet.d.ts +11 -0
- package/lib/core/greet.js +17 -0
- package/lib/core/ice.d.ts +31 -0
- package/lib/core/ice.js +48 -0
- package/lib/core/linkify.d.ts +11 -0
- package/lib/core/linkify.js +25 -0
- package/lib/core/logger.d.ts +17 -0
- package/lib/core/logger.js +53 -0
- package/lib/core/media.d.ts +52 -0
- package/lib/core/media.js +115 -0
- package/lib/core/mediaType.d.ts +21 -0
- package/lib/core/mediaType.js +66 -0
- package/lib/core/messagesReducer.d.ts +36 -0
- package/lib/core/messagesReducer.js +58 -0
- package/lib/core/persistence.d.ts +45 -0
- package/lib/core/persistence.js +63 -0
- package/lib/core/socketFactory.d.ts +16 -0
- package/lib/core/socketFactory.js +82 -0
- package/lib/core/types.d.ts +320 -0
- package/lib/core/types.js +30 -0
- package/lib/core/unread.d.ts +2 -0
- package/lib/core/unread.js +5 -0
- package/lib/i18n/ar.json +1 -0
- package/lib/i18n/en.json +1 -0
- package/lib/i18n/index.d.ts +7 -0
- package/lib/i18n/index.js +43 -0
- package/lib/index.d.ts +59 -0
- package/lib/index.js +142 -0
- package/lib/plugin/withWebchat.d.ts +53 -0
- package/lib/plugin/withWebchat.js +164 -0
- package/lib/state/WebchatProvider.d.ts +132 -0
- package/lib/state/WebchatProvider.js +906 -0
- package/lib/state/useWebchat.d.ts +1 -0
- package/lib/state/useWebchat.js +12 -0
- package/lib/theme/dir.d.ts +14 -0
- package/lib/theme/dir.js +20 -0
- package/lib/theme/themeFactory.d.ts +219 -0
- package/lib/theme/themeFactory.js +182 -0
- package/lib/ui/AttachButton.d.ts +35 -0
- package/lib/ui/AttachButton.js +26 -0
- package/lib/ui/AudioRecorder.d.ts +25 -0
- package/lib/ui/AudioRecorder.js +228 -0
- package/lib/ui/Bubble.d.ts +1 -0
- package/lib/ui/Bubble.js +265 -0
- package/lib/ui/CallControls.d.ts +27 -0
- package/lib/ui/CallControls.js +92 -0
- package/lib/ui/CallPlaceholder.d.ts +16 -0
- package/lib/ui/CallPlaceholder.js +73 -0
- package/lib/ui/Composer.d.ts +5 -0
- package/lib/ui/Composer.js +272 -0
- package/lib/ui/FileTile.d.ts +9 -0
- package/lib/ui/FileTile.js +31 -0
- package/lib/ui/Header.d.ts +52 -0
- package/lib/ui/Header.js +236 -0
- package/lib/ui/Icon.d.ts +21 -0
- package/lib/ui/Icon.js +110 -0
- package/lib/ui/ImageBubble.d.ts +11 -0
- package/lib/ui/ImageBubble.js +16 -0
- package/lib/ui/MediaUploadMenu.d.ts +23 -0
- package/lib/ui/MediaUploadMenu.js +68 -0
- package/lib/ui/MessageList.d.ts +1 -0
- package/lib/ui/MessageList.js +46 -0
- package/lib/ui/PoweredBy.d.ts +8 -0
- package/lib/ui/PoweredBy.js +14 -0
- package/lib/ui/PrechatForm.d.ts +1 -0
- package/lib/ui/PrechatForm.js +230 -0
- package/lib/ui/QuickReplies.d.ts +1 -0
- package/lib/ui/QuickReplies.js +24 -0
- package/lib/ui/TypingIndicator.d.ts +9 -0
- package/lib/ui/TypingIndicator.js +88 -0
- package/lib/ui/VideoBubble.d.ts +10 -0
- package/lib/ui/VideoBubble.js +130 -0
- package/lib/ui/VideoCall.d.ts +34 -0
- package/lib/ui/VideoCall.js +191 -0
- package/lib/ui/VideoTile.d.ts +25 -0
- package/lib/ui/VideoTile.js +13 -0
- package/lib/ui/VoiceMessage.d.ts +19 -0
- package/lib/ui/VoiceMessage.js +127 -0
- package/lib/ui/WebChat.d.ts +10 -0
- package/lib/ui/WebChat.js +386 -0
- package/lib/ui/openLink.d.ts +1 -0
- package/lib/ui/openLink.js +16 -0
- package/package.json +94 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
export type SessionStatus = "idle" | "connecting" | "connected" | "session-pending" | "session-confirmed" | "reconnecting" | "disconnected" | "session-failed";
|
|
2
|
+
export type WebChatErrorCode = "connection" | "session-timeout" | "send" | "config-fetch" | "permission-denied" | "media-webrtc";
|
|
3
|
+
export interface QuickReply {
|
|
4
|
+
title: string;
|
|
5
|
+
payload: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A configurable image reference (web parity — agent `avatar`, `closeImage`,
|
|
9
|
+
* `openLauncherImage`, `closeLauncherImage`). Web stores `{ name, size, url }`;
|
|
10
|
+
* the SDK only needs `url` to render and `name` for a11y/labels, so `size` is
|
|
11
|
+
* intentionally omitted. Both fields are optional — an empty object means "no
|
|
12
|
+
* custom image" and the consumer falls back to the built-in glyph.
|
|
13
|
+
*/
|
|
14
|
+
export interface ConfigImage {
|
|
15
|
+
url?: string;
|
|
16
|
+
name?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The two feedback reactions a user can apply to a received (bot/agent) message
|
|
20
|
+
* (web parity). The stored `Message.userReaction` widens this to allow `null`
|
|
21
|
+
* (no/cleared reaction); the toggle verbs (`unlike`/`undislike`) are transport
|
|
22
|
+
* strings on the wire, not reaction states.
|
|
23
|
+
*/
|
|
24
|
+
export type MessageReaction = "like" | "dislike";
|
|
25
|
+
export interface Message {
|
|
26
|
+
/** client-generated stable key for reconciliation (the SDK's own id). */
|
|
27
|
+
key: string;
|
|
28
|
+
/**
|
|
29
|
+
* Server-assigned stable message id (web `messageKey`). Distinct from `key`
|
|
30
|
+
* (the SDK's client-side reconciliation id). Carried through verbatim from the
|
|
31
|
+
* `bot_uttered` payload; it is the id echoed on the `activity`/`activityAck`
|
|
32
|
+
* reaction events. Present only on server-originated messages.
|
|
33
|
+
*/
|
|
34
|
+
messageKey?: string;
|
|
35
|
+
sender: "user" | "response";
|
|
36
|
+
text?: string;
|
|
37
|
+
quick_replies?: QuickReply[];
|
|
38
|
+
media?: string[];
|
|
39
|
+
files?: unknown[];
|
|
40
|
+
mediaUrl?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Message-level MIME (web `message.type`). Backstops attachment classification
|
|
43
|
+
* when a hosted media URL has no file extension and the file object carries no
|
|
44
|
+
* own mime — so a received image/video still renders inline instead of as a
|
|
45
|
+
* document tile / browser link.
|
|
46
|
+
*/
|
|
47
|
+
type?: string;
|
|
48
|
+
timestamp: number;
|
|
49
|
+
status?: "pending" | "sent" | "failed";
|
|
50
|
+
/**
|
|
51
|
+
* The user's current feedback reaction on this message (web parity). `null`
|
|
52
|
+
* (or absent) = no reaction. Mutually exclusive — set by the `REACT` reducer
|
|
53
|
+
* action / inbound `activityAck`.
|
|
54
|
+
*/
|
|
55
|
+
userReaction?: MessageReaction | null;
|
|
56
|
+
/**
|
|
57
|
+
* Per-message server options carried verbatim from `bot_uttered`. `enableReaction`
|
|
58
|
+
* gates the thumbs-up/down feedback row (web `options.enableReaction`); the index
|
|
59
|
+
* signature preserves any other server-sent option keys untouched.
|
|
60
|
+
*/
|
|
61
|
+
options?: {
|
|
62
|
+
enableReaction?: boolean;
|
|
63
|
+
} & Record<string, any>;
|
|
64
|
+
}
|
|
65
|
+
export interface OutgoingPayload {
|
|
66
|
+
message: string;
|
|
67
|
+
text?: string;
|
|
68
|
+
session_id: string;
|
|
69
|
+
customData: {
|
|
70
|
+
language: string;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Base64 data-URL STRINGS (web parity: `media: filesBase64`). NOT objects — the
|
|
74
|
+
* backend reads each entry as a string and rejects objects with
|
|
75
|
+
* "MsgToExp: invalid media string".
|
|
76
|
+
*/
|
|
77
|
+
media?: string[];
|
|
78
|
+
/** Web parity: the first attachment's MIME type (web `typeMedia: files[0].type`). */
|
|
79
|
+
typeMedia?: string;
|
|
80
|
+
messageKey?: string;
|
|
81
|
+
type?: string;
|
|
82
|
+
/** S9: free-form host metadata passed through to the backend untouched. */
|
|
83
|
+
metadata?: Record<string, unknown>;
|
|
84
|
+
/**
|
|
85
|
+
* Pre-chat form submission (web parity: ChatContainer sends the collected fields as
|
|
86
|
+
* `prechatFormSubmission` on the /chitchat.greet message). Only present on the greet.
|
|
87
|
+
*/
|
|
88
|
+
prechatFormSubmission?: Record<string, string>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Full webchat configuration (S8). Fields split conceptually into:
|
|
92
|
+
* - connection (channelId/configUrl/connectionUrl) — required to talk to a tenant
|
|
93
|
+
* - server-driven theming/i18n (interfaceTheme, publicStyle, language)
|
|
94
|
+
* - behaviour flags the host or server can toggle.
|
|
95
|
+
*
|
|
96
|
+
* `mergeConfig` (configClient) applies precedence prop > server > default, so every
|
|
97
|
+
* non-connection field is optional here; the connection trio is required.
|
|
98
|
+
*/
|
|
99
|
+
export interface Config {
|
|
100
|
+
/** Tenant channel id — selects the socket path and storage namespace. */
|
|
101
|
+
channelId: string;
|
|
102
|
+
/** Remote endpoint that returns the server-side config JSON. */
|
|
103
|
+
configUrl: string;
|
|
104
|
+
/** WebSocket host (no scheme — the socket factory prepends `wss://`). */
|
|
105
|
+
connectionUrl: string;
|
|
106
|
+
/** Theme variant key (interfaceThemeEnum: '' | 'experia' | 'digitalGovernment'). */
|
|
107
|
+
interfaceTheme?: string;
|
|
108
|
+
/** Tenant colour/font overrides (themeColor, defaultFontColor, …). */
|
|
109
|
+
publicStyle?: PublicStyle;
|
|
110
|
+
/** Tenant chat-bubble style overrides (sentMsgBg, receivedMsgBg, …) — server-driven. */
|
|
111
|
+
chatSectionStyle?: Record<string, any>;
|
|
112
|
+
/** Tenant header style overrides (bgColor, titleColor, videoCallBtn*, …) — server-driven. */
|
|
113
|
+
headerSectionStyle?: Record<string, any>;
|
|
114
|
+
/** Tenant composer/send style overrides (textFieldBg, sendBtnBg, …) — server-driven. */
|
|
115
|
+
sendSectionStyle?: Record<string, any>;
|
|
116
|
+
/** Tenant launcher (FAB) style overrides (buttonColor, buttonBg, buttonWidth, …) — server-driven (web `wedgitSectionStyle`). */
|
|
117
|
+
wedgitSectionStyle?: Record<string, any>;
|
|
118
|
+
/** Initial language ('en' | 'ar' | …); drives dir = 'ar' ? 'rtl' : 'ltr'. */
|
|
119
|
+
language?: string;
|
|
120
|
+
/** Connect the socket automatically (vs. waiting for an explicit open). */
|
|
121
|
+
autoConnection?: boolean;
|
|
122
|
+
/** Master switch: when false the socket never connects regardless of open state. */
|
|
123
|
+
enableConnection?: boolean;
|
|
124
|
+
/** Open the chat surface on first load. */
|
|
125
|
+
openOnLoad?: boolean;
|
|
126
|
+
/** Send the welcome/greet flow on a new session. */
|
|
127
|
+
sendWelcomeMessage?: boolean;
|
|
128
|
+
/** Disable the composer input (read-only / bot-driven conversations). */
|
|
129
|
+
disabledInput?: boolean;
|
|
130
|
+
/** Expose the video-call entry point. */
|
|
131
|
+
makeVideoCall?: boolean;
|
|
132
|
+
/** Auto-join an incoming video call without an explicit tap (web `autoJoinVideoCall`; default false). */
|
|
133
|
+
autoJoinVideoCall?: boolean;
|
|
134
|
+
/** Show the file/image upload control (web `uploadMedia`; default true). */
|
|
135
|
+
uploadMedia?: boolean;
|
|
136
|
+
/** Show the voice-note recorder (web `uploadAudio`; default true). */
|
|
137
|
+
uploadAudio?: boolean;
|
|
138
|
+
/** Show the image option in the attach menu (web `uploadImage`; default true). */
|
|
139
|
+
uploadImage?: boolean;
|
|
140
|
+
/** Show the document option in the attach menu (web `uploadDocuments`; default true). */
|
|
141
|
+
uploadDocuments?: boolean;
|
|
142
|
+
/** Show the video option in the attach menu (web `uploadVideo`; default true). */
|
|
143
|
+
uploadVideo?: boolean;
|
|
144
|
+
/** Show the emoji-picker button (web `emoji`; default false per web defaultConfig). */
|
|
145
|
+
emoji?: boolean;
|
|
146
|
+
/** Show the header close/back button (default shown; only `false` hides it). */
|
|
147
|
+
showCloseButton?: boolean;
|
|
148
|
+
/** Show the floating launcher button (web `showButtonChat`; default true). */
|
|
149
|
+
showButtonChat?: boolean;
|
|
150
|
+
/** Render the per-message timestamp row (web `showMessageDate`; default true). */
|
|
151
|
+
showMessageDate?: boolean;
|
|
152
|
+
/** Render the typing indicator while the agent is typing (web `displayTypingIndication`; default false). */
|
|
153
|
+
displayTypingIndication?: boolean;
|
|
154
|
+
/** Render the "powered by" badge below the message list (web `showPoweredBy`; default true). */
|
|
155
|
+
showPoweredBy?: boolean;
|
|
156
|
+
/** Show the agent avatar on header + received messages (web `showAvatar`; default true). */
|
|
157
|
+
showAvatar?: boolean;
|
|
158
|
+
/** Agent avatar image (web `config.avatar`; `{ url, name }`). */
|
|
159
|
+
avatar?: ConfigImage;
|
|
160
|
+
/** Custom header close-button image (web `config.closeImage`; `{ url, name }`). */
|
|
161
|
+
closeImage?: ConfigImage;
|
|
162
|
+
/** Custom launcher (open) image (web `config.openLauncherImage`; `{ url, name }`). */
|
|
163
|
+
openLauncherImage?: ConfigImage;
|
|
164
|
+
/** Custom launcher (close/minimized) image (web `config.closeLauncherImage`; `{ url, name }`). */
|
|
165
|
+
closeLauncherImage?: ConfigImage;
|
|
166
|
+
/** Header title text (web `config.title`; falls back to host prop when absent). */
|
|
167
|
+
title?: string;
|
|
168
|
+
/** Header subtitle text under the title (web `config.subTitle`). */
|
|
169
|
+
subTitle?: string;
|
|
170
|
+
/** Text shown in the header "connecting" banner (web `config.connectingText`). */
|
|
171
|
+
connectingText?: string;
|
|
172
|
+
/** Composer placeholder override (web `config.inputTextFieldHint`). */
|
|
173
|
+
inputTextFieldHint?: string;
|
|
174
|
+
/** Where to place the online/offline status indicator (web `config.statusIndicatorPosition`; default 'top-right'). */
|
|
175
|
+
statusIndicatorPosition?: string;
|
|
176
|
+
/** Pre-chat form descriptor (web `config.prechatForm`); `.enabled` gates the form. */
|
|
177
|
+
prechatForm?: PrechatForm;
|
|
178
|
+
/**
|
|
179
|
+
* Persisted-history storage backend (web `config.storage`). On web this selects
|
|
180
|
+
* `localStorage` vs `sessionStorage` vs in-memory. The RN analog (Tier C #33):
|
|
181
|
+
* - "localStorage" (default) -> the persistent AsyncStorage-backed store (history
|
|
182
|
+
* survives across app launches; the 24h sliding TTL still applies).
|
|
183
|
+
* - "sessionStorage" | "memory" -> an EPHEMERAL in-memory store (history does NOT
|
|
184
|
+
* survive an app relaunch; closest RN analog to a per-session/non-durable store).
|
|
185
|
+
* Only honored when the host injects NO store of its own — a host-supplied store
|
|
186
|
+
* always wins (see `selectStore` in persistence.ts). Default "localStorage".
|
|
187
|
+
*/
|
|
188
|
+
storage?: "localStorage" | "sessionStorage" | "memory";
|
|
189
|
+
/**
|
|
190
|
+
* Hide the launcher/surface while not connected (web `config.hideWhenNotConnected`,
|
|
191
|
+
* default true on web — though effectively dead there). RN semantics (Tier C #34):
|
|
192
|
+
* the launcher/surface is hidden ONLY after a connection was established and then
|
|
193
|
+
* lost (status left "connected"/"session-confirmed" having previously reached it),
|
|
194
|
+
* NEVER on the initial pre-connect — otherwise the user could never open to connect.
|
|
195
|
+
* Default false (opt-in) so the SDK's open-to-connect flow is unchanged unless set.
|
|
196
|
+
*/
|
|
197
|
+
hideWhenNotConnected?: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Inline-embedded vs floating-widget layout (web `config.embedded`). RN analog
|
|
200
|
+
* (Tier C #31): when true the OPEN surface lays out inline within its parent
|
|
201
|
+
* (no absolute/floating positioning, no launcher-overlay padding) so a host can
|
|
202
|
+
* embed it in a screen; when false (default) the surface fills its mount as today.
|
|
203
|
+
* Host mounting ultimately controls placement in RN — this flag only adjusts the
|
|
204
|
+
* Surface's own container style. Default false.
|
|
205
|
+
*/
|
|
206
|
+
embedded?: boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Full-height vs bounded open-surface sizing (web `config.fullScreenHeight`). RN
|
|
209
|
+
* analog (Tier C #32): when true (or unset) the open surface fills available height
|
|
210
|
+
* (`flex: 1`, today's behaviour); when explicitly false it is capped to a bounded
|
|
211
|
+
* height (`maxHeight`) so it does not consume the whole mount. Host mounting also
|
|
212
|
+
* influences final height in RN. Default true (omit/true => full height).
|
|
213
|
+
*/
|
|
214
|
+
fullScreenHeight?: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Widget shell type (web `config.typeWidget`: "default" | "drawer" | embedded
|
|
217
|
+
* shell). Tier C #30: the SDK has a SINGLE Surface + optional FAB Launcher and no
|
|
218
|
+
* DrawerWidget/embedded-shell analog beyond the `embedded` flag, so only "default"
|
|
219
|
+
* maps; any non-default value is treated as "default" (no error). Resolved by
|
|
220
|
+
* DOCUMENTATION, not new behaviour. Default "default".
|
|
221
|
+
*/
|
|
222
|
+
typeWidget?: string;
|
|
223
|
+
/** Sliding session TTL in ms (24h default applied by consumers). */
|
|
224
|
+
ttlMs?: number;
|
|
225
|
+
/**
|
|
226
|
+
* DEV-only: trace every socket message (outbound emits + inbound events +
|
|
227
|
+
* lifecycle) to the console/Metro for debugging. Never enable in production —
|
|
228
|
+
* full payloads (incl. session ids / content) are logged.
|
|
229
|
+
*/
|
|
230
|
+
debug?: boolean;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* A `{ en, ar }` localized string pair (web parity — `interfaces/index.ts`
|
|
234
|
+
* `LocalizedText`). The renderer reads `text[language] || text.en` so an absent
|
|
235
|
+
* translation falls back to English rather than blanking.
|
|
236
|
+
*/
|
|
237
|
+
export type LocalizedText = {
|
|
238
|
+
en: string;
|
|
239
|
+
ar: string;
|
|
240
|
+
};
|
|
241
|
+
/** Supported pre-chat field input kinds (web parity). */
|
|
242
|
+
export type PrechatFieldType = "text" | "email" | "phone" | "dropdown";
|
|
243
|
+
/** A single selectable option for a `dropdown` field (web parity). */
|
|
244
|
+
export interface PrechatFieldOption {
|
|
245
|
+
value: string;
|
|
246
|
+
label: LocalizedText;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* One pre-chat form field (web `interfaces/index.ts` `PrechatField`). `label`,
|
|
250
|
+
* `placeholder`, and `errorMessage` are localized `{en,ar}` pairs; `required`
|
|
251
|
+
* defaults to TRUE (web semantics — only an explicit `false` makes it optional).
|
|
252
|
+
* `options` is required only for `type === "dropdown"`.
|
|
253
|
+
*/
|
|
254
|
+
export interface PrechatField {
|
|
255
|
+
key: string;
|
|
256
|
+
type: PrechatFieldType;
|
|
257
|
+
label: LocalizedText;
|
|
258
|
+
placeholder?: LocalizedText;
|
|
259
|
+
required?: boolean;
|
|
260
|
+
errorMessage?: LocalizedText;
|
|
261
|
+
options?: PrechatFieldOption[];
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Pre-chat form descriptor (web `config.prechatForm`). Now fully typed at parity
|
|
265
|
+
* with the web schema: `.enabled` gates the form, `.fields[]` drives per-field
|
|
266
|
+
* rendering/validation, and `.headline`/`.submitLabel` are optional localized
|
|
267
|
+
* `{en,ar}` strings. The trailing index signature is retained so an unknown
|
|
268
|
+
* server key on the object never breaks the structural type.
|
|
269
|
+
*/
|
|
270
|
+
export interface PrechatForm {
|
|
271
|
+
/** Master gate — only show the form when explicitly enabled. */
|
|
272
|
+
enabled?: boolean;
|
|
273
|
+
/** Form fields rendered in order (text / email / phone / dropdown). */
|
|
274
|
+
fields?: PrechatField[];
|
|
275
|
+
/** Optional localized headline shown above the fields. */
|
|
276
|
+
headline?: LocalizedText;
|
|
277
|
+
/** Optional localized submit-button label (falls back to the i18n default). */
|
|
278
|
+
submitLabel?: LocalizedText;
|
|
279
|
+
[k: string]: any;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Tenant style overrides carried on `Config.publicStyle`. Kept structurally
|
|
283
|
+
* identical to the theme layer's `PublicStyle` so `buildTheme` can consume it
|
|
284
|
+
* directly without a cross-import (core stays framework-agnostic).
|
|
285
|
+
*/
|
|
286
|
+
export interface PublicStyle {
|
|
287
|
+
themeColor?: string;
|
|
288
|
+
defaultFontColor?: string;
|
|
289
|
+
defaultFontSize?: number;
|
|
290
|
+
defaultFontWeight?: string;
|
|
291
|
+
/**
|
|
292
|
+
* Tenant custom font (web `publicStyle.defaultFontFamily`). Web injects an
|
|
293
|
+
* `@font-face` per weight at runtime; RN registers each weight as its own font
|
|
294
|
+
* family via `expo-font` loadAsync (see {@link createExpoFontLoader}). `fonts`
|
|
295
|
+
* holds one remote TTF per weight (ExtraLight..Black). All fields optional.
|
|
296
|
+
*/
|
|
297
|
+
defaultFontFamily?: {
|
|
298
|
+
name?: string;
|
|
299
|
+
fonts?: Array<{
|
|
300
|
+
url: string;
|
|
301
|
+
fontWeight?: string;
|
|
302
|
+
fontName?: string;
|
|
303
|
+
}>;
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Maps the backend's string error keys (web parity — emitted on the socket) to
|
|
308
|
+
* the SDK's typed {@link WebChatErrorCode}. Unknown keys fall back to
|
|
309
|
+
* 'connection' at the call site.
|
|
310
|
+
*/
|
|
311
|
+
export declare const WEB_ERROR_CODE_MAP: Record<string, WebChatErrorCode>;
|
|
312
|
+
/** Translate a backend error key to a typed code, defaulting to 'connection'. */
|
|
313
|
+
export declare const mapWebErrorCode: (key: string | undefined) => WebChatErrorCode;
|
|
314
|
+
export declare class WebChatError extends Error {
|
|
315
|
+
code: WebChatErrorCode | "session-timeout";
|
|
316
|
+
recoverable: boolean;
|
|
317
|
+
cause?: unknown | undefined;
|
|
318
|
+
constructor(code: WebChatErrorCode | "session-timeout", message: string, recoverable: boolean, cause?: unknown | undefined);
|
|
319
|
+
}
|
|
320
|
+
export declare const isWebChatError: (e: unknown) => e is WebChatError;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isWebChatError = exports.WebChatError = exports.mapWebErrorCode = exports.WEB_ERROR_CODE_MAP = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Maps the backend's string error keys (web parity — emitted on the socket) to
|
|
6
|
+
* the SDK's typed {@link WebChatErrorCode}. Unknown keys fall back to
|
|
7
|
+
* 'connection' at the call site.
|
|
8
|
+
*/
|
|
9
|
+
exports.WEB_ERROR_CODE_MAP = {
|
|
10
|
+
send_message_fail: "send",
|
|
11
|
+
request_socket_session_fail: "session-timeout",
|
|
12
|
+
get_config_fail: "config-fetch",
|
|
13
|
+
socket_connection_fail: "connection",
|
|
14
|
+
media_upload_fail: "send",
|
|
15
|
+
};
|
|
16
|
+
/** Translate a backend error key to a typed code, defaulting to 'connection'. */
|
|
17
|
+
const mapWebErrorCode = (key) => (key && exports.WEB_ERROR_CODE_MAP[key]) || "connection";
|
|
18
|
+
exports.mapWebErrorCode = mapWebErrorCode;
|
|
19
|
+
class WebChatError extends Error {
|
|
20
|
+
constructor(code, message, recoverable, cause) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.code = code;
|
|
23
|
+
this.recoverable = recoverable;
|
|
24
|
+
this.cause = cause;
|
|
25
|
+
this.name = "WebChatError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.WebChatError = WebChatError;
|
|
29
|
+
const isWebChatError = (e) => e instanceof WebChatError;
|
|
30
|
+
exports.isWebChatError = isWebChatError;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unreadCount = void 0;
|
|
4
|
+
const unreadCount = (messages, lastReadAt) => messages.filter((m) => m.sender === "response" && m.timestamp > lastReadAt).length;
|
|
5
|
+
exports.unreadCount = unreadCount;
|
package/lib/i18n/ar.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "send": "إرسال", "open_chat": "افتح المحادثة", "start_chat": "ابدأ المحادثة", "type_message": "اكتب رسالة", "start_video_call": "بدء مكالمة فيديو", "back": "رجوع", "close": "إغلاق", "mute": "كتم الميكروفون", "unmute": "إلغاء كتم الميكروفون", "camera_on": "تشغيل الكاميرا", "camera_off": "إيقاف الكاميرا", "leave_call": "إنهاء المكالمة", "flip_camera": "تبديل الكاميرا", "speaker": "مكبر الصوت", "call_error": "الوصول إلى الكاميرا والميكروفون مطلوب لإجراء مكالمات الفيديو.", "open_settings": "فتح الإعدادات", "cancel": "إلغاء", "upload_image": "صورة", "upload_video": "فيديو", "upload_document": "مستند", "record_audio": "تسجيل صوتي", "connecting": "جارٍ الاتصال…", "camera_off_status": "الكاميرا متوقفة", "you": "أنت", "agent": "الوكيل" }
|
package/lib/i18n/en.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "send": "Send", "open_chat": "Open chat", "start_chat": "Start chat", "type_message": "Type a message", "start_video_call": "Start video call", "back": "Back", "close": "Close", "mute": "Mute microphone", "unmute": "Unmute microphone", "camera_on": "Turn camera on", "camera_off": "Turn camera off", "leave_call": "Leave call", "flip_camera": "Flip camera", "speaker": "Speaker", "call_error": "Camera and microphone access is required for video calls.", "open_settings": "Open Settings", "cancel": "Cancel", "upload_image": "Photo", "upload_video": "Video", "upload_document": "Document", "record_audio": "Record audio", "connecting": "Connecting…", "camera_off_status": "Camera off", "you": "You", "agent": "Agent" }
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language-keyed string lookup with an EN fallback (audit #8 — no hardcoded
|
|
3
|
+
* English). Returns the key itself when neither the requested language nor EN
|
|
4
|
+
* has it, so a missing key is visible rather than silently blank.
|
|
5
|
+
*/
|
|
6
|
+
export declare function makeT(language?: string): (key: string) => string;
|
|
7
|
+
export declare function initI18n(language?: string): any;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.makeT = makeT;
|
|
7
|
+
exports.initI18n = initI18n;
|
|
8
|
+
// src/i18n/index.ts
|
|
9
|
+
//
|
|
10
|
+
// Two i18n surfaces share the SAME bundled JSON strings:
|
|
11
|
+
//
|
|
12
|
+
// - makeT(language): a tiny, synchronous, language-keyed lookup with an EN
|
|
13
|
+
// fallback. It imports en/ar JSON as plain objects so NO native peer
|
|
14
|
+
// (react-native-localize) is pulled in, and it works before initI18n has run.
|
|
15
|
+
// This is the helper every prop-driven UI component (Composer/Header/
|
|
16
|
+
// CallControls/VideoCall/WebChat launcher) uses to translate (audit #8).
|
|
17
|
+
//
|
|
18
|
+
// - initI18n(language): the full i18next runtime, lazily wired by the provider.
|
|
19
|
+
// It is the only consumer of react-native-localize, which is lazy-required
|
|
20
|
+
// INSIDE the function so a static `import { makeT } from "../i18n"` never
|
|
21
|
+
// loads the native peer.
|
|
22
|
+
const en_json_1 = __importDefault(require("./en.json"));
|
|
23
|
+
const ar_json_1 = __importDefault(require("./ar.json"));
|
|
24
|
+
const STRINGS = { en: en_json_1.default, ar: ar_json_1.default };
|
|
25
|
+
/**
|
|
26
|
+
* Language-keyed string lookup with an EN fallback (audit #8 — no hardcoded
|
|
27
|
+
* English). Returns the key itself when neither the requested language nor EN
|
|
28
|
+
* has it, so a missing key is visible rather than silently blank.
|
|
29
|
+
*/
|
|
30
|
+
function makeT(language) {
|
|
31
|
+
const lang = language === "ar" ? "ar" : "en";
|
|
32
|
+
return (key) => { var _a, _b, _c; return (_c = (_b = (_a = STRINGS[lang]) === null || _a === void 0 ? void 0 : _a[key]) !== null && _b !== void 0 ? _b : STRINGS.en[key]) !== null && _c !== void 0 ? _c : key; };
|
|
33
|
+
}
|
|
34
|
+
function initI18n(language) {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
37
|
+
const i18n = (_a = require("i18next").default) !== null && _a !== void 0 ? _a : require("i18next");
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
39
|
+
const { getLocales } = require("react-native-localize");
|
|
40
|
+
const lng = language !== null && language !== void 0 ? language : (((_b = getLocales()[0]) === null || _b === void 0 ? void 0 : _b.languageCode) === "ar" ? "ar" : "en");
|
|
41
|
+
i18n.init({ resources: { en: { translation: en_json_1.default }, ar: { translation: ar_json_1.default } }, lng, fallbackLng: "en", interpolation: { escapeValue: false } });
|
|
42
|
+
return i18n;
|
|
43
|
+
}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export { createWebchatClient } from "./core/WebchatClient";
|
|
2
|
+
export type { MinimalSocket, WebchatClientOptions } from "./core/WebchatClient";
|
|
3
|
+
export { createSocket } from "./core/socketFactory";
|
|
4
|
+
export { messagesReducer, initialState } from "./core/messagesReducer";
|
|
5
|
+
export type { MessagesState, MessagesAction } from "./core/messagesReducer";
|
|
6
|
+
export { unreadCount } from "./core/unread";
|
|
7
|
+
export { buildGreet, shouldGreet } from "./core/greet";
|
|
8
|
+
export { MemoryStore, saveSession, loadSession, clearSession, } from "./core/persistence";
|
|
9
|
+
export type { KeyValueStore, PersistedSession } from "./core/persistence";
|
|
10
|
+
export { linkify, isSafeHref } from "./core/linkify";
|
|
11
|
+
export type { Token } from "./core/linkify";
|
|
12
|
+
export { dirStyles } from "./theme/dir";
|
|
13
|
+
export type { Dir } from "./theme/dir";
|
|
14
|
+
export { resolveVariant, buildTheme } from "./theme/themeFactory";
|
|
15
|
+
export type { Variant, PublicStyle, WebChatTheme } from "./theme/themeFactory";
|
|
16
|
+
export * from "./core/types";
|
|
17
|
+
export { fetchConfig, mergeConfig, DEFAULT_CONFIG } from "./core/configClient";
|
|
18
|
+
export type { FetchLike, ServerConfig } from "./core/configClient";
|
|
19
|
+
export { createLogger, logger } from "./core/logger";
|
|
20
|
+
export type { Logger } from "./core/logger";
|
|
21
|
+
export { validateSelection, acceptedMimeTypes, stripBase64OnAck, DEFAULT_LIMITS, } from "./core/media";
|
|
22
|
+
export type { MediaFile, MediaLimits, RejectReason, RejectedFile, ValidationResult, } from "./core/media";
|
|
23
|
+
export { toDataUrl, toMediaEntry } from "./adapters/picker";
|
|
24
|
+
export type { Asset, PickerAdapter, PickImagesOptions, PickDocumentsOptions, MediaEntry, } from "./adapters/picker";
|
|
25
|
+
export { CANONICAL_AUDIO_MIME, NoopAudioAdapter } from "./adapters/audio";
|
|
26
|
+
export type { AudioAdapter, RecordingResult } from "./adapters/audio";
|
|
27
|
+
export { createExpoPicker, createExpoAudioAdapter, createExpoReadBase64, } from "./adapters/expoDefaults";
|
|
28
|
+
export { WebChat } from "./ui/WebChat";
|
|
29
|
+
export type { WebChatHandle } from "./ui/WebChat";
|
|
30
|
+
export { ImageBubble } from "./ui/ImageBubble";
|
|
31
|
+
export type { ImageBubbleProps } from "./ui/ImageBubble";
|
|
32
|
+
export { FileTile } from "./ui/FileTile";
|
|
33
|
+
export type { FileTileProps } from "./ui/FileTile";
|
|
34
|
+
export { AttachButton } from "./ui/AttachButton";
|
|
35
|
+
export type { AttachButtonProps, PendingAttachment } from "./ui/AttachButton";
|
|
36
|
+
export { MediaUploadMenu } from "./ui/MediaUploadMenu";
|
|
37
|
+
export type { MediaUploadMenuProps, MediaUploadOption } from "./ui/MediaUploadMenu";
|
|
38
|
+
export { Icon } from "./ui/Icon";
|
|
39
|
+
export type { IconName, IconProps } from "./ui/Icon";
|
|
40
|
+
export { AudioRecorder } from "./ui/AudioRecorder";
|
|
41
|
+
export type { AudioRecorderProps } from "./ui/AudioRecorder";
|
|
42
|
+
export { VoiceMessage } from "./ui/VoiceMessage";
|
|
43
|
+
export type { VoiceMessageProps } from "./ui/VoiceMessage";
|
|
44
|
+
export { TypingIndicator } from "./ui/TypingIndicator";
|
|
45
|
+
export { PoweredBy } from "./ui/PoweredBy";
|
|
46
|
+
export { createVideoCallClient } from "./core/VideoCallClient";
|
|
47
|
+
export type { VideoCallClient, VideoCallClientOptions, VideoCallEvent, WebRTCFactory, FakeableStream, FakeableTrack, FakeablePeerConnection, MinimalSocket as VideoCallSocket, } from "./core/VideoCallClient";
|
|
48
|
+
export { iceServers, isForwardableCandidate, TURN_URL, TURN_USERNAME, TURN_CREDENTIAL, STUN_URL, } from "./core/ice";
|
|
49
|
+
export type { PcConfig, IceServer as VideoIceServer, CandidateType } from "./core/ice";
|
|
50
|
+
export { reactNativeWebRTCFactory, teardownPeerConnection } from "./adapters/webrtc";
|
|
51
|
+
export type { RTCPeerConnectionLike, MediaStreamLike, MediaStreamTrackLike, PeerConnectionConfig, MediaStreamConstraints, } from "./adapters/webrtc";
|
|
52
|
+
export { AudioRoute, reactNativeAudioRoute } from "./adapters/audioRoute";
|
|
53
|
+
export type { InCallManagerLike, AudioRouteStartOptions } from "./adapters/audioRoute";
|
|
54
|
+
export { VideoCall } from "./ui/VideoCall";
|
|
55
|
+
export type { VideoCallProps, AudioRouteLike } from "./ui/VideoCall";
|
|
56
|
+
export { CallControls } from "./ui/CallControls";
|
|
57
|
+
export type { CallControlsProps } from "./ui/CallControls";
|
|
58
|
+
export { VideoTile } from "./ui/VideoTile";
|
|
59
|
+
export type { VideoTileProps, VideoTileStream } from "./ui/VideoTile";
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Public entrypoint — framework-agnostic core + theme layer (Phase 0 + Phase 1 logic).
|
|
3
|
+
// The React `state/` provider and `ui/` components are added with the RN toolchain layer.
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
16
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.reactNativeWebRTCFactory = exports.STUN_URL = exports.TURN_CREDENTIAL = exports.TURN_USERNAME = exports.TURN_URL = exports.isForwardableCandidate = exports.iceServers = exports.createVideoCallClient = exports.PoweredBy = exports.TypingIndicator = exports.VoiceMessage = exports.AudioRecorder = exports.Icon = exports.MediaUploadMenu = exports.AttachButton = exports.FileTile = exports.ImageBubble = exports.WebChat = exports.createExpoReadBase64 = exports.createExpoAudioAdapter = exports.createExpoPicker = exports.NoopAudioAdapter = exports.CANONICAL_AUDIO_MIME = exports.toMediaEntry = exports.toDataUrl = exports.DEFAULT_LIMITS = exports.stripBase64OnAck = exports.acceptedMimeTypes = exports.validateSelection = exports.logger = exports.createLogger = exports.DEFAULT_CONFIG = exports.mergeConfig = exports.fetchConfig = exports.buildTheme = exports.resolveVariant = exports.dirStyles = exports.isSafeHref = exports.linkify = exports.clearSession = exports.loadSession = exports.saveSession = exports.MemoryStore = exports.shouldGreet = exports.buildGreet = exports.unreadCount = exports.initialState = exports.messagesReducer = exports.createSocket = exports.createWebchatClient = void 0;
|
|
20
|
+
exports.VideoTile = exports.CallControls = exports.VideoCall = exports.reactNativeAudioRoute = exports.AudioRoute = exports.teardownPeerConnection = void 0;
|
|
21
|
+
// Transport + protocol
|
|
22
|
+
var WebchatClient_1 = require("./core/WebchatClient");
|
|
23
|
+
Object.defineProperty(exports, "createWebchatClient", { enumerable: true, get: function () { return WebchatClient_1.createWebchatClient; } });
|
|
24
|
+
var socketFactory_1 = require("./core/socketFactory");
|
|
25
|
+
Object.defineProperty(exports, "createSocket", { enumerable: true, get: function () { return socketFactory_1.createSocket; } });
|
|
26
|
+
// State logic
|
|
27
|
+
var messagesReducer_1 = require("./core/messagesReducer");
|
|
28
|
+
Object.defineProperty(exports, "messagesReducer", { enumerable: true, get: function () { return messagesReducer_1.messagesReducer; } });
|
|
29
|
+
Object.defineProperty(exports, "initialState", { enumerable: true, get: function () { return messagesReducer_1.initialState; } });
|
|
30
|
+
var unread_1 = require("./core/unread");
|
|
31
|
+
Object.defineProperty(exports, "unreadCount", { enumerable: true, get: function () { return unread_1.unreadCount; } });
|
|
32
|
+
var greet_1 = require("./core/greet");
|
|
33
|
+
Object.defineProperty(exports, "buildGreet", { enumerable: true, get: function () { return greet_1.buildGreet; } });
|
|
34
|
+
Object.defineProperty(exports, "shouldGreet", { enumerable: true, get: function () { return greet_1.shouldGreet; } });
|
|
35
|
+
// Persistence
|
|
36
|
+
var persistence_1 = require("./core/persistence");
|
|
37
|
+
Object.defineProperty(exports, "MemoryStore", { enumerable: true, get: function () { return persistence_1.MemoryStore; } });
|
|
38
|
+
Object.defineProperty(exports, "saveSession", { enumerable: true, get: function () { return persistence_1.saveSession; } });
|
|
39
|
+
Object.defineProperty(exports, "loadSession", { enumerable: true, get: function () { return persistence_1.loadSession; } });
|
|
40
|
+
Object.defineProperty(exports, "clearSession", { enumerable: true, get: function () { return persistence_1.clearSession; } });
|
|
41
|
+
// Text rendering
|
|
42
|
+
var linkify_1 = require("./core/linkify");
|
|
43
|
+
Object.defineProperty(exports, "linkify", { enumerable: true, get: function () { return linkify_1.linkify; } });
|
|
44
|
+
Object.defineProperty(exports, "isSafeHref", { enumerable: true, get: function () { return linkify_1.isSafeHref; } });
|
|
45
|
+
// Theme + RTL
|
|
46
|
+
var dir_1 = require("./theme/dir");
|
|
47
|
+
Object.defineProperty(exports, "dirStyles", { enumerable: true, get: function () { return dir_1.dirStyles; } });
|
|
48
|
+
var themeFactory_1 = require("./theme/themeFactory");
|
|
49
|
+
Object.defineProperty(exports, "resolveVariant", { enumerable: true, get: function () { return themeFactory_1.resolveVariant; } });
|
|
50
|
+
Object.defineProperty(exports, "buildTheme", { enumerable: true, get: function () { return themeFactory_1.buildTheme; } });
|
|
51
|
+
// Shared types
|
|
52
|
+
__exportStar(require("./core/types"), exports);
|
|
53
|
+
// Config fetch + merge (S5/S8): server view + prop>server>default precedence
|
|
54
|
+
var configClient_1 = require("./core/configClient");
|
|
55
|
+
Object.defineProperty(exports, "fetchConfig", { enumerable: true, get: function () { return configClient_1.fetchConfig; } });
|
|
56
|
+
Object.defineProperty(exports, "mergeConfig", { enumerable: true, get: function () { return configClient_1.mergeConfig; } });
|
|
57
|
+
Object.defineProperty(exports, "DEFAULT_CONFIG", { enumerable: true, get: function () { return configClient_1.DEFAULT_CONFIG; } });
|
|
58
|
+
// Dev-gated logger (C18): no-ops in release, never logs session_id/content
|
|
59
|
+
var logger_1 = require("./core/logger");
|
|
60
|
+
Object.defineProperty(exports, "createLogger", { enumerable: true, get: function () { return logger_1.createLogger; } });
|
|
61
|
+
Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_1.logger; } });
|
|
62
|
+
// Media (Phase 2): policy/limit helpers — pure, no I/O
|
|
63
|
+
var media_1 = require("./core/media");
|
|
64
|
+
Object.defineProperty(exports, "validateSelection", { enumerable: true, get: function () { return media_1.validateSelection; } });
|
|
65
|
+
Object.defineProperty(exports, "acceptedMimeTypes", { enumerable: true, get: function () { return media_1.acceptedMimeTypes; } });
|
|
66
|
+
Object.defineProperty(exports, "stripBase64OnAck", { enumerable: true, get: function () { return media_1.stripBase64OnAck; } });
|
|
67
|
+
Object.defineProperty(exports, "DEFAULT_LIMITS", { enumerable: true, get: function () { return media_1.DEFAULT_LIMITS; } });
|
|
68
|
+
// Adapters (Phase 2): injectable picker + audio capabilities (real impls live in the example
|
|
69
|
+
// apps; tests inject fakes — the core never calls a native module directly)
|
|
70
|
+
var picker_1 = require("./adapters/picker");
|
|
71
|
+
Object.defineProperty(exports, "toDataUrl", { enumerable: true, get: function () { return picker_1.toDataUrl; } });
|
|
72
|
+
Object.defineProperty(exports, "toMediaEntry", { enumerable: true, get: function () { return picker_1.toMediaEntry; } });
|
|
73
|
+
var audio_1 = require("./adapters/audio");
|
|
74
|
+
Object.defineProperty(exports, "CANONICAL_AUDIO_MIME", { enumerable: true, get: function () { return audio_1.CANONICAL_AUDIO_MIME; } });
|
|
75
|
+
Object.defineProperty(exports, "NoopAudioAdapter", { enumerable: true, get: function () { return audio_1.NoopAudioAdapter; } });
|
|
76
|
+
// Batteries-included default adapters: auto-wired inside <WebChat> from installed
|
|
77
|
+
// Expo peers (expo-image-picker / expo-document-picker / expo-file-system / expo-audio),
|
|
78
|
+
// each returning undefined when its OPTIONAL peer is absent (graceful degradation).
|
|
79
|
+
// Exported so a host can compose its own surface or override selectively.
|
|
80
|
+
var expoDefaults_1 = require("./adapters/expoDefaults");
|
|
81
|
+
Object.defineProperty(exports, "createExpoPicker", { enumerable: true, get: function () { return expoDefaults_1.createExpoPicker; } });
|
|
82
|
+
Object.defineProperty(exports, "createExpoAudioAdapter", { enumerable: true, get: function () { return expoDefaults_1.createExpoAudioAdapter; } });
|
|
83
|
+
Object.defineProperty(exports, "createExpoReadBase64", { enumerable: true, get: function () { return expoDefaults_1.createExpoReadBase64; } });
|
|
84
|
+
// Public component
|
|
85
|
+
var WebChat_1 = require("./ui/WebChat");
|
|
86
|
+
Object.defineProperty(exports, "WebChat", { enumerable: true, get: function () { return WebChat_1.WebChat; } });
|
|
87
|
+
// Media UI (Phase 2): exported for hosts that compose their own surface
|
|
88
|
+
var ImageBubble_1 = require("./ui/ImageBubble");
|
|
89
|
+
Object.defineProperty(exports, "ImageBubble", { enumerable: true, get: function () { return ImageBubble_1.ImageBubble; } });
|
|
90
|
+
var FileTile_1 = require("./ui/FileTile");
|
|
91
|
+
Object.defineProperty(exports, "FileTile", { enumerable: true, get: function () { return FileTile_1.FileTile; } });
|
|
92
|
+
var AttachButton_1 = require("./ui/AttachButton");
|
|
93
|
+
Object.defineProperty(exports, "AttachButton", { enumerable: true, get: function () { return AttachButton_1.AttachButton; } });
|
|
94
|
+
// Media-upload selector: the controlled bottom-sheet menu the composer opens
|
|
95
|
+
// from the attach button (image / document / record-audio rows).
|
|
96
|
+
var MediaUploadMenu_1 = require("./ui/MediaUploadMenu");
|
|
97
|
+
Object.defineProperty(exports, "MediaUploadMenu", { enumerable: true, get: function () { return MediaUploadMenu_1.MediaUploadMenu; } });
|
|
98
|
+
// Themeable Material-style icon set (SVG with a Text-glyph fallback when the
|
|
99
|
+
// optional react-native-svg peer is absent).
|
|
100
|
+
var Icon_1 = require("./ui/Icon");
|
|
101
|
+
Object.defineProperty(exports, "Icon", { enumerable: true, get: function () { return Icon_1.Icon; } });
|
|
102
|
+
var AudioRecorder_1 = require("./ui/AudioRecorder");
|
|
103
|
+
Object.defineProperty(exports, "AudioRecorder", { enumerable: true, get: function () { return AudioRecorder_1.AudioRecorder; } });
|
|
104
|
+
var VoiceMessage_1 = require("./ui/VoiceMessage");
|
|
105
|
+
Object.defineProperty(exports, "VoiceMessage", { enumerable: true, get: function () { return VoiceMessage_1.VoiceMessage; } });
|
|
106
|
+
// Chrome features (Tier B-3a): typing indicator + powered-by badge.
|
|
107
|
+
var TypingIndicator_1 = require("./ui/TypingIndicator");
|
|
108
|
+
Object.defineProperty(exports, "TypingIndicator", { enumerable: true, get: function () { return TypingIndicator_1.TypingIndicator; } });
|
|
109
|
+
var PoweredBy_1 = require("./ui/PoweredBy");
|
|
110
|
+
Object.defineProperty(exports, "PoweredBy", { enumerable: true, get: function () { return PoweredBy_1.PoweredBy; } });
|
|
111
|
+
// --- Phase 3: video calls (WebRTC) -----------------------------------------
|
|
112
|
+
// Signaling core (answerer-only state machine) + its injectable seams. The WebRTC
|
|
113
|
+
// factory is the only native seam; tests/chat-only consumers never load it.
|
|
114
|
+
var VideoCallClient_1 = require("./core/VideoCallClient");
|
|
115
|
+
Object.defineProperty(exports, "createVideoCallClient", { enumerable: true, get: function () { return VideoCallClient_1.createVideoCallClient; } });
|
|
116
|
+
// Static ICE / pc_config helpers (web parity, B12) + the host-candidate filter (C7).
|
|
117
|
+
var ice_1 = require("./core/ice");
|
|
118
|
+
Object.defineProperty(exports, "iceServers", { enumerable: true, get: function () { return ice_1.iceServers; } });
|
|
119
|
+
Object.defineProperty(exports, "isForwardableCandidate", { enumerable: true, get: function () { return ice_1.isForwardableCandidate; } });
|
|
120
|
+
Object.defineProperty(exports, "TURN_URL", { enumerable: true, get: function () { return ice_1.TURN_URL; } });
|
|
121
|
+
Object.defineProperty(exports, "TURN_USERNAME", { enumerable: true, get: function () { return ice_1.TURN_USERNAME; } });
|
|
122
|
+
Object.defineProperty(exports, "TURN_CREDENTIAL", { enumerable: true, get: function () { return ice_1.TURN_CREDENTIAL; } });
|
|
123
|
+
Object.defineProperty(exports, "STUN_URL", { enumerable: true, get: function () { return ice_1.STUN_URL; } });
|
|
124
|
+
// Real native adapters (lazy-require native bindings inside; importing the type is free)
|
|
125
|
+
// + the teardown helper that fully releases the camera/mic (C10).
|
|
126
|
+
var webrtc_1 = require("./adapters/webrtc");
|
|
127
|
+
Object.defineProperty(exports, "reactNativeWebRTCFactory", { enumerable: true, get: function () { return webrtc_1.reactNativeWebRTCFactory; } });
|
|
128
|
+
Object.defineProperty(exports, "teardownPeerConnection", { enumerable: true, get: function () { return webrtc_1.teardownPeerConnection; } });
|
|
129
|
+
var audioRoute_1 = require("./adapters/audioRoute");
|
|
130
|
+
Object.defineProperty(exports, "AudioRoute", { enumerable: true, get: function () { return audioRoute_1.AudioRoute; } });
|
|
131
|
+
Object.defineProperty(exports, "reactNativeAudioRoute", { enumerable: true, get: function () { return audioRoute_1.reactNativeAudioRoute; } });
|
|
132
|
+
// Call UI: full in-call screen + the control bar + a single video tile (compose your own).
|
|
133
|
+
var VideoCall_1 = require("./ui/VideoCall");
|
|
134
|
+
Object.defineProperty(exports, "VideoCall", { enumerable: true, get: function () { return VideoCall_1.VideoCall; } });
|
|
135
|
+
var CallControls_1 = require("./ui/CallControls");
|
|
136
|
+
Object.defineProperty(exports, "CallControls", { enumerable: true, get: function () { return CallControls_1.CallControls; } });
|
|
137
|
+
var VideoTile_1 = require("./ui/VideoTile");
|
|
138
|
+
Object.defineProperty(exports, "VideoTile", { enumerable: true, get: function () { return VideoTile_1.VideoTile; } });
|
|
139
|
+
// Expo config-plugin (Phase 2 / Task 7): permission injection for media + mic.
|
|
140
|
+
// Hosts add it to app.json/app.config: `"plugins": ["@experiaapp/webchat-react-native"]`
|
|
141
|
+
// (resolves to `app.plugin.js` at the package root). Not re-exported here because the
|
|
142
|
+
// plugin module is consumed by the Expo CLI, not imported into app code.
|