@revrag-ai/embed-react-native 1.0.16 → 1.0.17

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.
Files changed (93) hide show
  1. package/README.md +6 -108
  2. package/dist/commonjs/api/api.js +6 -5
  3. package/dist/commonjs/api/api.js.map +1 -1
  4. package/dist/commonjs/components/Embed/EmbedButton.js +138 -345
  5. package/dist/commonjs/components/Embed/EmbedButton.js.map +1 -1
  6. package/dist/commonjs/components/Embed/EmbedVoice.js +16 -4
  7. package/dist/commonjs/components/Embed/EmbedVoice.js.map +1 -1
  8. package/dist/commonjs/context/EmbedProvider.js +638 -0
  9. package/dist/commonjs/context/EmbedProvider.js.map +1 -0
  10. package/dist/commonjs/events/embed.event.js +141 -54
  11. package/dist/commonjs/events/embed.event.js.map +1 -1
  12. package/dist/commonjs/hooks/EmbedButton.animations.js +181 -0
  13. package/dist/commonjs/hooks/EmbedButton.animations.js.map +1 -0
  14. package/dist/commonjs/hooks/EmbedButton.helpers.js +90 -0
  15. package/dist/commonjs/hooks/EmbedButton.helpers.js.map +1 -0
  16. package/dist/commonjs/hooks/EmbedButton.hooks.js +165 -0
  17. package/dist/commonjs/hooks/EmbedButton.hooks.js.map +1 -0
  18. package/dist/commonjs/hooks/initialize.js +65 -25
  19. package/dist/commonjs/hooks/initialize.js.map +1 -1
  20. package/dist/commonjs/hooks/voiceagent.js +1 -18
  21. package/dist/commonjs/hooks/voiceagent.js.map +1 -1
  22. package/dist/commonjs/index.js +16 -1
  23. package/dist/commonjs/index.js.map +1 -1
  24. package/dist/commonjs/index.types.js +1 -2
  25. package/dist/commonjs/index.types.js.map +1 -1
  26. package/dist/commonjs/utils/constant.js +88 -0
  27. package/dist/commonjs/utils/constant.js.map +1 -0
  28. package/dist/commonjs/utils/reanimated.helper.js +2 -3
  29. package/dist/commonjs/utils/reanimated.helper.js.map +1 -1
  30. package/dist/module/api/api.js +6 -6
  31. package/dist/module/api/api.js.map +1 -1
  32. package/dist/module/components/Embed/EmbedButton.js +140 -347
  33. package/dist/module/components/Embed/EmbedButton.js.map +1 -1
  34. package/dist/module/components/Embed/EmbedVoice.js +16 -4
  35. package/dist/module/components/Embed/EmbedVoice.js.map +1 -1
  36. package/dist/module/context/EmbedProvider.js +626 -0
  37. package/dist/module/context/EmbedProvider.js.map +1 -0
  38. package/dist/module/events/embed.event.js +143 -53
  39. package/dist/module/events/embed.event.js.map +1 -1
  40. package/dist/module/hooks/EmbedButton.animations.js +172 -0
  41. package/dist/module/hooks/EmbedButton.animations.js.map +1 -0
  42. package/dist/module/hooks/EmbedButton.helpers.js +80 -0
  43. package/dist/module/hooks/EmbedButton.helpers.js.map +1 -0
  44. package/dist/module/hooks/EmbedButton.hooks.js +160 -0
  45. package/dist/module/hooks/EmbedButton.hooks.js.map +1 -0
  46. package/dist/module/hooks/initialize.js +66 -26
  47. package/dist/module/hooks/initialize.js.map +1 -1
  48. package/dist/module/hooks/voiceagent.js +1 -17
  49. package/dist/module/hooks/voiceagent.js.map +1 -1
  50. package/dist/module/index.js +4 -2
  51. package/dist/module/index.js.map +1 -1
  52. package/dist/module/index.types.js +1 -2
  53. package/dist/module/index.types.js.map +1 -1
  54. package/dist/module/utils/constant.js +82 -0
  55. package/dist/module/utils/constant.js.map +1 -0
  56. package/dist/module/utils/reanimated.helper.js +2 -3
  57. package/dist/module/utils/reanimated.helper.js.map +1 -1
  58. package/dist/typescript/src/api/api.d.ts +4 -3
  59. package/dist/typescript/src/api/api.d.ts.map +1 -1
  60. package/dist/typescript/src/api/types/embed.api.types.d.ts +1 -1
  61. package/dist/typescript/src/api/types/embed.api.types.d.ts.map +1 -1
  62. package/dist/typescript/src/components/Embed/EmbedButton.d.ts +5 -25
  63. package/dist/typescript/src/components/Embed/EmbedButton.d.ts.map +1 -1
  64. package/dist/typescript/src/components/Embed/EmbedVoice.d.ts.map +1 -1
  65. package/dist/typescript/src/context/EmbedProvider.d.ts +306 -0
  66. package/dist/typescript/src/context/EmbedProvider.d.ts.map +1 -0
  67. package/dist/typescript/src/events/embed.event.d.ts +74 -10
  68. package/dist/typescript/src/events/embed.event.d.ts.map +1 -1
  69. package/dist/typescript/src/hooks/EmbedButton.animations.d.ts +38 -0
  70. package/dist/typescript/src/hooks/EmbedButton.animations.d.ts.map +1 -0
  71. package/dist/typescript/src/hooks/EmbedButton.helpers.d.ts +49 -0
  72. package/dist/typescript/src/hooks/EmbedButton.helpers.d.ts.map +1 -0
  73. package/dist/typescript/src/hooks/EmbedButton.hooks.d.ts +49 -0
  74. package/dist/typescript/src/hooks/EmbedButton.hooks.d.ts.map +1 -0
  75. package/dist/typescript/src/hooks/initialize.d.ts.map +1 -1
  76. package/dist/typescript/src/hooks/types/initialize.types.d.ts +1 -1
  77. package/dist/typescript/src/hooks/types/initialize.types.d.ts.map +1 -1
  78. package/dist/typescript/src/hooks/voiceagent.d.ts.map +1 -1
  79. package/dist/typescript/src/index.d.ts +10 -4
  80. package/dist/typescript/src/index.d.ts.map +1 -1
  81. package/dist/typescript/src/index.types.d.ts +2 -3
  82. package/dist/typescript/src/index.types.d.ts.map +1 -1
  83. package/dist/typescript/src/utils/constant.d.ts +45 -0
  84. package/dist/typescript/src/utils/constant.d.ts.map +1 -0
  85. package/dist/typescript/src/utils/reanimated.helper.d.ts.map +1 -1
  86. package/package.json +6 -3
  87. package/react-native.config.js +1 -0
  88. package/dist/commonjs/events/eventEmitter.js +0 -43
  89. package/dist/commonjs/events/eventEmitter.js.map +0 -1
  90. package/dist/module/events/eventEmitter.js +0 -39
  91. package/dist/module/events/eventEmitter.js.map +0 -1
  92. package/dist/typescript/src/events/eventEmitter.d.ts +0 -9
  93. package/dist/typescript/src/events/eventEmitter.d.ts.map +0 -1
@@ -11,63 +11,32 @@ var _reactNative = require("react-native");
11
11
  var _reactNativeGestureHandler = require("react-native-gesture-handler");
12
12
  var _reactNativeLinearGradient = _interopRequireDefault(require("react-native-linear-gradient"));
13
13
  var _voiceagent = require("../../hooks/voiceagent.js");
14
- var _storeKey = require("../../store/store.key.js");
15
14
  var _EmbedButtonStyle = require("../styles/EmbedButton.style.js");
16
- var _reanimatedHelper = require("../../utils/reanimated.helper.js");
17
15
  var _EmbedVoice = _interopRequireDefault(require("./EmbedVoice.js"));
18
16
  var _EmbedAudioWave = require("./EmbedAudioWave.js");
19
- var _permision = require("../../utils/permision.js");
20
17
  var _embedEvent = _interopRequireWildcard(require("../../events/embed.event.js"));
18
+ var _EmbedButtonHelpers = require("../../hooks/EmbedButton.helpers.js");
19
+ var _EmbedButtonHooks = require("../../hooks/EmbedButton.hooks.js");
20
+ var _EmbedButtonAnimations = require("../../hooks/EmbedButton.animations.js");
21
21
  var _jsxRuntime = require("react/jsx-runtime");
22
22
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
23
23
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
24
24
  /**
25
- * @file OnwidButton.tsx
26
- * @description A customizable floating action button component for React Native applications.
27
- * This component provides a draggable, expandable button with animation support and gradient styling.
25
+ * @file EmbedButton.tsx
26
+ * @description A customizable floating action button component for voice agent interactions.
27
+ * Features: draggable, expandable, animated, with call controls and auto-trigger support.
28
28
  */
29
29
 
30
- // Get reanimated API with fallbacks
31
- const {
32
- useSharedValue,
33
- useAnimatedStyle,
34
- withTiming,
35
- withSpring,
36
- withRepeat,
37
- withSequence,
38
- runOnJS,
39
- Easing,
40
- Animated,
41
- isAvailable: isReanimatedAvailable
42
- } = (0, _reanimatedHelper.getReanimatedAPI)();
30
+ // Helpers and constants
43
31
 
44
- // Show warning if reanimated is not available
45
- if (!isReanimatedAvailable) {
46
- (0, _reanimatedHelper.showReanimatedSetupError)();
47
- }
48
- const {
49
- width: SCREEN_WIDTH,
50
- height: SCREEN_HEIGHT
51
- } = _reactNative.Dimensions.get('window');
52
- const BUTTON_WIDTH = 60;
53
- const EXPANDED_WIDTH = SCREEN_WIDTH * 0.9;
54
- const BUTTON_HEIGHT = 60;
55
- const GRADIENT_COLORS = ['#1E0844', '#B391F3'];
56
-
57
- // Define mic icons as base64 images for portability
58
- const MIC_ON_ICON = 'https://revrag-dev.s3.ap-south-1.amazonaws.com/Avatars/Mute+button.png';
59
- const MIC_OFF_ICON = 'https://revrag-dev.s3.ap-south-1.amazonaws.com/Avatars/unmute.png';
32
+ // Custom hooks
60
33
 
61
- // Add end call icon
62
- const END_CALL_ICON = 'https://revrag-dev.s3.ap-south-1.amazonaws.com/Avatars/end+button.png';
63
- const AMPLIFY_ANIMATION = 'https://revrag-dev.s3.ap-south-1.amazonaws.com/Avatars/amplify.json';
34
+ // Animation hooks
64
35
 
65
- /**
66
- * Default styles configuration for the button
67
- */
36
+ // ==================== STYLES CONFIG ====================
68
37
  const defaultStyles = {
69
- buttonWidth: 60,
70
- buttonHeight: 60,
38
+ buttonWidth: _EmbedButtonHelpers.BUTTON_DIMENSIONS.WIDTH,
39
+ buttonHeight: _EmbedButtonHelpers.BUTTON_DIMENSIONS.HEIGHT,
71
40
  borderRadius: 100,
72
41
  marginBottom: 20,
73
42
  spacing: {
@@ -80,37 +49,17 @@ const defaultStyles = {
80
49
  }
81
50
  };
82
51
 
52
+ // ==================== MAIN COMPONENT ====================
83
53
  /**
84
- * OnwidButton Component
85
- *
86
- * A floating action button that can be dragged around the screen and expanded to show additional content.
87
- * Features include:
88
- * - Draggable functionality
89
- * - Expandable menu
90
- * - Animated transitions
91
- * - Gradient background
92
- * - Customizable styling
54
+ * EmbedButton - Main voice agent floating action button
93
55
  *
94
- * @component
95
56
  * @example
96
57
  * ```tsx
97
- * <OnwidButton
98
- * isOpen={false}
99
- * onPress={(isOpen) => console.log('Button pressed:', isOpen)}
100
- * menuComponent={<YourMenuComponent />}
101
- * />
58
+ * <EmbedButton />
102
59
  * ```
103
60
  */
104
-
105
- /**
106
- * Generates random sentences for testing or placeholder content
107
- * @param count - Number of sentences to generate (default: 1)
108
- * @param minWords - Minimum words per sentence (default: 5)
109
- * @param maxWords - Maximum words per sentence (default: 15)
110
- * @returns Array of random sentences
111
- */
112
-
113
61
  function EmbedButton() {
62
+ // ==================== VOICE AGENT STATE ====================
114
63
  const {
115
64
  initializeVoiceAgent,
116
65
  tokenDetails,
@@ -120,305 +69,143 @@ function EmbedButton() {
120
69
  muteMic,
121
70
  unmuteMic,
122
71
  connectionState,
123
- roomRef,
124
- getPopupDescription
72
+ roomRef
125
73
  } = (0, _voiceagent.useVoiceAgent)();
126
- // State management
127
- const [configData, setConfigData] = (0, _react.useState)(null);
128
- const [popupDescription, setPopupDescription] = (0, _react.useState)('');
74
+
75
+ // ==================== LOCAL STATE ====================
129
76
  const [isOpen, setIsOpen] = (0, _react.useState)(false);
130
- const [callDuration, setCallDuration] = (0, _react.useState)(0);
131
- const timerRef = (0, _react.useRef)(null);
132
77
  const lottieRef = (0, _react.useRef)(null);
78
+ const styles = (0, _react.useMemo)(() => (0, _EmbedButtonStyle.createEmbedButtonStyles)(defaultStyles), []);
133
79
 
134
- // Track previous states for event emission
135
- const previousIsOpenRef = (0, _react.useRef)(false);
136
- const previousIsAutoOpenRef = (0, _react.useRef)(false);
137
-
138
- // Animation values
139
- const isPressed = useSharedValue(false);
140
- const offset = useSharedValue({
141
- x: 0,
142
- y: 0
80
+ // ==================== CUSTOM HOOKS ====================
81
+ const configData = (0, _EmbedButtonHooks.useConfigData)();
82
+ const {
83
+ callDuration,
84
+ resetDuration
85
+ } = (0, _EmbedButtonHooks.useCallDuration)(connectionState);
86
+ const {
87
+ handleStartCall,
88
+ handleEndCall,
89
+ handleMicToggle
90
+ } = (0, _EmbedButtonHooks.useCallManagement)({
91
+ initializeVoiceAgent,
92
+ endCall,
93
+ muteMic,
94
+ unmuteMic,
95
+ isMicMuted,
96
+ resetDuration,
97
+ setIsOpen
143
98
  });
144
- const start = useSharedValue({
145
- x: 0,
146
- y: 0
99
+ const {
100
+ isAutoOpen,
101
+ setIsAutoOpen
102
+ } = (0, _EmbedButtonHooks.useInactivityBehavior)({
103
+ configData,
104
+ isOpen,
105
+ isLoading,
106
+ hasActiveToken: !!tokenDetails?.token,
107
+ onStartCall: handleStartCall
147
108
  });
148
- const menuAnimation = useSharedValue(0);
149
- const buttonWidth = useSharedValue(BUTTON_WIDTH);
150
- const buttonScale = useSharedValue(1);
151
- // Styles
152
- const styles = (0, _EmbedButtonStyle.createEmbedButtonStyles)(defaultStyles);
153
- const [isAutoOpen, setIsAutoOpen] = (0, _react.useState)(false);
154
-
155
- // Track popup visibility changes and emit events
156
- (0, _react.useEffect)(() => {
157
- const currentPopupVisible = isOpen || isAutoOpen;
158
- const previousPopupVisible = previousIsOpenRef.current || previousIsAutoOpenRef.current;
159
-
160
- // Only trigger when popup visibility actually changes
161
- if (currentPopupVisible !== previousPopupVisible) {
162
- console.log('currentPopupVisible', currentPopupVisible);
163
- _embedEvent.default.event.emit(_embedEvent.AgentEvent.POPUP_MESSAGE_VISIBLE, {
164
- value: currentPopupVisible,
165
- metadata: {
166
- trigger: 'user_interaction'
167
- }
168
- });
169
- // Embed.emitPopupVisibilityChange(currentPopupVisible, 'user_interaction');
170
- }
171
109
 
172
- // Update previous state refs
173
- previousIsOpenRef.current = isOpen;
174
- previousIsAutoOpenRef.current = isAutoOpen;
175
- }, [isOpen, isAutoOpen]);
176
- (0, _react.useEffect)(() => {
177
- const autoOpenTimer = setTimeout(async () => {
178
- if (!isOpen) {
179
- const response = await getPopupDescription();
180
- if (response) {
181
- setPopupDescription(response);
182
- setIsAutoOpen(true);
183
- } else {
184
- // todo: handle no popup description found
185
- console.warn('No popup description found');
186
- }
187
- }
188
- }, 15000); // 15 seconds
189
-
190
- return () => {
191
- clearTimeout(autoOpenTimer);
192
- };
193
- }, [isOpen]);
194
-
195
- /**
196
- * Fetch agent configuration data
197
- */
198
- (0, _react.useEffect)(() => {
199
- const fetchAgentData = async () => {
200
- try {
201
- const data = await (0, _storeKey.getAgentData)('@config_data');
202
- setConfigData(data?.ui_config);
203
- } catch (error) {
204
- // todo: handle error fetching agent data
205
- }
206
- };
207
- fetchAgentData();
208
- }, []);
110
+ // ==================== ANIMATIONS ====================
111
+ const animationValues = (0, _EmbedButtonAnimations.useAnimationValues)();
112
+ const {
113
+ isPressed,
114
+ offset,
115
+ start,
116
+ menuAnimation,
117
+ buttonWidth,
118
+ buttonScale
119
+ } = animationValues;
120
+ (0, _EmbedButtonAnimations.useButtonAnimations)(isOpen, menuAnimation, buttonWidth);
121
+ (0, _EmbedButtonAnimations.useBreathingAnimation)(isOpen, isAutoOpen, buttonScale);
122
+ const buttonAnimatedStyles = (0, _EmbedButtonAnimations.useButtonAnimatedStyles)(isOpen, offset, buttonWidth, isPressed, buttonScale);
123
+ const popupAnimatedStyles = (0, _EmbedButtonAnimations.usePopupAnimatedStyles)(offset, isPressed);
124
+ const panGesture = (0, _react.useMemo)(() => (0, _EmbedButtonAnimations.createPanGesture)(isPressed, offset, start, isOpen, setIsAutoOpen), [isPressed, offset, start, isOpen, setIsAutoOpen]);
209
125
 
210
- /**
211
- * Set up a timer to track call duration when connected
212
- */
126
+ // ==================== AGENT EVENT EMISSIONS ====================
127
+ // Emit agent connected/disconnected events based on connection state
213
128
  (0, _react.useEffect)(() => {
214
- if (connectionState === 'connected' && !timerRef.current) {
215
- timerRef.current = setInterval(() => {
216
- setCallDuration(prev => prev + 1);
217
- }, 1000);
218
- } else if (connectionState !== 'connected' && timerRef.current) {
219
- clearInterval(timerRef.current);
220
- timerRef.current = null;
221
-
222
- // If we were previously connected and now disconnected, show an error
223
- if (callDuration > 0) {
224
- // todo: handle call disconnected
225
- }
226
- }
227
- return () => {
228
- if (timerRef.current) {
229
- clearInterval(timerRef.current);
230
- timerRef.current = null;
129
+ const emitConnectionEvent = async () => {
130
+ if (connectionState === 'connected') {
131
+ await _embedEvent.default.event.emit(_embedEvent.AgentEvent.AGENT_CONNECTED, {
132
+ timestamp: new Date().toISOString(),
133
+ metadata: {
134
+ callDuration: 0
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
+ });
231
145
  }
232
146
  };
233
- }, [connectionState, callDuration]);
234
-
235
- /**
236
- * Handle menu animation and button width transitions
237
- */
238
- (0, _react.useEffect)(() => {
239
- menuAnimation.value = withTiming(isOpen ? 0.8 : 0, {
240
- duration: 300
147
+ emitConnectionEvent().catch(error => {
148
+ console.error('Error emitting connection event:', error);
241
149
  });
242
- buttonWidth.value = withTiming(isOpen ? EXPANDED_WIDTH : BUTTON_WIDTH);
243
- }, [isOpen, menuAnimation, buttonWidth]);
150
+ }, [connectionState, callDuration]);
244
151
 
245
- // Add breathing animation when button is closed but isAutoOpen is true
152
+ // Emit popup visibility events when isAutoOpen changes
246
153
  (0, _react.useEffect)(() => {
247
- if (!isOpen && isAutoOpen) {
248
- // Start breathing animation with faster speed
249
- buttonScale.value = withRepeat(withSequence(withTiming(1.1, {
250
- duration: 1500,
251
- // Reduced from 1000ms to 600ms
252
- easing: Easing.inOut(Easing.ease)
253
- }), withTiming(1, {
254
- duration: 1500,
255
- // Reduced from 1000ms to 600ms
256
- easing: Easing.inOut(Easing.ease)
257
- })), -1,
258
- // Infinite repeat
259
- false // Don't reverse
260
- );
261
- } else {
262
- // Reset animation
263
- buttonScale.value = withTiming(1, {
264
- duration: 300
154
+ const emitPopupEvent = async () => {
155
+ await _embedEvent.default.event.emit(_embedEvent.AgentEvent.POPUP_MESSAGE_VISIBLE, {
156
+ value: isAutoOpen,
157
+ metadata: {
158
+ trigger: isAutoOpen ? 'auto_inactivity' : 'manual_dismiss'
159
+ }
265
160
  });
266
- }
267
- }, [isOpen, isAutoOpen]);
268
-
269
- /**
270
- * Animated styles for the button
271
- */
272
- const animatedStyles = useAnimatedStyle(() => {
273
- const maxX = SCREEN_WIDTH - (isOpen ? EXPANDED_WIDTH : BUTTON_WIDTH) - 35;
274
- const clampedX = Math.min(Math.max(offset.value.x, -maxX), 0);
275
- return {
276
- width: buttonWidth.value,
277
- height: BUTTON_HEIGHT,
278
- transform: [{
279
- translateX: clampedX
280
- }, {
281
- translateY: offset.value.y
282
- }, {
283
- scale: withSpring(isPressed.value ? 0.95 : buttonScale.value)
284
- }],
285
- justifyContent: isOpen ? 'space-between' : 'flex-start',
286
- overflow: 'hidden'
287
- };
288
- });
289
-
290
- /**
291
- * Animated styles for the text
292
- */
293
- const animatedTextStyles = useAnimatedStyle(() => {
294
- const maxX = SCREEN_WIDTH;
295
- const clampedX = Math.min(Math.max(offset.value.x, -maxX), 0);
296
- return {
297
- transform: [{
298
- translateX: clampedX
299
- }, {
300
- translateY: offset.value.y
301
- }, {
302
- scale: withSpring(isPressed.value ? 1 : 1)
303
- }]
304
- };
305
- });
306
-
307
- /**
308
- * Pan gesture handler for drag functionality
309
- */
310
- const gesture = _reactNativeGestureHandler.Gesture.Pan().onBegin(() => {
311
- isPressed.value = true;
312
- if (isAutoOpen) {
313
- runOnJS(setIsAutoOpen)(false);
314
- }
315
- }).onUpdate(e => {
316
- const maxX = SCREEN_WIDTH - (isOpen ? EXPANDED_WIDTH : BUTTON_WIDTH) - 0;
317
- const newX = Math.min(Math.max(e.translationX + start.value.x, -maxX), 0);
318
- const maxY = SCREEN_HEIGHT - 150;
319
- const newY = Math.min(Math.max(e.translationY + start.value.y, -maxY), 0);
320
- offset.value = {
321
- x: newX,
322
- y: newY
323
161
  };
324
- }).onEnd(() => {
325
- start.value = {
326
- x: offset.value.x,
327
- y: offset.value.y
328
- };
329
- }).onFinalize(() => {
330
- isPressed.value = false;
331
- });
162
+ emitPopupEvent().catch(error => {
163
+ console.error('Error emitting popup visibility event:', error);
164
+ });
165
+ }, [isAutoOpen]);
332
166
 
333
- /**
334
- * Handle button press events
335
- */
336
- const handlePress = () => {
167
+ // ==================== HANDLERS ====================
168
+ const handleButtonPress = () => {
337
169
  setIsOpen(!isOpen);
338
170
  setIsAutoOpen(false);
339
171
  };
340
- const handleStartCall = async () => {
341
- await (0, _permision.checkPermissions)();
342
- setCallDuration(0);
343
- await initializeVoiceAgent();
344
- };
345
-
346
- /**
347
- * Render the button icon/animation
348
- */
349
-
350
- const remoteSource = (0, _react.useMemo)(() => ({
351
- uri: configData?.icon_animation || AMPLIFY_ANIMATION
352
- }), [configData?.icon_animation]);
353
- const renderIcon = () => {
354
- // When isAutoOpen is true, we don't play the Lottie animation
355
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
356
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_lottieReactNative.default, {
357
- ref: lottieRef,
358
- source: remoteSource,
359
- autoPlay: true,
360
- loop: true,
361
- style: styles.iconImage,
362
- enableMergePathsAndroidForKitKatAndAbove: true,
363
- enableSafeModeAndroid: true
364
- })
365
- });
366
- };
367
172
  const handleConnected = () => {
368
- // todo: handle call connected
369
- };
370
- const handleEndCall = async () => {
371
- setIsOpen(false);
372
- if (timerRef.current) {
373
- clearInterval(timerRef.current);
374
- timerRef.current = null;
375
- }
376
- setCallDuration(0);
377
- await endCall();
378
- };
379
- const handleMicToggle = () => {
380
- if (isMicMuted) {
381
- unmuteMic();
382
- } else {
383
- muteMic();
384
- }
173
+ // Hook for handling successful connection
385
174
  };
386
175
 
387
- // Format duration to MM:SS
388
- const formatDuration = seconds => {
389
- const minutes = Math.floor(seconds / 60);
390
- const remainingSeconds = seconds % 60;
391
- return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
392
- };
393
- console.log('tokenDetails', tokenDetails);
176
+ // ==================== COMPUTED VALUES ====================
177
+ const lottieSource = (0, _react.useMemo)(() => ({
178
+ uri: configData?.icon_animation || _EmbedButtonHelpers.ICON_URLS.AMPLIFY_ANIMATION
179
+ }), [configData?.icon_animation]);
180
+ const statusText = (0, _react.useMemo)(() => {
181
+ if (isLoading) return 'Connecting...';
182
+ if (tokenDetails?.token) return (0, _EmbedButtonHelpers.formatDuration)(callDuration);
183
+ return configData?.agent_type || 'Onboarding Agent';
184
+ }, [isLoading, tokenDetails?.token, callDuration, configData?.agent_type]);
185
+ const gradientColors = configData?.gradient || _EmbedButtonHelpers.DEFAULT_GRADIENT_COLORS;
186
+ const agentName = configData?.agent_name || 'Your AI Agent';
187
+ const popupText = configData?.popup_description || 'Any doubts? Ask agent now';
188
+ const connectButtonText = configData?.connect_button_title || 'Start Call';
394
189
 
395
- // Get the status text based on current state
396
- const getStatusText = () => {
397
- if (isLoading) {
398
- return 'Connecting...';
399
- } else if (tokenDetails?.token) {
400
- return `${formatDuration(callDuration)}`;
401
- } else {
402
- return configData?.agent_type || 'Onboarding Agent';
403
- }
404
- };
190
+ // ==================== EARLY RETURNS ====================
405
191
  if (!configData) return null;
192
+
193
+ // ==================== RENDER ====================
406
194
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
407
195
  style: styles.container,
408
- children: [isAutoOpen && !isOpen && /*#__PURE__*/(0, _jsxRuntime.jsx)(Animated.View, {
409
- style: [animatedTextStyles, styles.popupContainer],
196
+ children: [isAutoOpen && !isOpen && /*#__PURE__*/(0, _jsxRuntime.jsx)(_EmbedButtonAnimations.Animated.View, {
197
+ style: [popupAnimatedStyles, styles.popupContainer],
410
198
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
411
199
  style: styles.popupText,
412
- children: popupDescription || 'Revrag'
200
+ children: popupText
413
201
  })
414
202
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector, {
415
- gesture: gesture,
416
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Animated.View, {
417
- style: [styles.button, animatedStyles, styles.buttonContent, {
418
- pointerEvents: 'auto'
419
- }],
203
+ gesture: panGesture,
204
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_EmbedButtonAnimations.Animated.View, {
205
+ pointerEvents: "auto",
206
+ style: [styles.button, buttonAnimatedStyles, styles.buttonContent],
420
207
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeLinearGradient.default, {
421
- colors: configData?.gradient || GRADIENT_COLORS,
208
+ colors: gradientColors,
422
209
  start: {
423
210
  x: 0,
424
211
  y: 0
@@ -434,25 +221,33 @@ function EmbedButton() {
434
221
  y: 0.5
435
222
  },
436
223
  children: [tokenDetails?.token && /*#__PURE__*/(0, _jsxRuntime.jsx)(_EmbedVoice.default, {
437
- url: tokenDetails?.server_url,
438
- token: tokenDetails?.token,
224
+ url: tokenDetails.server_url,
225
+ token: tokenDetails.token,
439
226
  onDisconnected: handleEndCall,
440
227
  roomRef: roomRef,
441
228
  onConnected: handleConnected
442
229
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
443
- onPress: handlePress,
230
+ onPress: handleButtonPress,
444
231
  style: styles.pressable,
445
- children: renderIcon()
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
+ })
446
241
  }), isOpen && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
447
242
  style: styles.expandedContentContainer,
448
243
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
449
244
  style: styles.leftContentSection,
450
245
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
451
246
  style: [styles.agentNameText, styles.leftAlignedText],
452
- children: configData?.agent_name || 'Revrag'
247
+ children: agentName
453
248
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
454
249
  style: [styles.leftAlignedText, styles.statusText],
455
- children: getStatusText()
250
+ children: statusText
456
251
  })]
457
252
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
458
253
  style: styles.middleContentSection,
@@ -468,7 +263,7 @@ function EmbedButton() {
468
263
  style: styles.startCallButton,
469
264
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
470
265
  style: styles.startCallText,
471
- children: configData?.start_call_text || 'Start Call'
266
+ children: connectButtonText
472
267
  })
473
268
  })
474
269
  }), tokenDetails?.token && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
@@ -478,7 +273,7 @@ function EmbedButton() {
478
273
  onPress: handleMicToggle,
479
274
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
480
275
  source: {
481
- uri: isMicMuted ? MIC_OFF_ICON : MIC_ON_ICON
276
+ uri: isMicMuted ? _EmbedButtonHelpers.ICON_URLS.MIC_OFF : _EmbedButtonHelpers.ICON_URLS.MIC_ON
482
277
  },
483
278
  style: styles.buttonImage
484
279
  })
@@ -487,7 +282,7 @@ function EmbedButton() {
487
282
  style: styles.endCallButton,
488
283
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
489
284
  source: {
490
- uri: END_CALL_ICON
285
+ uri: _EmbedButtonHelpers.ICON_URLS.END_CALL
491
286
  },
492
287
  style: styles.buttonImage
493
288
  })
@@ -500,7 +295,5 @@ function EmbedButton() {
500
295
  })]
501
296
  });
502
297
  }
503
-
504
- // Export default for easier imports
505
298
  var _default = exports.default = EmbedButton;
506
299
  //# sourceMappingURL=EmbedButton.js.map