@revrag-ai/embed-react-native 1.0.5 → 1.0.7
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/LICENSE +1 -1
- package/README.md +13 -382
- package/android/CMakeLists.txt +15 -0
- package/android/build.gradle +77 -25
- package/android/cpp-adapter.cpp +8 -0
- package/android/generated/java/com/revragai/embedreactnative/NativeEmbedReactNativeSpec.java +37 -0
- package/android/generated/jni/CMakeLists.txt +49 -0
- package/android/generated/jni/RNEmbedReactNativeSpec-generated.cpp +32 -0
- package/android/generated/jni/RNEmbedReactNativeSpec.h +31 -0
- package/android/generated/jni/react/renderer/components/RNEmbedReactNativeSpec/RNEmbedReactNativeSpecJSI-generated.cpp +28 -0
- package/android/generated/jni/react/renderer/components/RNEmbedReactNativeSpec/RNEmbedReactNativeSpecJSI.h +67 -0
- package/android/gradle.properties +5 -5
- package/cpp/revrag-ai-embed-react-native.cpp +7 -0
- package/cpp/revrag-ai-embed-react-native.h +8 -0
- package/ios/EmbedReactNative.h +9 -0
- package/ios/{Onwid.mm → EmbedReactNative.mm} +4 -4
- package/ios/generated/RNEmbedReactNativeSpec/RNEmbedReactNativeSpec-generated.mm +29 -0
- package/ios/generated/RNEmbedReactNativeSpec/RNEmbedReactNativeSpec.h +50 -0
- package/ios/generated/RNEmbedReactNativeSpecJSI-generated.cpp +28 -0
- package/ios/generated/RNEmbedReactNativeSpecJSI.h +67 -0
- package/lib/commonjs/NativeEmbedReactNative.js +9 -0
- package/lib/commonjs/api/api.js +256 -0
- package/lib/commonjs/api/types/embed.api.types.js +2 -0
- package/lib/commonjs/components/Embed/EmbedAudioWave.js +157 -0
- package/lib/commonjs/components/Embed/EmbedButton.js +511 -0
- package/lib/commonjs/components/Embed/EmbedVoice.js +131 -0
- package/lib/commonjs/components/styles/EmbedButton.style.js +248 -0
- package/lib/commonjs/events/embed.event.js +74 -0
- package/lib/commonjs/hooks/initialize.js +102 -0
- package/lib/commonjs/hooks/initialize.livekit.js +20 -0
- package/lib/commonjs/hooks/types/initialize.types.js +2 -0
- package/lib/commonjs/hooks/types/voiceAgent.types.js +6 -0
- package/lib/commonjs/hooks/voiceagent.js +358 -0
- package/lib/commonjs/index.js +34 -0
- package/lib/commonjs/index.types.js +22 -0
- package/lib/commonjs/store/store.key.js +46 -0
- package/lib/commonjs/utils/reanimated.helper.js +100 -0
- package/lib/module/NativeEmbedReactNative.js +5 -0
- package/lib/module/api/api.js +248 -0
- package/lib/module/api/types/embed.api.types.js +2 -0
- package/lib/module/components/Embed/EmbedAudioWave.js +152 -0
- package/lib/module/components/Embed/EmbedButton.js +506 -0
- package/lib/module/components/Embed/EmbedVoice.js +127 -0
- package/lib/module/components/styles/EmbedButton.style.js +243 -0
- package/lib/module/events/embed.event.js +70 -0
- package/lib/module/hooks/initialize.js +79 -75
- package/lib/module/hooks/{initializelivekit.js → initialize.livekit.js} +7 -4
- package/lib/module/hooks/types/initialize.types.js +2 -0
- package/lib/module/hooks/types/voiceAgent.types.js +4 -0
- package/lib/module/hooks/voiceagent.js +353 -0
- package/lib/module/index.js +6 -60
- package/lib/module/index.types.js +23 -0
- package/lib/module/store/store.key.js +38 -0
- package/lib/module/utils/reanimated.helper.js +94 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/package.json +69 -27
- package/react-native.config.js +8 -14
- package/revrag-ai-embed-react-native.podspec +41 -0
- package/Onwid.podspec +0 -20
- package/ios/Onwid.h +0 -5
- package/lib/index.d.ts +0 -77
- package/lib/module/Event/onwid.js +0 -74
- package/lib/module/NativeOnwid.js +0 -4
- package/lib/module/component/OnwidButton.js +0 -366
- package/lib/module/component/audiowave.js +0 -137
- package/lib/module/component/voice.js +0 -103
- package/lib/module/hooks/initialize.types.js +0 -2
- package/lib/module/hooks/voiceAgent.js +0 -334
- package/lib/module/hooks/voiceAgent.types.js +0 -2
- package/lib/module/onwidApi/api.js +0 -184
- package/lib/module/onwidApi/api.types.js +0 -2
- package/lib/module/store.key.js +0 -47
- package/lib/module/style/onwidButton.style.js +0 -230
- package/lib/module/utils/reanimatedHelpers.js +0 -87
- package/lib/module/utils/utils.js +0 -1
- package/lib/typescript/Event/onwid.d.ts +0 -13
- package/lib/typescript/NativeOnwid.d.ts +0 -6
- package/lib/typescript/component/OnwidButton.d.ts +0 -28
- package/lib/typescript/component/audiowave.d.ts +0 -6
- package/lib/typescript/component/voice.d.ts +0 -15
- package/lib/typescript/hooks/initialize.d.ts +0 -2
- package/lib/typescript/hooks/initialize.types.d.ts +0 -5
- package/lib/typescript/hooks/initializelivekit.d.ts +0 -3
- package/lib/typescript/hooks/voiceAgent.d.ts +0 -2
- package/lib/typescript/hooks/voiceAgent.types.d.ts +0 -16
- package/lib/typescript/index.d.ts +0 -27
- package/lib/typescript/onwidApi/api.d.ts +0 -53
- package/lib/typescript/onwidApi/api.types.d.ts +0 -21
- package/lib/typescript/store.key.d.ts +0 -3
- package/lib/typescript/style/onwidButton.style.d.ts +0 -98
- package/lib/typescript/utils/reanimatedHelpers.d.ts +0 -29
- package/lib/typescript/utils/utils.d.ts +0 -0
- package/scripts/verify-setup.js +0 -90
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { getAgentData, setAgentData } from "../store/store.key.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* APIService class that ensures proper initialization before API calls
|
|
7
|
+
*/
|
|
8
|
+
export class APIService {
|
|
9
|
+
static instance = null;
|
|
10
|
+
apiBaseUrl = null;
|
|
11
|
+
isInitialized = false;
|
|
12
|
+
constructor() {}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Get singleton instance of APIService
|
|
16
|
+
*/
|
|
17
|
+
static getInstance() {
|
|
18
|
+
if (!APIService.instance) {
|
|
19
|
+
APIService.instance = new APIService();
|
|
20
|
+
}
|
|
21
|
+
return APIService.instance;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Initialize the API service with the base URL
|
|
26
|
+
*/
|
|
27
|
+
async initialize() {
|
|
28
|
+
if (this.isInitialized && this.apiBaseUrl) {
|
|
29
|
+
return; // Already initialized
|
|
30
|
+
}
|
|
31
|
+
const AgentData = await getAgentData();
|
|
32
|
+
console.log('AgentData', AgentData);
|
|
33
|
+
if (AgentData?.onwidUrl) {
|
|
34
|
+
this.apiBaseUrl = AgentData.onwidUrl;
|
|
35
|
+
this.isInitialized = true;
|
|
36
|
+
console.log('API_BASE_URL initialized:', this.apiBaseUrl);
|
|
37
|
+
} else {
|
|
38
|
+
throw new Error('API base URL not found in keychain');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Ensure the service is initialized before making API calls
|
|
44
|
+
*/
|
|
45
|
+
async ensureInitialized() {
|
|
46
|
+
if (!this.isInitialized || !this.apiBaseUrl) {
|
|
47
|
+
await this.initialize();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get headers with stored API key
|
|
53
|
+
*/
|
|
54
|
+
async getHeaders() {
|
|
55
|
+
const AgentData = await getAgentData();
|
|
56
|
+
if (!AgentData?.apiKey) {
|
|
57
|
+
throw new Error('API key not found in keychain');
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
'Content-Type': 'application/json',
|
|
61
|
+
'Authorization': `Bearer ${AgentData.apiKey}`,
|
|
62
|
+
'X-Revrag-Embedded-Key': AgentData.apiKey
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Register a new user/device on initialization
|
|
68
|
+
* @returns Promise with registration response
|
|
69
|
+
*/
|
|
70
|
+
async registerOnInitialize() {
|
|
71
|
+
try {
|
|
72
|
+
await this.ensureInitialized();
|
|
73
|
+
console.log('registerOnInitialize ApiData', this.apiBaseUrl);
|
|
74
|
+
const headers = await this.getHeaders();
|
|
75
|
+
const response = await fetch(`${this.apiBaseUrl}/embedded-agent/initialize`, {
|
|
76
|
+
method: 'GET',
|
|
77
|
+
headers: headers
|
|
78
|
+
});
|
|
79
|
+
const data = await response.json();
|
|
80
|
+
console.log('dat config data after register', data);
|
|
81
|
+
await setAgentData(data, '@config_data');
|
|
82
|
+
if (!response.ok) {
|
|
83
|
+
console.log('registerOnInitialize error', data.error);
|
|
84
|
+
throw new Error(data.error || 'Registration failed');
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
success: true,
|
|
88
|
+
data: data
|
|
89
|
+
};
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.log('registerOnInitialize error', error);
|
|
92
|
+
|
|
93
|
+
// Enhanced error handling for common iOS network issues
|
|
94
|
+
let errorMessage = 'Unknown error occurred';
|
|
95
|
+
if (error instanceof Error) {
|
|
96
|
+
errorMessage = error.message;
|
|
97
|
+
|
|
98
|
+
// iOS ATS related errors
|
|
99
|
+
if (error.message.includes('The resource could not be loaded') || error.message.includes('App Transport Security')) {
|
|
100
|
+
errorMessage = `Network request blocked by iOS App Transport Security. ` + `Please configure ATS exceptions in Info.plist for HTTP endpoints, ` + `or use HTTPS instead. Error: ${error.message}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Network connectivity errors
|
|
104
|
+
if (error.message.includes('Network request failed') || error.message.includes('Failed to fetch')) {
|
|
105
|
+
errorMessage = `Network request failed. Please check your internet connection ` + `and ensure the API endpoint (${this.apiBaseUrl}) is accessible. ` + `Error: ${error.message}`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Timeout errors
|
|
109
|
+
if (error.message.includes('timeout')) {
|
|
110
|
+
errorMessage = `Request timeout. The API server may be slow to respond or unreachable. ` + `Error: ${error.message}`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
success: false,
|
|
115
|
+
error: errorMessage
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Update user data
|
|
122
|
+
* @param params Update parameters including userId and data to update
|
|
123
|
+
* @returns Promise with update response
|
|
124
|
+
*/
|
|
125
|
+
async updateUserData(params) {
|
|
126
|
+
try {
|
|
127
|
+
await this.ensureInitialized();
|
|
128
|
+
console.log('params', params, `${this.apiBaseUrl}/embedded-agent/user-context/update?app_user_id=${params.data.app_user_id}`);
|
|
129
|
+
console.log('updateUserData');
|
|
130
|
+
const headers = await this.getHeaders();
|
|
131
|
+
const response = await fetch(`${this.apiBaseUrl}/embedded-agent/user-context/update?app_user_id=${params.data.app_user_id}`, {
|
|
132
|
+
method: 'PUT',
|
|
133
|
+
headers,
|
|
134
|
+
body: JSON.stringify({
|
|
135
|
+
[params.eventKey]: params.data
|
|
136
|
+
})
|
|
137
|
+
});
|
|
138
|
+
const data = await response.json();
|
|
139
|
+
console.log('data after update', data);
|
|
140
|
+
if (!response.ok) {
|
|
141
|
+
throw new Error(data.error || 'Update failed');
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
success: true
|
|
145
|
+
};
|
|
146
|
+
} catch (error) {
|
|
147
|
+
console.log('updateUserData error', error);
|
|
148
|
+
|
|
149
|
+
// Enhanced error handling for common iOS network issues
|
|
150
|
+
let errorMessage = 'Unknown error occurred';
|
|
151
|
+
if (error instanceof Error) {
|
|
152
|
+
errorMessage = error.message;
|
|
153
|
+
|
|
154
|
+
// iOS ATS related errors
|
|
155
|
+
if (error.message.includes('The resource could not be loaded') || error.message.includes('App Transport Security')) {
|
|
156
|
+
errorMessage = `Network request blocked by iOS App Transport Security. ` + `Please configure ATS exceptions in Info.plist for HTTP endpoints, ` + `or use HTTPS instead. Error: ${error.message}`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Network connectivity errors
|
|
160
|
+
if (error.message.includes('Network request failed') || error.message.includes('Failed to fetch')) {
|
|
161
|
+
errorMessage = `Network request failed. Please check your internet connection ` + `and ensure the API endpoint (${this.apiBaseUrl}) is accessible. ` + `Error: ${error.message}`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Timeout errors
|
|
165
|
+
if (error.message.includes('timeout')) {
|
|
166
|
+
errorMessage = `Request timeout. The API server may be slow to respond or unreachable. ` + `Error: ${error.message}`;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
success: false,
|
|
171
|
+
error: errorMessage
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Get token details for a user
|
|
178
|
+
* @param params Parameters including app_user_id and call_type
|
|
179
|
+
* @returns Promise with token details
|
|
180
|
+
*/
|
|
181
|
+
async getTokenDetails(params) {
|
|
182
|
+
try {
|
|
183
|
+
await this.ensureInitialized();
|
|
184
|
+
const headers = await this.getHeaders();
|
|
185
|
+
console.log('params', this.apiBaseUrl, params, headers, `${this.apiBaseUrl}/embedded-agent/token`);
|
|
186
|
+
const response = await fetch(`${this.apiBaseUrl}/embedded-agent/token`, {
|
|
187
|
+
method: 'POST',
|
|
188
|
+
headers,
|
|
189
|
+
body: JSON.stringify(params)
|
|
190
|
+
});
|
|
191
|
+
const data = await response.json();
|
|
192
|
+
console.log('data', data);
|
|
193
|
+
if (!response.ok) {
|
|
194
|
+
throw new Error(data.error || 'Failed to get token details');
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
success: true,
|
|
198
|
+
data: data
|
|
199
|
+
};
|
|
200
|
+
} catch (error) {
|
|
201
|
+
console.log('getTokenDetails error', error);
|
|
202
|
+
|
|
203
|
+
// Enhanced error handling for common iOS network issues
|
|
204
|
+
let errorMessage = 'Unknown error occurred';
|
|
205
|
+
if (error instanceof Error) {
|
|
206
|
+
errorMessage = error.message;
|
|
207
|
+
|
|
208
|
+
// iOS ATS related errors
|
|
209
|
+
if (error.message.includes('The resource could not be loaded') || error.message.includes('App Transport Security')) {
|
|
210
|
+
errorMessage = `Network request blocked by iOS App Transport Security. ` + `Please configure ATS exceptions in Info.plist for HTTP endpoints, ` + `or use HTTPS instead. Error: ${error.message}`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Network connectivity errors
|
|
214
|
+
if (error.message.includes('Network request failed') || error.message.includes('Failed to fetch')) {
|
|
215
|
+
errorMessage = `Network request failed. Please check your internet connection ` + `and ensure the API endpoint (${this.apiBaseUrl}) is accessible. ` + `Error: ${error.message}`;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Timeout errors
|
|
219
|
+
if (error.message.includes('timeout')) {
|
|
220
|
+
errorMessage = `Request timeout. The API server may be slow to respond or unreachable. ` + `Error: ${error.message}`;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
success: false,
|
|
225
|
+
error: errorMessage
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Export convenience functions for backward compatibility
|
|
232
|
+
export const initializeApi = async () => {
|
|
233
|
+
const apiService = APIService.getInstance();
|
|
234
|
+
await apiService.initialize();
|
|
235
|
+
};
|
|
236
|
+
export const registerOnInitialize = async () => {
|
|
237
|
+
const apiService = APIService.getInstance();
|
|
238
|
+
return await apiService.registerOnInitialize();
|
|
239
|
+
};
|
|
240
|
+
export const updateUserData = async params => {
|
|
241
|
+
const apiService = APIService.getInstance();
|
|
242
|
+
return await apiService.updateUserData(params);
|
|
243
|
+
};
|
|
244
|
+
export const getTokenDetails = async params => {
|
|
245
|
+
const apiService = APIService.getInstance();
|
|
246
|
+
return await apiService.getTokenDetails(params);
|
|
247
|
+
};
|
|
248
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { View, Animated } from 'react-native';
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
// React Native compatible waveform simulator
|
|
7
|
+
const useReactNativeAudioWaveform = roomRef => {
|
|
8
|
+
const [isAudioActive, setIsAudioActive] = useState(false);
|
|
9
|
+
const intervalRef = useRef(null);
|
|
10
|
+
const [currentHeights, setCurrentHeights] = useState(Array(10).fill(0));
|
|
11
|
+
|
|
12
|
+
// Create animated values for each bar
|
|
13
|
+
const barCount = 10;
|
|
14
|
+
const animatedBars = useRef(Array(barCount).fill(0).map(() => new Animated.Value(0))).current;
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
// Check if there's an active room connection AND if agent is talking
|
|
17
|
+
const checkAudioActivity = () => {
|
|
18
|
+
const room = roomRef.current;
|
|
19
|
+
if (room?.state !== 'connected') {
|
|
20
|
+
setIsAudioActive(false);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Check if any remote participant is currently speaking
|
|
25
|
+
let isAgentSpeaking = false;
|
|
26
|
+
|
|
27
|
+
// Loop through all remote participants
|
|
28
|
+
room.remoteParticipants.forEach(participant => {
|
|
29
|
+
const audioTrackPublications = Array.from(participant.getTrackPublications().values());
|
|
30
|
+
const remoteAudioTrack = audioTrackPublications.find(pub => pub.track?.kind === 'audio');
|
|
31
|
+
|
|
32
|
+
// Check if this participant has audio track, is not muted, and is actively speaking
|
|
33
|
+
if (remoteAudioTrack?.track && !remoteAudioTrack?.isMuted) {
|
|
34
|
+
// Check audio level to detect actual speech (optional but more accurate)
|
|
35
|
+
const audioLevel = participant.audioLevel || 0;
|
|
36
|
+
if (audioLevel > 0.05) {
|
|
37
|
+
// Threshold for detecting speech
|
|
38
|
+
isAgentSpeaking = true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
setIsAudioActive(isAgentSpeaking);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Initial check
|
|
46
|
+
checkAudioActivity();
|
|
47
|
+
|
|
48
|
+
// Set up periodic checking for room state changes
|
|
49
|
+
intervalRef.current = setInterval(checkAudioActivity, 500);
|
|
50
|
+
|
|
51
|
+
// Clean up on unmount
|
|
52
|
+
return () => {
|
|
53
|
+
if (intervalRef.current) {
|
|
54
|
+
clearInterval(intervalRef.current);
|
|
55
|
+
intervalRef.current = null;
|
|
56
|
+
}
|
|
57
|
+
setIsAudioActive(false);
|
|
58
|
+
};
|
|
59
|
+
}, [roomRef]);
|
|
60
|
+
|
|
61
|
+
// Continuous smooth animation
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
const animateWaveform = () => {
|
|
64
|
+
// Generate smooth waveform data - stop animation completely when not active
|
|
65
|
+
const targetHeights = isAudioActive ? Array(barCount).fill(0).map((_, index) => {
|
|
66
|
+
const timeOffset = Date.now() / 800 + index * 0.3;
|
|
67
|
+
const baseHeight = 0.5;
|
|
68
|
+
const amplitude = 0.5;
|
|
69
|
+
const height = baseHeight + amplitude * Math.abs(Math.sin(timeOffset));
|
|
70
|
+
return Math.max(0.1, Math.min(1.0, height));
|
|
71
|
+
}) : Array(barCount).fill(0); // Completely freeze animation when mic is muted
|
|
72
|
+
|
|
73
|
+
// Update current heights for conditional logic
|
|
74
|
+
setCurrentHeights(targetHeights);
|
|
75
|
+
const animations = animatedBars.map((animatedValue, index) => {
|
|
76
|
+
const targetHeight = targetHeights[index] || 0;
|
|
77
|
+
return Animated.timing(animatedValue, {
|
|
78
|
+
toValue: targetHeight,
|
|
79
|
+
duration: isAudioActive ? 400 : 600,
|
|
80
|
+
// Slower fade out when going inactive
|
|
81
|
+
useNativeDriver: false
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
Animated.parallel(animations).start();
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// Start animation immediately and repeat
|
|
88
|
+
animateWaveform();
|
|
89
|
+
const animationInterval = setInterval(animateWaveform, 300);
|
|
90
|
+
return () => {
|
|
91
|
+
clearInterval(animationInterval);
|
|
92
|
+
};
|
|
93
|
+
}, [isAudioActive, animatedBars]);
|
|
94
|
+
return {
|
|
95
|
+
animatedBars,
|
|
96
|
+
currentHeights,
|
|
97
|
+
isActive: isAudioActive
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
export const WaveformVisualizer = ({
|
|
101
|
+
roomRef
|
|
102
|
+
}) => {
|
|
103
|
+
const {
|
|
104
|
+
animatedBars,
|
|
105
|
+
currentHeights
|
|
106
|
+
} = useReactNativeAudioWaveform(roomRef);
|
|
107
|
+
console.log('animatedBars', animatedBars);
|
|
108
|
+
return /*#__PURE__*/_jsx(View, {
|
|
109
|
+
style: {
|
|
110
|
+
flexDirection: 'row',
|
|
111
|
+
alignItems: 'center',
|
|
112
|
+
height: '100%',
|
|
113
|
+
alignSelf: 'center',
|
|
114
|
+
// width: '100%',
|
|
115
|
+
// flex: 1,
|
|
116
|
+
justifyContent: 'center',
|
|
117
|
+
// position: 'absolute',
|
|
118
|
+
zIndex: 1000
|
|
119
|
+
},
|
|
120
|
+
children: animatedBars.map((animatedHeight, idx) => {
|
|
121
|
+
// Use the tracked height values instead of trying to access animated value directly
|
|
122
|
+
const currentHeightValue = currentHeights[idx] || 0.1;
|
|
123
|
+
|
|
124
|
+
// Apply conditional logic based on height
|
|
125
|
+
let conditionalValue;
|
|
126
|
+
if (currentHeightValue > 0.7) {
|
|
127
|
+
conditionalValue = 1;
|
|
128
|
+
} else if (currentHeightValue >= 0.4 && currentHeightValue <= 0.5) {
|
|
129
|
+
conditionalValue = 5;
|
|
130
|
+
} else {
|
|
131
|
+
conditionalValue = 1;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// You can use conditionalValue for width, color, or other properties
|
|
135
|
+
return /*#__PURE__*/_jsx(Animated.View, {
|
|
136
|
+
style: {
|
|
137
|
+
width: conditionalValue === 10 ? 4 : 4,
|
|
138
|
+
borderRadius: 100,
|
|
139
|
+
// Example: wider bars for value 5
|
|
140
|
+
height: animatedHeight.interpolate({
|
|
141
|
+
inputRange: [0, 1],
|
|
142
|
+
outputRange: [0, 25]
|
|
143
|
+
}),
|
|
144
|
+
alignSelf: 'center',
|
|
145
|
+
backgroundColor: idx <= 1 || idx >= 8 ? 'rgba(255, 255, 255, 0.5)' : 'white',
|
|
146
|
+
margin: 1.5
|
|
147
|
+
}
|
|
148
|
+
}, idx);
|
|
149
|
+
})
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=EmbedAudioWave.js.map
|