@revrag-ai/embed-react-native 1.0.5 → 1.0.6

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 (75) hide show
  1. package/dist/commonjs/Event/onwid.js +70 -0
  2. package/dist/commonjs/NativeOnwid.js +5 -0
  3. package/dist/commonjs/button.json +1 -0
  4. package/dist/commonjs/component/OnwidButton.js +507 -0
  5. package/dist/commonjs/component/audiowave.js +153 -0
  6. package/dist/commonjs/component/voice.js +127 -0
  7. package/dist/commonjs/hooks/initialize.js +96 -0
  8. package/dist/commonjs/hooks/initialize.types.js +2 -0
  9. package/{lib/module → dist/commonjs}/hooks/initializelivekit.js +7 -4
  10. package/dist/commonjs/hooks/voiceAgent.js +353 -0
  11. package/dist/commonjs/hooks/voiceAgent.types.js +4 -0
  12. package/dist/commonjs/index.d.js +22 -0
  13. package/dist/commonjs/index.js +34 -0
  14. package/dist/commonjs/onwidApi/api.js +185 -0
  15. package/dist/commonjs/onwidApi/api.types.js +2 -0
  16. package/dist/commonjs/package.json +1 -0
  17. package/dist/commonjs/store.key.js +38 -0
  18. package/dist/commonjs/style/onwidButton.style.js +243 -0
  19. package/dist/commonjs/utils/reanimatedHelpers.js +94 -0
  20. package/dist/commonjs/utils/utils.js +2 -0
  21. package/dist/module/Event/onwid.js +70 -0
  22. package/dist/module/NativeOnwid.js +5 -0
  23. package/dist/module/button.json +1 -0
  24. package/dist/module/component/OnwidButton.js +507 -0
  25. package/dist/module/component/audiowave.js +153 -0
  26. package/dist/module/component/voice.js +127 -0
  27. package/dist/module/hooks/initialize.js +96 -0
  28. package/dist/module/hooks/initialize.types.js +2 -0
  29. package/dist/module/hooks/initializelivekit.js +17 -0
  30. package/dist/module/hooks/voiceAgent.js +353 -0
  31. package/dist/module/hooks/voiceAgent.types.js +4 -0
  32. package/dist/module/index.d.js +22 -0
  33. package/dist/module/index.js +34 -0
  34. package/dist/module/onwidApi/api.js +185 -0
  35. package/dist/module/onwidApi/api.types.js +2 -0
  36. package/dist/module/store.key.js +38 -0
  37. package/dist/module/style/onwidButton.style.js +243 -0
  38. package/dist/module/utils/reanimatedHelpers.js +94 -0
  39. package/dist/module/utils/utils.js +2 -0
  40. package/{lib → dist}/typescript/Event/onwid.d.ts +1 -0
  41. package/{lib → dist}/typescript/NativeOnwid.d.ts +1 -0
  42. package/{lib → dist}/typescript/component/OnwidButton.d.ts +1 -0
  43. package/{lib → dist}/typescript/component/audiowave.d.ts +1 -0
  44. package/{lib → dist}/typescript/component/voice.d.ts +1 -0
  45. package/{lib → dist}/typescript/hooks/initialize.d.ts +1 -0
  46. package/{lib → dist}/typescript/hooks/initialize.types.d.ts +1 -0
  47. package/{lib → dist}/typescript/hooks/initializelivekit.d.ts +1 -0
  48. package/{lib → dist}/typescript/hooks/voiceAgent.d.ts +1 -0
  49. package/{lib → dist}/typescript/hooks/voiceAgent.types.d.ts +1 -0
  50. package/{lib → dist}/typescript/index.d.ts +3 -3
  51. package/{lib → dist}/typescript/onwidApi/api.d.ts +1 -0
  52. package/{lib → dist}/typescript/onwidApi/api.types.d.ts +1 -0
  53. package/{lib → dist}/typescript/store.key.d.ts +1 -0
  54. package/{lib → dist}/typescript/style/onwidButton.style.d.ts +1 -0
  55. package/{lib → dist}/typescript/utils/reanimatedHelpers.d.ts +1 -0
  56. package/dist/typescript/utils/utils.d.ts +1 -0
  57. package/package.json +29 -21
  58. package/lib/index.d.ts +0 -77
  59. package/lib/module/Event/onwid.js +0 -74
  60. package/lib/module/NativeOnwid.js +0 -4
  61. package/lib/module/component/OnwidButton.js +0 -366
  62. package/lib/module/component/audiowave.js +0 -137
  63. package/lib/module/component/voice.js +0 -103
  64. package/lib/module/hooks/initialize.js +0 -92
  65. package/lib/module/hooks/initialize.types.js +0 -2
  66. package/lib/module/hooks/voiceAgent.js +0 -334
  67. package/lib/module/hooks/voiceAgent.types.js +0 -2
  68. package/lib/module/index.js +0 -61
  69. package/lib/module/onwidApi/api.js +0 -184
  70. package/lib/module/onwidApi/api.types.js +0 -2
  71. package/lib/module/store.key.js +0 -47
  72. package/lib/module/style/onwidButton.style.js +0 -230
  73. package/lib/module/utils/reanimatedHelpers.js +0 -87
  74. package/lib/module/utils/utils.js +0 -1
  75. package/lib/typescript/utils/utils.d.ts +0 -0
package/package.json CHANGED
@@ -1,25 +1,26 @@
1
1
  {
2
2
  "name": "@revrag-ai/embed-react-native",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Voice Agent SDK for React Native - AI-powered voice communication with real-time speech processing",
5
- "main": "./lib/module/index.js",
6
- "types": "./lib/typescript/src/index.d.ts",
5
+ "main": "./dist/commonjs/index.js",
6
+ "module": "./dist/module/index.js",
7
+ "types": "./dist/typescript/index.d.ts",
7
8
  "typesVersions": {
8
9
  "*": {
9
- "*": ["./lib/typescript/src/*", "./lib/index.d.ts"]
10
+ "*": ["./dist/typescript/*"]
10
11
  }
11
12
  },
12
13
  "exports": {
13
14
  ".": {
14
- "types": "./lib/typescript/src/index.d.ts",
15
- "import": "./lib/module/index.js",
16
- "require": "./lib/module/index.js",
17
- "default": "./lib/module/index.js"
15
+ "types": "./dist/typescript/index.d.ts",
16
+ "import": "./dist/module/index.js",
17
+ "require": "./dist/commonjs/index.js",
18
+ "default": "./dist/module/index.js"
18
19
  },
19
20
  "./package.json": "./package.json"
20
21
  },
21
22
  "files": [
22
- "lib",
23
+ "dist",
23
24
  "android",
24
25
  "ios",
25
26
  "cpp",
@@ -27,9 +28,9 @@
27
28
  "scripts",
28
29
  "*.podspec",
29
30
  "react-native.config.js",
30
- "!lib/**/*.map",
31
- "!lib/**/*.test.*",
32
- "!lib/**/*.spec.*",
31
+ "!dist/**/*.map",
32
+ "!dist/**/*.test.*",
33
+ "!dist/**/*.spec.*",
33
34
  "!ios/build",
34
35
  "!android/build",
35
36
  "!android/gradle",
@@ -47,17 +48,17 @@
47
48
  "test": "jest",
48
49
  "typecheck": "tsc",
49
50
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
50
- "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
51
- "prepare": "yarn manual-build",
52
- "manual-build": "node manual-build.js",
51
+ "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build dist",
52
+ "prepare": "bob build",
53
+ "build": "bob build",
53
54
  "fix-js": "node fix-js-files.js",
54
55
  "verify-setup": "node scripts/verify-setup.js",
55
- "prepublishOnly": "yarn manual-build && yarn fix-js",
56
+ "prepublishOnly": "bob build && yarn fix-js",
56
57
  "release": "release-it --only-version",
57
58
  "protect": "node -e \"const crypto = require('crypto'); const fs = require('fs'); const config = { hash: crypto.randomBytes(32).toString('hex'), createdAt: new Date().toISOString(), note: 'Protected build', version: require('./package.json').version }; fs.writeFileSync('.onwid-security.json', JSON.stringify(config, null, 2)); console.log('✅ Code protected');\"",
58
- "publish:safe": "yarn clean && yarn manual-build && yarn fix-js && yarn protect && npm publish --access public",
59
- "publish:beta": "yarn clean && yarn manual-build && yarn fix-js && yarn protect && npm publish --access public --tag beta",
60
- "publish:alpha": "yarn clean && yarn manual-build && yarn fix-js && yarn protect && npm publish --access public --tag alpha"
59
+ "publish:safe": "yarn clean && bob build && yarn fix-js && yarn protect && npm publish --access public",
60
+ "publish:beta": "yarn clean && bob build && yarn fix-js && yarn protect && npm publish --access public --tag beta",
61
+ "publish:alpha": "yarn clean && bob build && yarn fix-js && yarn protect && npm publish --access public --tag alpha"
61
62
  },
62
63
  "keywords": [
63
64
  "react-native",
@@ -137,7 +138,7 @@
137
138
  "preset": "react-native",
138
139
  "modulePathIgnorePatterns": [
139
140
  "<rootDir>/example/node_modules",
140
- "<rootDir>/lib/"
141
+ "<rootDir>/dist/"
141
142
  ]
142
143
  },
143
144
  "commitlint": {
@@ -173,11 +174,18 @@
173
174
  },
174
175
  "react-native-builder-bob": {
175
176
  "source": "src",
176
- "output": "lib",
177
+ "output": "dist",
177
178
  "targets": [
179
+ [
180
+ "commonjs",
181
+ {
182
+ "configFile": true
183
+ }
184
+ ],
178
185
  [
179
186
  "module",
180
187
  {
188
+ "configFile": true,
181
189
  "esm": true
182
190
  }
183
191
  ],
package/lib/index.d.ts DELETED
@@ -1,77 +0,0 @@
1
- /**
2
- * @file index.d.ts
3
- * @description TypeScript declarations for the Onwid React Native library.
4
- */
5
-
6
- import { ConnectionState, Room } from 'livekit-client';
7
- import { RefObject } from 'react';
8
-
9
- // Component declarations
10
- export declare function OnwidButton(): JSX.Element;
11
-
12
- // Hook type declarations
13
- export interface UseInitializeProps {
14
- apiKey: string;
15
- agentId?: string;
16
- onwidUrl?: string;
17
- metadata?: any;
18
- }
19
-
20
- export interface UseVoiceAgentReturn {
21
- initializeVoiceAgent: () => Promise<void>;
22
- isLoading: boolean;
23
- error: string | null;
24
- tokenDetails: any;
25
- endCall: () => Promise<void>;
26
- room: Room;
27
- roomRef: RefObject<Room>;
28
- isMicMuted: boolean;
29
- muteMic: () => void;
30
- unmuteMic: () => void;
31
- connectionState: ConnectionState;
32
- cleanup: () => void;
33
- }
34
-
35
- // Hook declarations
36
- export declare const useInitialize: (props: UseInitializeProps) => void;
37
- export declare const useVoiceAgent: () => UseVoiceAgentReturn;
38
-
39
- // API type declarations
40
- export interface ApiResponse<T> {
41
- success: boolean;
42
- data?: T;
43
- error?: string;
44
- }
45
-
46
- export interface RegisterRequest {
47
- apiKey: string;
48
- onwidUrl: string;
49
- metadata?: Record<string, any>;
50
- }
51
-
52
- export interface TokenDetails {
53
- token: string;
54
- expiresAt: number;
55
- apiKey: string;
56
- config: Record<string, any>;
57
- server_url: string;
58
- }
59
-
60
- export interface UpdateDataRequest {
61
- eventKey: string;
62
- data: Record<string, any>;
63
- }
64
-
65
- // Event system declarations
66
- export enum EventKeys {
67
- USER_DATA = 'user_data',
68
- SCREEN_STATE = 'state_data',
69
- }
70
-
71
- export declare class OnWid {
72
- Event(eventKey: string, data: any): Promise<void>;
73
- on(eventKey: EventKeys, callback: (data: any) => void): void;
74
- }
75
-
76
- export declare const onwid: OnWid;
77
- export declare const registerAgent: any;
@@ -1,74 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EventKeys = void 0;
4
- const store_key_1 = require("../store.key");
5
- const api_1 = require("../onwidApi/api");
6
- // Predefined event keys
7
- var EventKeys;
8
- (function (EventKeys) {
9
- EventKeys["USER_DATA"] = "user_data";
10
- EventKeys["SCREEN_STATE"] = "state_data";
11
- })(EventKeys || (exports.EventKeys = EventKeys = {}));
12
- class OnWid {
13
- constructor() {
14
- this.events = {};
15
- }
16
- // Automatically adds a default listener if none exists
17
- ensureDefaultListener(eventKey) {
18
- if (!this.events[eventKey]) {
19
- this.events[eventKey] = [
20
- (data) => {
21
- console.log(`[Default] Event handled for ${eventKey}:`, data);
22
- },
23
- ];
24
- }
25
- }
26
- async Event(eventKey, data) {
27
- var _a;
28
- if (!Object.values(EventKeys).includes(eventKey)) {
29
- console.error(`Invalid event key: ${eventKey}`);
30
- throw new Error(`Invalid event key: ${eventKey}. Must be one of: ${Object.values(EventKeys).join(', ')}`);
31
- }
32
- const key = eventKey;
33
- if (key !== EventKeys.USER_DATA) {
34
- const userIdentity = await (0, store_key_1.getAgentData)(EventKeys.USER_DATA);
35
- if (userIdentity) {
36
- data.app_user_id = userIdentity.app_user_id;
37
- }
38
- else {
39
- throw new Error('User identity not found');
40
- }
41
- }
42
- // Ensure a default listener is registered if not already
43
- this.ensureDefaultListener(key);
44
- console.log('response,updateUserDatniuioioioa');
45
- // Trigger API call
46
- try {
47
- const apiService = api_1.APIService.getInstance();
48
- const response = await apiService.updateUserData({
49
- eventKey: key,
50
- data,
51
- });
52
- console.log('response,updateUserData', response);
53
- if (!response.success) {
54
- console.error('Failed to trigger API for event:', eventKey);
55
- }
56
- (0, store_key_1.setAgentData)(data, key);
57
- }
58
- catch (error) {
59
- console.error('Error triggering API:', error);
60
- }
61
- // Trigger event listeners
62
- (_a = this.events[key]) === null || _a === void 0 ? void 0 : _a.forEach((callback) => callback(data));
63
- }
64
- // Still allow custom listeners (optional)
65
- on(eventKey, callback) {
66
- var _a;
67
- if (!this.events[eventKey]) {
68
- this.events[eventKey] = [];
69
- }
70
- (_a = this.events[eventKey]) === null || _a === void 0 ? void 0 : _a.push(callback);
71
- }
72
- }
73
- const onwid = new OnWid();
74
- exports.default = onwid;
@@ -1,4 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const react_native_1 = require("react-native");
4
- exports.default = react_native_1.TurboModuleRegistry.getEnforcing('Onwid');
@@ -1,366 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.OnwidButton = OnwidButton;
7
- const jsx_runtime_1 = require("react/jsx-runtime");
8
- const lottie_react_native_1 = __importDefault(require("lottie-react-native"));
9
- const react_1 = require("react");
10
- const react_native_1 = require("react-native");
11
- const react_native_gesture_handler_1 = require("react-native-gesture-handler");
12
- const react_native_linear_gradient_1 = __importDefault(require("react-native-linear-gradient"));
13
- const voice_1 = __importDefault(require("../component/voice"));
14
- const voiceAgent_1 = require("../hooks/voiceAgent");
15
- const store_key_1 = require("../store.key");
16
- const onwidButton_style_1 = require("../style/onwidButton.style");
17
- const reanimatedHelpers_1 = require("../utils/reanimatedHelpers");
18
- const audiowave_1 = require("./audiowave");
19
- // Get reanimated API with fallbacks
20
- const { useSharedValue, useAnimatedStyle, withTiming, withSpring, withRepeat, withSequence, runOnJS, Easing, Animated, isAvailable: isReanimatedAvailable, } = (0, reanimatedHelpers_1.getReanimatedAPI)();
21
- // Show warning if reanimated is not available
22
- if (!isReanimatedAvailable) {
23
- (0, reanimatedHelpers_1.showReanimatedSetupError)();
24
- }
25
- const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = react_native_1.Dimensions.get('window');
26
- const BUTTON_WIDTH = 60;
27
- const EXPANDED_WIDTH = SCREEN_WIDTH * 0.9;
28
- const BUTTON_HEIGHT = 60;
29
- const GRADIENT_COLORS = ['#1E0844', '#B391F3'];
30
- // Define mic icons as base64 images for portability
31
- const MIC_ON_ICON = 'https://revrag-dev.s3.ap-south-1.amazonaws.com/Avatars/Mute+button.png';
32
- const MIC_OFF_ICON = 'https://revrag-dev.s3.ap-south-1.amazonaws.com/Avatars/unmute.png';
33
- // Add end call icon
34
- const END_CALL_ICON = 'https://revrag-dev.s3.ap-south-1.amazonaws.com/Avatars/end+button.png';
35
- const AMPLIFY_ANIMATION = 'https://revrag-dev.s3.ap-south-1.amazonaws.com/Avatars/amplify.json';
36
- /**
37
- * Default styles configuration for the button
38
- */
39
- const defaultStyles = {
40
- buttonWidth: 60,
41
- buttonHeight: 60,
42
- borderRadius: 100,
43
- marginBottom: 20,
44
- spacing: {
45
- SMALL: 10,
46
- MEDIUM: 15,
47
- LARGE: 25,
48
- },
49
- };
50
- /**
51
- * OnwidButton Component
52
- *
53
- * A floating action button that can be dragged around the screen and expanded to show additional content.
54
- * Features include:
55
- * - Draggable functionality
56
- * - Expandable menu
57
- * - Animated transitions
58
- * - Gradient background
59
- * - Customizable styling
60
- *
61
- * @component
62
- * @example
63
- * ```tsx
64
- * <OnwidButton
65
- * isOpen={false}
66
- * onPress={(isOpen) => console.log('Button pressed:', isOpen)}
67
- * menuComponent={<YourMenuComponent />}
68
- * />
69
- * ```
70
- */
71
- function OnwidButton() {
72
- var _a;
73
- const { initializeVoiceAgent, tokenDetails, endCall, isLoading, isMicMuted, muteMic, unmuteMic, connectionState, roomRef, } = (0, voiceAgent_1.useVoiceAgent)();
74
- // State management
75
- const [configData, setConfigData] = (0, react_1.useState)(null);
76
- const [isOpen, setIsOpen] = (0, react_1.useState)(false);
77
- const [callDuration, setCallDuration] = (0, react_1.useState)(0);
78
- const timerRef = (0, react_1.useRef)(null);
79
- const lottieRef = (0, react_1.useRef)(null);
80
- console.log('roomRef', (_a = roomRef.current) === null || _a === void 0 ? void 0 : _a.localParticipant);
81
- // Animation values
82
- const isPressed = useSharedValue(false);
83
- const offset = useSharedValue({ x: 0, y: 0 });
84
- const start = useSharedValue({ x: 0, y: 0 });
85
- const menuAnimation = useSharedValue(0);
86
- const buttonWidth = useSharedValue(BUTTON_WIDTH);
87
- const buttonScale = useSharedValue(1);
88
- // Styles
89
- const styles = (0, onwidButton_style_1.createOnwidButtonStyles)(defaultStyles);
90
- const [isAutoOpen, setIsAutoOpen] = (0, react_1.useState)(false);
91
- (0, react_1.useEffect)(() => {
92
- const autoOpenTimer = setTimeout(() => {
93
- if (!isOpen) {
94
- console.log('autoOpenTimer', isOpen);
95
- setIsAutoOpen(true);
96
- }
97
- }, 15000); // 15 seconds
98
- return () => {
99
- clearTimeout(autoOpenTimer);
100
- };
101
- }, [isOpen]);
102
- /**
103
- * Fetch agent configuration data
104
- */
105
- (0, react_1.useEffect)(() => {
106
- const fetchAgentData = async () => {
107
- try {
108
- const data = await (0, store_key_1.getAgentData)('@config_data');
109
- setConfigData(data === null || data === void 0 ? void 0 : data.ui_config);
110
- }
111
- catch (error) {
112
- console.error('Error retrieving agent data:', error);
113
- }
114
- };
115
- fetchAgentData();
116
- }, []);
117
- /**
118
- * Set up a timer to track call duration when connected
119
- */
120
- (0, react_1.useEffect)(() => {
121
- if (connectionState === 'connected' && !timerRef.current) {
122
- timerRef.current = setInterval(() => {
123
- setCallDuration((prev) => prev + 1);
124
- }, 1000);
125
- }
126
- else if (connectionState !== 'connected' && timerRef.current) {
127
- clearInterval(timerRef.current);
128
- timerRef.current = null;
129
- // If we were previously connected and now disconnected, show an error
130
- if (callDuration > 0) {
131
- console.log('Call unexpectedly disconnected after', callDuration, 'seconds');
132
- }
133
- }
134
- return () => {
135
- if (timerRef.current) {
136
- clearInterval(timerRef.current);
137
- timerRef.current = null;
138
- }
139
- };
140
- }, [connectionState, callDuration]);
141
- /**
142
- * Handle menu animation and button width transitions
143
- */
144
- (0, react_1.useEffect)(() => {
145
- menuAnimation.value = withTiming(isOpen ? 0.8 : 0, {
146
- duration: 300,
147
- });
148
- buttonWidth.value = withTiming(isOpen ? EXPANDED_WIDTH : BUTTON_WIDTH);
149
- }, [isOpen, menuAnimation, buttonWidth]);
150
- // Add breathing animation when button is closed but isAutoOpen is true
151
- (0, react_1.useEffect)(() => {
152
- if (!isOpen && isAutoOpen) {
153
- // Start breathing animation with faster speed
154
- buttonScale.value = withRepeat(withSequence(withTiming(1.1, {
155
- duration: 1500, // Reduced from 1000ms to 600ms
156
- easing: Easing.inOut(Easing.ease),
157
- }), withTiming(1, {
158
- duration: 1500, // Reduced from 1000ms to 600ms
159
- easing: Easing.inOut(Easing.ease),
160
- })), -1, // Infinite repeat
161
- false // Don't reverse
162
- );
163
- }
164
- else {
165
- // Reset animation
166
- buttonScale.value = withTiming(1, { duration: 300 });
167
- }
168
- }, [isOpen, isAutoOpen]);
169
- /**
170
- * Animated styles for the button
171
- */
172
- const animatedStyles = useAnimatedStyle(() => {
173
- const maxX = SCREEN_WIDTH - (isOpen ? EXPANDED_WIDTH : BUTTON_WIDTH) - 35;
174
- const clampedX = Math.min(Math.max(offset.value.x, -maxX), 0);
175
- return {
176
- width: buttonWidth.value,
177
- height: BUTTON_HEIGHT,
178
- transform: [
179
- { translateX: clampedX },
180
- { translateY: offset.value.y },
181
- { scale: withSpring(isPressed.value ? 0.95 : buttonScale.value) },
182
- ],
183
- justifyContent: isOpen ? 'space-between' : 'flex-start',
184
- overflow: 'hidden',
185
- };
186
- });
187
- /**
188
- * Animated styles for the text
189
- */
190
- const animatedTextStyles = useAnimatedStyle(() => {
191
- const maxX = SCREEN_WIDTH;
192
- const clampedX = Math.min(Math.max(offset.value.x, -maxX), 0);
193
- return {
194
- transform: [
195
- { translateX: clampedX },
196
- { translateY: offset.value.y },
197
- { scale: withSpring(isPressed.value ? 1 : 1) },
198
- ],
199
- };
200
- });
201
- /**
202
- * Pan gesture handler for drag functionality
203
- */
204
- const gesture = react_native_gesture_handler_1.Gesture.Pan()
205
- .onBegin(() => {
206
- isPressed.value = true;
207
- if (isAutoOpen) {
208
- runOnJS(setIsAutoOpen)(false);
209
- }
210
- })
211
- .onUpdate((e) => {
212
- const maxX = SCREEN_WIDTH - (isOpen ? EXPANDED_WIDTH : BUTTON_WIDTH) - 0;
213
- const newX = Math.min(Math.max(e.translationX + start.value.x, -maxX), 0);
214
- const maxY = SCREEN_HEIGHT - 150;
215
- const newY = Math.min(Math.max(e.translationY + start.value.y, -maxY), 0);
216
- offset.value = {
217
- x: newX,
218
- y: newY,
219
- };
220
- })
221
- .onEnd(() => {
222
- start.value = {
223
- x: offset.value.x,
224
- y: offset.value.y,
225
- };
226
- })
227
- .onFinalize(() => {
228
- isPressed.value = false;
229
- });
230
- /**
231
- * Handle button press events
232
- */
233
- const handlePress = () => {
234
- console.log('handlePress', isOpen);
235
- console.log('isAutoOpen', isAutoOpen);
236
- // cleanup();
237
- setIsOpen(!isOpen);
238
- setIsAutoOpen(false);
239
- };
240
- const handleStartCall = async () => {
241
- setCallDuration(0);
242
- await initializeVoiceAgent();
243
- };
244
- /**
245
- * Render the button icon/animation
246
- */
247
- const remoteSource = (0, react_1.useMemo)(() => ({
248
- uri: (configData === null || configData === void 0 ? void 0 : configData.icon_animation) || AMPLIFY_ANIMATION,
249
- }), [configData === null || configData === void 0 ? void 0 : configData.icon_animation]);
250
- const renderIcon = () => {
251
- // When isAutoOpen is true, we don't play the Lottie animation
252
- return ((0, jsx_runtime_1.jsx)(react_native_1.View, { children: (0, jsx_runtime_1.jsx)(lottie_react_native_1.default, { ref: lottieRef, source: remoteSource, autoPlay: true, loop: true, style: styles.iconImage, enableMergePathsAndroidForKitKatAndAbove: true, enableSafeModeAndroid: true }) }));
253
- };
254
- const handleConnected = () => {
255
- console.log('Call connected');
256
- };
257
- const handleEndCall = async () => {
258
- setIsOpen(false);
259
- if (timerRef.current) {
260
- clearInterval(timerRef.current);
261
- timerRef.current = null;
262
- }
263
- setCallDuration(0);
264
- await endCall();
265
- };
266
- const handleMicToggle = () => {
267
- if (isMicMuted) {
268
- unmuteMic();
269
- }
270
- else {
271
- muteMic();
272
- }
273
- };
274
- // Format duration to MM:SS
275
- const formatDuration = (seconds) => {
276
- const minutes = Math.floor(seconds / 60);
277
- const remainingSeconds = seconds % 60;
278
- return `${minutes.toString().padStart(2, '0')}:${remainingSeconds
279
- .toString()
280
- .padStart(2, '0')}`;
281
- };
282
- // Get the status text based on current state
283
- const getStatusText = () => {
284
- if (isLoading) {
285
- return 'Connecting...';
286
- }
287
- else if (tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.token) {
288
- return `Call Duration: ${formatDuration(callDuration)}`;
289
- }
290
- else {
291
- return (configData === null || configData === void 0 ? void 0 : configData.agent_type) || 'Onboarding Agent';
292
- }
293
- };
294
- if (!configData)
295
- return null;
296
- return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: styles.container, children: [isAutoOpen && !isOpen && ((0, jsx_runtime_1.jsx)(Animated.View, { style: [
297
- animatedTextStyles,
298
- {
299
- position: 'absolute',
300
- borderRadius: 5,
301
- paddingVertical: 2,
302
- paddingHorizontal: 10,
303
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
304
- bottom: BUTTON_HEIGHT + 40,
305
- // right: Math.abs(offset.value.x) + BUTTON_WIDTH + 0,
306
- },
307
- ], children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: { color: 'white', fontSize: 10, fontWeight: '500' }, children: (configData === null || configData === void 0 ? void 0 : configData.popup_description) || 'Revrag' }) })), (0, jsx_runtime_1.jsx)(react_native_gesture_handler_1.GestureDetector, { gesture: gesture, children: (0, jsx_runtime_1.jsx)(Animated.View, { style: [
308
- styles.button,
309
- animatedStyles,
310
- styles.buttonContent,
311
- {
312
- pointerEvents: 'auto',
313
- },
314
- ], children: (0, jsx_runtime_1.jsxs)(react_native_linear_gradient_1.default, { colors: (configData === null || configData === void 0 ? void 0 : configData.gradient) || GRADIENT_COLORS, start: { x: 0, y: 0 }, end: { x: 1, y: 0 }, style: [
315
- styles.linearGradient,
316
- {
317
- width: '100%',
318
- flexDirection: 'row',
319
- alignItems: 'center',
320
- paddingHorizontal: 0,
321
- paddingLeft: 0,
322
- paddingRight: isOpen ? 5 : 0,
323
- },
324
- ], angle: 0, angleCenter: { x: 0.5, y: 0.5 }, children: [(tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.token) && ((0, jsx_runtime_1.jsx)(voice_1.default, { url: tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.server_url, token: tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.token, onDisconnected: handleEndCall, roomRef: roomRef, onConnected: handleConnected })), (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
325
- styles.rowContainer,
326
- {
327
- flexShrink: 0,
328
- width: BUTTON_WIDTH,
329
- padding: 0,
330
- margin: 0,
331
- },
332
- ], children: (0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { onPress: handlePress, style: styles.pressable, children: renderIcon() }) }), isOpen && ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: {
333
- flex: 1,
334
- flexDirection: 'row',
335
- height: BUTTON_HEIGHT - 10,
336
- marginLeft: 0,
337
- marginRight: 0,
338
- }, children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { style: {
339
- flex: 1,
340
- justifyContent: 'center',
341
- alignItems: 'flex-start',
342
- paddingLeft: 8,
343
- paddingRight: 4,
344
- }, children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [
345
- styles.agentNameText,
346
- { flexShrink: 1, textAlign: 'left' },
347
- ], children: (configData === null || configData === void 0 ? void 0 : configData.agent_name) || 'Revrag' }), (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [
348
- styles.statusText,
349
- { flexShrink: 1, textAlign: 'left' },
350
- ], children: getStatusText() })] }), (0, jsx_runtime_1.jsx)(react_native_1.View, { style: {
351
- flex: 1,
352
- justifyContent: 'center',
353
- alignItems: 'center',
354
- paddingHorizontal: 4,
355
- }, children: (0, jsx_runtime_1.jsx)(audiowave_1.WaveformVisualizer, { roomRef: roomRef }) }), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: {
356
- flex: 1,
357
- justifyContent: 'center',
358
- alignItems: 'flex-end',
359
- paddingLeft: 4,
360
- paddingRight: 8,
361
- }, children: [!(tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.token) && ((0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { onPress: handleStartCall, style: styles.startCallButton, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.startCallText, children: (configData === null || configData === void 0 ? void 0 : configData.start_call_text) || 'Start Call' }) })), (tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.token) && ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [styles.buttonContainer], children: [(0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { style: styles.muteButton, onPress: handleMicToggle, children: (0, jsx_runtime_1.jsx)(react_native_1.Image, { source: {
362
- uri: isMicMuted ? MIC_OFF_ICON : MIC_ON_ICON,
363
- }, style: styles.buttonImage }) }), (0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { onPress: handleEndCall, style: styles.endCallButton, children: (0, jsx_runtime_1.jsx)(react_native_1.Image, { source: { uri: END_CALL_ICON }, style: styles.buttonImage }) })] }))] })] }))] }) }) })] }));
364
- }
365
- // Export default for easier imports
366
- exports.default = OnwidButton;