@fishjam-cloud/react-native-client 0.4.1 → 0.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.
Files changed (127) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/src/main/java/io/fishjam/reactnative/EmitableEvents.kt +104 -20
  3. package/android/src/main/java/io/fishjam/reactnative/RNFishjamClient.kt +83 -99
  4. package/android/src/main/java/io/fishjam/reactnative/RNFishjamClientModule.kt +21 -30
  5. package/android/src/main/java/io/fishjam/reactnative/VideoRendererViewModule.kt +6 -2
  6. package/android/src/main/java/io/fishjam/reactnative/VideoView.kt +41 -3
  7. package/android/src/main/java/io/fishjam/reactnative/extensions/CaptureDevice.kt +17 -0
  8. package/android/src/main/java/io/fishjam/reactnative/foregroundService/FishjamForegroundService.kt +10 -4
  9. package/android/src/main/java/io/fishjam/reactnative/foregroundService/ForegroundServiceManager.kt +41 -70
  10. package/android/src/main/java/io/fishjam/reactnative/foregroundService/ForegroundServiceState.kt +46 -0
  11. package/android/src/main/java/io/fishjam/reactnative/managers/ListenerManager.kt +22 -0
  12. package/android/src/main/java/io/fishjam/reactnative/managers/LocalCameraTracksChangedListenersManager.kt +2 -15
  13. package/android/src/main/java/io/fishjam/reactnative/managers/LocalTracksSwitchListenersManager.kt +1 -11
  14. package/android/src/main/java/io/fishjam/reactnative/managers/TracksUpdateListenersManager.kt +1 -15
  15. package/build/RNFishjamClientModule.d.ts +28 -12
  16. package/build/RNFishjamClientModule.d.ts.map +1 -1
  17. package/build/RNFishjamClientModule.js +19 -4
  18. package/build/RNFishjamClientModule.js.map +1 -1
  19. package/build/common/client.d.ts +0 -4
  20. package/build/common/client.d.ts.map +1 -1
  21. package/build/common/client.js +0 -4
  22. package/build/common/client.js.map +1 -1
  23. package/build/common/metadata.d.ts +1 -1
  24. package/build/common/metadata.js +1 -1
  25. package/build/common/metadata.js.map +1 -1
  26. package/build/common/webRTC.d.ts +2 -1
  27. package/build/common/webRTC.d.ts.map +1 -1
  28. package/build/common/webRTC.js.map +1 -1
  29. package/build/components/FishjamRoom/GridTrackItem.d.ts +11 -0
  30. package/build/components/FishjamRoom/GridTrackItem.d.ts.map +1 -0
  31. package/build/components/FishjamRoom/GridTrackItem.js +56 -0
  32. package/build/components/FishjamRoom/GridTrackItem.js.map +1 -0
  33. package/build/components/FishjamRoom/VideosGrid.d.ts +3 -0
  34. package/build/components/FishjamRoom/VideosGrid.d.ts.map +1 -0
  35. package/build/components/FishjamRoom/VideosGrid.js +20 -0
  36. package/build/components/FishjamRoom/VideosGrid.js.map +1 -0
  37. package/build/components/FishjamRoom/index.d.ts +6 -0
  38. package/build/components/FishjamRoom/index.d.ts.map +1 -0
  39. package/build/components/FishjamRoom/index.js +29 -0
  40. package/build/components/FishjamRoom/index.js.map +1 -0
  41. package/build/components/FishjamRoom/parsePeersToTracks.d.ts +4 -0
  42. package/build/components/FishjamRoom/parsePeersToTracks.d.ts.map +1 -0
  43. package/build/components/FishjamRoom/parsePeersToTracks.js +34 -0
  44. package/build/components/FishjamRoom/parsePeersToTracks.js.map +1 -0
  45. package/build/components/VideoRendererView.d.ts +6 -1
  46. package/build/components/VideoRendererView.d.ts.map +1 -1
  47. package/build/components/VideoRendererView.js.map +1 -1
  48. package/build/debug/stats/useRTCStatistics.d.ts.map +1 -1
  49. package/build/debug/stats/useRTCStatistics.js +13 -13
  50. package/build/debug/stats/useRTCStatistics.js.map +1 -1
  51. package/build/hooks/internal/useFishjamEvent.d.ts +3 -0
  52. package/build/hooks/internal/useFishjamEvent.d.ts.map +1 -0
  53. package/build/hooks/internal/useFishjamEvent.js +11 -0
  54. package/build/hooks/internal/useFishjamEvent.js.map +1 -0
  55. package/build/hooks/internal/useFishjamEventState.d.ts +3 -0
  56. package/build/hooks/internal/useFishjamEventState.d.ts.map +1 -0
  57. package/build/hooks/internal/useFishjamEventState.js +18 -0
  58. package/build/hooks/internal/useFishjamEventState.js.map +1 -0
  59. package/build/hooks/useAppScreenShare.d.ts.map +1 -1
  60. package/build/hooks/useAppScreenShare.js +6 -8
  61. package/build/hooks/useAppScreenShare.js.map +1 -1
  62. package/build/hooks/useAudioSettings.d.ts.map +1 -1
  63. package/build/hooks/useAudioSettings.js +8 -11
  64. package/build/hooks/useAudioSettings.js.map +1 -1
  65. package/build/hooks/useBandwidthEstimation.d.ts.map +1 -1
  66. package/build/hooks/useBandwidthEstimation.js +3 -4
  67. package/build/hooks/useBandwidthEstimation.js.map +1 -1
  68. package/build/hooks/useCamera.d.ts +6 -2
  69. package/build/hooks/useCamera.d.ts.map +1 -1
  70. package/build/hooks/useCamera.js +19 -23
  71. package/build/hooks/useCamera.js.map +1 -1
  72. package/build/hooks/useConnection.d.ts +42 -0
  73. package/build/hooks/useConnection.d.ts.map +1 -0
  74. package/build/hooks/useConnection.js +33 -0
  75. package/build/hooks/useConnection.js.map +1 -0
  76. package/build/hooks/useForegroundService.d.ts +12 -20
  77. package/build/hooks/useForegroundService.d.ts.map +1 -1
  78. package/build/hooks/useForegroundService.js +14 -4
  79. package/build/hooks/useForegroundService.js.map +1 -1
  80. package/build/hooks/useMicrophone.d.ts.map +1 -1
  81. package/build/hooks/useMicrophone.js +5 -11
  82. package/build/hooks/useMicrophone.js.map +1 -1
  83. package/build/hooks/usePeerStatus.d.ts +2 -3
  84. package/build/hooks/usePeerStatus.d.ts.map +1 -1
  85. package/build/hooks/usePeerStatus.js +4 -10
  86. package/build/hooks/usePeerStatus.js.map +1 -1
  87. package/build/hooks/usePeers.d.ts +50 -11
  88. package/build/hooks/usePeers.d.ts.map +1 -1
  89. package/build/hooks/usePeers.js +42 -18
  90. package/build/hooks/usePeers.js.map +1 -1
  91. package/build/hooks/useReconnection.d.ts +1 -1
  92. package/build/hooks/useReconnection.d.ts.map +1 -1
  93. package/build/hooks/useReconnection.js +4 -10
  94. package/build/hooks/useReconnection.js.map +1 -1
  95. package/build/hooks/useScreenShare.d.ts.map +1 -1
  96. package/build/hooks/useScreenShare.js +11 -16
  97. package/build/hooks/useScreenShare.js.map +1 -1
  98. package/build/hooks/useUpdatePeerMetadata.d.ts +15 -0
  99. package/build/hooks/useUpdatePeerMetadata.d.ts.map +1 -0
  100. package/build/hooks/useUpdatePeerMetadata.js +21 -0
  101. package/build/hooks/useUpdatePeerMetadata.js.map +1 -0
  102. package/build/index.d.ts +24 -16
  103. package/build/index.d.ts.map +1 -1
  104. package/build/index.js +18 -6
  105. package/build/index.js.map +1 -1
  106. package/build/types.d.ts +1 -1
  107. package/build/types.d.ts.map +1 -1
  108. package/build/types.js.map +1 -1
  109. package/build/utils/errorListener.d.ts.map +1 -1
  110. package/build/utils/errorListener.js +3 -4
  111. package/build/utils/errorListener.js.map +1 -1
  112. package/ios/Events.swift +94 -19
  113. package/ios/RNFishjamClient.podspec +1 -1
  114. package/ios/RNFishjamClient.swift +84 -114
  115. package/ios/RNFishjamClientModule.swift +14 -10
  116. package/ios/Utils.swift +0 -20
  117. package/ios/VideoPreviewView.swift +13 -13
  118. package/ios/VideoRendererView.swift +28 -25
  119. package/ios/VideoRendererViewModule.swift +8 -4
  120. package/ios/extensions/AVCaptureDevice.swift +20 -0
  121. package/package.json +11 -14
  122. package/plugin/build/withFishjamAndroid.js +18 -20
  123. package/plugin/build/withFishjamIos.js +99 -103
  124. package/build/hooks/useFishjamEvent.d.ts +0 -18
  125. package/build/hooks/useFishjamEvent.d.ts.map +0 -1
  126. package/build/hooks/useFishjamEvent.js +0 -27
  127. package/build/hooks/useFishjamEvent.js.map +0 -1
@@ -2,16 +2,18 @@ package io.fishjam.reactnative
2
2
 
3
3
  import android.animation.ValueAnimator
4
4
  import android.content.Context
5
+ import android.content.res.Resources
5
6
  import android.graphics.Color
7
+ import android.graphics.Rect
6
8
  import android.graphics.drawable.ColorDrawable
9
+ import android.os.Handler
10
+ import android.os.Looper
7
11
  import android.view.animation.LinearInterpolator
8
12
  import com.fishjamcloud.client.media.LocalVideoTrack
9
13
  import com.fishjamcloud.client.media.VideoTrack
10
14
  import expo.modules.kotlin.AppContext
11
15
  import expo.modules.kotlin.views.ExpoView
12
16
  import io.fishjam.reactnative.managers.LocalTrackSwitchListener
13
- import kotlinx.coroutines.CoroutineScope
14
- import kotlinx.coroutines.Dispatchers
15
17
  import kotlinx.coroutines.delay
16
18
  import org.webrtc.RendererCommon
17
19
 
@@ -35,7 +37,41 @@ abstract class VideoView(
35
37
  }
36
38
  }
37
39
 
38
- val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
40
+ private val checkVisibilityHandler: Handler = Handler(Looper.getMainLooper())
41
+
42
+ // If set to `null` the view will always be rendered
43
+ var checkVisibilityDelayMillis: Long? = null
44
+ set(value) {
45
+ field = value
46
+ if (value == null) {
47
+ getVideoTrack()?.shouldReceive(true)
48
+ } else {
49
+ checkVisibilityHandler.post(checkVisibility)
50
+ }
51
+ }
52
+
53
+ private val checkVisibility =
54
+ object : Runnable {
55
+ override fun run() {
56
+ checkVisibilityDelayMillis?.let {
57
+ getVideoTrack()?.shouldReceive(isVisibleOnScreen)
58
+ checkVisibilityHandler.postDelayed(this, it)
59
+ }
60
+ }
61
+ }
62
+
63
+ private val isVisibleOnScreen: Boolean
64
+ get() {
65
+ if (!isShown) {
66
+ return false
67
+ }
68
+
69
+ val globalVisibleRect = Rect()
70
+ getGlobalVisibleRect(globalVisibleRect)
71
+ val displayMetrics = Resources.getSystem().displayMetrics
72
+ val screen = Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)
73
+ return screen.intersect(globalVisibleRect)
74
+ }
39
75
 
40
76
  init {
41
77
  RNFishjamClient.localTracksSwitchListenerManager.add(this)
@@ -53,6 +89,7 @@ abstract class VideoView(
53
89
  }
54
90
 
55
91
  open fun dispose() {
92
+ checkVisibilityHandler.removeCallbacksAndMessages(null)
56
93
  videoView.release()
57
94
  }
58
95
 
@@ -74,5 +111,6 @@ abstract class VideoView(
74
111
 
75
112
  fun setupTrack() {
76
113
  videoView.setMirror((getVideoTrack() as? LocalVideoTrack)?.isFrontCamera() ?: false)
114
+ checkVisibilityHandler.post(checkVisibility)
77
115
  }
78
116
  }
@@ -0,0 +1,17 @@
1
+ package io.fishjam.reactnative.extensions
2
+
3
+ import com.fishjamcloud.client.media.CaptureDevice
4
+
5
+ typealias LocalCamera = Map<String, Any>
6
+
7
+ fun CaptureDevice.toLocalCamera(): LocalCamera =
8
+ mapOf<String, Any>(
9
+ "id" to deviceName,
10
+ "name" to deviceName,
11
+ "facingDirection" to
12
+ when (true) {
13
+ isFrontFacing -> "front"
14
+ isBackFacing -> "back"
15
+ else -> "unspecified"
16
+ }
17
+ )
@@ -18,7 +18,9 @@ class FishjamForegroundService : Service() {
18
18
 
19
19
  private val binder = LocalBinder()
20
20
 
21
- inner class LocalBinder : Binder()
21
+ inner class LocalBinder : Binder() {
22
+ fun getService(): FishjamForegroundService = this@FishjamForegroundService
23
+ }
22
24
 
23
25
  override fun onBind(intent: Intent): IBinder = binder
24
26
 
@@ -27,6 +29,11 @@ class FishjamForegroundService : Service() {
27
29
  flags: Int,
28
30
  startId: Int
29
31
  ): Int {
32
+ restartService(intent)
33
+ return START_NOT_STICKY
34
+ }
35
+
36
+ fun restartService(intent: Intent?) {
30
37
  val channelId = intent!!.getStringExtra("channelId")!!
31
38
  val channelName = intent.getStringExtra("channelName")!!
32
39
  val notificationTitle = intent.getStringExtra("notificationTitle")!!
@@ -49,12 +56,11 @@ class FishjamForegroundService : Service() {
49
56
  .setContentTitle(notificationTitle)
50
57
  .setContentText(notificationContent)
51
58
  .setContentIntent(pendingIntent)
59
+ .setSmallIcon(android.R.drawable.ic_dialog_info)
52
60
  .build()
53
61
 
54
62
  createNotificationChannel(channelId, channelName)
55
63
  startForegroundWithNotification(notification, foregroundServiceType)
56
-
57
- return START_NOT_STICKY
58
64
  }
59
65
 
60
66
  private fun startForegroundWithNotification(
@@ -87,7 +93,7 @@ class FishjamForegroundService : Service() {
87
93
  NotificationChannel(
88
94
  channelId,
89
95
  channelName,
90
- NotificationManager.IMPORTANCE_DEFAULT
96
+ NotificationManager.IMPORTANCE_HIGH
91
97
  )
92
98
  val notificationManager = getSystemService(NOTIFICATION_SERVICE) as? NotificationManager
93
99
  notificationManager?.createNotificationChannel(serviceChannel)
@@ -4,52 +4,30 @@ import android.content.ComponentName
4
4
  import android.content.Context
5
5
  import android.content.Intent
6
6
  import android.content.ServiceConnection
7
- import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
8
- import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
9
- import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
10
7
  import android.os.Build
11
8
  import android.os.IBinder
12
9
  import expo.modules.kotlin.AppContext
13
10
  import expo.modules.kotlin.exception.CodedException
14
- import io.fishjam.reactnative.ForegroundServiceNotificationConfig
15
- import io.fishjam.reactnative.ForegroundServicePermissionsConfig
16
- import io.fishjam.reactnative.utils.PermissionUtils
11
+ import io.fishjam.reactnative.ForegroundServiceConfig
17
12
  import kotlinx.coroutines.CancellableContinuation
18
13
  import kotlinx.coroutines.suspendCancellableCoroutine
19
14
  import kotlin.coroutines.resume
20
15
 
21
16
  class ForegroundServiceManager(
22
- private val appContext: AppContext,
23
- notificationConfig: ForegroundServiceNotificationConfig
17
+ private val appContext: AppContext
24
18
  ) {
25
19
  private val reactContext by lazy {
26
20
  appContext.reactContext ?: throw CodedException("reactContext not found")
27
21
  }
28
- private var isServiceBound: Boolean = false
29
- private var serviceConnectedContinuation: CancellableContinuation<Unit>? = null
30
22
 
23
+ private var serviceState = ForegroundServiceState()
24
+ private var serviceInstance: FishjamForegroundService? = null
25
+ private var serviceConnectedContinuation: CancellableContinuation<Unit>? = null
31
26
  private val serviceIntent =
32
27
  Intent(
33
28
  appContext.reactContext,
34
29
  FishjamForegroundService::class.java
35
- ).apply {
36
- putExtra(
37
- "channelId",
38
- notificationConfig.channelId.orThrow("channelId")
39
- )
40
- putExtra(
41
- "channelName",
42
- notificationConfig.channelName.orThrow("channelName")
43
- )
44
- putExtra(
45
- "notificationContent",
46
- notificationConfig.notificationContent.orThrow("notificationContent")
47
- )
48
- putExtra(
49
- "notificationTitle",
50
- notificationConfig.notificationTitle.orThrow("notificationTitle")
51
- )
52
- }
30
+ )
53
31
 
54
32
  private val connection =
55
33
  object : ServiceConnection {
@@ -57,26 +35,46 @@ class ForegroundServiceManager(
57
35
  className: ComponentName,
58
36
  service: IBinder
59
37
  ) {
60
- isServiceBound = true
38
+ serviceInstance = (service as FishjamForegroundService.LocalBinder).getService()
61
39
  serviceConnectedContinuation?.resume(Unit)
62
40
  serviceConnectedContinuation = null
63
41
  }
64
42
 
65
43
  override fun onServiceDisconnected(arg0: ComponentName) {
66
- isServiceBound = false
44
+ serviceInstance = null
67
45
  serviceConnectedContinuation?.cancel()
68
46
  serviceConnectedContinuation = null
69
47
  }
70
48
  }
71
49
 
72
- suspend fun startForegroundService(permissionsConfig: ForegroundServicePermissionsConfig) {
73
- val foregroundServiceTypes = buildForegroundServiceTypes(permissionsConfig)
50
+ fun updateServiceWithConfig(configUpdate: ForegroundServiceConfig) {
51
+ configUpdate.enableCamera?.let { serviceState.cameraEnabled = it }
52
+ configUpdate.enableMicrophone?.let { serviceState.microphoneEnabled = it }
53
+ configUpdate.channelId?.let { serviceState.channelId = it }
54
+ configUpdate.channelName?.let { serviceState.channelName = it }
55
+ configUpdate.notificationContent?.let { serviceState.notificationContent = it }
56
+ configUpdate.notificationTitle?.let { serviceState.notificationTitle = it }
57
+ }
58
+
59
+ fun updateService(update: ForegroundServiceState.() -> Unit) {
60
+ serviceState.update()
61
+ }
62
+
63
+ suspend fun start() {
64
+ val foregroundServiceTypes = serviceState.buildForegroundServiceTypes(appContext)
74
65
 
75
66
  if (foregroundServiceTypes.isEmpty()) {
67
+ stop()
76
68
  return
77
69
  }
78
70
 
79
- serviceIntent.putExtra("foregroundServiceTypes", foregroundServiceTypes.toIntArray())
71
+ serviceIntent.apply {
72
+ putExtra("channelId", serviceState.channelId)
73
+ putExtra("channelName", serviceState.channelName)
74
+ putExtra("notificationContent", serviceState.notificationContent)
75
+ putExtra("notificationTitle", serviceState.notificationTitle)
76
+ putExtra("foregroundServiceTypes", foregroundServiceTypes.toIntArray())
77
+ }
80
78
 
81
79
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
82
80
  reactContext.startForegroundService(serviceIntent)
@@ -87,61 +85,34 @@ class ForegroundServiceManager(
87
85
  bindServiceIfNeededAndAwait()
88
86
  }
89
87
 
90
- fun stopForegroundService() {
91
- if (isServiceBound) {
88
+ fun stop() {
89
+ if (serviceInstance != null) {
92
90
  appContext.currentActivity?.unbindService(connection)
93
91
  ?: throw CodedException("Current activity not found")
94
- isServiceBound = false
92
+ serviceInstance = null
95
93
  }
96
94
  reactContext.stopService(serviceIntent)
97
95
  serviceConnectedContinuation?.cancel()
98
96
  serviceConnectedContinuation = null
99
97
  }
100
98
 
101
- private fun buildForegroundServiceTypes(permissionsConfig: ForegroundServicePermissionsConfig): List<Int> =
102
- buildList {
103
- if (permissionsConfig.enableCamera) {
104
- addIfPermissionGranted(
105
- FOREGROUND_SERVICE_TYPE_CAMERA,
106
- "camera",
107
- PermissionUtils::hasCameraPermission
108
- )
109
- }
110
- if (permissionsConfig.enableMicrophone) {
111
- addIfPermissionGranted(
112
- FOREGROUND_SERVICE_TYPE_MICROPHONE,
113
- "microphone",
114
- PermissionUtils::hasMicrophonePermission
115
- )
116
- }
117
- if (permissionsConfig.enableScreenSharing) add(FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION)
118
- }
119
-
120
- private fun MutableList<Int>.addIfPermissionGranted(
121
- serviceType: Int,
122
- permissionName: String,
123
- hasPermission: (AppContext) -> Boolean
124
- ) {
125
- if (!hasPermission(appContext)) {
126
- throw CodedException("Cannot start a $permissionName foreground service without $permissionName permission.")
127
- }
128
- add(serviceType)
129
- }
130
-
131
99
  private suspend fun bindServiceIfNeededAndAwait() =
132
100
  suspendCancellableCoroutine { continuation ->
133
- if (!isServiceBound) {
101
+ if (serviceInstance == null) {
134
102
  serviceConnectedContinuation = continuation
135
103
  runCatching {
136
- appContext.currentActivity?.bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE)
104
+ appContext.currentActivity?.bindService(
105
+ serviceIntent,
106
+ connection,
107
+ Context.BIND_AUTO_CREATE
108
+ )
137
109
  }.onFailure { error ->
138
110
  continuation.cancel(CodedException("Failed to bind service: ${error.message}"))
139
111
  }
140
112
  } else {
113
+ serviceInstance?.restartService(serviceIntent)
141
114
  continuation.resume(Unit)
142
115
  serviceConnectedContinuation = null
143
116
  }
144
117
  }
145
118
  }
146
-
147
- private fun String?.orThrow(fieldName: String): String = this ?: throw CodedException("Missing `$fieldName` for startForegroundService")
@@ -0,0 +1,46 @@
1
+ package io.fishjam.reactnative.foregroundService
2
+
3
+ import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
4
+ import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
5
+ import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
6
+ import expo.modules.kotlin.AppContext
7
+ import expo.modules.kotlin.exception.CodedException
8
+ import io.fishjam.reactnative.utils.PermissionUtils
9
+
10
+ data class ForegroundServiceState(
11
+ var cameraEnabled: Boolean = false,
12
+ var microphoneEnabled: Boolean = false,
13
+ var screenSharingEnabled: Boolean = false,
14
+ var channelId: String = "com.fishjam.foregroundservice.channel",
15
+ var channelName: String = "Fishjam Notifications",
16
+ var notificationContent: String = "[PLACEHOLDER] Your video call is ongoing",
17
+ var notificationTitle: String = "[PLACEHOLDER] Tap to return to the call."
18
+ ) {
19
+ fun buildForegroundServiceTypes(appContext: AppContext): List<Int> =
20
+ buildList {
21
+ if (cameraEnabled) {
22
+ addIfPermissionGranted(
23
+ FOREGROUND_SERVICE_TYPE_CAMERA,
24
+ "camera"
25
+ ) { PermissionUtils.hasCameraPermission(appContext) }
26
+ }
27
+ if (microphoneEnabled) {
28
+ addIfPermissionGranted(
29
+ FOREGROUND_SERVICE_TYPE_MICROPHONE,
30
+ "microphone"
31
+ ) { PermissionUtils.hasMicrophonePermission(appContext) }
32
+ }
33
+ if (screenSharingEnabled) add(FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION)
34
+ }
35
+
36
+ private fun MutableList<Int>.addIfPermissionGranted(
37
+ serviceType: Int,
38
+ permissionName: String,
39
+ hasPermission: () -> Boolean
40
+ ) {
41
+ if (!hasPermission()) {
42
+ throw CodedException("Cannot start a $permissionName foreground service without $permissionName permission.")
43
+ }
44
+ add(serviceType)
45
+ }
46
+ }
@@ -0,0 +1,22 @@
1
+ package io.fishjam.reactnative.managers
2
+
3
+ abstract class ListenerManager<T> {
4
+ protected var listeners: MutableList<T> = mutableListOf()
5
+ private set
6
+
7
+ fun add(listener: T) {
8
+ listeners.add(listener)
9
+ }
10
+
11
+ fun remove(listener: T) {
12
+ listeners.remove(listener)
13
+ }
14
+ }
15
+
16
+ open class SingleListenerManager<T>(
17
+ private val notify: (T) -> Unit
18
+ ) : ListenerManager<T>() {
19
+ fun notifyListeners() {
20
+ for (listener in listeners) notify(listener)
21
+ }
22
+ }
@@ -4,18 +4,5 @@ interface LocalCameraTrackChangedListener {
4
4
  fun onLocalCameraTrackChanged()
5
5
  }
6
6
 
7
- class LocalCameraTracksChangedListenersManager {
8
- private var listeners: MutableList<LocalCameraTrackChangedListener> = mutableListOf()
9
-
10
- fun add(listener: LocalCameraTrackChangedListener) {
11
- listeners.add(listener)
12
- }
13
-
14
- fun remove(listener: LocalCameraTrackChangedListener) {
15
- listeners.remove(listener)
16
- }
17
-
18
- fun notifyListeners() {
19
- for (listener in listeners) listener.onLocalCameraTrackChanged()
20
- }
21
- }
7
+ class LocalCameraTracksChangedListenersManager :
8
+ SingleListenerManager<LocalCameraTrackChangedListener>(LocalCameraTrackChangedListener::onLocalCameraTrackChanged)
@@ -6,17 +6,7 @@ interface LocalTrackSwitchListener {
6
6
  suspend fun onLocalTrackSwitched()
7
7
  }
8
8
 
9
- class LocalTracksSwitchListenersManager {
10
- private val listeners: MutableList<LocalTrackSwitchListener> = mutableListOf()
11
-
12
- fun add(listener: LocalTrackSwitchListener) {
13
- listeners.add(listener)
14
- }
15
-
16
- fun remove(listener: LocalTrackSwitchListener) {
17
- listeners.remove(listener)
18
- }
19
-
9
+ class LocalTracksSwitchListenersManager : ListenerManager<LocalTrackSwitchListener>() {
20
10
  suspend fun notifyWillSwitch() {
21
11
  for (listener in listeners) listener.onLocalTrackWillSwitch()
22
12
  }
@@ -4,18 +4,4 @@ interface TrackUpdateListener {
4
4
  fun onTracksUpdate()
5
5
  }
6
6
 
7
- class TracksUpdateListenersManager {
8
- private val listeners: MutableList<TrackUpdateListener> = mutableListOf()
9
-
10
- fun add(listener: TrackUpdateListener) {
11
- listeners.add(listener)
12
- }
13
-
14
- fun remove(listener: TrackUpdateListener) {
15
- listeners.remove(listener)
16
- }
17
-
18
- fun notifyListeners() {
19
- for (listener in listeners) listener.onTracksUpdate()
20
- }
21
- }
7
+ class TracksUpdateListenersManager : SingleListenerManager<TrackUpdateListener>(TrackUpdateListener::onTracksUpdate)
@@ -1,15 +1,15 @@
1
- import { EventEmitter } from 'expo-modules-core';
2
- import { NativeModule } from 'react-native';
1
+ import type { NativeModule } from 'expo-modules-core/types';
3
2
  import type { RTCStats } from './debug/stats/types';
4
- import type { SimulcastConfig } from './types';
3
+ import type { GenericMetadata, SimulcastConfig } from './types';
5
4
  import type { CameraConfigInternal, Camera } from './hooks/useCamera';
6
5
  import type { Peer } from './hooks/usePeers';
7
6
  import type { ScreenShareOptionsInternal } from './hooks/useScreenShare';
8
7
  import type { ConnectionConfig } from './common/client';
9
8
  import { PeerStatus } from './hooks/usePeerStatus';
10
- import { ForegroundServiceNotificationConfig, ForegroundServicePermissionsConfigInternal } from './hooks/useForegroundService';
9
+ import { ForegroundServiceConfig } from './hooks/useForegroundService';
10
+ import { ReconnectionStatus } from './hooks/useReconnection';
11
11
  type Metadata = {
12
- [key: string]: any;
12
+ [key: string]: unknown;
13
13
  };
14
14
  type RNFishjamClient = {
15
15
  isMicrophoneOn: boolean;
@@ -17,10 +17,13 @@ type RNFishjamClient = {
17
17
  isScreenShareOn: boolean;
18
18
  isAppScreenShareOn: boolean;
19
19
  cameras: ReadonlyArray<Camera>;
20
+ currentCamera: Camera | null;
20
21
  peerStatus: PeerStatus;
22
+ reconnectionStatus: ReconnectionStatus;
23
+ getPeers: <PeerMetadataType extends Metadata, ServerMetadata extends Metadata = GenericMetadata>() => Peer<PeerMetadataType, ServerMetadata>[];
21
24
  joinRoom: (url: string, peerToken: string, peerMetadata: Metadata, config: ConnectionConfig) => Promise<void>;
22
25
  leaveRoom: () => Promise<void>;
23
- startCamera: (config: CameraConfigInternal) => Promise<void>;
26
+ startCamera: (config: CameraConfigInternal) => Promise<boolean>;
24
27
  toggleMicrophone: () => Promise<boolean>;
25
28
  toggleCamera: () => Promise<boolean>;
26
29
  flipCamera: () => Promise<void>;
@@ -28,10 +31,8 @@ type RNFishjamClient = {
28
31
  handleScreenSharePermission: () => Promise<'granted' | 'denied'>;
29
32
  toggleScreenShare: (screenShareOptions: Partial<ScreenShareOptionsInternal>) => Promise<void>;
30
33
  toggleAppScreenShare: (screenShareOptions: Partial<ScreenShareOptionsInternal>) => Promise<void>;
31
- getPeers: <PeerMetadataType extends Metadata>() => Promise<Peer<PeerMetadataType>[]>;
32
34
  updatePeerMetadata: <MetadataType extends Metadata>(metadata: MetadataType) => Promise<void>;
33
35
  updateVideoTrackMetadata: <MetadataType extends Metadata>(metadata: MetadataType) => Promise<void>;
34
- updateAudioTrackMetadata: <MetadataType extends Metadata>(metadata: MetadataType) => Promise<void>;
35
36
  updateScreenShareTrackMetadata: <MetadataType extends Metadata>(metadata: MetadataType) => Promise<void>;
36
37
  setOutputAudioDevice: (audioDevice: string) => Promise<void>;
37
38
  startAudioSwitcher: () => Promise<void>;
@@ -47,11 +48,26 @@ type RNFishjamClient = {
47
48
  setVideoTrackBandwidth: (bandwidth: number) => Promise<void>;
48
49
  changeWebRTCLoggingSeverity: (severity: string) => Promise<void>;
49
50
  getStatistics: () => Promise<RTCStats>;
50
- configureForegroundService: (config: ForegroundServiceNotificationConfig) => void;
51
- startForegroundService: (config: ForegroundServicePermissionsConfigInternal) => Promise<void>;
51
+ startForegroundService: (config: ForegroundServiceConfig) => Promise<void>;
52
52
  stopForegroundService: () => void;
53
53
  };
54
- export declare const nativeModuleEventEmitter: EventEmitter;
55
- declare const _default: RNFishjamClient & NativeModule;
54
+ export declare const ReceivableEvents: {
55
+ readonly IsMicrophoneOn: "IsMicrophoneOn";
56
+ readonly IsScreenShareOn: "IsScreenShareOn";
57
+ readonly IsAppScreenShareOn: "IsAppScreenShareOn";
58
+ readonly SimulcastConfigUpdate: "SimulcastConfigUpdate";
59
+ readonly PeersUpdate: "PeersUpdate";
60
+ readonly AudioDeviceUpdate: "AudioDeviceUpdate";
61
+ readonly SendMediaEvent: "SendMediaEvent";
62
+ readonly BandwidthEstimation: "BandwidthEstimation";
63
+ readonly ReconnectionRetriesLimitReached: "ReconnectionRetriesLimitReached";
64
+ readonly ReconnectionStarted: "ReconnectionStarted";
65
+ readonly Reconnected: "Reconnected";
66
+ readonly Warning: "Warning";
67
+ readonly PeerStatusChanged: "PeerStatusChanged";
68
+ readonly ReconnectionStatusChanged: "ReconnectionStatusChanged";
69
+ readonly CurrentCameraChanged: "CurrentCameraChanged";
70
+ };
71
+ declare const _default: RNFishjamClient & NativeModule<Record<keyof typeof ReceivableEvents, <T>(...args: T[]) => void>>;
56
72
  export default _default;
57
73
  //# sourceMappingURL=RNFishjamClientModule.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RNFishjamClientModule.d.ts","sourceRoot":"","sources":["../src/RNFishjamClientModule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RNFishjamClientModule.d.ts","sourceRoot":"","sources":["../src/RNFishjamClientModule.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,20 @@
1
- import { EventEmitter, requireNativeModule } from 'expo-modules-core';
2
- const nativeModule = requireNativeModule('RNFishjamClient');
3
- export const nativeModuleEventEmitter = new EventEmitter(nativeModule);
4
- export default nativeModule;
1
+ import { requireNativeModule } from 'expo-modules-core';
2
+ export const ReceivableEvents = {
3
+ IsMicrophoneOn: 'IsMicrophoneOn',
4
+ IsScreenShareOn: 'IsScreenShareOn',
5
+ IsAppScreenShareOn: 'IsAppScreenShareOn', // only for iOS
6
+ SimulcastConfigUpdate: 'SimulcastConfigUpdate',
7
+ PeersUpdate: 'PeersUpdate',
8
+ AudioDeviceUpdate: 'AudioDeviceUpdate',
9
+ SendMediaEvent: 'SendMediaEvent',
10
+ BandwidthEstimation: 'BandwidthEstimation',
11
+ ReconnectionRetriesLimitReached: 'ReconnectionRetriesLimitReached',
12
+ ReconnectionStarted: 'ReconnectionStarted',
13
+ Reconnected: 'Reconnected',
14
+ Warning: 'Warning',
15
+ PeerStatusChanged: 'PeerStatusChanged',
16
+ ReconnectionStatusChanged: 'ReconnectionStatusChanged',
17
+ CurrentCameraChanged: 'CurrentCameraChanged',
18
+ };
19
+ export default requireNativeModule('RNFishjamClient');
5
20
  //# sourceMappingURL=RNFishjamClientModule.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RNFishjamClientModule.js","sourceRoot":"","sources":["../src/RNFishjamClientModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAyFtE,MAAM,YAAY,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;AAC5D,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,YAAY,CAAC,YAAY,CAAC,CAAC;AAEvE,eAAe,YAA8C,CAAC","sourcesContent":["import { EventEmitter, requireNativeModule } from 'expo-modules-core';\nimport { NativeModule } from 'react-native';\n\nimport type { RTCStats } from './debug/stats/types';\nimport type { SimulcastConfig } from './types';\nimport type { CameraConfigInternal, Camera } from './hooks/useCamera';\nimport type { Peer } from './hooks/usePeers';\nimport type { ScreenShareOptionsInternal } from './hooks/useScreenShare';\nimport type { ConnectionConfig } from './common/client';\nimport { PeerStatus } from './hooks/usePeerStatus';\nimport {\n ForegroundServiceNotificationConfig,\n ForegroundServicePermissionsConfigInternal,\n} from './hooks/useForegroundService';\n\ntype Metadata = { [key: string]: any };\n\ntype RNFishjamClient = {\n isMicrophoneOn: boolean;\n isCameraOn: boolean;\n isScreenShareOn: boolean;\n isAppScreenShareOn: boolean; // only available on ios\n cameras: ReadonlyArray<Camera>;\n peerStatus: PeerStatus;\n joinRoom: (\n url: string,\n peerToken: string,\n peerMetadata: Metadata,\n config: ConnectionConfig,\n ) => Promise<void>;\n leaveRoom: () => Promise<void>;\n startCamera: (config: CameraConfigInternal) => Promise<void>;\n toggleMicrophone: () => Promise<boolean>;\n toggleCamera: () => Promise<boolean>;\n flipCamera: () => Promise<void>;\n switchCamera: (cameraId: string) => Promise<void>;\n handleScreenSharePermission: () => Promise<'granted' | 'denied'>;\n toggleScreenShare: (\n screenShareOptions: Partial<ScreenShareOptionsInternal>,\n ) => Promise<void>;\n toggleAppScreenShare: (\n screenShareOptions: Partial<ScreenShareOptionsInternal>,\n ) => Promise<void>;\n getPeers: <PeerMetadataType extends Metadata>() => Promise<\n Peer<PeerMetadataType>[]\n >;\n updatePeerMetadata: <MetadataType extends Metadata>(\n metadata: MetadataType,\n ) => Promise<void>;\n updateVideoTrackMetadata: <MetadataType extends Metadata>(\n metadata: MetadataType,\n ) => Promise<void>;\n updateAudioTrackMetadata: <MetadataType extends Metadata>(\n metadata: MetadataType,\n ) => Promise<void>;\n updateScreenShareTrackMetadata: <MetadataType extends Metadata>(\n metadata: MetadataType,\n ) => Promise<void>;\n setOutputAudioDevice: (audioDevice: string) => Promise<void>;\n startAudioSwitcher: () => Promise<void>;\n stopAudioSwitcher: () => Promise<void>;\n selectAudioSessionMode: (sessionMode: string) => Promise<void>;\n showAudioRoutePicker: () => Promise<void>;\n toggleScreenShareTrackEncoding: (\n encoding: string,\n ) => Promise<SimulcastConfig>;\n setScreenShareTrackBandwidth: (bandwidth: number) => Promise<void>;\n setScreenShareTrackEncodingBandwidth: (\n encoding: string,\n bandwidth: number,\n ) => Promise<void>;\n setTargetTrackEncoding: (trackId: string, encoding: string) => Promise<void>;\n toggleVideoTrackEncoding: (encoding: string) => Promise<SimulcastConfig>;\n setVideoTrackEncodingBandwidth: (\n encoding: string,\n bandwidth: number,\n ) => Promise<void>;\n setVideoTrackBandwidth: (bandwidth: number) => Promise<void>;\n changeWebRTCLoggingSeverity: (severity: string) => Promise<void>;\n getStatistics: () => Promise<RTCStats>;\n configureForegroundService: (\n config: ForegroundServiceNotificationConfig,\n ) => void;\n startForegroundService: (\n config: ForegroundServicePermissionsConfigInternal,\n ) => Promise<void>;\n stopForegroundService: () => void;\n};\n\nconst nativeModule = requireNativeModule('RNFishjamClient');\nexport const nativeModuleEventEmitter = new EventEmitter(nativeModule);\n\nexport default nativeModule as RNFishjamClient & NativeModule;\n"]}
1
+ {"version":3,"file":"RNFishjamClientModule.js","sourceRoot":"","sources":["../src/RNFishjamClientModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAoFxD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,iBAAiB;IAClC,kBAAkB,EAAE,oBAAoB,EAAE,eAAe;IACzD,qBAAqB,EAAE,uBAAuB;IAC9C,WAAW,EAAE,aAAa;IAC1B,iBAAiB,EAAE,mBAAmB;IACtC,cAAc,EAAE,gBAAgB;IAChC,mBAAmB,EAAE,qBAAqB;IAC1C,+BAA+B,EAAE,iCAAiC;IAClE,mBAAmB,EAAE,qBAAqB;IAC1C,WAAW,EAAE,aAAa;IAC1B,OAAO,EAAE,SAAS;IAClB,iBAAiB,EAAE,mBAAmB;IACtC,yBAAyB,EAAE,2BAA2B;IACtD,oBAAoB,EAAE,sBAAsB;CACpC,CAAC;AAEX,eAAe,mBAAmB,CAAC,iBAAiB,CAIjD,CAAC","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\n\nimport type { NativeModule } from 'expo-modules-core/types';\nimport type { RTCStats } from './debug/stats/types';\nimport type { GenericMetadata, SimulcastConfig } from './types';\nimport type { CameraConfigInternal, Camera } from './hooks/useCamera';\nimport type { Peer } from './hooks/usePeers';\nimport type { ScreenShareOptionsInternal } from './hooks/useScreenShare';\nimport type { ConnectionConfig } from './common/client';\nimport { PeerStatus } from './hooks/usePeerStatus';\nimport { ForegroundServiceConfig } from './hooks/useForegroundService';\nimport { ReconnectionStatus } from './hooks/useReconnection';\n\ntype Metadata = { [key: string]: unknown };\n\ntype RNFishjamClient = {\n isMicrophoneOn: boolean;\n isCameraOn: boolean;\n isScreenShareOn: boolean;\n isAppScreenShareOn: boolean; // only available on ios\n cameras: ReadonlyArray<Camera>;\n currentCamera: Camera | null;\n peerStatus: PeerStatus;\n reconnectionStatus: ReconnectionStatus;\n\n getPeers: <\n PeerMetadataType extends Metadata,\n ServerMetadata extends Metadata = GenericMetadata,\n >() => Peer<PeerMetadataType, ServerMetadata>[];\n\n joinRoom: (\n url: string,\n peerToken: string,\n peerMetadata: Metadata,\n config: ConnectionConfig,\n ) => Promise<void>;\n leaveRoom: () => Promise<void>;\n startCamera: (config: CameraConfigInternal) => Promise<boolean>;\n toggleMicrophone: () => Promise<boolean>;\n toggleCamera: () => Promise<boolean>;\n flipCamera: () => Promise<void>;\n switchCamera: (cameraId: string) => Promise<void>;\n handleScreenSharePermission: () => Promise<'granted' | 'denied'>;\n toggleScreenShare: (\n screenShareOptions: Partial<ScreenShareOptionsInternal>,\n ) => Promise<void>;\n toggleAppScreenShare: (\n screenShareOptions: Partial<ScreenShareOptionsInternal>,\n ) => Promise<void>;\n updatePeerMetadata: <MetadataType extends Metadata>(\n metadata: MetadataType,\n ) => Promise<void>;\n updateVideoTrackMetadata: <MetadataType extends Metadata>(\n metadata: MetadataType,\n ) => Promise<void>;\n updateScreenShareTrackMetadata: <MetadataType extends Metadata>(\n metadata: MetadataType,\n ) => Promise<void>;\n setOutputAudioDevice: (audioDevice: string) => Promise<void>;\n startAudioSwitcher: () => Promise<void>;\n stopAudioSwitcher: () => Promise<void>;\n selectAudioSessionMode: (sessionMode: string) => Promise<void>;\n showAudioRoutePicker: () => Promise<void>;\n toggleScreenShareTrackEncoding: (\n encoding: string,\n ) => Promise<SimulcastConfig>;\n setScreenShareTrackBandwidth: (bandwidth: number) => Promise<void>;\n setScreenShareTrackEncodingBandwidth: (\n encoding: string,\n bandwidth: number,\n ) => Promise<void>;\n setTargetTrackEncoding: (trackId: string, encoding: string) => Promise<void>;\n toggleVideoTrackEncoding: (encoding: string) => Promise<SimulcastConfig>;\n setVideoTrackEncodingBandwidth: (\n encoding: string,\n bandwidth: number,\n ) => Promise<void>;\n setVideoTrackBandwidth: (bandwidth: number) => Promise<void>;\n changeWebRTCLoggingSeverity: (severity: string) => Promise<void>;\n getStatistics: () => Promise<RTCStats>;\n startForegroundService: (config: ForegroundServiceConfig) => Promise<void>;\n stopForegroundService: () => void;\n};\n\nexport const ReceivableEvents = {\n IsMicrophoneOn: 'IsMicrophoneOn',\n IsScreenShareOn: 'IsScreenShareOn',\n IsAppScreenShareOn: 'IsAppScreenShareOn', // only for iOS\n SimulcastConfigUpdate: 'SimulcastConfigUpdate',\n PeersUpdate: 'PeersUpdate',\n AudioDeviceUpdate: 'AudioDeviceUpdate',\n SendMediaEvent: 'SendMediaEvent',\n BandwidthEstimation: 'BandwidthEstimation',\n ReconnectionRetriesLimitReached: 'ReconnectionRetriesLimitReached',\n ReconnectionStarted: 'ReconnectionStarted',\n Reconnected: 'Reconnected',\n Warning: 'Warning',\n PeerStatusChanged: 'PeerStatusChanged',\n ReconnectionStatusChanged: 'ReconnectionStatusChanged',\n CurrentCameraChanged: 'CurrentCameraChanged',\n} as const;\n\nexport default requireNativeModule('RNFishjamClient') as RNFishjamClient &\n NativeModule<\n // TODO: Make event arguments typesafe instead of generic.\n Record<keyof typeof ReceivableEvents, <T>(...args: T[]) => void>\n >;\n"]}
@@ -19,11 +19,7 @@ export type ConnectionConfig = {
19
19
  * @param peerToken token received from server (or Room Manager)
20
20
  * @param peerMetadata string indexed record with metadata, that will be available to all other peers
21
21
  * @param config additional connection configuration
22
- * @category Connection
23
22
  */
24
23
  export declare function joinRoom<PeerMetadata extends GenericMetadata = GenericMetadata>(url: string, peerToken: string, peerMetadata?: PeerMetadata, config?: ConnectionConfig): Promise<void>;
25
- /**
26
- * @category Connection
27
- */
28
24
  export declare function leaveRoom(): Promise<void>;
29
25
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/common/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAG3C,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,YAAY,SAAS,eAAe,GAAG,eAAe,EAEtD,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,YAAY,EAC3B,MAAM,CAAC,EAAE,gBAAgB,iBAQ1B;AACD;;GAEG;AACH,wBAAsB,SAAS,kBAE9B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/common/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAG3C,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,YAAY,SAAS,eAAe,GAAG,eAAe,EAEtD,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,YAAY,EAC3B,MAAM,CAAC,EAAE,gBAAgB,iBAQ1B;AAED,wBAAsB,SAAS,kBAE9B"}
@@ -4,14 +4,10 @@ import RNFishjamClientModule from '../RNFishjamClientModule';
4
4
  * @param peerToken token received from server (or Room Manager)
5
5
  * @param peerMetadata string indexed record with metadata, that will be available to all other peers
6
6
  * @param config additional connection configuration
7
- * @category Connection
8
7
  */
9
8
  export async function joinRoom(url, peerToken, peerMetadata, config) {
10
9
  await RNFishjamClientModule.joinRoom(url, peerToken, peerMetadata ?? {}, config ?? {});
11
10
  }
12
- /**
13
- * @category Connection
14
- */
15
11
  export async function leaveRoom() {
16
12
  await RNFishjamClientModule.leaveRoom();
17
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/common/client.ts"],"names":[],"mappings":"AACA,OAAO,qBAAqB,MAAM,0BAA0B,CAAC;AAkB7D;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAG5B,GAAW,EACX,SAAiB,EACjB,YAA2B,EAC3B,MAAyB;IAEzB,MAAM,qBAAqB,CAAC,QAAQ,CAClC,GAAG,EACH,SAAS,EACT,YAAY,IAAI,EAAE,EAClB,MAAM,IAAI,EAAE,CACb,CAAC;AACJ,CAAC;AACD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,qBAAqB,CAAC,SAAS,EAAE,CAAC;AAC1C,CAAC","sourcesContent":["import { GenericMetadata } from '../types';\nimport RNFishjamClientModule from '../RNFishjamClientModule';\n\nexport type ConnectionConfig = {\n /**\n * Configuration for automatic reconnection\n * sdk uses a linear backoff algorithm, that is the formula\n * for the delay of the nth attempt is\n * n * delayMs + initialDelayMs\n *\n * Pass 0 for maxAttempts to disable automatic reconnection\n */\n reconnectConfig?: {\n maxAttempts?: number;\n initialDelayMs?: number;\n delayMs?: number;\n };\n};\n\n/**\n * @param url fishjam Url\n * @param peerToken token received from server (or Room Manager)\n * @param peerMetadata string indexed record with metadata, that will be available to all other peers\n * @param config additional connection configuration\n * @category Connection\n */\nexport async function joinRoom<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n>(\n url: string,\n peerToken: string,\n peerMetadata?: PeerMetadata,\n config?: ConnectionConfig,\n) {\n await RNFishjamClientModule.joinRoom(\n url,\n peerToken,\n peerMetadata ?? {},\n config ?? {},\n );\n}\n/**\n * @category Connection\n */\nexport async function leaveRoom() {\n await RNFishjamClientModule.leaveRoom();\n}\n"]}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/common/client.ts"],"names":[],"mappings":"AACA,OAAO,qBAAqB,MAAM,0BAA0B,CAAC;AAkB7D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAG5B,GAAW,EACX,SAAiB,EACjB,YAA2B,EAC3B,MAAyB;IAEzB,MAAM,qBAAqB,CAAC,QAAQ,CAClC,GAAG,EACH,SAAS,EACT,YAAY,IAAI,EAAE,EAClB,MAAM,IAAI,EAAE,CACb,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,qBAAqB,CAAC,SAAS,EAAE,CAAC;AAC1C,CAAC","sourcesContent":["import { GenericMetadata } from '../types';\nimport RNFishjamClientModule from '../RNFishjamClientModule';\n\nexport type ConnectionConfig = {\n /**\n * Configuration for automatic reconnection\n * sdk uses a linear backoff algorithm, that is the formula\n * for the delay of the nth attempt is\n * n * delayMs + initialDelayMs\n *\n * Pass 0 for maxAttempts to disable automatic reconnection\n */\n reconnectConfig?: {\n maxAttempts?: number;\n initialDelayMs?: number;\n delayMs?: number;\n };\n};\n\n/**\n * @param url fishjam Url\n * @param peerToken token received from server (or Room Manager)\n * @param peerMetadata string indexed record with metadata, that will be available to all other peers\n * @param config additional connection configuration\n */\nexport async function joinRoom<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n>(\n url: string,\n peerToken: string,\n peerMetadata?: PeerMetadata,\n config?: ConnectionConfig,\n) {\n await RNFishjamClientModule.joinRoom(\n url,\n peerToken,\n peerMetadata ?? {},\n config ?? {},\n );\n}\n\nexport async function leaveRoom() {\n await RNFishjamClientModule.leaveRoom();\n}\n"]}