edoctor-sendbird-calls 1.0.0
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 +20 -0
- package/README.md +33 -0
- package/android/build.gradle +82 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +34 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/ComingCallActivity.java +41 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/RNSendBirdCallsModule.java +2068 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/RNSendBirdCallsPackage.java +32 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/RNVSendBirdCallsVideo.java +10 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/RNVSendBirdCallsVideoManager.java +77 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/RNVideoViewGroup.java +109 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/SharedUtils.java +127 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/VcCallReceiver.java +37 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/VcHeadlessService.java +23 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/VoIPBaseService.java +100 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/VoIPService.java +164 -0
- package/android/src/main/java/com/edoctorsendbirdcalls/XiaomiUtilities.java +75 -0
- package/android/src/main/res/drawable/bar_selector_white.xml +18 -0
- package/android/src/main/res/drawable/button_answer.xml +8 -0
- package/android/src/main/res/drawable/button_reject.xml +8 -0
- package/android/src/main/res/drawable/call_notification_line.xml +8 -0
- package/android/src/main/res/drawable/ic_answer.xml +5 -0
- package/android/src/main/res/drawable/ic_call_notification_answer.xml +6 -0
- package/android/src/main/res/drawable/ic_call_notification_decline.xml +9 -0
- package/android/src/main/res/drawable/ic_reject.xml +5 -0
- package/android/src/main/res/drawable/rn_edit_text_material.xml +36 -0
- package/android/src/main/res/layout/call_notification.xml +124 -0
- package/edoctor-sendbird-calls.podspec +27 -0
- package/ios/CXCallManager.swift +211 -0
- package/ios/CXProvider.swift +38 -0
- package/ios/Extensions/UIKit/UIColor.swift +30 -0
- package/ios/Extensions/UIKit/UIView+Extension.swift +61 -0
- package/ios/Extensions/UIKit/UIViewController.swift +28 -0
- package/ios/PrivacyInfo.xcprivacy +47 -0
- package/ios/RNSendBirdCalls-Bridging-Header.h +3 -0
- package/ios/RNSendBirdCalls.mm +94 -0
- package/ios/RNSendBirdCalls.swift +549 -0
- package/ios/RNSendBirdCallsHelper.swift +28 -0
- package/ios/RNVSendBirdCallsVideo.swift +55 -0
- package/ios/RNVSendBirdCallsVideoManager.mm +6 -0
- package/ios/RNVSendBirdCallsVideoManager.swift +15 -0
- package/ios/SendBirdCallsExtentions.swift +46 -0
- package/lib/module/SendBirdCalls.js +377 -0
- package/lib/module/SendBirdCalls.js.map +1 -0
- package/lib/module/SendBirdCallsEvents.js +108 -0
- package/lib/module/SendBirdCallsEvents.js.map +1 -0
- package/lib/module/SendBirdCallsVideo.js +33 -0
- package/lib/module/SendBirdCallsVideo.js.map +1 -0
- package/lib/module/index.js +14 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/index.type.js +2 -0
- package/lib/module/index.type.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/SendBirdCalls.d.ts +63 -0
- package/lib/typescript/src/SendBirdCalls.d.ts.map +1 -0
- package/lib/typescript/src/SendBirdCallsEvents.d.ts +36 -0
- package/lib/typescript/src/SendBirdCallsEvents.d.ts.map +1 -0
- package/lib/typescript/src/SendBirdCallsVideo.d.ts +18 -0
- package/lib/typescript/src/SendBirdCallsVideo.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +5 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/index.type.d.ts +14 -0
- package/lib/typescript/src/index.type.d.ts.map +1 -0
- package/package.json +154 -0
- package/src/SendBirdCalls.ts +472 -0
- package/src/SendBirdCallsEvents.ts +141 -0
- package/src/SendBirdCallsVideo.tsx +44 -0
- package/src/index.tsx +11 -0
- package/src/index.type.ts +20 -0
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
import { NativeModules, Platform } from 'react-native';
|
|
2
|
+
|
|
3
|
+
const RNSendBirdCalls = NativeModules.RNSendBirdCalls;
|
|
4
|
+
const isIOS = Platform.OS === 'ios';
|
|
5
|
+
|
|
6
|
+
// Types for better type safety
|
|
7
|
+
interface AuthResult {
|
|
8
|
+
succeeded: boolean;
|
|
9
|
+
userId?: string;
|
|
10
|
+
nickname?: string;
|
|
11
|
+
errorCode?: string;
|
|
12
|
+
errorMessage?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface CallResult {
|
|
16
|
+
succeeded: boolean;
|
|
17
|
+
callId?: string;
|
|
18
|
+
caller?: string;
|
|
19
|
+
callee?: string;
|
|
20
|
+
errorCode?: string;
|
|
21
|
+
errorMessage?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface RecordingResult {
|
|
25
|
+
succeeded: boolean;
|
|
26
|
+
recordingId?: string;
|
|
27
|
+
filePath?: string;
|
|
28
|
+
errorCode?: string;
|
|
29
|
+
errorMessage?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface DeviceStatusResult {
|
|
33
|
+
succeeded: boolean;
|
|
34
|
+
isLocked?: boolean;
|
|
35
|
+
isInForeground?: boolean;
|
|
36
|
+
errorMessage?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default (function SendBirdCalls() {
|
|
40
|
+
// MARK: - Authentication
|
|
41
|
+
const authenticate = async (
|
|
42
|
+
userId: string,
|
|
43
|
+
accessToken: string
|
|
44
|
+
): Promise<AuthResult | undefined> => {
|
|
45
|
+
try {
|
|
46
|
+
return await RNSendBirdCalls.authenticate(userId, accessToken ?? '');
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.log('error at authenticate', error);
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const deAuthenticate = async (): Promise<AuthResult | undefined> => {
|
|
54
|
+
try {
|
|
55
|
+
return await RNSendBirdCalls.deAuthenticate();
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.log('error at deAuthenticate', error);
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// MARK: - Initialization
|
|
63
|
+
const initSendBird = async (
|
|
64
|
+
appId: string
|
|
65
|
+
): Promise<AuthResult | undefined> => {
|
|
66
|
+
try {
|
|
67
|
+
return await RNSendBirdCalls.initSendBird(appId);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.log('error at initSendBird', error);
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const shareStorage = (appId: string): void => {
|
|
75
|
+
try {
|
|
76
|
+
RNSendBirdCalls.shareStorage(appId);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.log('error at shareStorage', error);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// MARK: - VoIP and Push Notifications
|
|
83
|
+
const voipRegistry = (): void => {
|
|
84
|
+
try {
|
|
85
|
+
if (isIOS) {
|
|
86
|
+
RNSendBirdCalls.voipRegistry();
|
|
87
|
+
}
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.log('error at voipRegistry', error);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const registerPushToken = async (
|
|
94
|
+
token: string
|
|
95
|
+
): Promise<AuthResult | undefined> => {
|
|
96
|
+
try {
|
|
97
|
+
if (!isIOS) {
|
|
98
|
+
return await RNSendBirdCalls.registerPushToken(token);
|
|
99
|
+
}
|
|
100
|
+
return { succeeded: false, errorMessage: 'Not supported on iOS' };
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.log('error at registerPushToken', error);
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const unregisterPushToken = async (
|
|
108
|
+
token: string
|
|
109
|
+
): Promise<AuthResult | undefined> => {
|
|
110
|
+
try {
|
|
111
|
+
if (!isIOS) {
|
|
112
|
+
return await RNSendBirdCalls.unregisterPushToken(token);
|
|
113
|
+
}
|
|
114
|
+
return { succeeded: false, errorMessage: 'Not supported on iOS' };
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.log('error at unregisterPushToken', error);
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// MARK: - Call Management
|
|
122
|
+
const dial = async (
|
|
123
|
+
calleeId: string,
|
|
124
|
+
isVideoCall: boolean,
|
|
125
|
+
isVideoEnable = true,
|
|
126
|
+
isAudioEnable = true,
|
|
127
|
+
appointmentScheduleId: string,
|
|
128
|
+
eClinicId: string
|
|
129
|
+
): Promise<CallResult | undefined> => {
|
|
130
|
+
try {
|
|
131
|
+
return await RNSendBirdCalls.dial(
|
|
132
|
+
calleeId,
|
|
133
|
+
isVideoCall,
|
|
134
|
+
isVideoEnable,
|
|
135
|
+
isAudioEnable,
|
|
136
|
+
appointmentScheduleId,
|
|
137
|
+
eClinicId
|
|
138
|
+
);
|
|
139
|
+
} catch (error) {
|
|
140
|
+
console.log('error at dial', error);
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const acceptCall = async (
|
|
146
|
+
callId: string,
|
|
147
|
+
isVideoEnable = true,
|
|
148
|
+
isAudioEnable = true
|
|
149
|
+
): Promise<CallResult | undefined> => {
|
|
150
|
+
try {
|
|
151
|
+
return await RNSendBirdCalls.acceptCall(
|
|
152
|
+
callId,
|
|
153
|
+
isVideoEnable,
|
|
154
|
+
isAudioEnable
|
|
155
|
+
);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
console.log('error at acceptCall', error);
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const endCall = async (): Promise<CallResult | undefined> => {
|
|
163
|
+
try {
|
|
164
|
+
return await RNSendBirdCalls.endCall();
|
|
165
|
+
} catch (error) {
|
|
166
|
+
console.log('error at endCall', error);
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const endAllCalls = async (): Promise<AuthResult | undefined> => {
|
|
172
|
+
try {
|
|
173
|
+
return await RNSendBirdCalls.endAllCalls();
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.log('error at endAllCalls', error);
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const getOngoingCalls = async (): Promise<
|
|
181
|
+
Record<string, any>[] | undefined
|
|
182
|
+
> => {
|
|
183
|
+
try {
|
|
184
|
+
return await RNSendBirdCalls.getOngoingCalls();
|
|
185
|
+
} catch (error) {
|
|
186
|
+
console.log('error at getOngoingCalls', error);
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// MARK: - Call Info (Fixed method name)
|
|
192
|
+
const getCallInfo = async (): Promise<CallResult | undefined> => {
|
|
193
|
+
try {
|
|
194
|
+
// Use getCallInfo for Android (as defined in native module)
|
|
195
|
+
if (!isIOS) {
|
|
196
|
+
return await RNSendBirdCalls.getCallInfo();
|
|
197
|
+
}
|
|
198
|
+
// For iOS, you might need to implement this method or use getOngoingCalls
|
|
199
|
+
const ongoingCalls: CallResult[] =
|
|
200
|
+
(await getOngoingCalls()) as CallResult[];
|
|
201
|
+
return ongoingCalls && ongoingCalls.length > 0
|
|
202
|
+
? ongoingCalls[0]
|
|
203
|
+
: undefined;
|
|
204
|
+
} catch (error) {
|
|
205
|
+
console.log('error at getCallInfo', error);
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const getCall = async (callId: string): Promise<CallResult | undefined> => {
|
|
211
|
+
try {
|
|
212
|
+
if (!isIOS) {
|
|
213
|
+
return await RNSendBirdCalls.getCall(callId);
|
|
214
|
+
}
|
|
215
|
+
return { succeeded: false, errorMessage: 'Not supported on iOS' };
|
|
216
|
+
} catch (error) {
|
|
217
|
+
console.log('error at getCall', error);
|
|
218
|
+
return undefined;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// MARK: - Audio/Video Controls
|
|
223
|
+
const muteMicrophone = async (): Promise<AuthResult | undefined> => {
|
|
224
|
+
try {
|
|
225
|
+
return await RNSendBirdCalls.muteMicrophone();
|
|
226
|
+
} catch (error) {
|
|
227
|
+
console.log('error at muteMicrophone', error);
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const unmuteMicrophone = async (): Promise<AuthResult | undefined> => {
|
|
233
|
+
try {
|
|
234
|
+
return await RNSendBirdCalls.unmuteMicrophone();
|
|
235
|
+
} catch (error) {
|
|
236
|
+
console.log('error at unmuteMicrophone', error);
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const startVideo = async (): Promise<AuthResult | undefined> => {
|
|
242
|
+
try {
|
|
243
|
+
return await RNSendBirdCalls.startVideo();
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.log('error at startVideo', error);
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const stopVideo = async (): Promise<AuthResult | undefined> => {
|
|
251
|
+
try {
|
|
252
|
+
return await RNSendBirdCalls.stopVideo();
|
|
253
|
+
} catch (error) {
|
|
254
|
+
console.log('error at stopVideo', error);
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const switchCamera = async (): Promise<AuthResult | undefined> => {
|
|
260
|
+
try {
|
|
261
|
+
return await RNSendBirdCalls.switchCamera();
|
|
262
|
+
} catch (error) {
|
|
263
|
+
console.log('error at switchCamera', error);
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
// MARK: - Recording
|
|
269
|
+
const startRecording = async (
|
|
270
|
+
fileName: string,
|
|
271
|
+
isRemote: boolean
|
|
272
|
+
): Promise<RecordingResult | undefined> => {
|
|
273
|
+
try {
|
|
274
|
+
return await RNSendBirdCalls.startRecording(fileName, isRemote);
|
|
275
|
+
} catch (error) {
|
|
276
|
+
console.log('error at startRecording', error);
|
|
277
|
+
return undefined;
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const stopRecording = async (
|
|
282
|
+
recordingId: string
|
|
283
|
+
): Promise<AuthResult | undefined> => {
|
|
284
|
+
try {
|
|
285
|
+
return await RNSendBirdCalls.stopRecording(recordingId);
|
|
286
|
+
} catch (error) {
|
|
287
|
+
console.log('error at stopRecording', error);
|
|
288
|
+
return undefined;
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// MARK: - Sound Configuration
|
|
293
|
+
const addDirectCallSound = (
|
|
294
|
+
soundType: 'DIALING' | 'RINGING' | 'RECONNECTING' | 'RECONNECTED',
|
|
295
|
+
filename: string
|
|
296
|
+
): void => {
|
|
297
|
+
try {
|
|
298
|
+
RNSendBirdCalls.addDirectCallSound(soundType, filename);
|
|
299
|
+
} catch (error) {
|
|
300
|
+
console.log('error at addDirectCallSound', error);
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
const setDirectCallDialingSoundOnWhenSilentMode = async (
|
|
305
|
+
isEnabled: boolean
|
|
306
|
+
): Promise<AuthResult | undefined> => {
|
|
307
|
+
try {
|
|
308
|
+
if (!isIOS) {
|
|
309
|
+
return await RNSendBirdCalls.setDirectCallDialingSoundOnWhenSilentMode(
|
|
310
|
+
isEnabled
|
|
311
|
+
);
|
|
312
|
+
} else {
|
|
313
|
+
RNSendBirdCalls.setDirectCallDialingSoundOnWhenSilentMode(isEnabled);
|
|
314
|
+
return { succeeded: true };
|
|
315
|
+
}
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.log('error at setDirectCallDialingSoundOnWhenSilentMode', error);
|
|
318
|
+
return undefined;
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// MARK: - Android Specific Features
|
|
323
|
+
const getDeviceLocked = async (): Promise<DeviceStatusResult | undefined> => {
|
|
324
|
+
try {
|
|
325
|
+
if (!isIOS) {
|
|
326
|
+
return await RNSendBirdCalls.getDeviceLocked();
|
|
327
|
+
}
|
|
328
|
+
return { succeeded: false, errorMessage: 'Not supported on iOS' };
|
|
329
|
+
} catch (error) {
|
|
330
|
+
console.log('error at getDeviceLocked', error);
|
|
331
|
+
return undefined;
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const isAppInForeground = async (): Promise<
|
|
336
|
+
DeviceStatusResult | undefined
|
|
337
|
+
> => {
|
|
338
|
+
try {
|
|
339
|
+
if (!isIOS) {
|
|
340
|
+
return await RNSendBirdCalls.isAppInForeground();
|
|
341
|
+
}
|
|
342
|
+
return { succeeded: false, errorMessage: 'Not supported on iOS' };
|
|
343
|
+
} catch (error) {
|
|
344
|
+
console.log('error at isAppInForeground', error);
|
|
345
|
+
return undefined;
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const wakeAppIncomingCall = (params: Record<string, any> = {}): void => {
|
|
350
|
+
try {
|
|
351
|
+
if (!isIOS) {
|
|
352
|
+
RNSendBirdCalls.wakeAppIncomingCall(params);
|
|
353
|
+
}
|
|
354
|
+
} catch (error) {
|
|
355
|
+
console.log('error at wakeAppIncomingCall', error);
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const navigateMainApp = (params: Record<string, any> = {}): void => {
|
|
360
|
+
try {
|
|
361
|
+
if (!isIOS) {
|
|
362
|
+
RNSendBirdCalls.navigateMainApp(params);
|
|
363
|
+
}
|
|
364
|
+
} catch (error) {
|
|
365
|
+
console.log('error at navigateMainApp', error);
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
const finishLockedScreenUI = (): void => {
|
|
370
|
+
try {
|
|
371
|
+
if (!isIOS) {
|
|
372
|
+
RNSendBirdCalls.finishLockedScreenUI();
|
|
373
|
+
}
|
|
374
|
+
} catch (error) {
|
|
375
|
+
console.log('error at finishLockedScreenUI', error);
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
const cancelComingCallNotification = (): void => {
|
|
380
|
+
try {
|
|
381
|
+
if (!isIOS) {
|
|
382
|
+
RNSendBirdCalls.cancelComingCallNotification();
|
|
383
|
+
}
|
|
384
|
+
} catch (error) {
|
|
385
|
+
console.log('error at cancelComingCallNotification', error);
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
// MARK: - Legacy Authentication Methods (Android specific)
|
|
390
|
+
const endIncomingCallNeedAuthentication = async (
|
|
391
|
+
callId: string
|
|
392
|
+
): Promise<CallResult | undefined> => {
|
|
393
|
+
try {
|
|
394
|
+
if (!isIOS) {
|
|
395
|
+
return await RNSendBirdCalls.endIncomingCallNeedAuthentication(callId);
|
|
396
|
+
}
|
|
397
|
+
return { succeeded: false, errorMessage: 'Not supported on iOS' };
|
|
398
|
+
} catch (error) {
|
|
399
|
+
console.log('error at endIncomingCallNeedAuthentication', error);
|
|
400
|
+
return undefined;
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
const acceptIncomingCallNeedAuthentication = async (
|
|
405
|
+
callId: string,
|
|
406
|
+
isVideoEnable = true,
|
|
407
|
+
isAudioEnable = true
|
|
408
|
+
): Promise<CallResult | undefined> => {
|
|
409
|
+
try {
|
|
410
|
+
if (!isIOS) {
|
|
411
|
+
return await RNSendBirdCalls.acceptIncomingCallNeedAuthentication(
|
|
412
|
+
callId,
|
|
413
|
+
isVideoEnable,
|
|
414
|
+
isAudioEnable
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
return { succeeded: false, errorMessage: 'Not supported on iOS' };
|
|
418
|
+
} catch (error) {
|
|
419
|
+
console.log('error at acceptIncomingCallNeedAuthentication', error);
|
|
420
|
+
return undefined;
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
return {
|
|
425
|
+
// Core functionality
|
|
426
|
+
authenticate,
|
|
427
|
+
deAuthenticate,
|
|
428
|
+
initSendBird,
|
|
429
|
+
shareStorage,
|
|
430
|
+
|
|
431
|
+
// VoIP and Push
|
|
432
|
+
voipRegistry,
|
|
433
|
+
registerPushToken,
|
|
434
|
+
unregisterPushToken,
|
|
435
|
+
|
|
436
|
+
// Call management
|
|
437
|
+
dial,
|
|
438
|
+
acceptCall,
|
|
439
|
+
endCall,
|
|
440
|
+
endAllCalls,
|
|
441
|
+
getOngoingCalls,
|
|
442
|
+
getCallInfo,
|
|
443
|
+
getCall,
|
|
444
|
+
|
|
445
|
+
// Audio/Video controls
|
|
446
|
+
muteMicrophone,
|
|
447
|
+
unmuteMicrophone,
|
|
448
|
+
startVideo,
|
|
449
|
+
stopVideo,
|
|
450
|
+
switchCamera,
|
|
451
|
+
|
|
452
|
+
// Recording
|
|
453
|
+
startRecording,
|
|
454
|
+
stopRecording,
|
|
455
|
+
|
|
456
|
+
// Sound configuration
|
|
457
|
+
addDirectCallSound,
|
|
458
|
+
setDirectCallDialingSoundOnWhenSilentMode,
|
|
459
|
+
|
|
460
|
+
// Android specific
|
|
461
|
+
getDeviceLocked,
|
|
462
|
+
isAppInForeground,
|
|
463
|
+
wakeAppIncomingCall,
|
|
464
|
+
navigateMainApp,
|
|
465
|
+
finishLockedScreenUI,
|
|
466
|
+
cancelComingCallNotification,
|
|
467
|
+
|
|
468
|
+
// Legacy methods
|
|
469
|
+
endIncomingCallNeedAuthentication,
|
|
470
|
+
acceptIncomingCallNeedAuthentication,
|
|
471
|
+
};
|
|
472
|
+
})();
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
CallbackRingingType,
|
|
5
|
+
CallbackCallDidAcceptType,
|
|
6
|
+
CallbackConnectedType,
|
|
7
|
+
CallbackCallEndedType,
|
|
8
|
+
CallbackReconnectingType,
|
|
9
|
+
CallbackReconnectedType,
|
|
10
|
+
} from './index.type';
|
|
11
|
+
|
|
12
|
+
const RNSendBirdCalls = NativeModules.RNSendBirdCalls;
|
|
13
|
+
|
|
14
|
+
export default (function SendBirdCallsEvents() {
|
|
15
|
+
const eventNames: Record<string, string> = {
|
|
16
|
+
onRinging: 'onRinging',
|
|
17
|
+
onCallDidAccept: 'onCallDidAccept',
|
|
18
|
+
onConnected: 'onConnected',
|
|
19
|
+
onEnded: 'onEnded',
|
|
20
|
+
onReconnected: 'onReconnected',
|
|
21
|
+
onReconnecting: 'onReconnecting',
|
|
22
|
+
onRemoteAudioSettingsChanged: 'onRemoteAudioSettingsChanged',
|
|
23
|
+
onRemoteVideoSettingsChanged: 'onRemoteVideoSettingsChanged',
|
|
24
|
+
onRecordingSucceeded: 'onRecordingSucceeded',
|
|
25
|
+
onRecordingFailed: 'onRecordingFailed',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Use appropriate event emitter based on platform
|
|
29
|
+
const eventEmitter =
|
|
30
|
+
Platform.OS === 'ios'
|
|
31
|
+
? new NativeEventEmitter(RNSendBirdCalls)
|
|
32
|
+
: new NativeEventEmitter();
|
|
33
|
+
|
|
34
|
+
const numberOfEvents: Record<string, number> = Object.values(
|
|
35
|
+
eventNames
|
|
36
|
+
).reduce((acc, name) => ({ ...acc, [name]: 0 }), {});
|
|
37
|
+
|
|
38
|
+
const createListener = (
|
|
39
|
+
eventName: string,
|
|
40
|
+
callback: any
|
|
41
|
+
): { remove: () => void } => {
|
|
42
|
+
// Initialize counter if it doesn't exist
|
|
43
|
+
if (numberOfEvents[eventName] === undefined) {
|
|
44
|
+
numberOfEvents[eventName] = 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (numberOfEvents[eventName] === 0) {
|
|
48
|
+
RNSendBirdCalls.setNativeEvent(eventName);
|
|
49
|
+
}
|
|
50
|
+
numberOfEvents[eventName] += 1;
|
|
51
|
+
|
|
52
|
+
const subscription = eventEmitter.addListener(eventName, callback);
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
remove: () => {
|
|
56
|
+
if (numberOfEvents[eventName] === 1) {
|
|
57
|
+
RNSendBirdCalls.removeNativeEvent(eventName);
|
|
58
|
+
}
|
|
59
|
+
if (
|
|
60
|
+
numberOfEvents[eventName] !== undefined &&
|
|
61
|
+
numberOfEvents[eventName] > 0
|
|
62
|
+
) {
|
|
63
|
+
numberOfEvents[eventName] -= 1;
|
|
64
|
+
}
|
|
65
|
+
subscription.remove();
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const listenerRinging = (callback: CallbackRingingType) => {
|
|
71
|
+
const eventName = eventNames.onRinging!;
|
|
72
|
+
return createListener(eventName, callback);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const listenerCallDidAccept = (callback: CallbackCallDidAcceptType) => {
|
|
76
|
+
const eventName = eventNames.onCallDidAccept!;
|
|
77
|
+
return createListener(eventName, callback);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const listenerConnected = (callback: CallbackConnectedType) => {
|
|
81
|
+
const eventName = eventNames.onConnected!;
|
|
82
|
+
return createListener(eventName, callback);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const listenerEnded = (callback: CallbackCallEndedType) => {
|
|
86
|
+
const eventName = eventNames.onEnded!;
|
|
87
|
+
return createListener(eventName, callback);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const listenerReconnecting = (callback: CallbackReconnectingType) => {
|
|
91
|
+
const eventName = eventNames.onReconnecting!;
|
|
92
|
+
return createListener(eventName, callback);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const listenerReconnected = (callback: CallbackReconnectedType) => {
|
|
96
|
+
const eventName = eventNames.onReconnected!;
|
|
97
|
+
return createListener(eventName, callback);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const listenerRemoteAudioSettingsChanged = (callback: () => void) => {
|
|
101
|
+
const eventName = eventNames.onRemoteAudioSettingsChanged!;
|
|
102
|
+
return createListener(eventName, callback);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const listenerRemoteVideoSettingsChanged = (callback: () => void) => {
|
|
106
|
+
const eventName = eventNames.onRemoteVideoSettingsChanged!;
|
|
107
|
+
return createListener(eventName, callback);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const listenerRecordingSucceeded = (callback: () => void) => {
|
|
111
|
+
const eventName = eventNames.onRecordingSucceeded!;
|
|
112
|
+
return createListener(eventName, callback);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const listenerRecordingFailed = (callback: () => void) => {
|
|
116
|
+
const eventName = eventNames.onRecordingFailed!;
|
|
117
|
+
return createListener(eventName, callback);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const resetListener = () => {
|
|
121
|
+
Object.keys(numberOfEvents).forEach((key) => {
|
|
122
|
+
numberOfEvents[key] = 0;
|
|
123
|
+
RNSendBirdCalls.removeNativeEvent(key);
|
|
124
|
+
});
|
|
125
|
+
RNSendBirdCalls.removeAllEvents();
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
listenerRinging,
|
|
130
|
+
listenerCallDidAccept,
|
|
131
|
+
listenerConnected,
|
|
132
|
+
listenerEnded,
|
|
133
|
+
listenerReconnected,
|
|
134
|
+
listenerReconnecting,
|
|
135
|
+
listenerRemoteAudioSettingsChanged,
|
|
136
|
+
listenerRemoteVideoSettingsChanged,
|
|
137
|
+
listenerRecordingSucceeded,
|
|
138
|
+
listenerRecordingFailed,
|
|
139
|
+
resetListener,
|
|
140
|
+
};
|
|
141
|
+
})();
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { requireNativeComponent, type ViewStyle } from 'react-native';
|
|
2
|
+
|
|
3
|
+
// Define the native component interface
|
|
4
|
+
interface NativeVideoProps {
|
|
5
|
+
callId: string;
|
|
6
|
+
local: boolean;
|
|
7
|
+
scaleFit: boolean;
|
|
8
|
+
style?: ViewStyle;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Require the native component
|
|
12
|
+
const RNVSendBirdCallsVideo = requireNativeComponent<NativeVideoProps>('RNVSendBirdCallsVideo');
|
|
13
|
+
|
|
14
|
+
// Props interface for the React component
|
|
15
|
+
interface SendBirdCallsVideoProps {
|
|
16
|
+
callId: string;
|
|
17
|
+
local: boolean;
|
|
18
|
+
scaleFit?: boolean;
|
|
19
|
+
style?: ViewStyle;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* SendBird Calls Video Component
|
|
24
|
+
*
|
|
25
|
+
* @param callId - The ID of the active call
|
|
26
|
+
* @param local - true for local video (self), false for remote video (other person)
|
|
27
|
+
* @param scaleFit - true to scale video to fit container, false to fill container
|
|
28
|
+
* @param style - Custom styles for the video view
|
|
29
|
+
*/
|
|
30
|
+
export default function SendBirdCallsVideo({
|
|
31
|
+
callId,
|
|
32
|
+
local,
|
|
33
|
+
scaleFit = true,
|
|
34
|
+
style
|
|
35
|
+
}: SendBirdCallsVideoProps) {
|
|
36
|
+
return (
|
|
37
|
+
<RNVSendBirdCallsVideo
|
|
38
|
+
callId={callId}
|
|
39
|
+
local={local}
|
|
40
|
+
scaleFit={scaleFit}
|
|
41
|
+
style={style}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
}
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Main SendBird Calls functionality
|
|
2
|
+
export { default as SendBirdCalls } from './SendBirdCalls';
|
|
3
|
+
|
|
4
|
+
// Event handling
|
|
5
|
+
export { default as SendBirdCallsEvents } from './SendBirdCallsEvents';
|
|
6
|
+
|
|
7
|
+
// Video component
|
|
8
|
+
export { default as SendBirdCallsVideo } from './SendBirdCallsVideo';
|
|
9
|
+
|
|
10
|
+
// Type definitions
|
|
11
|
+
export * from './index.type';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
type CallbackRingingDataType = Record<string, any>
|
|
2
|
+
export type CallbackRingingType = (data: CallbackRingingDataType) => void
|
|
3
|
+
|
|
4
|
+
type CallbackCallDidAcceptDataType = Record<string, any>
|
|
5
|
+
export type CallbackCallDidAcceptType = (data:CallbackCallDidAcceptDataType) => void
|
|
6
|
+
|
|
7
|
+
type CallbackConnectedDataType = Record<string, any>
|
|
8
|
+
export type CallbackConnectedType = (data: CallbackConnectedDataType) => void
|
|
9
|
+
|
|
10
|
+
type CallbackCallEndedDataType = Record<string, any>
|
|
11
|
+
export type CallbackCallEndedType = (data: CallbackCallEndedDataType) => void
|
|
12
|
+
|
|
13
|
+
type CallbackReconnectingDataType = Record<string, any>
|
|
14
|
+
export type CallbackReconnectingType = (data: CallbackReconnectingDataType) => void
|
|
15
|
+
|
|
16
|
+
type CallbackReconnectedDataType = Record<string, any>
|
|
17
|
+
export type CallbackReconnectedType = (data: CallbackReconnectedDataType) => void
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|