@100mslive/react-native-hms 1.5.0 → 1.6.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/android/src/main/java/com/reactnativehmssdk/HMSManager.kt +52 -24
- package/android/src/main/java/com/reactnativehmssdk/HMSRNSDK.kt +245 -62
- package/android/src/main/java/com/reactnativehmssdk/HMSView.kt +15 -6
- package/ios/HMSConstants.swift +3 -1
- package/ios/HMSDecoder.swift +1 -1
- package/ios/HMSHelper.swift +44 -7
- package/ios/HMSManager.m +8 -0
- package/ios/HMSManager.swift +35 -1
- package/ios/HMSRNSDK.swift +268 -38
- package/lib/commonjs/classes/HMSAudioTrackSettings.js +14 -0
- package/lib/commonjs/classes/HMSAudioTrackSettings.js.map +1 -1
- package/lib/commonjs/classes/HMSEncoder.js +2 -1
- package/lib/commonjs/classes/HMSEncoder.js.map +1 -1
- package/lib/commonjs/classes/HMSIOSAudioMode.js +13 -0
- package/lib/commonjs/classes/HMSIOSAudioMode.js.map +1 -0
- package/lib/commonjs/classes/HMSSDK.js +50 -0
- package/lib/commonjs/classes/HMSSDK.js.map +1 -1
- package/lib/commonjs/classes/HMSSessionStore.js +173 -0
- package/lib/commonjs/classes/HMSSessionStore.js.map +1 -0
- package/lib/commonjs/classes/HMSUpdateListenerActions.js +8 -0
- package/lib/commonjs/classes/HMSUpdateListenerActions.js.map +1 -1
- package/lib/commonjs/classes/HMSVideoTrackSettings.js +5 -0
- package/lib/commonjs/classes/HMSVideoTrackSettings.js.map +1 -1
- package/lib/commonjs/index.js +12 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/utils/emitter/EventEmitter.js +162 -0
- package/lib/commonjs/utils/emitter/EventEmitter.js.map +1 -0
- package/lib/commonjs/utils/emitter/_EmitterSubscription.js +46 -0
- package/lib/commonjs/utils/emitter/_EmitterSubscription.js.map +1 -0
- package/lib/commonjs/utils/emitter/_EventSubscription.js +36 -0
- package/lib/commonjs/utils/emitter/_EventSubscription.js.map +1 -0
- package/lib/commonjs/utils/emitter/_EventSubscriptionVendor.js +90 -0
- package/lib/commonjs/utils/emitter/_EventSubscriptionVendor.js.map +1 -0
- package/lib/commonjs/utils/index.js +17 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/module/classes/HMSAudioTrackSettings.js +14 -0
- package/lib/module/classes/HMSAudioTrackSettings.js.map +1 -1
- package/lib/module/classes/HMSEncoder.js +2 -1
- package/lib/module/classes/HMSEncoder.js.map +1 -1
- package/lib/module/classes/HMSIOSAudioMode.js +6 -0
- package/lib/module/classes/HMSIOSAudioMode.js.map +1 -0
- package/lib/module/classes/HMSSDK.js +50 -0
- package/lib/module/classes/HMSSDK.js.map +1 -1
- package/lib/module/classes/HMSSessionStore.js +166 -0
- package/lib/module/classes/HMSSessionStore.js.map +1 -0
- package/lib/module/classes/HMSUpdateListenerActions.js +8 -0
- package/lib/module/classes/HMSUpdateListenerActions.js.map +1 -1
- package/lib/module/classes/HMSVideoTrackSettings.js +5 -0
- package/lib/module/classes/HMSVideoTrackSettings.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/emitter/EventEmitter.js +151 -0
- package/lib/module/utils/emitter/EventEmitter.js.map +1 -0
- package/lib/module/utils/emitter/_EmitterSubscription.js +39 -0
- package/lib/module/utils/emitter/_EmitterSubscription.js.map +1 -0
- package/lib/module/utils/emitter/_EventSubscription.js +29 -0
- package/lib/module/utils/emitter/_EventSubscription.js.map +1 -0
- package/lib/module/utils/emitter/_EventSubscriptionVendor.js +83 -0
- package/lib/module/utils/emitter/_EventSubscriptionVendor.js.map +1 -0
- package/lib/module/utils/index.js +2 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/typescript/classes/HMSAudioTrackSettings.d.ts +14 -0
- package/lib/typescript/classes/HMSIOSAudioMode.d.ts +4 -0
- package/lib/typescript/classes/HMSSDK.d.ts +16 -0
- package/lib/typescript/classes/HMSSessionStore.d.ts +63 -0
- package/lib/typescript/classes/HMSUpdateListenerActions.d.ts +9 -1
- package/lib/typescript/classes/HMSVideoTrackSettings.d.ts +5 -0
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/utils/emitter/EventEmitter.d.ts +91 -0
- package/lib/typescript/utils/emitter/_EmitterSubscription.d.ts +29 -0
- package/lib/typescript/utils/emitter/_EventSubscription.d.ts +19 -0
- package/lib/typescript/utils/emitter/_EventSubscriptionVendor.d.ts +44 -0
- package/lib/typescript/utils/index.d.ts +1 -0
- package/package.json +21 -2
- package/sdk-versions.json +2 -2
- package/src/classes/HMSAudioTrackSettings.ts +16 -0
- package/src/classes/HMSEncoder.ts +1 -0
- package/src/classes/HMSIOSAudioMode.ts +4 -0
- package/src/classes/HMSSDK.tsx +70 -4
- package/src/classes/HMSSessionStore.ts +209 -0
- package/src/classes/HMSUpdateListenerActions.ts +8 -0
- package/src/classes/HMSVideoTrackSettings.ts +5 -0
- package/src/index.ts +5 -0
- package/src/utils/emitter/EventEmitter.ts +160 -0
- package/src/utils/emitter/_EmitterSubscription.ts +44 -0
- package/src/utils/emitter/_EventSubscription.ts +28 -0
- package/src/utils/emitter/_EventSubscriptionVendor.ts +89 -0
- package/src/utils/index.ts +1 -0
|
@@ -2,6 +2,7 @@ package com.reactnativehmssdk
|
|
|
2
2
|
|
|
3
3
|
import android.content.Intent
|
|
4
4
|
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
|
5
|
+
import android.util.Log
|
|
5
6
|
import com.facebook.react.bridge.*
|
|
6
7
|
import com.facebook.react.bridge.UiThreadUtil.runOnUiThread
|
|
7
8
|
import kotlinx.coroutines.launch
|
|
@@ -17,6 +18,8 @@ import live.hms.video.sdk.models.enums.HMSPeerUpdate
|
|
|
17
18
|
import live.hms.video.sdk.models.enums.HMSRoomUpdate
|
|
18
19
|
import live.hms.video.sdk.models.enums.HMSTrackUpdate
|
|
19
20
|
import live.hms.video.sdk.models.trackchangerequest.HMSChangeTrackStateRequest
|
|
21
|
+
import live.hms.video.sessionstore.HMSKeyChangeListener
|
|
22
|
+
import live.hms.video.sessionstore.HmsSessionStore
|
|
20
23
|
import live.hms.video.signal.init.HMSTokenListener
|
|
21
24
|
import live.hms.video.signal.init.TokenRequest
|
|
22
25
|
import live.hms.video.signal.init.TokenRequestOptions
|
|
@@ -29,7 +32,7 @@ class HMSRNSDK(
|
|
|
29
32
|
data: ReadableMap?,
|
|
30
33
|
HmsDelegate: HMSManager,
|
|
31
34
|
sdkId: String,
|
|
32
|
-
reactApplicationContext: ReactApplicationContext
|
|
35
|
+
reactApplicationContext: ReactApplicationContext,
|
|
33
36
|
) {
|
|
34
37
|
var hmsSDK: HMSSDK? = null
|
|
35
38
|
var screenshareCallback: Promise? = null
|
|
@@ -45,6 +48,8 @@ class HMSRNSDK(
|
|
|
45
48
|
private var id: String = sdkId
|
|
46
49
|
private var self = this
|
|
47
50
|
private var eventsEnableStatus = mutableMapOf<String, Boolean>()
|
|
51
|
+
private var sessionStore: HmsSessionStore? = null
|
|
52
|
+
private val keyChangeObservers = mutableMapOf<String, HMSKeyChangeListener?>()
|
|
48
53
|
|
|
49
54
|
init {
|
|
50
55
|
val builder = HMSSDK.Builder(reactApplicationContext)
|
|
@@ -100,7 +105,7 @@ class HMSRNSDK(
|
|
|
100
105
|
message,
|
|
101
106
|
message,
|
|
102
107
|
null,
|
|
103
|
-
false
|
|
108
|
+
false,
|
|
104
109
|
)
|
|
105
110
|
data.putString("id", id)
|
|
106
111
|
data.putMap("error", HMSDecoder.getError(hmsError))
|
|
@@ -111,6 +116,21 @@ class HMSRNSDK(
|
|
|
111
116
|
callback?.reject("6002", message)
|
|
112
117
|
}
|
|
113
118
|
|
|
119
|
+
// Handle resetting states and data cleanup
|
|
120
|
+
private fun cleanup() {
|
|
121
|
+
screenshareCallback = null
|
|
122
|
+
audioshareCallback = null
|
|
123
|
+
isAudioSharing = false
|
|
124
|
+
recentRoleChangeRequest = null
|
|
125
|
+
previewInProgress = false
|
|
126
|
+
reconnectingStage = false
|
|
127
|
+
networkQualityUpdatesAttached = false
|
|
128
|
+
eventsEnableStatus.clear()
|
|
129
|
+
sessionStore = null
|
|
130
|
+
keyChangeObservers.clear()
|
|
131
|
+
HMSDecoder.clearRestrictDataStates()
|
|
132
|
+
}
|
|
133
|
+
|
|
114
134
|
fun emitHMSError(error: HMSException) {
|
|
115
135
|
if (eventsEnableStatus["ON_ERROR"] != true) {
|
|
116
136
|
return
|
|
@@ -138,7 +158,7 @@ class HMSRNSDK(
|
|
|
138
158
|
val requiredKeys =
|
|
139
159
|
HMSHelper.getUnavailableRequiredKey(
|
|
140
160
|
credentials,
|
|
141
|
-
arrayOf(Pair("username", "String"), Pair("authToken", "String"))
|
|
161
|
+
arrayOf(Pair("username", "String"), Pair("authToken", "String")),
|
|
142
162
|
)
|
|
143
163
|
if (requiredKeys === null) {
|
|
144
164
|
previewInProgress = true
|
|
@@ -210,7 +230,7 @@ class HMSRNSDK(
|
|
|
210
230
|
data.putString("id", id)
|
|
211
231
|
delegate.emitEvent("ON_PREVIEW", data)
|
|
212
232
|
}
|
|
213
|
-
}
|
|
233
|
+
},
|
|
214
234
|
)
|
|
215
235
|
} else {
|
|
216
236
|
val errorMessage = "preview: $requiredKeys"
|
|
@@ -226,7 +246,7 @@ class HMSRNSDK(
|
|
|
226
246
|
val requiredKeys =
|
|
227
247
|
HMSHelper.getUnavailableRequiredKey(
|
|
228
248
|
credentials,
|
|
229
|
-
arrayOf(Pair("username", "String"), Pair("authToken", "String"))
|
|
249
|
+
arrayOf(Pair("username", "String"), Pair("authToken", "String")),
|
|
230
250
|
)
|
|
231
251
|
if (requiredKeys === null) {
|
|
232
252
|
reconnectingStage = false
|
|
@@ -245,15 +265,14 @@ class HMSRNSDK(
|
|
|
245
265
|
HMSDecoder.getHmsChangeTrackStateRequest(details, id)
|
|
246
266
|
delegate.emitEvent(
|
|
247
267
|
"ON_CHANGE_TRACK_STATE_REQUEST",
|
|
248
|
-
decodedChangeTrackStateRequest
|
|
268
|
+
decodedChangeTrackStateRequest,
|
|
249
269
|
)
|
|
250
270
|
}
|
|
251
271
|
|
|
252
272
|
override fun onRemovedFromRoom(notification: HMSRemovedFromRoom) {
|
|
253
273
|
super.onRemovedFromRoom(notification)
|
|
254
|
-
|
|
255
|
-
HMSDecoder.clearRestrictDataStates()
|
|
256
274
|
if (eventsEnableStatus["ON_REMOVED_FROM_ROOM"] != true) {
|
|
275
|
+
cleanup() // resetting states and doing data cleanup
|
|
257
276
|
return
|
|
258
277
|
}
|
|
259
278
|
val data: WritableMap = Arguments.createMap()
|
|
@@ -268,6 +287,7 @@ class HMSRNSDK(
|
|
|
268
287
|
data.putString("id", id)
|
|
269
288
|
|
|
270
289
|
delegate.emitEvent("ON_REMOVED_FROM_ROOM", data)
|
|
290
|
+
cleanup() // resetting states and doing data cleanup
|
|
271
291
|
}
|
|
272
292
|
|
|
273
293
|
override fun onError(error: HMSException) {
|
|
@@ -396,7 +416,17 @@ class HMSRNSDK(
|
|
|
396
416
|
val decodedChangeRoleRequest = HMSDecoder.getHmsRoleChangeRequest(request, id)
|
|
397
417
|
delegate.emitEvent("ON_ROLE_CHANGE_REQUEST", decodedChangeRoleRequest)
|
|
398
418
|
}
|
|
399
|
-
|
|
419
|
+
|
|
420
|
+
override fun onSessionStoreAvailable(sessionStore: HmsSessionStore) {
|
|
421
|
+
self.sessionStore = sessionStore
|
|
422
|
+
if (eventsEnableStatus["ON_SESSION_STORE_AVAILABLE"] != true) {
|
|
423
|
+
return
|
|
424
|
+
}
|
|
425
|
+
val data: WritableMap = Arguments.createMap()
|
|
426
|
+
data.putString("id", id)
|
|
427
|
+
delegate.emitEvent("ON_SESSION_STORE_AVAILABLE", data)
|
|
428
|
+
}
|
|
429
|
+
},
|
|
400
430
|
)
|
|
401
431
|
} catch (e: HMSException) {
|
|
402
432
|
self.emitHMSError(e)
|
|
@@ -425,7 +455,7 @@ class HMSRNSDK(
|
|
|
425
455
|
data.putString("id", id)
|
|
426
456
|
delegate.emitEvent("ON_SPEAKER", data)
|
|
427
457
|
}
|
|
428
|
-
}
|
|
458
|
+
},
|
|
429
459
|
)
|
|
430
460
|
|
|
431
461
|
hmsSDK?.addRtcStatsObserver(
|
|
@@ -433,7 +463,7 @@ class HMSRNSDK(
|
|
|
433
463
|
override fun onLocalAudioStats(
|
|
434
464
|
audioStats: HMSLocalAudioStats,
|
|
435
465
|
hmsTrack: HMSTrack?,
|
|
436
|
-
hmsPeer: HMSPeer
|
|
466
|
+
hmsPeer: HMSPeer?,
|
|
437
467
|
) {
|
|
438
468
|
if (eventsEnableStatus["ON_LOCAL_AUDIO_STATS"] != true || hmsPeer == null || hmsTrack == null) {
|
|
439
469
|
return
|
|
@@ -453,7 +483,7 @@ class HMSRNSDK(
|
|
|
453
483
|
override fun onLocalVideoStats(
|
|
454
484
|
videoStats: List<HMSLocalVideoStats>,
|
|
455
485
|
hmsTrack: HMSTrack?,
|
|
456
|
-
hmsPeer: HMSPeer
|
|
486
|
+
hmsPeer: HMSPeer?,
|
|
457
487
|
) {
|
|
458
488
|
if (eventsEnableStatus["ON_LOCAL_VIDEO_STATS"] != true || hmsPeer == null || hmsTrack == null) {
|
|
459
489
|
return
|
|
@@ -489,7 +519,7 @@ class HMSRNSDK(
|
|
|
489
519
|
override fun onRemoteAudioStats(
|
|
490
520
|
audioStats: HMSRemoteAudioStats,
|
|
491
521
|
hmsTrack: HMSTrack?,
|
|
492
|
-
hmsPeer: HMSPeer
|
|
522
|
+
hmsPeer: HMSPeer?,
|
|
493
523
|
) {
|
|
494
524
|
if (eventsEnableStatus["ON_REMOTE_AUDIO_STATS"] != true || hmsPeer == null || hmsTrack == null) {
|
|
495
525
|
return
|
|
@@ -509,7 +539,7 @@ class HMSRNSDK(
|
|
|
509
539
|
override fun onRemoteVideoStats(
|
|
510
540
|
videoStats: HMSRemoteVideoStats,
|
|
511
541
|
hmsTrack: HMSTrack?,
|
|
512
|
-
hmsPeer: HMSPeer
|
|
542
|
+
hmsPeer: HMSPeer?,
|
|
513
543
|
) {
|
|
514
544
|
if (eventsEnableStatus["ON_REMOTE_VIDEO_STATS"] != true || hmsPeer == null || hmsTrack == null) {
|
|
515
545
|
return
|
|
@@ -525,7 +555,7 @@ class HMSRNSDK(
|
|
|
525
555
|
data.putString("id", id)
|
|
526
556
|
delegate.emitEvent("ON_REMOTE_VIDEO_STATS", data)
|
|
527
557
|
}
|
|
528
|
-
}
|
|
558
|
+
},
|
|
529
559
|
)
|
|
530
560
|
}
|
|
531
561
|
} else {
|
|
@@ -538,7 +568,7 @@ class HMSRNSDK(
|
|
|
538
568
|
val requiredKeys =
|
|
539
569
|
HMSHelper.getUnavailableRequiredKey(
|
|
540
570
|
data,
|
|
541
|
-
arrayOf(Pair("roomCode", "String"))
|
|
571
|
+
arrayOf(Pair("roomCode", "String")),
|
|
542
572
|
)
|
|
543
573
|
|
|
544
574
|
if (requiredKeys === null) {
|
|
@@ -560,7 +590,7 @@ class HMSRNSDK(
|
|
|
560
590
|
override fun onTokenSuccess(string: String) {
|
|
561
591
|
promise.resolve(string)
|
|
562
592
|
}
|
|
563
|
-
}
|
|
593
|
+
},
|
|
564
594
|
)
|
|
565
595
|
} else {
|
|
566
596
|
val errorMessage = "getAuthTokenByRoomCode: $requiredKeys"
|
|
@@ -598,11 +628,6 @@ class HMSRNSDK(
|
|
|
598
628
|
hmsSDK?.leave(
|
|
599
629
|
object : HMSActionResultListener {
|
|
600
630
|
override fun onSuccess() {
|
|
601
|
-
isAudioSharing = false
|
|
602
|
-
screenshareCallback = null
|
|
603
|
-
audioshareCallback = null
|
|
604
|
-
networkQualityUpdatesAttached = false
|
|
605
|
-
HMSDecoder.clearRestrictDataStates()
|
|
606
631
|
if (fromPIP) {
|
|
607
632
|
context.currentActivity?.moveTaskToBack(false)
|
|
608
633
|
|
|
@@ -615,6 +640,7 @@ class HMSRNSDK(
|
|
|
615
640
|
} else {
|
|
616
641
|
callback?.resolve(emitHMSSuccess())
|
|
617
642
|
}
|
|
643
|
+
cleanup() // resetting states and doing data cleanup
|
|
618
644
|
}
|
|
619
645
|
|
|
620
646
|
override fun onError(error: HMSException) {
|
|
@@ -623,7 +649,7 @@ class HMSRNSDK(
|
|
|
623
649
|
}
|
|
624
650
|
self.emitHMSError(error)
|
|
625
651
|
}
|
|
626
|
-
}
|
|
652
|
+
},
|
|
627
653
|
)
|
|
628
654
|
}
|
|
629
655
|
}
|
|
@@ -632,7 +658,7 @@ class HMSRNSDK(
|
|
|
632
658
|
val requiredKeys =
|
|
633
659
|
HMSHelper.getUnavailableRequiredKey(
|
|
634
660
|
data,
|
|
635
|
-
arrayOf(Pair("message", "String"), Pair("type", "String"))
|
|
661
|
+
arrayOf(Pair("message", "String"), Pair("type", "String")),
|
|
636
662
|
)
|
|
637
663
|
if (requiredKeys === null) {
|
|
638
664
|
hmsSDK?.sendBroadcastMessage(
|
|
@@ -646,7 +672,7 @@ class HMSRNSDK(
|
|
|
646
672
|
override fun onSuccess(hmsMessage: HMSMessage) {
|
|
647
673
|
callback?.resolve(emitHMSSuccess(hmsMessage))
|
|
648
674
|
}
|
|
649
|
-
}
|
|
675
|
+
},
|
|
650
676
|
)
|
|
651
677
|
} else {
|
|
652
678
|
val errorMessage = "sendBroadcastMessage: $requiredKeys"
|
|
@@ -659,7 +685,7 @@ class HMSRNSDK(
|
|
|
659
685
|
val requiredKeys =
|
|
660
686
|
HMSHelper.getUnavailableRequiredKey(
|
|
661
687
|
data,
|
|
662
|
-
arrayOf(Pair("message", "String"), Pair("roles", "Array"), Pair("type", "String"))
|
|
688
|
+
arrayOf(Pair("message", "String"), Pair("roles", "Array"), Pair("type", "String")),
|
|
663
689
|
)
|
|
664
690
|
if (requiredKeys === null) {
|
|
665
691
|
val targetedRoles = data.getArray("roles")?.toArrayList() as? ArrayList<String>
|
|
@@ -678,7 +704,7 @@ class HMSRNSDK(
|
|
|
678
704
|
override fun onSuccess(hmsMessage: HMSMessage) {
|
|
679
705
|
callback?.resolve(emitHMSSuccess(hmsMessage))
|
|
680
706
|
}
|
|
681
|
-
}
|
|
707
|
+
},
|
|
682
708
|
)
|
|
683
709
|
} else {
|
|
684
710
|
val errorMessage = "sendGroupMessage: $requiredKeys"
|
|
@@ -691,7 +717,7 @@ class HMSRNSDK(
|
|
|
691
717
|
val requiredKeys =
|
|
692
718
|
HMSHelper.getUnavailableRequiredKey(
|
|
693
719
|
data,
|
|
694
|
-
arrayOf(Pair("message", "String"), Pair("peerId", "String"), Pair("type", "String"))
|
|
720
|
+
arrayOf(Pair("message", "String"), Pair("peerId", "String"), Pair("type", "String")),
|
|
695
721
|
)
|
|
696
722
|
if (requiredKeys === null) {
|
|
697
723
|
val peerId = data.getString("peerId")
|
|
@@ -709,7 +735,7 @@ class HMSRNSDK(
|
|
|
709
735
|
override fun onSuccess(hmsMessage: HMSMessage) {
|
|
710
736
|
callback?.resolve(emitHMSSuccess(hmsMessage))
|
|
711
737
|
}
|
|
712
|
-
}
|
|
738
|
+
},
|
|
713
739
|
)
|
|
714
740
|
} else {
|
|
715
741
|
self.emitCustomError("PEER_NOT_FOUND")
|
|
@@ -727,7 +753,7 @@ class HMSRNSDK(
|
|
|
727
753
|
val requiredKeys =
|
|
728
754
|
HMSHelper.getUnavailableRequiredKey(
|
|
729
755
|
data,
|
|
730
|
-
arrayOf(Pair("peerId", "String"), Pair("role", "String"), Pair("force", "Boolean"))
|
|
756
|
+
arrayOf(Pair("peerId", "String"), Pair("role", "String"), Pair("force", "Boolean")),
|
|
731
757
|
)
|
|
732
758
|
if (requiredKeys === null) {
|
|
733
759
|
val peerId = data.getString("peerId")
|
|
@@ -751,7 +777,7 @@ class HMSRNSDK(
|
|
|
751
777
|
self.emitHMSError(error)
|
|
752
778
|
callback?.reject(error.code.toString(), error.message)
|
|
753
779
|
}
|
|
754
|
-
}
|
|
780
|
+
},
|
|
755
781
|
)
|
|
756
782
|
}
|
|
757
783
|
}
|
|
@@ -766,7 +792,7 @@ class HMSRNSDK(
|
|
|
766
792
|
val requiredKeys =
|
|
767
793
|
HMSHelper.getUnavailableRequiredKey(
|
|
768
794
|
data,
|
|
769
|
-
arrayOf(Pair("peerId", "String"), Pair("role", "String"), Pair("force", "Boolean"))
|
|
795
|
+
arrayOf(Pair("peerId", "String"), Pair("role", "String"), Pair("force", "Boolean")),
|
|
770
796
|
)
|
|
771
797
|
if (requiredKeys === null) {
|
|
772
798
|
val peerId = data.getString("peerId")
|
|
@@ -790,7 +816,7 @@ class HMSRNSDK(
|
|
|
790
816
|
self.emitHMSError(error)
|
|
791
817
|
promise?.reject(error.code.toString(), error.message)
|
|
792
818
|
}
|
|
793
|
-
}
|
|
819
|
+
},
|
|
794
820
|
)
|
|
795
821
|
}
|
|
796
822
|
}
|
|
@@ -805,7 +831,7 @@ class HMSRNSDK(
|
|
|
805
831
|
val requiredKeys =
|
|
806
832
|
HMSHelper.getUnavailableRequiredKey(
|
|
807
833
|
data,
|
|
808
|
-
arrayOf(Pair("ofRoles", "Array"), Pair("toRole", "String"))
|
|
834
|
+
arrayOf(Pair("ofRoles", "Array"), Pair("toRole", "String")),
|
|
809
835
|
)
|
|
810
836
|
if (requiredKeys === null) {
|
|
811
837
|
val ofRoles = data.getArray("ofRoles")
|
|
@@ -831,7 +857,7 @@ class HMSRNSDK(
|
|
|
831
857
|
self.emitHMSError(error)
|
|
832
858
|
promise?.reject(error.code.toString(), error.message)
|
|
833
859
|
}
|
|
834
|
-
}
|
|
860
|
+
},
|
|
835
861
|
)
|
|
836
862
|
}
|
|
837
863
|
}
|
|
@@ -846,7 +872,7 @@ class HMSRNSDK(
|
|
|
846
872
|
val requiredKeys =
|
|
847
873
|
HMSHelper.getUnavailableRequiredKey(
|
|
848
874
|
data,
|
|
849
|
-
arrayOf(Pair("trackId", "String"), Pair("mute", "Boolean"))
|
|
875
|
+
arrayOf(Pair("trackId", "String"), Pair("mute", "Boolean")),
|
|
850
876
|
)
|
|
851
877
|
if (requiredKeys === null) {
|
|
852
878
|
val trackId = data.getString("trackId")
|
|
@@ -864,7 +890,7 @@ class HMSRNSDK(
|
|
|
864
890
|
self.emitHMSError(error)
|
|
865
891
|
callback?.reject(error.code.toString(), error.message)
|
|
866
892
|
}
|
|
867
|
-
}
|
|
893
|
+
},
|
|
868
894
|
)
|
|
869
895
|
}
|
|
870
896
|
} else {
|
|
@@ -915,7 +941,7 @@ class HMSRNSDK(
|
|
|
915
941
|
self.emitHMSError(error)
|
|
916
942
|
callback?.reject(error.code.toString(), error.message)
|
|
917
943
|
}
|
|
918
|
-
}
|
|
944
|
+
},
|
|
919
945
|
)
|
|
920
946
|
} else {
|
|
921
947
|
val errorMessage = "changeTrackStateForRoles: $requiredKeys"
|
|
@@ -946,7 +972,7 @@ class HMSRNSDK(
|
|
|
946
972
|
val requiredKeys =
|
|
947
973
|
HMSHelper.getUnavailableRequiredKey(
|
|
948
974
|
data,
|
|
949
|
-
arrayOf(Pair("peerId", "String"), Pair("reason", "String"))
|
|
975
|
+
arrayOf(Pair("peerId", "String"), Pair("reason", "String")),
|
|
950
976
|
)
|
|
951
977
|
if (requiredKeys === null) {
|
|
952
978
|
val peerId = data.getString("peerId")
|
|
@@ -964,7 +990,7 @@ class HMSRNSDK(
|
|
|
964
990
|
self.emitHMSError(error)
|
|
965
991
|
callback?.reject(error.code.toString(), error.message)
|
|
966
992
|
}
|
|
967
|
-
}
|
|
993
|
+
},
|
|
968
994
|
)
|
|
969
995
|
} else {
|
|
970
996
|
self.emitCustomError("PEER_NOT_FOUND")
|
|
@@ -981,7 +1007,7 @@ class HMSRNSDK(
|
|
|
981
1007
|
val requiredKeys =
|
|
982
1008
|
HMSHelper.getUnavailableRequiredKey(
|
|
983
1009
|
data,
|
|
984
|
-
arrayOf(Pair("lock", "Boolean"), Pair("reason", "String"))
|
|
1010
|
+
arrayOf(Pair("lock", "Boolean"), Pair("reason", "String")),
|
|
985
1011
|
)
|
|
986
1012
|
if (requiredKeys === null) {
|
|
987
1013
|
hmsSDK?.endRoom(
|
|
@@ -990,12 +1016,13 @@ class HMSRNSDK(
|
|
|
990
1016
|
object : HMSActionResultListener {
|
|
991
1017
|
override fun onSuccess() {
|
|
992
1018
|
callback?.resolve(emitHMSSuccess())
|
|
1019
|
+
cleanup() // resetting states and doing data cleanup
|
|
993
1020
|
}
|
|
994
1021
|
override fun onError(error: HMSException) {
|
|
995
1022
|
self.emitHMSError(error)
|
|
996
1023
|
callback?.reject(error.code.toString(), error.message)
|
|
997
1024
|
}
|
|
998
|
-
}
|
|
1025
|
+
},
|
|
999
1026
|
)
|
|
1000
1027
|
} else {
|
|
1001
1028
|
val errorMessage = "endRoom: $requiredKeys"
|
|
@@ -1016,7 +1043,7 @@ class HMSRNSDK(
|
|
|
1016
1043
|
self.emitHMSError(error)
|
|
1017
1044
|
callback?.reject(error.code.toString(), error.message)
|
|
1018
1045
|
}
|
|
1019
|
-
}
|
|
1046
|
+
},
|
|
1020
1047
|
)
|
|
1021
1048
|
recentRoleChangeRequest = null
|
|
1022
1049
|
} else {
|
|
@@ -1039,7 +1066,7 @@ class HMSRNSDK(
|
|
|
1039
1066
|
override fun onError(error: HMSException) {
|
|
1040
1067
|
customError = error
|
|
1041
1068
|
}
|
|
1042
|
-
}
|
|
1069
|
+
},
|
|
1043
1070
|
)
|
|
1044
1071
|
}
|
|
1045
1072
|
if (customError === null) {
|
|
@@ -1073,7 +1100,7 @@ class HMSRNSDK(
|
|
|
1073
1100
|
val requiredKeys =
|
|
1074
1101
|
HMSHelper.getUnavailableRequiredKey(
|
|
1075
1102
|
data,
|
|
1076
|
-
arrayOf(Pair("trackId", "String"), Pair("playbackAllowed", "Boolean"))
|
|
1103
|
+
arrayOf(Pair("trackId", "String"), Pair("playbackAllowed", "Boolean")),
|
|
1077
1104
|
)
|
|
1078
1105
|
if (requiredKeys === null) {
|
|
1079
1106
|
val trackId = data.getString("trackId")
|
|
@@ -1141,7 +1168,7 @@ class HMSRNSDK(
|
|
|
1141
1168
|
val requiredKeys =
|
|
1142
1169
|
HMSHelper.getUnavailableRequiredKey(
|
|
1143
1170
|
data,
|
|
1144
|
-
arrayOf(Pair("trackId", "String"), Pair("volume", "Float"))
|
|
1171
|
+
arrayOf(Pair("trackId", "String"), Pair("volume", "Float")),
|
|
1145
1172
|
)
|
|
1146
1173
|
|
|
1147
1174
|
if (requiredKeys === null) {
|
|
@@ -1217,7 +1244,7 @@ class HMSRNSDK(
|
|
|
1217
1244
|
callback?.reject(error.code.toString(), error.message)
|
|
1218
1245
|
self.emitHMSError(error)
|
|
1219
1246
|
}
|
|
1220
|
-
}
|
|
1247
|
+
},
|
|
1221
1248
|
)
|
|
1222
1249
|
}
|
|
1223
1250
|
} else {
|
|
@@ -1231,7 +1258,7 @@ class HMSRNSDK(
|
|
|
1231
1258
|
val requiredKeys =
|
|
1232
1259
|
HMSHelper.getUnavailableRequiredKey(
|
|
1233
1260
|
data,
|
|
1234
|
-
arrayOf(Pair("record", "Boolean"), Pair("meetingURL", "String"))
|
|
1261
|
+
arrayOf(Pair("record", "Boolean"), Pair("meetingURL", "String")),
|
|
1235
1262
|
)
|
|
1236
1263
|
if (requiredKeys === null) {
|
|
1237
1264
|
val config = HMSHelper.getRtmpConfig(data)
|
|
@@ -1250,7 +1277,7 @@ class HMSRNSDK(
|
|
|
1250
1277
|
callback?.reject(error.code.toString(), error.message)
|
|
1251
1278
|
self.emitHMSError(error)
|
|
1252
1279
|
}
|
|
1253
|
-
}
|
|
1280
|
+
},
|
|
1254
1281
|
)
|
|
1255
1282
|
}
|
|
1256
1283
|
} else {
|
|
@@ -1270,7 +1297,7 @@ class HMSRNSDK(
|
|
|
1270
1297
|
callback?.reject(error.code.toString(), error.message)
|
|
1271
1298
|
self.emitHMSError(error)
|
|
1272
1299
|
}
|
|
1273
|
-
}
|
|
1300
|
+
},
|
|
1274
1301
|
)
|
|
1275
1302
|
}
|
|
1276
1303
|
|
|
@@ -1300,7 +1327,7 @@ class HMSRNSDK(
|
|
|
1300
1327
|
screenshareCallback = null
|
|
1301
1328
|
callback?.resolve(emitHMSSuccess())
|
|
1302
1329
|
}
|
|
1303
|
-
}
|
|
1330
|
+
},
|
|
1304
1331
|
)
|
|
1305
1332
|
}
|
|
1306
1333
|
|
|
@@ -1316,7 +1343,7 @@ class HMSRNSDK(
|
|
|
1316
1343
|
callback?.reject(error.code.toString(), error.message)
|
|
1317
1344
|
self.emitHMSError(error)
|
|
1318
1345
|
}
|
|
1319
|
-
}
|
|
1346
|
+
},
|
|
1320
1347
|
)
|
|
1321
1348
|
}
|
|
1322
1349
|
|
|
@@ -1331,7 +1358,7 @@ class HMSRNSDK(
|
|
|
1331
1358
|
callback?.reject(error.code.toString(), error.message)
|
|
1332
1359
|
self.emitHMSError(error)
|
|
1333
1360
|
}
|
|
1334
|
-
}
|
|
1361
|
+
},
|
|
1335
1362
|
)
|
|
1336
1363
|
}
|
|
1337
1364
|
|
|
@@ -1371,7 +1398,7 @@ class HMSRNSDK(
|
|
|
1371
1398
|
callback?.reject(error.code.toString(), error.message)
|
|
1372
1399
|
self.emitHMSError(error)
|
|
1373
1400
|
}
|
|
1374
|
-
}
|
|
1401
|
+
},
|
|
1375
1402
|
)
|
|
1376
1403
|
} else {
|
|
1377
1404
|
self.emitCustomError("NAME_UNDEFINED")
|
|
@@ -1428,7 +1455,7 @@ class HMSRNSDK(
|
|
|
1428
1455
|
object : HMSAudioManager.AudioManagerDeviceChangeListener {
|
|
1429
1456
|
override fun onAudioDeviceChanged(
|
|
1430
1457
|
device: HMSAudioManager.AudioDevice?,
|
|
1431
|
-
audioDevicesList: Set<HMSAudioManager.AudioDevice
|
|
1458
|
+
audioDevicesList: Set<HMSAudioManager.AudioDevice>?,
|
|
1432
1459
|
) {
|
|
1433
1460
|
if (eventsEnableStatus["ON_AUDIO_DEVICE_CHANGED"] != true) {
|
|
1434
1461
|
return
|
|
@@ -1443,7 +1470,7 @@ class HMSRNSDK(
|
|
|
1443
1470
|
override fun onError(error: HMSException) {
|
|
1444
1471
|
self.emitHMSError(error)
|
|
1445
1472
|
}
|
|
1446
|
-
}
|
|
1473
|
+
},
|
|
1447
1474
|
)
|
|
1448
1475
|
}
|
|
1449
1476
|
|
|
@@ -1483,7 +1510,7 @@ class HMSRNSDK(
|
|
|
1483
1510
|
audioshareCallback = null
|
|
1484
1511
|
callback?.resolve(emitHMSSuccess())
|
|
1485
1512
|
}
|
|
1486
|
-
}
|
|
1513
|
+
},
|
|
1487
1514
|
)
|
|
1488
1515
|
}
|
|
1489
1516
|
|
|
@@ -1506,6 +1533,7 @@ class HMSRNSDK(
|
|
|
1506
1533
|
}
|
|
1507
1534
|
}
|
|
1508
1535
|
|
|
1536
|
+
@Deprecated("SessionMetaData APIs has been deprecated in favour of Session Store APIs", ReplaceWith("setSessionMetadataForKey"), DeprecationLevel.WARNING)
|
|
1509
1537
|
fun setSessionMetaData(data: ReadableMap, callback: Promise?) {
|
|
1510
1538
|
if (data.hasKey("sessionMetaData")) {
|
|
1511
1539
|
val sessionMetaData = data.getString("sessionMetaData")
|
|
@@ -1520,7 +1548,7 @@ class HMSRNSDK(
|
|
|
1520
1548
|
callback?.reject(error.code.toString(), error.message)
|
|
1521
1549
|
self.emitHMSError(error)
|
|
1522
1550
|
}
|
|
1523
|
-
}
|
|
1551
|
+
},
|
|
1524
1552
|
)
|
|
1525
1553
|
} else {
|
|
1526
1554
|
val errorMessage = "setSessionMetaData: sessionMetaData_Is_Required"
|
|
@@ -1529,18 +1557,23 @@ class HMSRNSDK(
|
|
|
1529
1557
|
}
|
|
1530
1558
|
}
|
|
1531
1559
|
|
|
1560
|
+
@Deprecated("SessionMetaData APIs has been deprecated in favour of Session Store APIs", ReplaceWith("getSessionMetadataForKey"), DeprecationLevel.WARNING)
|
|
1532
1561
|
fun getSessionMetaData(callback: Promise?) {
|
|
1533
1562
|
hmsSDK?.getSessionMetaData(
|
|
1534
1563
|
object : HMSSessionMetadataListener {
|
|
1535
|
-
override fun onSuccess(sessionMetadata:
|
|
1536
|
-
|
|
1564
|
+
override fun onSuccess(sessionMetadata: Any?) {
|
|
1565
|
+
if (sessionMetadata is String?) {
|
|
1566
|
+
callback?.resolve(sessionMetadata)
|
|
1567
|
+
} else {
|
|
1568
|
+
callback?.reject("6002", "Session Store: Unsupported type received, only String type is supported")
|
|
1569
|
+
}
|
|
1537
1570
|
}
|
|
1538
1571
|
|
|
1539
1572
|
override fun onError(error: HMSException) {
|
|
1540
1573
|
callback?.reject(error.code.toString(), error.message)
|
|
1541
1574
|
self.emitHMSError(error)
|
|
1542
1575
|
}
|
|
1543
|
-
}
|
|
1576
|
+
},
|
|
1544
1577
|
)
|
|
1545
1578
|
}
|
|
1546
1579
|
|
|
@@ -1879,7 +1912,7 @@ class HMSRNSDK(
|
|
|
1879
1912
|
val savePath = File(imagePath)
|
|
1880
1913
|
|
|
1881
1914
|
cameraControl.captureImageAtMaxSupportedResolution(
|
|
1882
|
-
savePath
|
|
1915
|
+
savePath,
|
|
1883
1916
|
) { success ->
|
|
1884
1917
|
if (flashActionOnSuccess > 0) {
|
|
1885
1918
|
cameraControl.setFlash(flashActionOnSuccess === 1)
|
|
@@ -1896,4 +1929,154 @@ class HMSRNSDK(
|
|
|
1896
1929
|
rejectCallback(promise, errorMessage)
|
|
1897
1930
|
}
|
|
1898
1931
|
}
|
|
1932
|
+
|
|
1933
|
+
// Mark: Session Store
|
|
1934
|
+
|
|
1935
|
+
fun setSessionMetadataForKey(data: ReadableMap, promise: Promise?) {
|
|
1936
|
+
val requiredKeys = HMSHelper.getUnavailableRequiredKey(data, arrayOf(Pair("key", "String")))
|
|
1937
|
+
if (requiredKeys === null) {
|
|
1938
|
+
val key = data.getString("key")!!
|
|
1939
|
+
val value = data.getString("value")
|
|
1940
|
+
|
|
1941
|
+
sessionStore.let {
|
|
1942
|
+
if (it === null) {
|
|
1943
|
+
val errorMessage = "setSessionMetadataForKey: HmsSessionStore instance is not available!"
|
|
1944
|
+
rejectCallback(promise, errorMessage)
|
|
1945
|
+
return
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1948
|
+
it.set(
|
|
1949
|
+
value, // data/value
|
|
1950
|
+
key, // key
|
|
1951
|
+
object : HMSActionResultListener {
|
|
1952
|
+
override fun onError(error: HMSException) {
|
|
1953
|
+
promise?.reject(error.code.toString(), error.message)
|
|
1954
|
+
}
|
|
1955
|
+
override fun onSuccess() {
|
|
1956
|
+
val result: WritableMap = Arguments.createMap()
|
|
1957
|
+
result.putBoolean("success", true)
|
|
1958
|
+
result.putString("finalValue", value)
|
|
1959
|
+
promise?.resolve(result)
|
|
1960
|
+
}
|
|
1961
|
+
},
|
|
1962
|
+
)
|
|
1963
|
+
}
|
|
1964
|
+
} else {
|
|
1965
|
+
val errorMessage = "setSessionMetadataForKey: $requiredKeys"
|
|
1966
|
+
rejectCallback(promise, errorMessage)
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
fun getSessionMetadataForKey(data: ReadableMap, promise: Promise?) {
|
|
1971
|
+
val requiredKeys = HMSHelper.getUnavailableRequiredKey(data, arrayOf(Pair("key", "String")))
|
|
1972
|
+
if (requiredKeys === null) {
|
|
1973
|
+
val key = data.getString("key")!!
|
|
1974
|
+
|
|
1975
|
+
sessionStore.let {
|
|
1976
|
+
if (it === null) {
|
|
1977
|
+
val errorMessage = "setSessionMetadataForKey: HmsSessionStore instance is not available!"
|
|
1978
|
+
rejectCallback(promise, errorMessage)
|
|
1979
|
+
return
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
it.get(
|
|
1983
|
+
key,
|
|
1984
|
+
object : HMSSessionMetadataListener {
|
|
1985
|
+
override fun onError(error: HMSException) {
|
|
1986
|
+
promise?.reject(error.code.toString(), error.message)
|
|
1987
|
+
}
|
|
1988
|
+
override fun onSuccess(sessionMetadata: Any?) {
|
|
1989
|
+
if (sessionMetadata is String?) {
|
|
1990
|
+
promise?.resolve(sessionMetadata)
|
|
1991
|
+
} else {
|
|
1992
|
+
promise?.reject("6002", "Session Store: Unsupported type received for '$key' key, only String type is supported")
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
},
|
|
1996
|
+
)
|
|
1997
|
+
}
|
|
1998
|
+
} else {
|
|
1999
|
+
val errorMessage = "getSessionMetadataForKey: $requiredKeys"
|
|
2000
|
+
rejectCallback(promise, errorMessage)
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
fun addKeyChangeListener(data: ReadableMap, promise: Promise?) {
|
|
2005
|
+
val requiredKeys = HMSHelper.getUnavailableRequiredKey(data, arrayOf(Pair("keys", "Array"), Pair("uniqueId", "String")))
|
|
2006
|
+
if (requiredKeys === null) {
|
|
2007
|
+
val keys = ArrayList(data.getArray("keys")!!.toArrayList().map { it.toString() })
|
|
2008
|
+
val uniqueId = data.getString("uniqueId")!!
|
|
2009
|
+
|
|
2010
|
+
sessionStore.let {
|
|
2011
|
+
if (it === null) {
|
|
2012
|
+
val errorMessage = "setSessionMetadataForKey: HmsSessionStore instance is not available!"
|
|
2013
|
+
rejectCallback(promise, errorMessage)
|
|
2014
|
+
return
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
val keyChangeListener = object : HMSKeyChangeListener {
|
|
2018
|
+
override fun onKeyChanged(key: String, value: Any?) {
|
|
2019
|
+
val map = Arguments.createMap()
|
|
2020
|
+
map.putString("id", id)
|
|
2021
|
+
map.putString("key", key)
|
|
2022
|
+
if (value is String?) {
|
|
2023
|
+
map.putString("value", value)
|
|
2024
|
+
} else {
|
|
2025
|
+
Log.e("HMSRNSDK", "Session Store: '$value' value received for '$key' key, expected only NullableString type for value")
|
|
2026
|
+
map.putString("value", null) // resetting value to `null`, as the current type is not supported
|
|
2027
|
+
}
|
|
2028
|
+
delegate.emitEvent("ON_SESSION_STORE_CHANGED", map)
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
val actionResultListener = object : HMSActionResultListener {
|
|
2033
|
+
override fun onError(error: HMSException) {
|
|
2034
|
+
promise?.reject(error.code.toString(), error.message)
|
|
2035
|
+
}
|
|
2036
|
+
override fun onSuccess() {
|
|
2037
|
+
keyChangeObservers[uniqueId] = keyChangeListener
|
|
2038
|
+
promise?.resolve(true)
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
it.addKeyChangeListener(
|
|
2043
|
+
keys,
|
|
2044
|
+
keyChangeListener,
|
|
2045
|
+
actionResultListener,
|
|
2046
|
+
)
|
|
2047
|
+
}
|
|
2048
|
+
} else {
|
|
2049
|
+
val errorMessage = "addKeyChangeListener: $requiredKeys"
|
|
2050
|
+
rejectCallback(promise, errorMessage)
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
fun removeKeyChangeListener(data: ReadableMap, promise: Promise?) {
|
|
2055
|
+
val requiredKeys = HMSHelper.getUnavailableRequiredKey(data, arrayOf(Pair("uniqueId", "String")))
|
|
2056
|
+
if (requiredKeys === null) {
|
|
2057
|
+
val uniqueId = data.getString("uniqueId")!!
|
|
2058
|
+
|
|
2059
|
+
sessionStore.let { localSessionStore ->
|
|
2060
|
+
if (localSessionStore === null) {
|
|
2061
|
+
val errorMessage = "removeKeyChangeListener: HmsSessionStore instance is not available!"
|
|
2062
|
+
rejectCallback(promise, errorMessage)
|
|
2063
|
+
return
|
|
2064
|
+
}
|
|
2065
|
+
|
|
2066
|
+
keyChangeObservers[uniqueId].let {
|
|
2067
|
+
if (it == null) {
|
|
2068
|
+
val errorMessage = "removeKeyChangeListener: No listener found to remove for the '$uniqueId' uniqueId passed."
|
|
2069
|
+
rejectCallback(promise, errorMessage)
|
|
2070
|
+
} else {
|
|
2071
|
+
localSessionStore.removeKeyChangeListener(it)
|
|
2072
|
+
keyChangeObservers.remove(uniqueId)
|
|
2073
|
+
promise?.resolve(true)
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
} else {
|
|
2078
|
+
val errorMessage = "removeKeyChangeListener: $requiredKeys"
|
|
2079
|
+
rejectCallback(promise, errorMessage)
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
1899
2082
|
}
|