@revrag-ai/embed-react-native 1.0.26 → 1.0.28
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 +5 -0
- package/android/build.gradle +1 -0
- package/dist/commonjs/api/api.js.map +1 -1
- package/dist/commonjs/assets/fonts/PlaywriteNZBasic-ExtraLight.ttf +0 -0
- package/dist/commonjs/assets/fonts/PlaywriteNZBasic-Light.ttf +0 -0
- package/dist/commonjs/assets/fonts/PlaywriteNZBasic-Regular.ttf +0 -0
- package/dist/commonjs/assets/fonts/PlaywriteNZBasic-Thin.ttf +0 -0
- package/dist/commonjs/components/DynamicComponent/Typewriter.js +124 -0
- package/dist/commonjs/components/DynamicComponent/Typewriter.js.map +1 -0
- package/dist/commonjs/components/Embed/EmbedButton.js +362 -113
- package/dist/commonjs/components/Embed/EmbedButton.js.map +1 -1
- package/dist/commonjs/components/styles/EmbedButton.style.js +112 -158
- package/dist/commonjs/components/styles/EmbedButton.style.js.map +1 -1
- package/dist/commonjs/context/EmbedProvider.js +187 -14
- package/dist/commonjs/context/EmbedProvider.js.map +1 -1
- package/dist/commonjs/events/clickEventTracker.js +210 -0
- package/dist/commonjs/events/clickEventTracker.js.map +1 -0
- package/dist/commonjs/events/embed.event.js +11 -3
- package/dist/commonjs/events/embed.event.js.map +1 -1
- package/dist/commonjs/hooks/EmbedButton.animations.js +115 -15
- package/dist/commonjs/hooks/EmbedButton.animations.js.map +1 -1
- package/dist/commonjs/hooks/EmbedButton.helpers.js +11 -3
- package/dist/commonjs/hooks/EmbedButton.helpers.js.map +1 -1
- package/dist/commonjs/hooks/EmbedButton.hooks.js +17 -11
- package/dist/commonjs/hooks/EmbedButton.hooks.js.map +1 -1
- package/dist/commonjs/hooks/voiceagent.js +34 -12
- package/dist/commonjs/hooks/voiceagent.js.map +1 -1
- package/dist/commonjs/index.js +6 -2
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/utils/constant.js +6 -1
- package/dist/commonjs/utils/constant.js.map +1 -1
- package/dist/commonjs/utils/permision.js +42 -1
- package/dist/commonjs/utils/permision.js.map +1 -1
- package/dist/commonjs/utils/reanimated.helper.js +4 -0
- package/dist/commonjs/utils/reanimated.helper.js.map +1 -1
- package/dist/module/api/api.js.map +1 -1
- package/dist/module/assets/fonts/PlaywriteNZBasic-ExtraLight.ttf +0 -0
- package/dist/module/assets/fonts/PlaywriteNZBasic-Light.ttf +0 -0
- package/dist/module/assets/fonts/PlaywriteNZBasic-Regular.ttf +0 -0
- package/dist/module/assets/fonts/PlaywriteNZBasic-Thin.ttf +0 -0
- package/dist/module/components/DynamicComponent/Typewriter.js +122 -0
- package/dist/module/components/DynamicComponent/Typewriter.js.map +1 -0
- package/dist/module/components/Embed/EmbedButton.js +367 -118
- package/dist/module/components/Embed/EmbedButton.js.map +1 -1
- package/dist/module/components/styles/EmbedButton.style.js +111 -157
- package/dist/module/components/styles/EmbedButton.style.js.map +1 -1
- package/dist/module/context/EmbedProvider.js +187 -14
- package/dist/module/context/EmbedProvider.js.map +1 -1
- package/dist/module/events/clickEventTracker.js +199 -0
- package/dist/module/events/clickEventTracker.js.map +1 -0
- package/dist/module/events/embed.event.js +11 -3
- package/dist/module/events/embed.event.js.map +1 -1
- package/dist/module/hooks/EmbedButton.animations.js +109 -13
- package/dist/module/hooks/EmbedButton.animations.js.map +1 -1
- package/dist/module/hooks/EmbedButton.helpers.js +10 -2
- package/dist/module/hooks/EmbedButton.helpers.js.map +1 -1
- package/dist/module/hooks/EmbedButton.hooks.js +17 -11
- package/dist/module/hooks/EmbedButton.hooks.js.map +1 -1
- package/dist/module/hooks/voiceagent.js +34 -12
- package/dist/module/hooks/voiceagent.js.map +1 -1
- package/dist/module/index.js +8 -3
- package/dist/module/index.js.map +1 -1
- package/dist/module/utils/constant.js +6 -1
- package/dist/module/utils/constant.js.map +1 -1
- package/dist/module/utils/permision.js +42 -1
- package/dist/module/utils/permision.js.map +1 -1
- package/dist/module/utils/reanimated.helper.js +4 -0
- package/dist/module/utils/reanimated.helper.js.map +1 -1
- package/dist/typescript/src/api/api.d.ts.map +1 -1
- package/dist/typescript/src/components/DynamicComponent/Typewriter.d.ts +15 -0
- package/dist/typescript/src/components/DynamicComponent/Typewriter.d.ts.map +1 -0
- package/dist/typescript/src/components/Embed/EmbedButton.d.ts +7 -1
- package/dist/typescript/src/components/Embed/EmbedButton.d.ts.map +1 -1
- package/dist/typescript/src/components/styles/EmbedButton.style.d.ts +22 -114
- package/dist/typescript/src/components/styles/EmbedButton.style.d.ts.map +1 -1
- package/dist/typescript/src/context/EmbedProvider.d.ts +30 -0
- package/dist/typescript/src/context/EmbedProvider.d.ts.map +1 -1
- package/dist/typescript/src/events/__tests__/agent-event-emitter.test.d.ts +5 -0
- package/dist/typescript/src/events/__tests__/agent-event-emitter.test.d.ts.map +1 -0
- package/dist/typescript/src/events/__tests__/clickEventTracker.test.d.ts +5 -0
- package/dist/typescript/src/events/__tests__/clickEventTracker.test.d.ts.map +1 -0
- package/dist/typescript/src/events/__tests__/embed.event.test.d.ts +5 -0
- package/dist/typescript/src/events/__tests__/embed.event.test.d.ts.map +1 -0
- package/dist/typescript/src/events/__tests__/embed.validators.test.d.ts +5 -0
- package/dist/typescript/src/events/__tests__/embed.validators.test.d.ts.map +1 -0
- package/dist/typescript/src/events/clickEventTracker.d.ts +70 -0
- package/dist/typescript/src/events/clickEventTracker.d.ts.map +1 -0
- package/dist/typescript/src/events/embed.event.d.ts.map +1 -1
- package/dist/typescript/src/hooks/EmbedButton.animations.d.ts +29 -6
- package/dist/typescript/src/hooks/EmbedButton.animations.d.ts.map +1 -1
- package/dist/typescript/src/hooks/EmbedButton.helpers.d.ts +60 -8
- package/dist/typescript/src/hooks/EmbedButton.helpers.d.ts.map +1 -1
- package/dist/typescript/src/hooks/EmbedButton.hooks.d.ts +4 -2
- package/dist/typescript/src/hooks/EmbedButton.hooks.d.ts.map +1 -1
- package/dist/typescript/src/hooks/types/voiceAgent.types.d.ts +2 -0
- package/dist/typescript/src/hooks/types/voiceAgent.types.d.ts.map +1 -1
- package/dist/typescript/src/hooks/voiceagent.d.ts.map +1 -1
- package/dist/typescript/src/index.d.ts +8 -9
- package/dist/typescript/src/index.d.ts.map +1 -1
- package/dist/typescript/src/utils/constant.d.ts +1 -1
- package/dist/typescript/src/utils/constant.d.ts.map +1 -1
- package/dist/typescript/src/utils/permision.d.ts.map +1 -1
- package/dist/typescript/src/utils/reanimated.helper.d.ts +2 -0
- package/dist/typescript/src/utils/reanimated.helper.d.ts.map +1 -1
- package/package.json +3 -8
- package/react-native.config.js +1 -0
- package/revrag-ai-embed-react-native.podspec +1 -0
- package/src/assets/fonts/PlaywriteNZBasic-ExtraLight.ttf +0 -0
- package/src/assets/fonts/PlaywriteNZBasic-Light.ttf +0 -0
- package/src/assets/fonts/PlaywriteNZBasic-Regular.ttf +0 -0
- package/src/assets/fonts/PlaywriteNZBasic-Thin.ttf +0 -0
|
@@ -5,17 +5,19 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.EmbedButton = EmbedButton;
|
|
7
7
|
exports.default = void 0;
|
|
8
|
+
var _livekitClient = require("livekit-client");
|
|
8
9
|
var _lottieReactNative = _interopRequireDefault(require("lottie-react-native"));
|
|
9
10
|
var _react = require("react");
|
|
10
11
|
var _reactNative = require("react-native");
|
|
11
12
|
var _reactNativeGestureHandler = require("react-native-gesture-handler");
|
|
12
13
|
var _reactNativeLinearGradient = _interopRequireDefault(require("react-native-linear-gradient"));
|
|
14
|
+
var _embedEvent = _interopRequireWildcard(require("../../events/embed.event.js"));
|
|
13
15
|
var _voiceagent = require("../../hooks/voiceagent.js");
|
|
14
16
|
var _EmbedButtonStyle = require("../styles/EmbedButton.style.js");
|
|
15
17
|
var _EmbedAudioWave = require("./EmbedAudioWave.js");
|
|
16
18
|
var _EmbedVoice = _interopRequireDefault(require("./EmbedVoice.js"));
|
|
17
|
-
var _embedEvent = _interopRequireWildcard(require("../../events/embed.event.js"));
|
|
18
19
|
var _EmbedButtonHelpers = require("../../hooks/EmbedButton.helpers.js");
|
|
20
|
+
var _Typewriter = _interopRequireDefault(require("../DynamicComponent/Typewriter.js"));
|
|
19
21
|
var _EmbedButtonHooks = require("../../hooks/EmbedButton.hooks.js");
|
|
20
22
|
var _EmbedButtonAnimations = require("../../hooks/EmbedButton.animations.js");
|
|
21
23
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -50,35 +52,57 @@ const defaultStyles = {
|
|
|
50
52
|
};
|
|
51
53
|
|
|
52
54
|
// ==================== MAIN COMPONENT ====================
|
|
55
|
+
|
|
53
56
|
/**
|
|
54
57
|
* EmbedButton - Main voice agent floating action button
|
|
55
58
|
*
|
|
56
59
|
* @example
|
|
57
60
|
* ```tsx
|
|
58
61
|
* <EmbedButton />
|
|
62
|
+
* <EmbedButton containerInset={{ right: 16, bottom: 24 }} />
|
|
59
63
|
* ```
|
|
60
64
|
*/
|
|
61
|
-
function EmbedButton(
|
|
65
|
+
function EmbedButton({
|
|
66
|
+
containerInset
|
|
67
|
+
} = {}) {
|
|
62
68
|
// ==================== VOICE AGENT STATE ====================
|
|
63
69
|
const {
|
|
64
|
-
initializeVoiceAgent,
|
|
65
70
|
tokenDetails,
|
|
66
|
-
endCall,
|
|
67
71
|
isLoading,
|
|
68
72
|
isMicMuted,
|
|
73
|
+
connectionState,
|
|
74
|
+
roomRef,
|
|
69
75
|
muteMic,
|
|
76
|
+
endCall,
|
|
70
77
|
unmuteMic,
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
clearDataReceived,
|
|
79
|
+
dataTranscription: livekitData,
|
|
80
|
+
initializeVoiceAgent
|
|
73
81
|
} = (0, _voiceagent.useVoiceAgent)();
|
|
74
82
|
|
|
75
83
|
// ==================== LOCAL STATE ====================
|
|
76
84
|
const [isOpen, setIsOpen] = (0, _react.useState)(false);
|
|
85
|
+
const [expandDirection, setExpandDirection] = (0, _react.useState)('right');
|
|
77
86
|
const lottieRef = (0, _react.useRef)(null);
|
|
78
|
-
const
|
|
87
|
+
const calculationScrollRef = (0, _react.useRef)(null);
|
|
88
|
+
const userScrolledUpRef = (0, _react.useRef)(false);
|
|
89
|
+
const SCROLL_END_THRESHOLD = 20;
|
|
90
|
+
|
|
91
|
+
// Reset "user scrolled up" when calculation content changes so new content auto-scrolls to bottom
|
|
92
|
+
(0, _react.useEffect)(() => {
|
|
93
|
+
if (livekitData?.type === 'calculation') {
|
|
94
|
+
userScrolledUpRef.current = false;
|
|
95
|
+
}
|
|
96
|
+
}, [livekitData?.list, livekitData?.type]);
|
|
79
97
|
|
|
80
98
|
// ==================== CUSTOM HOOKS ====================
|
|
81
99
|
const configData = (0, _EmbedButtonHooks.useConfigData)();
|
|
100
|
+
const styles = (0, _react.useMemo)(() => (0, _EmbedButtonStyle.createEmbedButtonStyles)({
|
|
101
|
+
...defaultStyles,
|
|
102
|
+
...(containerInset != null && {
|
|
103
|
+
containerInset
|
|
104
|
+
})
|
|
105
|
+
}, configData), [configData, containerInset]);
|
|
82
106
|
const {
|
|
83
107
|
callDuration,
|
|
84
108
|
resetDuration
|
|
@@ -88,13 +112,14 @@ function EmbedButton() {
|
|
|
88
112
|
handleEndCall,
|
|
89
113
|
handleMicToggle
|
|
90
114
|
} = (0, _EmbedButtonHooks.useCallManagement)({
|
|
91
|
-
|
|
115
|
+
isOpen,
|
|
116
|
+
isMicMuted,
|
|
92
117
|
endCall,
|
|
93
118
|
muteMic,
|
|
119
|
+
setIsOpen,
|
|
94
120
|
unmuteMic,
|
|
95
|
-
isMicMuted,
|
|
96
121
|
resetDuration,
|
|
97
|
-
|
|
122
|
+
initializeVoiceAgent
|
|
98
123
|
});
|
|
99
124
|
const {
|
|
100
125
|
isAutoOpen,
|
|
@@ -115,86 +140,175 @@ function EmbedButton() {
|
|
|
115
140
|
start,
|
|
116
141
|
menuAnimation,
|
|
117
142
|
buttonWidth,
|
|
118
|
-
buttonScale
|
|
143
|
+
buttonScale,
|
|
144
|
+
buttonHeight,
|
|
145
|
+
inputSectionProgress
|
|
119
146
|
} = animationValues;
|
|
120
|
-
(0, _EmbedButtonAnimations.useButtonAnimations)(isOpen, menuAnimation, buttonWidth);
|
|
147
|
+
(0, _EmbedButtonAnimations.useButtonAnimations)(isOpen || livekitData && Object.keys(livekitData).length > 0, menuAnimation, buttonWidth, offset, start, expandDirection);
|
|
148
|
+
(0, _EmbedButtonAnimations.useInputSectionAnimations)(livekitData && Object.keys(livekitData).length > 0, inputSectionProgress, buttonHeight);
|
|
121
149
|
(0, _EmbedButtonAnimations.useBreathingAnimation)(isOpen, isAutoOpen, buttonScale);
|
|
122
|
-
const buttonAnimatedStyles = (0, _EmbedButtonAnimations.useButtonAnimatedStyles)(isOpen, offset, buttonWidth, isPressed, buttonScale);
|
|
123
|
-
const
|
|
124
|
-
const
|
|
150
|
+
const buttonAnimatedStyles = (0, _EmbedButtonAnimations.useButtonAnimatedStyles)(isOpen, offset, buttonWidth, isPressed, buttonScale, buttonHeight);
|
|
151
|
+
const expandedContentAnimatedStyles = (0, _EmbedButtonAnimations.useExpandedContentAnimatedStyles)(menuAnimation);
|
|
152
|
+
const popupAnimatedStyles = (0, _EmbedButtonAnimations.usePopupAnimatedStyles)(offset, isPressed, expandDirection);
|
|
153
|
+
const panGesture = (0, _react.useMemo)(() => (0, _EmbedButtonAnimations.createPanGesture)(isPressed, offset, start, isOpen, setIsAutoOpen, setExpandDirection), [isPressed, offset, start, isOpen, setIsAutoOpen]);
|
|
125
154
|
|
|
126
155
|
// ==================== AGENT EVENT EMISSIONS ====================
|
|
127
156
|
// Emit agent connected/disconnected events based on connection state
|
|
157
|
+
// Track previous connection state to properly detect disconnection
|
|
158
|
+
const prevConnectionStateRef = (0, _react.useRef)(connectionState);
|
|
159
|
+
const lastEmittedEventRef = (0, _react.useRef)(null);
|
|
128
160
|
(0, _react.useEffect)(() => {
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
});
|
|
137
|
-
} else if (connectionState === 'disconnected' && callDuration > 0) {
|
|
138
|
-
// Only emit disconnected if we were previously connected
|
|
139
|
-
await _embedEvent.default.event.emit(_embedEvent.AgentEvent.AGENT_DISCONNECTED, {
|
|
140
|
-
timestamp: new Date().toISOString(),
|
|
141
|
-
metadata: {
|
|
142
|
-
callDuration
|
|
143
|
-
}
|
|
144
|
-
});
|
|
161
|
+
const prevState = prevConnectionStateRef.current;
|
|
162
|
+
|
|
163
|
+
// Check if we should emit connected event
|
|
164
|
+
if (connectionState === _livekitClient.ConnectionState.Connected && prevState !== _livekitClient.ConnectionState.Connected) {
|
|
165
|
+
// Prevent duplicate connected events
|
|
166
|
+
if (lastEmittedEventRef.current?.type === 'connected' && lastEmittedEventRef.current?.state === connectionState) {
|
|
167
|
+
return;
|
|
145
168
|
}
|
|
146
|
-
};
|
|
147
|
-
emitConnectionEvent().catch(error => {
|
|
148
|
-
console.error('Error emitting connection event:', error);
|
|
149
|
-
});
|
|
150
|
-
}, [connectionState]);
|
|
151
169
|
|
|
152
|
-
|
|
170
|
+
// Update refs IMMEDIATELY (synchronously) before async emit
|
|
171
|
+
prevConnectionStateRef.current = connectionState;
|
|
172
|
+
lastEmittedEventRef.current = {
|
|
173
|
+
type: 'connected',
|
|
174
|
+
state: connectionState
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// Emit connected when entering Connected state
|
|
178
|
+
_embedEvent.default.event.emit(_embedEvent.AgentEvent.AGENT_CONNECTED, {
|
|
179
|
+
timestamp: new Date().toISOString(),
|
|
180
|
+
metadata: {
|
|
181
|
+
callDuration: 0
|
|
182
|
+
}
|
|
183
|
+
}).catch(error => {
|
|
184
|
+
console.error('Error emitting connected event:', error);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Send analytics to backend when agent conversation has started (connected)
|
|
188
|
+
_embedEvent.default.Event(_embedEvent.EventKeys.ANALYTICS_DATA, {
|
|
189
|
+
event_name: 'agent_conversation_started'
|
|
190
|
+
}).catch(error => {
|
|
191
|
+
console.error('Error sending agent_conversation_started analytics:', error);
|
|
192
|
+
});
|
|
193
|
+
} else if (prevState === _livekitClient.ConnectionState.Connected && connectionState !== _livekitClient.ConnectionState.Connected) {
|
|
194
|
+
// Prevent duplicate disconnected events
|
|
195
|
+
if (lastEmittedEventRef.current?.type === 'disconnected') {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Update refs IMMEDIATELY (synchronously) before async emit
|
|
200
|
+
prevConnectionStateRef.current = connectionState;
|
|
201
|
+
lastEmittedEventRef.current = {
|
|
202
|
+
type: 'disconnected',
|
|
203
|
+
state: connectionState
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// Emit disconnected when LEAVING Connected state (to Connecting or Disconnected)
|
|
207
|
+
// This catches the transition: Connected -> Connecting -> Disconnected
|
|
208
|
+
_embedEvent.default.event.emit(_embedEvent.AgentEvent.AGENT_DISCONNECTED, {
|
|
209
|
+
timestamp: new Date().toISOString(),
|
|
210
|
+
metadata: {
|
|
211
|
+
callDuration
|
|
212
|
+
}
|
|
213
|
+
}).catch(error => {
|
|
214
|
+
console.error('Error emitting disconnected event:', error);
|
|
215
|
+
});
|
|
216
|
+
} else {
|
|
217
|
+
// Update previous state for other transitions
|
|
218
|
+
prevConnectionStateRef.current = connectionState;
|
|
219
|
+
}
|
|
220
|
+
}, [connectionState, callDuration]); // Include callDuration to get fresh value
|
|
221
|
+
|
|
222
|
+
// Emit popup_message_visible when the popup is actually shown (isAutoOpen && !isOpen)
|
|
153
223
|
(0, _react.useEffect)(() => {
|
|
224
|
+
const popupVisible = isAutoOpen && !isOpen;
|
|
225
|
+
if (!popupVisible) return;
|
|
154
226
|
const emitPopupEvent = async () => {
|
|
155
|
-
await _embedEvent.default.
|
|
156
|
-
|
|
227
|
+
await _embedEvent.default.Event(_embedEvent.EventKeys.ANALYTICS_DATA, {
|
|
228
|
+
event_name: 'popup_message_visible',
|
|
157
229
|
metadata: {
|
|
158
|
-
|
|
230
|
+
value: true,
|
|
231
|
+
trigger: 'auto_inactivity'
|
|
159
232
|
}
|
|
160
233
|
});
|
|
161
234
|
};
|
|
162
235
|
emitPopupEvent().catch(error => {
|
|
163
236
|
console.error('Error emitting popup visibility event:', error);
|
|
164
237
|
});
|
|
165
|
-
}, [isAutoOpen]);
|
|
238
|
+
}, [isAutoOpen, isOpen]);
|
|
239
|
+
|
|
240
|
+
// Emit gen_tool_triggered analytics when livekit data is first received
|
|
241
|
+
const prevLivekitDataRef = (0, _react.useRef)(false);
|
|
242
|
+
(0, _react.useEffect)(() => {
|
|
243
|
+
const isLivekitData = livekitData && Object.keys(livekitData).length > 0;
|
|
244
|
+
if (isLivekitData && !prevLivekitDataRef.current) {
|
|
245
|
+
prevLivekitDataRef.current = true;
|
|
246
|
+
_embedEvent.default.Event(_embedEvent.EventKeys.ANALYTICS_DATA, {
|
|
247
|
+
event_name: 'gen_tool_triggered',
|
|
248
|
+
metadata: {
|
|
249
|
+
source: 'livekit_data'
|
|
250
|
+
}
|
|
251
|
+
}).catch(error => {
|
|
252
|
+
console.error('Error sending gen_tool_triggered analytics:', error);
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
if (!isLivekitData) {
|
|
256
|
+
prevLivekitDataRef.current = false;
|
|
257
|
+
}
|
|
258
|
+
}, [livekitData]);
|
|
166
259
|
|
|
167
260
|
// ==================== HANDLERS ====================
|
|
168
|
-
const handleButtonPress = () => {
|
|
169
|
-
|
|
261
|
+
const handleButtonPress = (0, _react.useCallback)(async () => {
|
|
262
|
+
const eventName = isOpen ? 'agent_tap_to_close' : 'agent_tap_to_open';
|
|
263
|
+
try {
|
|
264
|
+
await _embedEvent.default.Event(_embedEvent.EventKeys.ANALYTICS_DATA, {
|
|
265
|
+
event_name: eventName,
|
|
266
|
+
metadata: {
|
|
267
|
+
button_pressed: 'button_pressed'
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
} catch (error) {
|
|
271
|
+
console.error('Error sending button_pressed analytics:', error);
|
|
272
|
+
}
|
|
273
|
+
setIsOpen(prev => !prev);
|
|
170
274
|
setIsAutoOpen(false);
|
|
171
|
-
};
|
|
172
|
-
const handleConnected = () => {
|
|
173
|
-
//
|
|
174
|
-
};
|
|
275
|
+
}, [isOpen, setIsAutoOpen]);
|
|
276
|
+
const handleConnected = (0, _react.useCallback)(() => {
|
|
277
|
+
// Reserved for connection success side effects (e.g. analytics)
|
|
278
|
+
}, []);
|
|
175
279
|
|
|
176
280
|
// ==================== COMPUTED VALUES ====================
|
|
177
281
|
const lottieSource = (0, _react.useMemo)(() => ({
|
|
178
|
-
uri: configData?.
|
|
179
|
-
}), [configData?.
|
|
282
|
+
uri: configData?.agentAvatar?.avatarUrl || _EmbedButtonHelpers.ICON_URLS.AMPLIFY_ANIMATION
|
|
283
|
+
}), [configData?.agentAvatar?.avatarUrl]);
|
|
284
|
+
const micIconSource = (0, _react.useMemo)(() => ({
|
|
285
|
+
uri: isMicMuted ? _EmbedButtonHelpers.ICON_URLS.MIC_OFF : _EmbedButtonHelpers.ICON_URLS.MIC_ON
|
|
286
|
+
}), [isMicMuted]);
|
|
180
287
|
const statusText = (0, _react.useMemo)(() => {
|
|
181
288
|
if (isLoading) return 'Connecting...';
|
|
182
289
|
if (tokenDetails?.token) return (0, _EmbedButtonHelpers.formatDuration)(callDuration);
|
|
183
|
-
return configData?.
|
|
184
|
-
}, [isLoading, tokenDetails?.token, callDuration, configData?.
|
|
185
|
-
const gradientColors = configData?.
|
|
186
|
-
const agentName = configData?.
|
|
187
|
-
const popupText = configData?.
|
|
188
|
-
const connectButtonText = configData?.
|
|
290
|
+
return configData?.agentTextContent?.agentType ?? 'Onboarding Agent';
|
|
291
|
+
}, [isLoading, tokenDetails?.token, callDuration, configData?.agentTextContent?.agentType]);
|
|
292
|
+
const gradientColors = configData?.colorPalette?.grad1 != null && configData?.colorPalette?.grad2 != null ? [configData.colorPalette.grad1, configData.colorPalette.grad2] : configData?.colorPalette?.grad1 != null && configData?.colorPalette?.grad2 != null ? [configData.colorPalette.grad1, configData.colorPalette.grad2] : _EmbedButtonHelpers.DEFAULT_GRADIENT_COLORS;
|
|
293
|
+
const agentName = configData?.agentTextContent?.agentName ?? 'Your AI Agent';
|
|
294
|
+
const popupText = configData?.collapsedView?.tooltipMessage ?? 'Any doubts? Ask agent now';
|
|
295
|
+
const connectButtonText = configData?.agentTextContent?.buttonText ?? 'Start Call';
|
|
296
|
+
const isLivekitData = livekitData && Object.keys(livekitData).length > 0;
|
|
297
|
+
const gradientStyle = (0, _react.useMemo)(() => [styles.linearGradient, isLivekitData ? styles.linearGradientColumn : isOpen ? styles.expandedLinearGradient : styles.collapsedLinearGradient], [isOpen, isLivekitData, styles]);
|
|
298
|
+
const isConnected = !!tokenDetails?.token;
|
|
189
299
|
|
|
190
300
|
// ==================== EARLY RETURNS ====================
|
|
191
301
|
if (!configData) return null;
|
|
192
302
|
|
|
193
303
|
// ==================== RENDER ====================
|
|
194
304
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
195
|
-
style: styles.container,
|
|
305
|
+
style: [styles.container, isLivekitData && {
|
|
306
|
+
bottom: _EmbedButtonHelpers.FOOTER_SAFE_INSET
|
|
307
|
+
}],
|
|
196
308
|
children: [isAutoOpen && !isOpen && /*#__PURE__*/(0, _jsxRuntime.jsx)(_EmbedButtonAnimations.Animated.View, {
|
|
197
309
|
style: [popupAnimatedStyles, styles.popupContainer],
|
|
310
|
+
accessibilityLabel: popupText,
|
|
311
|
+
accessibilityLiveRegion: "polite",
|
|
198
312
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
199
313
|
style: styles.popupText,
|
|
200
314
|
children: popupText
|
|
@@ -203,7 +317,7 @@ function EmbedButton() {
|
|
|
203
317
|
gesture: panGesture,
|
|
204
318
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_EmbedButtonAnimations.Animated.View, {
|
|
205
319
|
pointerEvents: "auto",
|
|
206
|
-
style: [styles.button, buttonAnimatedStyles, styles.buttonContent],
|
|
320
|
+
style: [styles.button, buttonAnimatedStyles, isLivekitData ? styles.expandedButtonWhite : styles.buttonContent],
|
|
207
321
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeLinearGradient.default, {
|
|
208
322
|
colors: gradientColors,
|
|
209
323
|
start: {
|
|
@@ -214,7 +328,7 @@ function EmbedButton() {
|
|
|
214
328
|
x: 1,
|
|
215
329
|
y: 0
|
|
216
330
|
},
|
|
217
|
-
style:
|
|
331
|
+
style: gradientStyle,
|
|
218
332
|
angle: 0,
|
|
219
333
|
angleCenter: {
|
|
220
334
|
x: 0.5,
|
|
@@ -226,67 +340,202 @@ function EmbedButton() {
|
|
|
226
340
|
onDisconnected: handleEndCall,
|
|
227
341
|
roomRef: roomRef,
|
|
228
342
|
onConnected: handleConnected
|
|
229
|
-
}), /*#__PURE__*/(0, _jsxRuntime.
|
|
230
|
-
|
|
231
|
-
style: styles.pressable,
|
|
232
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_lottieReactNative.default, {
|
|
233
|
-
ref: lottieRef,
|
|
234
|
-
source: lottieSource,
|
|
235
|
-
autoPlay: true,
|
|
236
|
-
loop: true,
|
|
237
|
-
style: styles.iconImage,
|
|
238
|
-
enableMergePathsAndroidForKitKatAndAbove: true,
|
|
239
|
-
enableSafeModeAndroid: true
|
|
240
|
-
})
|
|
241
|
-
}), isOpen && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
242
|
-
style: styles.expandedContentContainer,
|
|
343
|
+
}), isLivekitData ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
344
|
+
style: styles.expandedCallViewWrapper,
|
|
243
345
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
244
|
-
style: styles.
|
|
245
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
children:
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
roomRef: roomRef
|
|
256
|
-
})
|
|
257
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
258
|
-
style: styles.rightContentSection,
|
|
259
|
-
children: [!tokenDetails?.token && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
260
|
-
style: styles.buttonContainer,
|
|
261
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
262
|
-
onPress: handleStartCall,
|
|
263
|
-
style: styles.startCallButton,
|
|
264
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
265
|
-
style: styles.startCallText,
|
|
266
|
-
children: connectButtonText
|
|
267
|
-
})
|
|
346
|
+
style: styles.callContentArea,
|
|
347
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
348
|
+
onPress: () => clearDataReceived(),
|
|
349
|
+
style: styles.closeButton,
|
|
350
|
+
accessibilityLabel: "Close",
|
|
351
|
+
accessibilityRole: "button",
|
|
352
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
353
|
+
source: {
|
|
354
|
+
uri: _EmbedButtonHelpers.ICON_URLS.CLOSE_ICON
|
|
355
|
+
},
|
|
356
|
+
style: styles.popupCloseIcon
|
|
268
357
|
})
|
|
269
|
-
}),
|
|
270
|
-
style: styles.
|
|
271
|
-
children:
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
358
|
+
}), livekitData.type === 'calculation' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
359
|
+
style: styles.callContentTextContainer,
|
|
360
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.ScrollView, {
|
|
361
|
+
ref: calculationScrollRef,
|
|
362
|
+
style: styles.callContentScrollView,
|
|
363
|
+
contentContainerStyle: styles.callContentScrollViewContent,
|
|
364
|
+
showsVerticalScrollIndicator: true,
|
|
365
|
+
bounces: false,
|
|
366
|
+
nestedScrollEnabled: true,
|
|
367
|
+
onScroll: e => {
|
|
368
|
+
const {
|
|
369
|
+
contentOffset,
|
|
370
|
+
contentSize,
|
|
371
|
+
layoutMeasurement
|
|
372
|
+
} = e.nativeEvent;
|
|
373
|
+
const isAtBottom = contentOffset.y + layoutMeasurement.height >= contentSize.height - SCROLL_END_THRESHOLD;
|
|
374
|
+
userScrolledUpRef.current = !isAtBottom;
|
|
375
|
+
},
|
|
376
|
+
onContentSizeChange: () => {
|
|
377
|
+
if (!userScrolledUpRef.current) {
|
|
378
|
+
calculationScrollRef.current?.scrollToEnd({
|
|
379
|
+
animated: true
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Typewriter.default, {
|
|
384
|
+
lines: Array.isArray(livekitData.list) ? livekitData.list : [],
|
|
385
|
+
typingSpeed: 50,
|
|
386
|
+
textStyle: styles.callContentText,
|
|
387
|
+
showCursor: false,
|
|
388
|
+
onViewClose: flag => {
|
|
389
|
+
if (flag) {
|
|
390
|
+
clearDataReceived();
|
|
391
|
+
}
|
|
277
392
|
},
|
|
278
|
-
|
|
393
|
+
viewCloseDelay: livekitData.delay || 15000
|
|
279
394
|
})
|
|
280
|
-
})
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
395
|
+
})
|
|
396
|
+
})]
|
|
397
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
398
|
+
style: styles.expandedContentContainer,
|
|
399
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
400
|
+
onPress: handleButtonPress,
|
|
401
|
+
style: styles.pressable,
|
|
402
|
+
children: configData?.agentAvatar?.avatarType === 'image' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
403
|
+
source: {
|
|
404
|
+
uri: configData?.agentAvatar?.avatarUrl
|
|
405
|
+
},
|
|
406
|
+
style: styles.iconImage
|
|
407
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_lottieReactNative.default, {
|
|
408
|
+
ref: lottieRef,
|
|
409
|
+
source: lottieSource,
|
|
410
|
+
autoPlay: true,
|
|
411
|
+
loop: true,
|
|
412
|
+
style: styles.iconImage,
|
|
413
|
+
enableMergePathsAndroidForKitKatAndAbove: true,
|
|
414
|
+
enableSafeModeAndroid: true
|
|
415
|
+
})
|
|
416
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
417
|
+
style: styles.leftContentSection,
|
|
418
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
419
|
+
style: [styles.agentNameText, styles.leftAlignedText],
|
|
420
|
+
numberOfLines: 1,
|
|
421
|
+
ellipsizeMode: "tail",
|
|
422
|
+
children: agentName
|
|
423
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
424
|
+
style: [styles.leftAlignedText, styles.statusText],
|
|
425
|
+
numberOfLines: 1,
|
|
426
|
+
ellipsizeMode: "tail",
|
|
427
|
+
children: statusText
|
|
428
|
+
})]
|
|
429
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
430
|
+
style: styles.middleContentSection,
|
|
431
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_EmbedAudioWave.WaveformVisualizer, {
|
|
432
|
+
roomRef: roomRef
|
|
433
|
+
})
|
|
434
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
435
|
+
style: [styles.rightContentSection, styles.rightContentSectionPadded],
|
|
436
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
437
|
+
style: styles.buttonContainer,
|
|
438
|
+
children: !isConnected ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
439
|
+
onPress: handleStartCall,
|
|
440
|
+
style: styles.startCallButton,
|
|
441
|
+
accessibilityLabel: `Start call - ${connectButtonText}`,
|
|
442
|
+
accessibilityRole: "button",
|
|
443
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
444
|
+
style: styles.startCallText,
|
|
445
|
+
children: connectButtonText
|
|
446
|
+
})
|
|
447
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
448
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
449
|
+
style: styles.muteButton,
|
|
450
|
+
onPress: handleMicToggle,
|
|
451
|
+
accessibilityLabel: isMicMuted ? 'Unmute microphone' : 'Mute microphone',
|
|
452
|
+
accessibilityRole: "button",
|
|
453
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
454
|
+
source: micIconSource,
|
|
455
|
+
style: styles.buttonImage
|
|
456
|
+
})
|
|
457
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
458
|
+
onPress: handleEndCall,
|
|
459
|
+
style: styles.endCallButton,
|
|
460
|
+
accessibilityLabel: "End call",
|
|
461
|
+
accessibilityRole: "button",
|
|
462
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
463
|
+
source: {
|
|
464
|
+
uri: _EmbedButtonHelpers.ICON_URLS.END_CALL
|
|
465
|
+
},
|
|
466
|
+
style: styles.buttonImage
|
|
467
|
+
})
|
|
468
|
+
})]
|
|
288
469
|
})
|
|
470
|
+
})
|
|
471
|
+
})]
|
|
472
|
+
})]
|
|
473
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
474
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
475
|
+
onPress: handleButtonPress,
|
|
476
|
+
style: styles.pressable,
|
|
477
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_lottieReactNative.default, {
|
|
478
|
+
ref: lottieRef,
|
|
479
|
+
source: lottieSource,
|
|
480
|
+
autoPlay: true,
|
|
481
|
+
loop: true,
|
|
482
|
+
style: styles.iconImage,
|
|
483
|
+
enableMergePathsAndroidForKitKatAndAbove: true,
|
|
484
|
+
enableSafeModeAndroid: true
|
|
485
|
+
})
|
|
486
|
+
}), isOpen && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_EmbedButtonAnimations.Animated.View, {
|
|
487
|
+
style: [styles.expandedContentContainer, expandedContentAnimatedStyles],
|
|
488
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
489
|
+
style: styles.leftContentSection,
|
|
490
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
491
|
+
style: [styles.agentNameText, styles.leftAlignedText],
|
|
492
|
+
children: agentName
|
|
493
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
494
|
+
style: [styles.leftAlignedText, styles.statusText],
|
|
495
|
+
children: statusText
|
|
289
496
|
})]
|
|
497
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
498
|
+
style: styles.middleContentSection,
|
|
499
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_EmbedAudioWave.WaveformVisualizer, {
|
|
500
|
+
roomRef: roomRef
|
|
501
|
+
})
|
|
502
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
503
|
+
style: styles.rightContentSection,
|
|
504
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
505
|
+
style: styles.buttonContainer,
|
|
506
|
+
children: !isConnected ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
507
|
+
onPress: handleStartCall,
|
|
508
|
+
style: styles.startCallButton,
|
|
509
|
+
accessibilityLabel: `Start call - ${connectButtonText}`,
|
|
510
|
+
accessibilityRole: "button",
|
|
511
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
512
|
+
style: styles.startCallText,
|
|
513
|
+
children: connectButtonText
|
|
514
|
+
})
|
|
515
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
516
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
517
|
+
style: styles.muteButton,
|
|
518
|
+
onPress: handleMicToggle,
|
|
519
|
+
accessibilityLabel: isMicMuted ? 'Unmute microphone' : 'Mute microphone',
|
|
520
|
+
accessibilityRole: "button",
|
|
521
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
522
|
+
source: micIconSource,
|
|
523
|
+
style: styles.buttonImage
|
|
524
|
+
})
|
|
525
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
526
|
+
onPress: handleEndCall,
|
|
527
|
+
style: styles.endCallButton,
|
|
528
|
+
accessibilityLabel: "End call",
|
|
529
|
+
accessibilityRole: "button",
|
|
530
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
531
|
+
source: {
|
|
532
|
+
uri: _EmbedButtonHelpers.ICON_URLS.END_CALL
|
|
533
|
+
},
|
|
534
|
+
style: styles.buttonImage
|
|
535
|
+
})
|
|
536
|
+
})]
|
|
537
|
+
})
|
|
538
|
+
})
|
|
290
539
|
})]
|
|
291
540
|
})]
|
|
292
541
|
})]
|