react-native-altibbi 0.1.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.
Files changed (150) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +190 -0
  3. package/android/build.gradle +104 -0
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/AndroidManifest.xml +3 -0
  6. package/android/src/main/AndroidManifestNew.xml +2 -0
  7. package/android/src/main/java/com/altibbi/AltibbiModule.kt +18 -0
  8. package/android/src/main/java/com/altibbi/AltibbiPackage.kt +18 -0
  9. package/android/src/main/java/com/altibbi/OTCustomAudioDevice.java +1146 -0
  10. package/android/src/main/java/com/altibbi/OTPublisherLayout.java +61 -0
  11. package/android/src/main/java/com/altibbi/OTPublisherViewManager.java +30 -0
  12. package/android/src/main/java/com/altibbi/OTRN.java +101 -0
  13. package/android/src/main/java/com/altibbi/OTScreenCapturer.java +120 -0
  14. package/android/src/main/java/com/altibbi/OTSessionManager.java +1281 -0
  15. package/android/src/main/java/com/altibbi/OTSubscriberLayout.java +68 -0
  16. package/android/src/main/java/com/altibbi/OTSubscriberViewManager.java +30 -0
  17. package/android/src/main/java/com/altibbi/Socket.kt +294 -0
  18. package/android/src/main/java/com/altibbi/SocketEventEmitter.kt +25 -0
  19. package/android/src/main/java/com/altibbi/utils/EventUtils.java +189 -0
  20. package/android/src/main/java/com/altibbi/utils/Utils.java +135 -0
  21. package/ios/Altibbi-Bridging-Header.h +6 -0
  22. package/ios/Altibbi.mm +10 -0
  23. package/ios/Altibbi.swift +4 -0
  24. package/ios/OTCustomAudioDriver.swift +696 -0
  25. package/ios/OTPublisher.m +16 -0
  26. package/ios/OTPublisherManager.swift +21 -0
  27. package/ios/OTPublisherView.swift +28 -0
  28. package/ios/OTRN.swift +27 -0
  29. package/ios/OTScreenCapture.h +27 -0
  30. package/ios/OTScreenCapture.m +171 -0
  31. package/ios/OTSessionManager.m +127 -0
  32. package/ios/OTSessionManager.swift +866 -0
  33. package/ios/OTSubscriber.m +15 -0
  34. package/ios/OTSubscriberManager.swift +21 -0
  35. package/ios/OTSubscriberView.swift +29 -0
  36. package/ios/OpenTokReactNative.h +13 -0
  37. package/ios/OpenTokReactNative.m +13 -0
  38. package/ios/SocketReactNative.m +38 -0
  39. package/ios/SocketReactNative.swift +276 -0
  40. package/ios/Utils/EventUtils.swift +143 -0
  41. package/ios/Utils/Utils.swift +126 -0
  42. package/lib/commonjs/connection.js +200 -0
  43. package/lib/commonjs/connection.js.map +1 -0
  44. package/lib/commonjs/data.js +12 -0
  45. package/lib/commonjs/data.js.map +1 -0
  46. package/lib/commonjs/index.js +275 -0
  47. package/lib/commonjs/index.js.map +1 -0
  48. package/lib/commonjs/scoket.js +245 -0
  49. package/lib/commonjs/scoket.js.map +1 -0
  50. package/lib/commonjs/service.js +21 -0
  51. package/lib/commonjs/service.js.map +1 -0
  52. package/lib/commonjs/types.js +2 -0
  53. package/lib/commonjs/types.js.map +1 -0
  54. package/lib/commonjs/video/OT.js +57 -0
  55. package/lib/commonjs/video/OT.js.map +1 -0
  56. package/lib/commonjs/video/OTError.js +17 -0
  57. package/lib/commonjs/video/OTError.js.map +1 -0
  58. package/lib/commonjs/video/OTPublisher.js +171 -0
  59. package/lib/commonjs/video/OTPublisher.js.map +1 -0
  60. package/lib/commonjs/video/OTSession.js +205 -0
  61. package/lib/commonjs/video/OTSession.js.map +1 -0
  62. package/lib/commonjs/video/OTSubscriber.js +185 -0
  63. package/lib/commonjs/video/OTSubscriber.js.map +1 -0
  64. package/lib/commonjs/video/contexts/OTContext.js +11 -0
  65. package/lib/commonjs/video/contexts/OTContext.js.map +1 -0
  66. package/lib/commonjs/video/helpers/OTHelper.js +92 -0
  67. package/lib/commonjs/video/helpers/OTHelper.js.map +1 -0
  68. package/lib/commonjs/video/helpers/OTPublisherHelper.js +117 -0
  69. package/lib/commonjs/video/helpers/OTPublisherHelper.js.map +1 -0
  70. package/lib/commonjs/video/helpers/OTSessionHelper.js +206 -0
  71. package/lib/commonjs/video/helpers/OTSessionHelper.js.map +1 -0
  72. package/lib/commonjs/video/helpers/OTSubscriberHelper.js +121 -0
  73. package/lib/commonjs/video/helpers/OTSubscriberHelper.js.map +1 -0
  74. package/lib/commonjs/video/index.js +42 -0
  75. package/lib/commonjs/video/index.js.map +1 -0
  76. package/lib/commonjs/video/views/OTPublisherView.js +26 -0
  77. package/lib/commonjs/video/views/OTPublisherView.js.map +1 -0
  78. package/lib/commonjs/video/views/OTSubscriberView.js +25 -0
  79. package/lib/commonjs/video/views/OTSubscriberView.js.map +1 -0
  80. package/lib/module/connection.js +180 -0
  81. package/lib/module/connection.js.map +1 -0
  82. package/lib/module/data.js +6 -0
  83. package/lib/module/data.js.map +1 -0
  84. package/lib/module/index.js +12 -0
  85. package/lib/module/index.js.map +1 -0
  86. package/lib/module/scoket.js +235 -0
  87. package/lib/module/scoket.js.map +1 -0
  88. package/lib/module/service.js +14 -0
  89. package/lib/module/service.js.map +1 -0
  90. package/lib/module/types.js +2 -0
  91. package/lib/module/types.js.map +1 -0
  92. package/lib/module/video/OT.js +49 -0
  93. package/lib/module/video/OT.js.map +1 -0
  94. package/lib/module/video/OTError.js +10 -0
  95. package/lib/module/video/OTError.js.map +1 -0
  96. package/lib/module/video/OTPublisher.js +162 -0
  97. package/lib/module/video/OTPublisher.js.map +1 -0
  98. package/lib/module/video/OTSession.js +195 -0
  99. package/lib/module/video/OTSession.js.map +1 -0
  100. package/lib/module/video/OTSubscriber.js +175 -0
  101. package/lib/module/video/OTSubscriber.js.map +1 -0
  102. package/lib/module/video/contexts/OTContext.js +4 -0
  103. package/lib/module/video/contexts/OTContext.js.map +1 -0
  104. package/lib/module/video/helpers/OTHelper.js +82 -0
  105. package/lib/module/video/helpers/OTHelper.js.map +1 -0
  106. package/lib/module/video/helpers/OTPublisherHelper.js +110 -0
  107. package/lib/module/video/helpers/OTPublisherHelper.js.map +1 -0
  108. package/lib/module/video/helpers/OTSessionHelper.js +195 -0
  109. package/lib/module/video/helpers/OTSessionHelper.js.map +1 -0
  110. package/lib/module/video/helpers/OTSubscriberHelper.js +112 -0
  111. package/lib/module/video/helpers/OTSubscriberHelper.js.map +1 -0
  112. package/lib/module/video/index.js +7 -0
  113. package/lib/module/video/index.js.map +1 -0
  114. package/lib/module/video/views/OTPublisherView.js +18 -0
  115. package/lib/module/video/views/OTPublisherView.js.map +1 -0
  116. package/lib/module/video/views/OTSubscriberView.js +17 -0
  117. package/lib/module/video/views/OTSubscriberView.js.map +1 -0
  118. package/lib/typescript/src/connection.d.ts +40 -0
  119. package/lib/typescript/src/connection.d.ts.map +1 -0
  120. package/lib/typescript/src/data.d.ts +7 -0
  121. package/lib/typescript/src/data.d.ts.map +1 -0
  122. package/lib/typescript/src/index.d.ts +12 -0
  123. package/lib/typescript/src/index.d.ts.map +1 -0
  124. package/lib/typescript/src/scoket.d.ts +100 -0
  125. package/lib/typescript/src/scoket.d.ts.map +1 -0
  126. package/lib/typescript/src/service.d.ts +9 -0
  127. package/lib/typescript/src/service.d.ts.map +1 -0
  128. package/lib/typescript/src/types.d.ts +22 -0
  129. package/lib/typescript/src/types.d.ts.map +1 -0
  130. package/package.json +178 -0
  131. package/react-native-altibbi.podspec +46 -0
  132. package/src/connection.ts +255 -0
  133. package/src/data.ts +21 -0
  134. package/src/index.tsx +80 -0
  135. package/src/scoket.ts +365 -0
  136. package/src/service.ts +20 -0
  137. package/src/types.ts +22 -0
  138. package/src/video/OT.js +65 -0
  139. package/src/video/OTError.js +14 -0
  140. package/src/video/OTPublisher.js +193 -0
  141. package/src/video/OTSession.js +168 -0
  142. package/src/video/OTSubscriber.js +148 -0
  143. package/src/video/contexts/OTContext.js +5 -0
  144. package/src/video/helpers/OTHelper.js +91 -0
  145. package/src/video/helpers/OTPublisherHelper.js +122 -0
  146. package/src/video/helpers/OTSessionHelper.js +233 -0
  147. package/src/video/helpers/OTSubscriberHelper.js +125 -0
  148. package/src/video/index.js +13 -0
  149. package/src/video/views/OTPublisherView.js +19 -0
  150. package/src/video/views/OTSubscriberView.js +18 -0
package/src/scoket.ts ADDED
@@ -0,0 +1,365 @@
1
+ import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
2
+
3
+ const LINKING_ERROR =
4
+ `The package 'react-native-altibbi' doesn't seem to be linked. Make sure: \n\n` +
5
+ Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
6
+ '- You rebuilt the app after installing the package\n' +
7
+ '- You are not using Expo managed workflow\n';
8
+
9
+ const SocketReactNative = NativeModules.SocketReactNative
10
+ ? NativeModules.SocketReactNative
11
+ : new Proxy(
12
+ {},
13
+ {
14
+ get() {
15
+ throw new Error(LINKING_ERROR);
16
+ },
17
+ }
18
+ );
19
+
20
+ enum SocketEventName {
21
+ ON_AUTHORIZER = 'SocketReactNative:onAuthorizer',
22
+ ON_CONNECTION_STATE_CHANGE = 'SocketReactNative:onConnectionStateChange',
23
+ ON_SUBSCRIPTION_ERROR = 'SocketReactNative:onSubscriptionError',
24
+ ON_EVENT = 'SocketReactNative:onEvent',
25
+ ON_ERROR = 'SocketReactNative:onError',
26
+ ON_MEMBER_ADDED = 'SocketReactNative:onMemberAdded',
27
+ ON_MEMBER_REMOVED = 'SocketReactNative:onMemberRemoved',
28
+ }
29
+
30
+ export interface TBISocketAuthorizerResult {
31
+ /** required for private channels */
32
+ auth?: string;
33
+ /** required for encrypted channels */
34
+ shared_secret?: string;
35
+ /** required for presence channels, should be stringified JSON */
36
+ channel_data?: string;
37
+ }
38
+
39
+ export class TBISocketEvent {
40
+ channelName: string;
41
+ eventName: string;
42
+ data: any;
43
+ userId?: string;
44
+ constructor(args: {
45
+ channelName: string;
46
+ eventName: string;
47
+ data: any;
48
+ userId?: string;
49
+ }) {
50
+ this.channelName = args.channelName;
51
+ this.eventName = args.eventName;
52
+ this.data = args.data;
53
+ this.userId = args.userId;
54
+ }
55
+ toString() {
56
+ return `{ channelName: ${this.channelName}, eventName: ${this.eventName}, data: ${this.data}, userId: ${this.userId} }`;
57
+ }
58
+ }
59
+
60
+ export class TBISocketMember {
61
+ userId: string;
62
+ userInfo: any;
63
+ constructor(userId: string, userInfo: any) {
64
+ this.userId = userId;
65
+ this.userInfo = userInfo;
66
+ }
67
+
68
+ toString() {
69
+ return `{ userId: ${this.userId}, userInfo: ${JSON.stringify(
70
+ this.userInfo
71
+ )} }`;
72
+ }
73
+ }
74
+
75
+ export class TBISocketChannel {
76
+ channelName: string;
77
+ members = new Map<String, TBISocketMember>();
78
+ me?: TBISocketMember;
79
+ subscriptionCount?: Number;
80
+ onSubscriptionSucceeded?: (data: any) => void;
81
+ onSubscriptionCount?: (subscriptionCount: Number) => void;
82
+ onEvent?: (event: any) => void;
83
+ onMemberAdded?: (member: TBISocketMember) => void;
84
+ onMemberRemoved?: (member: TBISocketMember) => void;
85
+ constructor(args: {
86
+ channelName: string;
87
+ onSubscriptionSucceeded?: (data: any) => void;
88
+ onSubscriptionCount?: (subscriptionCount: Number) => void;
89
+ onEvent?: (member: TBISocketEvent) => void;
90
+ onMemberAdded?: (member: TBISocketMember) => void;
91
+ onMemberRemoved?: (member: TBISocketMember) => void;
92
+ me?: TBISocketMember;
93
+ }) {
94
+ this.channelName = args.channelName;
95
+ this.onSubscriptionSucceeded = args.onSubscriptionSucceeded;
96
+ this.onEvent = args.onEvent;
97
+ this.onMemberAdded = args.onMemberAdded;
98
+ this.onMemberRemoved = args.onMemberRemoved;
99
+ this.onSubscriptionCount = args.onSubscriptionCount;
100
+ this.me = args.me;
101
+ }
102
+
103
+ async unsubscribe() {
104
+ return TBISocket.getInstance().unsubscribe({
105
+ channelName: this.channelName,
106
+ });
107
+ }
108
+
109
+ async trigger(event: TBISocketEvent) {
110
+ if (event.channelName !== this.channelName) {
111
+ throw 'Event is not for this channel';
112
+ }
113
+ return TBISocket.getInstance().trigger(event);
114
+ }
115
+ }
116
+
117
+ export class TBISocket {
118
+ private static instance: TBISocket;
119
+ private socketEventEmitter = new NativeEventEmitter(SocketReactNative);
120
+ public channels = new Map<String, TBISocketChannel>();
121
+ public connectionState = 'DISCONNECTED';
122
+
123
+ private constructor() {}
124
+
125
+ static getInstance(): TBISocket {
126
+ if (!TBISocket.instance) {
127
+ TBISocket.instance = new TBISocket();
128
+ }
129
+ return TBISocket.instance;
130
+ }
131
+
132
+ private addListener(
133
+ socketEventName: SocketEventName,
134
+ callback: (event: any) => void
135
+ ) {
136
+ return this.socketEventEmitter.addListener(socketEventName, callback);
137
+ }
138
+
139
+ public init(args: {
140
+ apiKey: string;
141
+ cluster: string;
142
+ authEndpoint?: string;
143
+ useTLS?: boolean;
144
+ activityTimeout?: Number;
145
+ pongTimeout?: Number;
146
+ maxReconnectionAttempts?: Number;
147
+ maxReconnectGapInSeconds?: Number;
148
+ authorizerTimeoutInSeconds?: Number;
149
+ proxy?: string;
150
+ onConnectionStateChange?: (
151
+ currentState: string,
152
+ previousState: string
153
+ ) => void;
154
+ onAuthorizer?: (
155
+ channelName: string,
156
+ socketId: string
157
+ ) => Promise<TBISocketAuthorizerResult>;
158
+ onError?: (message: string, code: Number, e: any) => void;
159
+ onEvent?: (event: TBISocketEvent) => void;
160
+ onSubscriptionSucceeded?: (channelName: string, data: any) => void;
161
+ onSubscriptionError?: (
162
+ channelName: string,
163
+ message: string,
164
+ e: any
165
+ ) => void;
166
+ onSubscriptionCount?: (
167
+ channelName: string,
168
+ subscriptionCount: Number
169
+ ) => void;
170
+ onDecryptionFailure?: (eventName: string, reason: string) => void;
171
+ onMemberAdded?: (channelName: string, member: TBISocketMember) => void;
172
+ onMemberRemoved?: (channelName: string, member: TBISocketMember) => void;
173
+ }) {
174
+ this.removeAllListeners();
175
+
176
+ this.addListener(
177
+ SocketEventName.ON_CONNECTION_STATE_CHANGE,
178
+ (event: any) => {
179
+ this.connectionState = event.currentState.toUpperCase();
180
+ args.onConnectionStateChange?.(
181
+ event.currentState.toUpperCase(),
182
+ event.previousState.toUpperCase()
183
+ );
184
+ }
185
+ );
186
+
187
+ this.addListener(SocketEventName.ON_ERROR, (event: any) =>
188
+ args.onError?.(event.message, event.code, event.error)
189
+ );
190
+
191
+ this.addListener(SocketEventName.ON_EVENT, (event: any) => {
192
+ const channelName = event.channelName;
193
+ const eventName = event.eventName;
194
+ const data = event.data;
195
+ const userId = event.userId;
196
+ const channel = this.channels.get(channelName);
197
+
198
+ switch (eventName) {
199
+ case 'socket_internal:subscription_succeeded':
200
+ // Depending on the platform implementation we get json or a Map.
201
+ var decodedData = data instanceof Object ? data : JSON.parse(data);
202
+ for (const _userId in decodedData?.presence?.hash) {
203
+ const userInfo = decodedData?.presence?.hash[_userId];
204
+ var member = new TBISocketMember(_userId, userInfo);
205
+ channel?.members.set(member.userId, member);
206
+ if (_userId === userId && channel) {
207
+ channel.me = member;
208
+ }
209
+ }
210
+ args.onSubscriptionSucceeded?.(channelName, decodedData);
211
+ channel?.onSubscriptionSucceeded?.(decodedData);
212
+ break;
213
+ case 'socket_internal:subscription_count':
214
+ // Depending on the platform implementation we get json or a Map.
215
+ var decodedData = data instanceof Object ? data : JSON.parse(data);
216
+ if (channel) {
217
+ channel.subscriptionCount = decodedData.subscription_count;
218
+ }
219
+ args.onSubscriptionCount?.(
220
+ channelName,
221
+ decodedData.subscription_count
222
+ );
223
+ channel?.onSubscriptionCount?.(decodedData.subscription_count);
224
+ break;
225
+ default:
226
+ const socketEvent = new TBISocketEvent(event);
227
+ args.onEvent?.(socketEvent);
228
+ channel?.onEvent?.(socketEvent);
229
+ break;
230
+ }
231
+ });
232
+
233
+ this.addListener(SocketEventName.ON_MEMBER_ADDED, (event) => {
234
+ const user = event.user;
235
+ const channelName = event.channelName;
236
+ var member = new TBISocketMember(user.userId, user.userInfo);
237
+ const channel = this.channels.get(channelName);
238
+ channel?.members.set(member.userId, member);
239
+ args.onMemberAdded?.(channelName, member);
240
+ channel?.onMemberAdded?.(member);
241
+ });
242
+
243
+ this.addListener(SocketEventName.ON_MEMBER_REMOVED, (event) => {
244
+ const user = event.user;
245
+ const channelName = event.channelName;
246
+ var member = new TBISocketMember(user.userId, user.userInfo);
247
+ const channel = this.channels.get(channelName);
248
+ channel?.members.delete(member.userId);
249
+ args.onMemberRemoved?.(channelName, member);
250
+ channel?.onMemberRemoved?.(member);
251
+ });
252
+
253
+ this.addListener(
254
+ SocketEventName.ON_AUTHORIZER,
255
+ async ({ channelName, socketId }) => {
256
+ const data = await args.onAuthorizer?.(channelName, socketId);
257
+ if (data) {
258
+ await SocketReactNative.onAuthorizer(channelName, socketId, data);
259
+ }
260
+ }
261
+ );
262
+
263
+ this.addListener(
264
+ SocketEventName.ON_SUBSCRIPTION_ERROR,
265
+ async ({ channelName, message, type }) => {
266
+ args.onSubscriptionError?.(channelName, message, type);
267
+ }
268
+ );
269
+
270
+ return SocketReactNative.initialize({
271
+ apiKey: args.apiKey,
272
+ cluster: args.cluster,
273
+ authEndpoint: args.authEndpoint,
274
+ useTLS: args.useTLS,
275
+ activityTimeout: args.activityTimeout,
276
+ pongTimeout: args.pongTimeout,
277
+ maxReconnectionAttempts: args.maxReconnectionAttempts,
278
+ maxReconnectGapInSeconds: args.maxReconnectGapInSeconds,
279
+ authorizerTimeoutInSeconds: args.authorizerTimeoutInSeconds,
280
+ authorizer: args.onAuthorizer ? true : false,
281
+ proxy: args.proxy,
282
+ });
283
+ }
284
+
285
+ public async connect() {
286
+ return await SocketReactNative.connect();
287
+ }
288
+
289
+ public async disconnect() {
290
+ return await SocketReactNative.disconnect();
291
+ }
292
+
293
+ private unsubscribeAllChannels() {
294
+ const channelsCopy = new Map(this.channels);
295
+ channelsCopy.forEach((channel) => {
296
+ this.unsubscribe({ channelName: channel.channelName });
297
+ });
298
+ }
299
+
300
+ private removeAllListeners() {
301
+ this.socketEventEmitter.removeAllListeners(SocketEventName.ON_AUTHORIZER);
302
+ this.socketEventEmitter.removeAllListeners(SocketEventName.ON_ERROR);
303
+ this.socketEventEmitter.removeAllListeners(SocketEventName.ON_EVENT);
304
+ this.socketEventEmitter.removeAllListeners(SocketEventName.ON_MEMBER_ADDED);
305
+ this.socketEventEmitter.removeAllListeners(
306
+ SocketEventName.ON_MEMBER_REMOVED
307
+ );
308
+ }
309
+
310
+ public async reset() {
311
+ this.removeAllListeners();
312
+ this.unsubscribeAllChannels();
313
+ }
314
+
315
+ async subscribe(args: {
316
+ channelName: string;
317
+ onSubscriptionSucceeded?: (data: any) => void;
318
+ onSubscriptionError?: (
319
+ channelName: string,
320
+ message: string,
321
+ e: any
322
+ ) => void;
323
+ onMemberAdded?: (member: TBISocketMember) => void;
324
+ onMemberRemoved?: (member: TBISocketMember) => void;
325
+ onEvent?: (event: TBISocketEvent) => void;
326
+ }) {
327
+ const channel = this.channels.get(args.channelName);
328
+ if (channel) {
329
+ return channel;
330
+ }
331
+
332
+ const newChannel = new TBISocketChannel(args);
333
+ await SocketReactNative.subscribe(args.channelName);
334
+ this.channels.set(args.channelName, newChannel);
335
+ return newChannel;
336
+ }
337
+
338
+ public async unsubscribe({ channelName }: { channelName: string }) {
339
+ await SocketReactNative.unsubscribe(channelName);
340
+ this.channels.delete(channelName);
341
+ }
342
+
343
+ public async trigger(event: TBISocketEvent) {
344
+ if (
345
+ event.channelName.startsWith('private-') ||
346
+ event.channelName.startsWith('presence-')
347
+ ) {
348
+ await SocketReactNative.trigger(
349
+ event.channelName,
350
+ event.eventName,
351
+ event.data
352
+ );
353
+ } else {
354
+ throw 'Trigger event is only for private/presence channels';
355
+ }
356
+ }
357
+
358
+ public async getSocketId() {
359
+ return await SocketReactNative.getSocketId();
360
+ }
361
+
362
+ public getChannel(channelName: string): TBISocketChannel | undefined {
363
+ return this.channels.get(channelName);
364
+ }
365
+ }
package/src/service.ts ADDED
@@ -0,0 +1,20 @@
1
+ interface ConstantObject {
2
+ domain: string;
3
+ language: string;
4
+ token: string;
5
+ }
6
+
7
+ export let TBIConstants: ConstantObject = {
8
+ domain: '',
9
+ language: 'ar',
10
+ token: '',
11
+ };
12
+
13
+ export const init = (domain: string, language: string, token: string) => {
14
+ console.log("init", domain, language, token);
15
+ TBIConstants = {
16
+ domain,
17
+ language,
18
+ token,
19
+ };
20
+ };
package/src/types.ts ADDED
@@ -0,0 +1,22 @@
1
+ export type MediumType = 'chat' | 'gsm' | 'voip' | 'video';
2
+ export type BloodType = 'A+' | 'B+' | 'AB+' | 'O+' | 'A-' | 'B-' | 'AB-' | 'O-';
3
+ export type MaritalStatus = 'single' | 'married' | 'divorced' | 'widow';
4
+ export type BoolString = 'yes' | 'no';
5
+ export type GenderType = 'male' | 'female';
6
+ export interface UserType {
7
+ name?: string;
8
+ phoneNumber?: string;
9
+ email?: string;
10
+ dateOfBirth?: string;
11
+ gender?: GenderType;
12
+ insuranceId?: string;
13
+ policyNumber?: string;
14
+ nationalityNumber?: string;
15
+ height?: string;
16
+ weight?: string;
17
+ bloodType?: BloodType;
18
+ smoker?: BoolString;
19
+ alcoholic?: BoolString;
20
+ maritalStatus?: MaritalStatus;
21
+ }
22
+
@@ -0,0 +1,65 @@
1
+ import { NativeModules, NativeEventEmitter, PermissionsAndroid } from 'react-native';
2
+ import { each } from 'underscore';
3
+
4
+ const OT = NativeModules.OTSessionManager;
5
+ const nativeEvents = new NativeEventEmitter(OT);
6
+
7
+ const checkAndroidPermissions = () => new Promise((resolve, reject) => {
8
+ PermissionsAndroid.requestMultiple([
9
+ PermissionsAndroid.PERMISSIONS.CAMERA,
10
+ PermissionsAndroid.PERMISSIONS.RECORD_AUDIO])
11
+ .then((result) => {
12
+ const permissionsError = {};
13
+ permissionsError.permissionsDenied = [];
14
+ each(result, (permissionValue, permissionType) => {
15
+ // Check if the permission is denied or set to 'never_ask_again'.
16
+ if (permissionValue === 'denied' || permissionValue === 'never_ask_again' ) {
17
+ permissionsError.permissionsDenied.push(permissionType);
18
+ permissionsError.type = 'Permissions error';
19
+ }
20
+ });
21
+ if (permissionsError.permissionsDenied.length > 0) {
22
+ reject(permissionsError);
23
+ } else {
24
+ resolve();
25
+ }
26
+ })
27
+ .catch((error) => {
28
+ reject(error);
29
+ });
30
+ });
31
+
32
+ const setNativeEvents = (events) => {
33
+ const eventNames = Object.keys(events);
34
+ OT.setNativeEvents(eventNames);
35
+
36
+ let hasRegisteredEvents;
37
+ if (nativeEvents.listeners) {
38
+ const allEvents = nativeEvents.listeners();
39
+ hasRegisteredEvents = (eventType) => allEvents.includes(eventType);
40
+ } else {
41
+ hasRegisteredEvents = (eventType) => nativeEvents.listenerCount(eventType) > 0;
42
+ }
43
+
44
+ each(events, (eventHandler, eventType) => {
45
+ if (!hasRegisteredEvents(eventType)) {
46
+ nativeEvents.addListener(eventType, eventHandler);
47
+ }
48
+ });
49
+ };
50
+
51
+ const removeNativeEvents = (events) => {
52
+ const eventNames = Object.keys(events);
53
+ OT.removeNativeEvents(eventNames);
54
+ each(events, (_eventHandler, eventType) => {
55
+ nativeEvents.removeAllListeners(eventType);
56
+ });
57
+ };
58
+
59
+ export {
60
+ OT,
61
+ nativeEvents,
62
+ checkAndroidPermissions,
63
+ setNativeEvents,
64
+ removeNativeEvents,
65
+ };
@@ -0,0 +1,14 @@
1
+ const handleError = (error) => {
2
+ console.log('OTRN JS: There was an error: ', error);
3
+ };
4
+
5
+ const handleSignalError = (error) => {
6
+ if (error) {
7
+ console.log(`OTRN JS: There was an error sending the signal ${error}`);
8
+ }
9
+ };
10
+
11
+ export {
12
+ handleError,
13
+ handleSignalError,
14
+ };
@@ -0,0 +1,193 @@
1
+ import React, { Component } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { View, Platform } from 'react-native';
4
+ import { isNull } from 'underscore';
5
+ import {
6
+ checkAndroidPermissions,
7
+ OT,
8
+ removeNativeEvents,
9
+ nativeEvents,
10
+ setNativeEvents,
11
+ } from './OT';
12
+ import {
13
+ sanitizeProperties,
14
+ sanitizePublisherEvents,
15
+ } from './helpers/OTPublisherHelper';
16
+ import OTPublisherView from './views/OTPublisherView';
17
+ import { getOtrnErrorEventHandler } from './helpers/OTHelper';
18
+ import { isConnected } from './helpers/OTSessionHelper';
19
+ import OTContext from './contexts/OTContext';
20
+ const uuid = require('uuid/v4');
21
+
22
+ class OTPublisher extends Component {
23
+ constructor(props, context) {
24
+ super(props, context);
25
+ this.state = {
26
+ initError: null,
27
+ publisher: null,
28
+ publisherId: uuid(),
29
+ };
30
+ this.initComponent();
31
+ }
32
+ initComponent = () => {
33
+ this.componentEvents = {
34
+ sessionConnected:
35
+ Platform.OS === 'android'
36
+ ? 'session:onConnected'
37
+ : 'session:sessionDidConnect',
38
+ };
39
+ this.componentEventsArray = Object.values(this.componentEvents);
40
+ this.otrnEventHandler = getOtrnErrorEventHandler(this.props.eventHandlers);
41
+ this.publisherEvents = sanitizePublisherEvents(
42
+ this.state.publisherId,
43
+ this.props.eventHandlers
44
+ );
45
+ setNativeEvents(this.publisherEvents);
46
+ OT.setJSComponentEvents(this.componentEventsArray);
47
+ if (this.context.sessionId) {
48
+ this.sessionConnected = nativeEvents.addListener(
49
+ `${this.context.sessionId}:${this.componentEvents.sessionConnected}`,
50
+ () => this.sessionConnectedHandler()
51
+ );
52
+ }
53
+ };
54
+ componentDidMount() {
55
+ this.createPublisher();
56
+ }
57
+ componentDidUpdate(previousProps) {
58
+ const useDefault = (value, defaultValue) =>
59
+ value === undefined ? defaultValue : value;
60
+ const shouldUpdate = (key, defaultValue) => {
61
+ const previous = useDefault(previousProps.properties[key], defaultValue);
62
+ const current = useDefault(this.props.properties[key], defaultValue);
63
+ return previous !== current;
64
+ };
65
+
66
+ const updatePublisherProperty = (key, defaultValue) => {
67
+ if (shouldUpdate(key, defaultValue)) {
68
+ const value = useDefault(this.props.properties[key], defaultValue);
69
+ if (key === 'cameraPosition') {
70
+ OT.changeCameraPosition(this.state.publisherId, value);
71
+ } else if (key === 'videoContentHint') {
72
+ OT.changeVideoContentHint(this.state.publisherId, value);
73
+ } else {
74
+ OT[key](this.state.publisherId, value);
75
+ }
76
+ }
77
+ };
78
+
79
+ updatePublisherProperty('publishAudio', true);
80
+ updatePublisherProperty('publishVideo', true);
81
+ updatePublisherProperty('publishCaptions', false);
82
+ updatePublisherProperty('cameraPosition', 'front');
83
+ updatePublisherProperty('videoContentHint', '');
84
+ }
85
+ componentWillUnmount() {
86
+ OT.destroyPublisher(this.state.publisherId, (error) => {
87
+ if (error) {
88
+ this.otrnEventHandler(error);
89
+ } else {
90
+ this.sessionConnected.remove();
91
+ OT.removeJSComponentEvents(this.componentEventsArray);
92
+ removeNativeEvents(this.publisherEvents);
93
+ }
94
+ });
95
+ }
96
+ sessionConnectedHandler = () => {
97
+ if (isNull(this.state.publisher) && isNull(this.state.initError)) {
98
+ this.publish();
99
+ }
100
+ };
101
+ createPublisher() {
102
+ if (Platform.OS === 'android') {
103
+ checkAndroidPermissions()
104
+ .then(() => {
105
+ this.initPublisher();
106
+ })
107
+ .catch((error) => {
108
+ this.otrnEventHandler(error);
109
+ });
110
+ } else {
111
+ this.initPublisher();
112
+ }
113
+ }
114
+ initPublisher() {
115
+ const publisherProperties = sanitizeProperties(this.props.properties);
116
+ OT.initPublisher(
117
+ this.state.publisherId,
118
+ publisherProperties,
119
+ (initError) => {
120
+ if (initError) {
121
+ this.setState({
122
+ initError,
123
+ });
124
+ this.otrnEventHandler(initError);
125
+ } else {
126
+ if (this.context.sessionId) {
127
+ OT.getSessionInfo(this.context.sessionId, (session) => {
128
+ if (
129
+ !isNull(session) &&
130
+ isNull(this.state.publisher) &&
131
+ isConnected(session.connectionStatus)
132
+ ) {
133
+ this.publish();
134
+ }
135
+ });
136
+ }
137
+ }
138
+ }
139
+ );
140
+ }
141
+ publish() {
142
+ OT.publish(
143
+ this.context.sessionId,
144
+ this.state.publisherId,
145
+ (publishError) => {
146
+ if (publishError) {
147
+ this.otrnEventHandler(publishError);
148
+ } else {
149
+ this.setState({
150
+ publisher: true,
151
+ });
152
+ }
153
+ }
154
+ );
155
+ }
156
+ getRtcStatsReport() {
157
+ OT.getRtcStatsReport(this.state.publisherId);
158
+ }
159
+
160
+ setVideoTransformers(videoTransformers) {
161
+ OT.setVideoTransformers(this.state.publisherId, videoTransformers);
162
+ }
163
+
164
+ render() {
165
+ const { publisher, publisherId } = this.state;
166
+ const { sessionId } = this.context;
167
+ if (publisher && publisherId) {
168
+ return (
169
+ <OTPublisherView
170
+ publisherId={publisherId}
171
+ sessionId={sessionId}
172
+ {...this.props}
173
+ />
174
+ );
175
+ }
176
+ return <View />;
177
+ }
178
+ }
179
+ const viewPropTypes = View.propTypes;
180
+ OTPublisher.propTypes = {
181
+ ...viewPropTypes,
182
+ properties: PropTypes.object, // eslint-disable-line react/forbid-prop-types
183
+ eventHandlers: PropTypes.object, // eslint-disable-line react/forbid-prop-types
184
+ getRtcStatsReport: PropTypes.object, // eslint-disable-line react/forbid-prop-types
185
+ setVideoTransformers: PropTypes.func, // eslint-disable-line react/forbid-prop-types
186
+ };
187
+ OTPublisher.defaultProps = {
188
+ properties: {},
189
+ eventHandlers: {},
190
+ getRtcStatsReport: {},
191
+ };
192
+ OTPublisher.contextType = OTContext;
193
+ export default OTPublisher;