@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 @@
|
|
|
1
|
+
export declare function useWebchat(): import("./WebchatProvider").Ctx;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useWebchat = useWebchat;
|
|
4
|
+
// src/state/useWebchat.ts
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const WebchatProvider_1 = require("./WebchatProvider");
|
|
7
|
+
function useWebchat() {
|
|
8
|
+
const ctx = (0, react_1.useContext)(WebchatProvider_1.WebchatContext);
|
|
9
|
+
if (!ctx)
|
|
10
|
+
throw new Error("useWebchat must be used inside <WebChat>");
|
|
11
|
+
return ctx;
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type Dir = "ltr" | "rtl";
|
|
2
|
+
export declare function dirStyles(dir: Dir): {
|
|
3
|
+
isRtl: boolean;
|
|
4
|
+
rowDirection: "row" | "row-reverse";
|
|
5
|
+
textAlign: "left" | "right";
|
|
6
|
+
start: string;
|
|
7
|
+
end: string;
|
|
8
|
+
mirror: {
|
|
9
|
+
transform: {
|
|
10
|
+
scaleX: number;
|
|
11
|
+
}[];
|
|
12
|
+
};
|
|
13
|
+
bubbleTail(sender: "user" | "response"): "bottomRight" | "bottomLeft";
|
|
14
|
+
};
|
package/lib/theme/dir.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dirStyles = dirStyles;
|
|
4
|
+
function dirStyles(dir) {
|
|
5
|
+
const isRtl = dir === "rtl";
|
|
6
|
+
return {
|
|
7
|
+
isRtl,
|
|
8
|
+
rowDirection: (isRtl ? "row-reverse" : "row"),
|
|
9
|
+
textAlign: (isRtl ? "right" : "left"),
|
|
10
|
+
start: isRtl ? "right" : "left",
|
|
11
|
+
end: isRtl ? "left" : "right",
|
|
12
|
+
mirror: { transform: [{ scaleX: isRtl ? -1 : 1 }] },
|
|
13
|
+
bubbleTail(sender) {
|
|
14
|
+
const onStart = sender === "response";
|
|
15
|
+
const startCorner = isRtl ? "bottomRight" : "bottomLeft";
|
|
16
|
+
const endCorner = isRtl ? "bottomLeft" : "bottomRight";
|
|
17
|
+
return onStart ? startCorner : endCorner;
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
export type Variant = "experia" | "digitalGovernment";
|
|
2
|
+
export declare function resolveVariant(interfaceTheme?: string): Variant;
|
|
3
|
+
export interface PublicStyle {
|
|
4
|
+
themeColor?: string;
|
|
5
|
+
defaultFontColor?: string;
|
|
6
|
+
defaultFontSize?: number;
|
|
7
|
+
defaultFontWeight?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Tenant custom font (web `publicStyle.defaultFontFamily`). Kept structurally
|
|
10
|
+
* identical to core `PublicStyle.defaultFontFamily` so `buildTheme` consumes it
|
|
11
|
+
* without a cross-import. `fonts` is one remote TTF per weight (ExtraLight..Black).
|
|
12
|
+
*/
|
|
13
|
+
defaultFontFamily?: {
|
|
14
|
+
name?: string;
|
|
15
|
+
fonts?: Array<{
|
|
16
|
+
url: string;
|
|
17
|
+
fontWeight?: string;
|
|
18
|
+
fontName?: string;
|
|
19
|
+
}>;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Weight -> RN-registered family-name map produced by the apply phase after
|
|
24
|
+
* `createExpoFontLoader().loadBrandFonts(...)` resolves. Keys are the font
|
|
25
|
+
* `fontWeight` strings ("200", "400", "700", …) carried on each font entry; the
|
|
26
|
+
* `name` key (when present) maps the family-level name. An empty/undefined map
|
|
27
|
+
* means no custom font loaded — `resolveFontFamily` then returns `undefined`
|
|
28
|
+
* (system font), preserving today's look.
|
|
29
|
+
*/
|
|
30
|
+
export type LoadedFontMap = Record<string, string> | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the RN font family for a given weight from a loaded weight->family map.
|
|
33
|
+
* Returns `undefined` (caller falls back to the system font) when no map exists,
|
|
34
|
+
* the weight is absent, or the map has no entry for it. Pure — the apply phase
|
|
35
|
+
* passes the map produced by the loader plus the weight it wants to render.
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveFontFamily(map: LoadedFontMap, weight?: string | number): string | undefined;
|
|
38
|
+
/** Server-driven chat-bubble overrides (web `chatSectionStyle`). All optional. */
|
|
39
|
+
export interface ChatSectionStyle {
|
|
40
|
+
sentMsgBg?: string;
|
|
41
|
+
sentMsgFontColor?: string;
|
|
42
|
+
receivedMsgBg?: string;
|
|
43
|
+
receivedMsgFontColor?: string;
|
|
44
|
+
receivedMsgCornerRadius?: number;
|
|
45
|
+
sendMsgCornerRadius?: number;
|
|
46
|
+
msgPadding?: number;
|
|
47
|
+
msgFontSize?: number | string;
|
|
48
|
+
msgFontWeight?: string | number;
|
|
49
|
+
dateFontSize?: number | string;
|
|
50
|
+
dateFontWeight?: string | number;
|
|
51
|
+
quickReplyFontSize?: number | string;
|
|
52
|
+
quickReplyFontWeight?: string | number;
|
|
53
|
+
sentDateFontColor?: string;
|
|
54
|
+
receivedDateFontColor?: string;
|
|
55
|
+
quickReplyBg?: string;
|
|
56
|
+
quickReplyBorderWidth?: number;
|
|
57
|
+
quickReplyBorderRadius?: number;
|
|
58
|
+
quickReplyColor?: string;
|
|
59
|
+
quickReplyBorderColor?: string;
|
|
60
|
+
bgChatColor?: string;
|
|
61
|
+
sessionDateColor?: string;
|
|
62
|
+
avatarMsgWidth?: number | string;
|
|
63
|
+
avatarMsgHeight?: number | string;
|
|
64
|
+
[k: string]: any;
|
|
65
|
+
}
|
|
66
|
+
/** Server-driven header overrides (web `headerSectionStyle`). All optional. */
|
|
67
|
+
export interface HeaderSectionStyle {
|
|
68
|
+
bgColor?: string;
|
|
69
|
+
titleColor?: string;
|
|
70
|
+
subTitleColor?: string;
|
|
71
|
+
fontWeightTitle?: string | number;
|
|
72
|
+
fontWeightSubTitle?: string | number;
|
|
73
|
+
fontSizeTitle?: number | string;
|
|
74
|
+
fontSizeSubTitle?: number | string;
|
|
75
|
+
closeBtnColor?: string;
|
|
76
|
+
videoCallBtnColor?: string;
|
|
77
|
+
avatarWidth?: number | string;
|
|
78
|
+
avatarHeight?: number | string;
|
|
79
|
+
avatarBorderRadius?: number | string;
|
|
80
|
+
avatarObjectFit?: string;
|
|
81
|
+
onlineStatusColor?: string;
|
|
82
|
+
offlineStatusColor?: string;
|
|
83
|
+
statusIndicatorPosition?: string;
|
|
84
|
+
connectingTextColor?: string;
|
|
85
|
+
connectingTextBgcolor?: string;
|
|
86
|
+
alignConnectingText?: string;
|
|
87
|
+
fontSizeConnectText?: number | string;
|
|
88
|
+
fontWeightConnectText?: string | number;
|
|
89
|
+
[k: string]: any;
|
|
90
|
+
}
|
|
91
|
+
/** Server-driven composer/send overrides (web `sendSectionStyle`). All optional. */
|
|
92
|
+
export interface SendSectionStyle {
|
|
93
|
+
textFieldBg?: string;
|
|
94
|
+
textFeildColor?: string;
|
|
95
|
+
textFieldCornerRadius?: number;
|
|
96
|
+
hintFontColor?: string;
|
|
97
|
+
hintFontSize?: number | string;
|
|
98
|
+
hintFontWeight?: string | number;
|
|
99
|
+
sendBtnBg?: string;
|
|
100
|
+
sendBtnColor?: string;
|
|
101
|
+
sendBtnCornerRadius?: number;
|
|
102
|
+
uploadFileBtnColor?: string;
|
|
103
|
+
audioBtnColor?: string;
|
|
104
|
+
emojiBtnColor?: string;
|
|
105
|
+
uploadFileBtnBg?: string;
|
|
106
|
+
uploadFileBtnCornerRadius?: number;
|
|
107
|
+
[k: string]: any;
|
|
108
|
+
}
|
|
109
|
+
/** Server-driven launcher (FAB) overrides (web `wedgitSectionStyle`). All optional. */
|
|
110
|
+
export interface WedgitSectionStyle {
|
|
111
|
+
buttonColor?: string;
|
|
112
|
+
buttonBg?: string;
|
|
113
|
+
buttonWidth?: number | string;
|
|
114
|
+
buttonHeight?: number | string;
|
|
115
|
+
buttonBorderRadius?: number | string;
|
|
116
|
+
[k: string]: any;
|
|
117
|
+
}
|
|
118
|
+
export declare function buildTheme(variant: Variant, ps?: PublicStyle, cs?: ChatSectionStyle, hs?: HeaderSectionStyle, ss?: SendSectionStyle, ws?: WedgitSectionStyle, fontMap?: LoadedFontMap): {
|
|
119
|
+
variant: Variant;
|
|
120
|
+
colors: {
|
|
121
|
+
primary: string;
|
|
122
|
+
surface: string;
|
|
123
|
+
text: string;
|
|
124
|
+
};
|
|
125
|
+
font: {
|
|
126
|
+
size: number;
|
|
127
|
+
weight: string;
|
|
128
|
+
family: string | undefined;
|
|
129
|
+
familyMap: LoadedFontMap;
|
|
130
|
+
};
|
|
131
|
+
bubble: {
|
|
132
|
+
sentBg: string;
|
|
133
|
+
sentText: string;
|
|
134
|
+
receivedBg: string;
|
|
135
|
+
receivedText: string;
|
|
136
|
+
radius: number;
|
|
137
|
+
shadowColor: string;
|
|
138
|
+
shadowOpacity: number;
|
|
139
|
+
shadowRadius: number;
|
|
140
|
+
shadowOffset: {
|
|
141
|
+
width: number;
|
|
142
|
+
height: number;
|
|
143
|
+
};
|
|
144
|
+
elevation: number;
|
|
145
|
+
marginX: number;
|
|
146
|
+
padding: number;
|
|
147
|
+
sentRadius: number;
|
|
148
|
+
receivedRadius: number;
|
|
149
|
+
};
|
|
150
|
+
header: {
|
|
151
|
+
bg: string;
|
|
152
|
+
titleColor: string;
|
|
153
|
+
subTitleColor: string;
|
|
154
|
+
titleWeight: string | number;
|
|
155
|
+
subTitleWeight: string | number;
|
|
156
|
+
titleSize: string | number | undefined;
|
|
157
|
+
subTitleSize: string | number | undefined;
|
|
158
|
+
closeColor: string;
|
|
159
|
+
videoColor: string;
|
|
160
|
+
avatarWidth: number;
|
|
161
|
+
avatarHeight: number;
|
|
162
|
+
avatarBorderRadius: number;
|
|
163
|
+
avatarObjectFit: string;
|
|
164
|
+
onlineStatus: string;
|
|
165
|
+
offlineStatus: string;
|
|
166
|
+
statusIndicatorPosition: string;
|
|
167
|
+
connectingColor: string;
|
|
168
|
+
connectingBg: string;
|
|
169
|
+
connectingAlign: string;
|
|
170
|
+
connectingFontSize: string | number | undefined;
|
|
171
|
+
connectingFontWeight: string | number | undefined;
|
|
172
|
+
};
|
|
173
|
+
chat: {
|
|
174
|
+
bg: string;
|
|
175
|
+
dateColor: string;
|
|
176
|
+
msgFontSize: string | number | undefined;
|
|
177
|
+
msgFontWeight: string | number | undefined;
|
|
178
|
+
dateFontSize: string | number | undefined;
|
|
179
|
+
dateFontWeight: string | number | undefined;
|
|
180
|
+
quickReplyFontSize: string | number | undefined;
|
|
181
|
+
quickReplyFontWeight: string | number | undefined;
|
|
182
|
+
sentDateColor: string;
|
|
183
|
+
receivedDateColor: string;
|
|
184
|
+
avatarMsgWidth: number;
|
|
185
|
+
avatarMsgHeight: number;
|
|
186
|
+
};
|
|
187
|
+
send: {
|
|
188
|
+
fieldBg: string;
|
|
189
|
+
fieldColor: string;
|
|
190
|
+
fieldRadius: number;
|
|
191
|
+
hintColor: string;
|
|
192
|
+
hintFontSize: string | number | undefined;
|
|
193
|
+
hintFontWeight: string | number | undefined;
|
|
194
|
+
sendBtnBg: string;
|
|
195
|
+
sendBtnColor: string;
|
|
196
|
+
sendBtnRadius: number;
|
|
197
|
+
iconColor: string;
|
|
198
|
+
uploadIconColor: string;
|
|
199
|
+
emojiIconColor: string;
|
|
200
|
+
audioIconColor: string;
|
|
201
|
+
uploadBtnBg: string | undefined;
|
|
202
|
+
uploadBtnRadius: number | undefined;
|
|
203
|
+
};
|
|
204
|
+
quickReply: {
|
|
205
|
+
bg: string;
|
|
206
|
+
borderColor: string;
|
|
207
|
+
color: string;
|
|
208
|
+
borderWidth: number;
|
|
209
|
+
borderRadius: number;
|
|
210
|
+
};
|
|
211
|
+
launcher: {
|
|
212
|
+
buttonColor: string;
|
|
213
|
+
buttonBg: string;
|
|
214
|
+
buttonWidth: string | number;
|
|
215
|
+
buttonHeight: string | number;
|
|
216
|
+
buttonBorderRadius: string | number;
|
|
217
|
+
};
|
|
218
|
+
};
|
|
219
|
+
export type WebChatTheme = ReturnType<typeof buildTheme>;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveVariant = resolveVariant;
|
|
4
|
+
exports.resolveFontFamily = resolveFontFamily;
|
|
5
|
+
exports.buildTheme = buildTheme;
|
|
6
|
+
function resolveVariant(interfaceTheme) {
|
|
7
|
+
return interfaceTheme === "digitalGovernment" ? "digitalGovernment" : "experia";
|
|
8
|
+
}
|
|
9
|
+
const BASE = {
|
|
10
|
+
experia: { primary: "#6C5CE7", surface: "#FFFFFF" },
|
|
11
|
+
digitalGovernment: { primary: "#0B7A4B", surface: "#FCFCFD" },
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the RN font family for a given weight from a loaded weight->family map.
|
|
15
|
+
* Returns `undefined` (caller falls back to the system font) when no map exists,
|
|
16
|
+
* the weight is absent, or the map has no entry for it. Pure — the apply phase
|
|
17
|
+
* passes the map produced by the loader plus the weight it wants to render.
|
|
18
|
+
*/
|
|
19
|
+
function resolveFontFamily(map, weight) {
|
|
20
|
+
if (!map)
|
|
21
|
+
return undefined;
|
|
22
|
+
if (weight != null) {
|
|
23
|
+
const hit = map[String(weight)];
|
|
24
|
+
if (hit)
|
|
25
|
+
return hit;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Coerce a web style dimension to an RN numeric dimension. Web sends sizes as
|
|
31
|
+
* strings (e.g. `"40"`, `"50"`) or numbers; RN style width/height/borderRadius
|
|
32
|
+
* want a number. A non-numeric value falls back to `fallback`.
|
|
33
|
+
*/
|
|
34
|
+
function dim(v, fallback) {
|
|
35
|
+
if (typeof v === "number" && Number.isFinite(v))
|
|
36
|
+
return v;
|
|
37
|
+
if (typeof v === "string") {
|
|
38
|
+
const n = parseFloat(v);
|
|
39
|
+
if (Number.isFinite(n))
|
|
40
|
+
return n;
|
|
41
|
+
}
|
|
42
|
+
return fallback;
|
|
43
|
+
}
|
|
44
|
+
function buildTheme(variant, ps = {}, cs = {}, hs = {}, ss = {}, ws = {},
|
|
45
|
+
// Loaded weight->family map produced by the apply phase once the brand fonts
|
|
46
|
+
// resolve (createExpoFontLoader().loadBrandFonts). Absent/undefined on the
|
|
47
|
+
// pre-load build (and forever when no tenant font is configured / expo-font is
|
|
48
|
+
// absent) => `font.family`/`font.familyMap` stay undefined and every component
|
|
49
|
+
// omits `fontFamily` (system font, today's look). Passing the map once it
|
|
50
|
+
// resolves promotes `font.family` to the base-weight family and exposes the
|
|
51
|
+
// full map at `font.familyMap` so components can resolve per-weight families.
|
|
52
|
+
fontMap) {
|
|
53
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39;
|
|
54
|
+
const primary = (_a = ps.themeColor) !== null && _a !== void 0 ? _a : BASE[variant].primary;
|
|
55
|
+
const text = (_b = ps.defaultFontColor) !== null && _b !== void 0 ? _b : "#1A1A1A";
|
|
56
|
+
const baseWeight = (_c = ps.defaultFontWeight) !== null && _c !== void 0 ? _c : "400";
|
|
57
|
+
return {
|
|
58
|
+
variant,
|
|
59
|
+
colors: { primary, surface: BASE[variant].surface, text },
|
|
60
|
+
// `family: undefined` => system font (back-compat: unchanged when no tenant
|
|
61
|
+
// font configured). The apply phase replaces it with a loaded RN family name
|
|
62
|
+
// (per weight) via `resolveFontFamily(loadedMap, weight)` once the brand fonts
|
|
63
|
+
// resolve; the static theme never carries a not-yet-loaded remote family.
|
|
64
|
+
// `family` resolves the BASE weight (font.weight); `familyMap` carries the full
|
|
65
|
+
// weight->family map so components can resolve the family for the weight THEY
|
|
66
|
+
// render (msg/date/quick-reply/title/subtitle), falling back to undefined
|
|
67
|
+
// (system font) for any weight the tenant didn't ship.
|
|
68
|
+
font: {
|
|
69
|
+
size: (_d = ps.defaultFontSize) !== null && _d !== void 0 ? _d : 14,
|
|
70
|
+
weight: baseWeight,
|
|
71
|
+
family: resolveFontFamily(fontMap, baseWeight),
|
|
72
|
+
familyMap: fontMap,
|
|
73
|
+
},
|
|
74
|
+
// Bubble palette (audit: sender differentiation). Server chatSectionStyle wins,
|
|
75
|
+
// then sensible defaults: sent = brand primary on white text, received = white.
|
|
76
|
+
// Web parity adds a soft drop shadow + structured spacing/radius tokens.
|
|
77
|
+
bubble: {
|
|
78
|
+
sentBg: (_e = cs.sentMsgBg) !== null && _e !== void 0 ? _e : primary,
|
|
79
|
+
sentText: (_f = cs.sentMsgFontColor) !== null && _f !== void 0 ? _f : "#FFFFFF",
|
|
80
|
+
receivedBg: (_g = cs.receivedMsgBg) !== null && _g !== void 0 ? _g : "#FFFFFF",
|
|
81
|
+
receivedText: (_h = cs.receivedMsgFontColor) !== null && _h !== void 0 ? _h : text,
|
|
82
|
+
radius: (_j = cs.receivedMsgCornerRadius) !== null && _j !== void 0 ? _j : 12,
|
|
83
|
+
// soft drop shadow (web uses theme.palette.general.boxShadow); RN needs
|
|
84
|
+
// shadow* + elevation for a comparable result on iOS + Android.
|
|
85
|
+
shadowColor: "#000",
|
|
86
|
+
shadowOpacity: 0.12,
|
|
87
|
+
shadowRadius: 6,
|
|
88
|
+
shadowOffset: { width: 0, height: 2 },
|
|
89
|
+
elevation: 2,
|
|
90
|
+
marginX: 15,
|
|
91
|
+
padding: (_k = cs.msgPadding) !== null && _k !== void 0 ? _k : 8,
|
|
92
|
+
sentRadius: (_l = cs.sendMsgCornerRadius) !== null && _l !== void 0 ? _l : 8,
|
|
93
|
+
receivedRadius: (_m = cs.receivedMsgCornerRadius) !== null && _m !== void 0 ? _m : 8,
|
|
94
|
+
},
|
|
95
|
+
header: {
|
|
96
|
+
bg: (_o = hs.bgColor) !== null && _o !== void 0 ? _o : primary,
|
|
97
|
+
titleColor: (_p = hs.titleColor) !== null && _p !== void 0 ? _p : "#FFFFFF",
|
|
98
|
+
// subtitle: distinct color falls back to titleColor (web reuses title when unset).
|
|
99
|
+
subTitleColor: (_r = (_q = hs.subTitleColor) !== null && _q !== void 0 ? _q : hs.titleColor) !== null && _r !== void 0 ? _r : "#FFFFFF",
|
|
100
|
+
titleWeight: ((_s = hs.fontWeightTitle) !== null && _s !== void 0 ? _s : "700"),
|
|
101
|
+
subTitleWeight: ((_u = (_t = hs.fontWeightSubTitle) !== null && _t !== void 0 ? _t : ps.defaultFontWeight) !== null && _u !== void 0 ? _u : "400"),
|
|
102
|
+
// explicit title/subtitle sizes override the component's derived size+offset.
|
|
103
|
+
titleSize: hs.fontSizeTitle,
|
|
104
|
+
subTitleSize: hs.fontSizeSubTitle,
|
|
105
|
+
closeColor: (_v = hs.closeBtnColor) !== null && _v !== void 0 ? _v : "#FFFFFF",
|
|
106
|
+
videoColor: (_w = hs.videoCallBtnColor) !== null && _w !== void 0 ? _w : "#FFFFFF",
|
|
107
|
+
// header avatar sizing/shape (web headerSectionStyle avatar*); defaults match
|
|
108
|
+
// the SDK's currently-hardcoded 32x32 logo with a 16px radius.
|
|
109
|
+
avatarWidth: dim(hs.avatarWidth, 32),
|
|
110
|
+
avatarHeight: dim(hs.avatarHeight, 32),
|
|
111
|
+
avatarBorderRadius: dim(hs.avatarBorderRadius, 16),
|
|
112
|
+
// RN <Image resizeMode>; web `object-fit` cover/contain map 1:1, default cover.
|
|
113
|
+
avatarObjectFit: ((_x = hs.avatarObjectFit) !== null && _x !== void 0 ? _x : "cover"),
|
|
114
|
+
onlineStatus: (_y = hs.onlineStatusColor) !== null && _y !== void 0 ? _y : primary,
|
|
115
|
+
offlineStatus: (_z = hs.offlineStatusColor) !== null && _z !== void 0 ? _z : "#EB5757",
|
|
116
|
+
// status-dot placement (web `statusIndicatorPosition`).
|
|
117
|
+
statusIndicatorPosition: (_0 = hs.statusIndicatorPosition) !== null && _0 !== void 0 ? _0 : "top-right",
|
|
118
|
+
// connecting banner (no SDK UI yet — tokens reserved for Phase 2 wiring).
|
|
119
|
+
connectingColor: (_1 = hs.connectingTextColor) !== null && _1 !== void 0 ? _1 : ((_2 = hs.titleColor) !== null && _2 !== void 0 ? _2 : "#FFFFFF"),
|
|
120
|
+
connectingBg: (_3 = hs.connectingTextBgcolor) !== null && _3 !== void 0 ? _3 : "#B5B5B5",
|
|
121
|
+
connectingAlign: (_4 = hs.alignConnectingText) !== null && _4 !== void 0 ? _4 : "center",
|
|
122
|
+
connectingFontSize: hs.fontSizeConnectText,
|
|
123
|
+
connectingFontWeight: hs.fontWeightConnectText,
|
|
124
|
+
},
|
|
125
|
+
chat: {
|
|
126
|
+
bg: (_5 = cs.bgChatColor) !== null && _5 !== void 0 ? _5 : "#FFFFFF",
|
|
127
|
+
dateColor: (_6 = cs.sessionDateColor) !== null && _6 !== void 0 ? _6 : "#384250",
|
|
128
|
+
// message/date/quick-reply typography (web chatSectionStyle); undefined =>
|
|
129
|
+
// consumers fall back to font.size / no explicit weight.
|
|
130
|
+
msgFontSize: cs.msgFontSize,
|
|
131
|
+
msgFontWeight: cs.msgFontWeight,
|
|
132
|
+
dateFontSize: cs.dateFontSize,
|
|
133
|
+
dateFontWeight: cs.dateFontWeight,
|
|
134
|
+
quickReplyFontSize: cs.quickReplyFontSize,
|
|
135
|
+
quickReplyFontWeight: cs.quickReplyFontWeight,
|
|
136
|
+
// per-bubble timestamp colors (web sent/receivedDateFontColor); fall back to
|
|
137
|
+
// the existing session date color when unset.
|
|
138
|
+
sentDateColor: (_7 = cs.sentDateFontColor) !== null && _7 !== void 0 ? _7 : ((_8 = cs.sessionDateColor) !== null && _8 !== void 0 ? _8 : "#384250"),
|
|
139
|
+
receivedDateColor: (_9 = cs.receivedDateFontColor) !== null && _9 !== void 0 ? _9 : ((_10 = cs.sessionDateColor) !== null && _10 !== void 0 ? _10 : "#384250"),
|
|
140
|
+
// per-message (received) avatar sizing (web chatSectionStyle avatarMsg*);
|
|
141
|
+
// default 32 — a compact in-thread avatar (web default is 50).
|
|
142
|
+
avatarMsgWidth: dim(cs.avatarMsgWidth, 32),
|
|
143
|
+
avatarMsgHeight: dim(cs.avatarMsgHeight, 32),
|
|
144
|
+
},
|
|
145
|
+
send: {
|
|
146
|
+
fieldBg: (_11 = ss.textFieldBg) !== null && _11 !== void 0 ? _11 : "#F3F4F6",
|
|
147
|
+
fieldColor: (_12 = ss.textFeildColor) !== null && _12 !== void 0 ? _12 : "#2d2d2d",
|
|
148
|
+
fieldRadius: (_13 = ss.textFieldCornerRadius) !== null && _13 !== void 0 ? _13 : 4,
|
|
149
|
+
hintColor: (_14 = ss.hintFontColor) !== null && _14 !== void 0 ? _14 : "#6C737F",
|
|
150
|
+
hintFontSize: ss.hintFontSize,
|
|
151
|
+
hintFontWeight: ss.hintFontWeight,
|
|
152
|
+
sendBtnBg: (_15 = ss.sendBtnBg) !== null && _15 !== void 0 ? _15 : primary,
|
|
153
|
+
sendBtnColor: (_16 = ss.sendBtnColor) !== null && _16 !== void 0 ? _16 : "#FFFFFF",
|
|
154
|
+
sendBtnRadius: (_17 = ss.sendBtnCornerRadius) !== null && _17 !== void 0 ? _17 : 4,
|
|
155
|
+
// back-compat: the single folded icon color (kept so existing consumers work).
|
|
156
|
+
iconColor: (_20 = (_19 = (_18 = ss.uploadFileBtnColor) !== null && _18 !== void 0 ? _18 : ss.emojiBtnColor) !== null && _19 !== void 0 ? _19 : ss.audioBtnColor) !== null && _20 !== void 0 ? _20 : primary,
|
|
157
|
+
// independent icon colors (each falls back to the folded iconColor chain).
|
|
158
|
+
uploadIconColor: (_23 = (_22 = (_21 = ss.uploadFileBtnColor) !== null && _21 !== void 0 ? _21 : ss.emojiBtnColor) !== null && _22 !== void 0 ? _22 : ss.audioBtnColor) !== null && _23 !== void 0 ? _23 : primary,
|
|
159
|
+
emojiIconColor: (_26 = (_25 = (_24 = ss.emojiBtnColor) !== null && _24 !== void 0 ? _24 : ss.uploadFileBtnColor) !== null && _25 !== void 0 ? _25 : ss.audioBtnColor) !== null && _26 !== void 0 ? _26 : primary,
|
|
160
|
+
audioIconColor: (_29 = (_28 = (_27 = ss.audioBtnColor) !== null && _27 !== void 0 ? _27 : ss.uploadFileBtnColor) !== null && _28 !== void 0 ? _28 : ss.emojiBtnColor) !== null && _29 !== void 0 ? _29 : primary,
|
|
161
|
+
// attach-button background + radius (web uploadFileBtnBg/CornerRadius).
|
|
162
|
+
uploadBtnBg: ss.uploadFileBtnBg,
|
|
163
|
+
uploadBtnRadius: ss.uploadFileBtnCornerRadius,
|
|
164
|
+
},
|
|
165
|
+
quickReply: {
|
|
166
|
+
bg: (_30 = cs.quickReplyBg) !== null && _30 !== void 0 ? _30 : "#FFFFFF",
|
|
167
|
+
borderColor: (_31 = cs.quickReplyBorderColor) !== null && _31 !== void 0 ? _31 : primary,
|
|
168
|
+
color: (_32 = cs.quickReplyColor) !== null && _32 !== void 0 ? _32 : primary,
|
|
169
|
+
borderWidth: (_33 = cs.quickReplyBorderWidth) !== null && _33 !== void 0 ? _33 : 1,
|
|
170
|
+
borderRadius: (_34 = cs.quickReplyBorderRadius) !== null && _34 !== void 0 ? _34 : 15,
|
|
171
|
+
},
|
|
172
|
+
// Launcher (FAB) tokens (web wedgitSectionStyle). Defaults match the SDK's
|
|
173
|
+
// currently-hardcoded Launcher dimensions so unset config keeps today's look.
|
|
174
|
+
launcher: {
|
|
175
|
+
buttonColor: (_35 = ws.buttonColor) !== null && _35 !== void 0 ? _35 : "#FFFFFF",
|
|
176
|
+
buttonBg: (_36 = ws.buttonBg) !== null && _36 !== void 0 ? _36 : primary,
|
|
177
|
+
buttonWidth: (_37 = ws.buttonWidth) !== null && _37 !== void 0 ? _37 : 56,
|
|
178
|
+
buttonHeight: (_38 = ws.buttonHeight) !== null && _38 !== void 0 ? _38 : 56,
|
|
179
|
+
buttonBorderRadius: (_39 = ws.buttonBorderRadius) !== null && _39 !== void 0 ? _39 : 28,
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A single attachment awaiting send. Mirrors the normalized picker `Asset`
|
|
3
|
+
* shape loosely (only the fields the chip needs); `name` labels the chip.
|
|
4
|
+
*/
|
|
5
|
+
export interface PendingAttachment {
|
|
6
|
+
/** stable id used as the cancel target and React key */
|
|
7
|
+
id: string;
|
|
8
|
+
/** display name shown in the chip */
|
|
9
|
+
name: string;
|
|
10
|
+
/** optional lifecycle hint shown next to the name (queued/encoding/…) */
|
|
11
|
+
status?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface AttachButtonProps {
|
|
14
|
+
/**
|
|
15
|
+
* Injected picker trigger. Pressing the button calls this; the host wires it
|
|
16
|
+
* to a real PickerAdapter (or a fake in tests). It may be async.
|
|
17
|
+
*/
|
|
18
|
+
onPick: () => void | Promise<void>;
|
|
19
|
+
/** pending attachments to render as cancellable chips */
|
|
20
|
+
pending?: PendingAttachment[];
|
|
21
|
+
/** cancel a pending attachment by id */
|
|
22
|
+
onCancel?: (id: string) => void;
|
|
23
|
+
/** disable the button (e.g. at the max-file cap or during a video call) */
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
theme: any;
|
|
26
|
+
/** accessible label override; defaults to "Attach file" */
|
|
27
|
+
accessibilityLabel?: string;
|
|
28
|
+
/** attach-button background (web `uploadFileBtnBg`); undefined => transparent. */
|
|
29
|
+
backgroundColor?: string;
|
|
30
|
+
/** attach-button corner radius (web `uploadFileBtnCornerRadius`). */
|
|
31
|
+
borderRadius?: number;
|
|
32
|
+
/** glyph tint (web `uploadFileBtnColor`); undefined => default glyph colour. */
|
|
33
|
+
iconColor?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function AttachButton({ onPick, pending, onCancel, disabled, theme, accessibilityLabel, backgroundColor, borderRadius, iconColor, }: AttachButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AttachButton = AttachButton;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_native_1 = require("react-native");
|
|
6
|
+
function AttachButton({ onPick, pending = [], onCancel, disabled = false, theme, accessibilityLabel = "Attach file", backgroundColor, borderRadius, iconColor, }) {
|
|
7
|
+
var _a, _b;
|
|
8
|
+
return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { children: [(0, jsx_runtime_1.jsx)(react_native_1.Pressable, { testID: "attach-button", accessibilityRole: "button", accessibilityLabel: accessibilityLabel, accessibilityState: { disabled }, disabled: disabled, onPress: () => {
|
|
9
|
+
if (!disabled)
|
|
10
|
+
onPick();
|
|
11
|
+
},
|
|
12
|
+
// web parity: optional themed background + corner radius (uploadFileBtnBg /
|
|
13
|
+
// uploadFileBtnCornerRadius); undefined keys leave the bare icon button.
|
|
14
|
+
style: { padding: 6, opacity: disabled ? 0.4 : 1, backgroundColor, borderRadius }, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: { fontSize: ((_b = (_a = theme === null || theme === void 0 ? void 0 : theme.font) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 14) + 4, color: iconColor }, children: "📎" }) }), pending.length > 0 ? ((0, jsx_runtime_1.jsx)(react_native_1.View, { testID: "attach-pending", style: { flexDirection: "row", flexWrap: "wrap", gap: 6, padding: 4 }, children: pending.map((p) => {
|
|
15
|
+
var _a, _b, _c, _d;
|
|
16
|
+
return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { testID: `attach-chip-${p.id}`, style: {
|
|
17
|
+
flexDirection: "row",
|
|
18
|
+
alignItems: "center",
|
|
19
|
+
gap: 6,
|
|
20
|
+
paddingHorizontal: 8,
|
|
21
|
+
paddingVertical: 4,
|
|
22
|
+
borderRadius: 12,
|
|
23
|
+
backgroundColor: (_a = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _a === void 0 ? void 0 : _a.surface,
|
|
24
|
+
}, children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { numberOfLines: 1, style: { color: (_b = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _b === void 0 ? void 0 : _b.text, fontSize: (_c = theme === null || theme === void 0 ? void 0 : theme.font) === null || _c === void 0 ? void 0 : _c.size, flexShrink: 1 }, children: p.status ? `${p.name} · ${p.status}` : p.name }), (0, jsx_runtime_1.jsx)(react_native_1.Pressable, { testID: "attach-cancel", accessibilityRole: "button", accessibilityLabel: `Cancel ${p.name}`, onPress: () => onCancel === null || onCancel === void 0 ? void 0 : onCancel(p.id), style: { paddingHorizontal: 4 }, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: { color: (_d = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _d === void 0 ? void 0 : _d.text }, children: "✕" }) })] }, p.id));
|
|
25
|
+
}) })) : null] }));
|
|
26
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AudioAdapter, RecordingResult } from "../adapters/audio";
|
|
2
|
+
export interface AudioRecorderProps {
|
|
3
|
+
/** injected capture surface (fake in tests, real recorder on device). When it
|
|
4
|
+
* carries `recordingDelegated`, capture is driven via the expo-audio hook. */
|
|
5
|
+
adapter: AudioAdapter;
|
|
6
|
+
/** called with the completed recording once stop resolves */
|
|
7
|
+
onRecorded: (result: RecordingResult) => void;
|
|
8
|
+
/** optional typed-error sink for start/stop failures */
|
|
9
|
+
onError?: (err: unknown) => void;
|
|
10
|
+
/**
|
|
11
|
+
* suspend recording entirely (mic mutual-exclusion with a video call, §4.4).
|
|
12
|
+
* When true the toggle is disabled.
|
|
13
|
+
*/
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* When true, begin recording on mount (one-shot). Used when the recorder is
|
|
17
|
+
* launched from the media-upload selector's "record audio" row, so the user
|
|
18
|
+
* lands directly on the live timer instead of having to tap once more.
|
|
19
|
+
*/
|
|
20
|
+
autoStart?: boolean;
|
|
21
|
+
theme: any;
|
|
22
|
+
/** mic/record glyph tint (web `audioBtnColor`); undefined => default colour. */
|
|
23
|
+
iconColor?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function AudioRecorder({ adapter, onRecorded, onError, disabled, autoStart, theme, iconColor, }: AudioRecorderProps): import("react/jsx-runtime").JSX.Element | null;
|