@fishjam-cloud/react-native-client 0.15.0 → 0.16.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.
@@ -17,7 +17,9 @@ import com.fishjamcloud.client.media.LocalVideoTrack
17
17
  import com.fishjamcloud.client.media.RemoteAudioTrack
18
18
  import com.fishjamcloud.client.media.RemoteVideoTrack
19
19
  import com.fishjamcloud.client.media.Track
20
+ import com.fishjamcloud.client.media.VideoTrack
20
21
  import com.fishjamcloud.client.models.AuthError
22
+ import com.fishjamcloud.client.models.CustomSource
21
23
  import com.fishjamcloud.client.models.Endpoint
22
24
  import com.fishjamcloud.client.models.Metadata
23
25
  import com.fishjamcloud.client.models.Peer
@@ -151,6 +153,10 @@ class RNFishjamClient(
151
153
  }
152
154
  eventEmitter?.invoke(event.name, event.data)
153
155
  }
156
+
157
+ suspend fun createCustomSource(customSource: CustomSource) = fishjamClient.createCustomSource(customSource)
158
+
159
+ suspend fun removeCustomSource(customSource: CustomSource) = fishjamClient.removeCustomSource(customSource)
154
160
  }
155
161
 
156
162
  fun onModuleCreate(appContext: AppContext) {
@@ -517,6 +523,14 @@ class RNFishjamClient(
517
523
  "metadata" to track.metadata
518
524
  )
519
525
 
526
+ is VideoTrack -> // TODO(FCE-1418): Remove after refactoring LocalVideoTrack
527
+ mapOf(
528
+ "id" to track.id(),
529
+ "type" to "Video",
530
+ "metadata" to track.metadata,
531
+ "aspectRatio" to track.dimensions?.aspectRatio
532
+ )
533
+
520
534
  else -> {
521
535
  null
522
536
  }
@@ -2,45 +2,37 @@ package io.fishjam.reactnative
2
2
 
3
3
  import android.content.Context
4
4
  import com.fishjamcloud.client.media.LocalVideoTrack
5
- import com.fishjamcloud.client.media.VideoTrack
6
5
  import expo.modules.kotlin.AppContext
7
6
  import io.fishjam.reactnative.managers.LocalCameraTrackChangedListener
8
7
 
9
8
  class VideoPreviewView(
10
9
  context: Context,
11
10
  appContext: AppContext
12
- ) : VideoView(context, appContext),
11
+ ) : VideoRendererView(context, appContext),
13
12
  LocalCameraTrackChangedListener {
14
- private var localVideoTrack: LocalVideoTrack? = null
15
-
16
13
  private fun trySetLocalCameraTrack() {
17
- localVideoTrack =
14
+ (
18
15
  RNFishjamClient.fishjamClient.getLocalEndpoint().tracks.values.firstOrNull { track ->
19
16
  track is LocalVideoTrack
20
17
  } as? LocalVideoTrack?
21
- videoView.let { localVideoTrack?.addRenderer(it) }
22
- }
23
-
24
- private fun initialize() {
25
- trySetLocalCameraTrack()
26
- super.setupTrack()
18
+ )?.let {
19
+ init(it.id())
20
+ }
27
21
  }
28
22
 
29
23
  override fun onDetachedFromWindow() {
30
24
  RNFishjamClient.localCameraTracksChangedListenersManager.remove(this)
31
- videoView.let { localVideoTrack?.removeRenderer(it) }
32
25
  super.onDetachedFromWindow()
33
26
  }
34
27
 
35
28
  override fun onAttachedToWindow() {
36
29
  RNFishjamClient.localCameraTracksChangedListenersManager.add(this)
30
+ activeVideoTrack?.removeRenderer(videoView)
37
31
  super.onAttachedToWindow()
38
- initialize()
32
+ trySetLocalCameraTrack()
39
33
  }
40
34
 
41
- override fun getVideoTrack(): VideoTrack? = localVideoTrack
42
-
43
35
  override fun onLocalCameraTrackChanged() {
44
- if (localVideoTrack == null) trySetLocalCameraTrack()
36
+ if (activeVideoTrack == null) trySetLocalCameraTrack()
45
37
  }
46
38
  }
@@ -10,13 +10,13 @@ import kotlinx.coroutines.CoroutineScope
10
10
  import kotlinx.coroutines.Dispatchers
11
11
  import kotlinx.coroutines.launch
12
12
 
13
- class VideoRendererView(
13
+ open class VideoRendererView(
14
14
  context: Context,
15
15
  appContext: AppContext
16
16
  ) : VideoView(context, appContext),
17
17
  TrackUpdateListener,
18
18
  VideoTrackListener {
19
- private var activeVideoTrack: VideoTrack? = null
19
+ protected var activeVideoTrack: VideoTrack? = null
20
20
  private var trackId: String? = null
21
21
 
22
22
  init {
@@ -1 +1 @@
1
- {"version":3,"file":"eventPayloadValidator.d.ts","sourceRoot":"","sources":["../../src/utils/eventPayloadValidator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EACjB,MAAM,0BAA0B,CAAC;AAiClC,wBAAgB,0BAA0B,CACxC,CAAC,SAAS,MAAM,OAAO,gBAAgB,EACvC,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,IAAI,CAoDzD"}
1
+ {"version":3,"file":"eventPayloadValidator.d.ts","sourceRoot":"","sources":["../../src/utils/eventPayloadValidator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EACjB,MAAM,0BAA0B,CAAC;AAiClC,wBAAgB,0BAA0B,CACxC,CAAC,SAAS,MAAM,OAAO,gBAAgB,EACvC,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,IAAI,CAsDzD"}
@@ -55,7 +55,7 @@ export function validateNativeEventPayload(eventName, payload) {
55
55
  z.enum(['connecting', 'connected', 'error', 'idle']).parse(payload);
56
56
  break;
57
57
  case ReceivableEvents.ReconnectionStatusChanged:
58
- z.enum(['connecting', 'connected', 'error']).parse(payload);
58
+ z.enum(['connecting', 'connected', 'error', 'reconnecting']).parse(payload);
59
59
  break;
60
60
  case ReceivableEvents.CurrentCameraChanged:
61
61
  CameraChangedEventSchema.parse(payload);
@@ -1 +1 @@
1
- {"version":3,"file":"eventPayloadValidator.js","sourceRoot":"","sources":["../../src/utils/eventPayloadValidator.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n ReceivableEventPayloads,\n ReceivableEvents,\n} from '../RNFishjamClientModule';\n\nconst SimulcastConfigSchema = z.object({\n enabled: z.boolean(),\n activeEncodings: z.array(z.enum(['l', 'm', 'h'])),\n});\n\nconst AudioOutputDeviceSchema = z.object({\n name: z.string(),\n type: z.enum(['bluetooth', 'headset', 'speaker', 'earpiece']),\n});\n\nconst AudioDeviceEventSchema = z.object({\n availableDevices: z.array(AudioOutputDeviceSchema),\n selectedDevice: AudioOutputDeviceSchema.nullable(),\n});\n\nconst CameraSchema = z.object({\n id: z.string(),\n name: z.string(),\n facingDirection: z.enum(['front', 'back', 'unspecified']),\n});\n\nconst CameraChangedEventSchema = z.object({\n isCameraOn: z.boolean(),\n currentCamera: CameraSchema.nullable(),\n});\n\nconst TrackAspectRatioUpdatedEventSchema = z.object({\n trackId: z.string(),\n aspectRatio: z.number(),\n});\n\nexport function validateNativeEventPayload<\n T extends keyof typeof ReceivableEvents,\n>(eventName: T, payload: ReceivableEventPayloads[T]): void {\n switch (eventName) {\n case ReceivableEvents.IsMicrophoneOn:\n case ReceivableEvents.IsScreenShareOn:\n case ReceivableEvents.IsAppScreenShareOn:\n z.boolean().parse(payload);\n break;\n\n case ReceivableEvents.SimulcastConfigUpdate:\n SimulcastConfigSchema.parse(payload);\n break;\n\n case ReceivableEvents.PeersUpdate:\n break;\n\n case ReceivableEvents.AudioDeviceUpdate:\n AudioDeviceEventSchema.parse(payload);\n break;\n\n case ReceivableEvents.BandwidthEstimation:\n z.number().nullable().parse(payload);\n break;\n\n case ReceivableEvents.ReconnectionRetriesLimitReached:\n case ReceivableEvents.ReconnectionStarted:\n case ReceivableEvents.Reconnected:\n z.undefined().parse(payload);\n break;\n\n case ReceivableEvents.Warning:\n z.string().parse(payload);\n break;\n\n case ReceivableEvents.PeerStatusChanged:\n z.enum(['connecting', 'connected', 'error', 'idle']).parse(payload);\n break;\n\n case ReceivableEvents.ReconnectionStatusChanged:\n z.enum(['connecting', 'connected', 'error']).parse(payload);\n break;\n\n case ReceivableEvents.CurrentCameraChanged:\n CameraChangedEventSchema.parse(payload);\n break;\n\n case ReceivableEvents.TrackAspectRatioUpdated:\n TrackAspectRatioUpdatedEventSchema.parse(payload);\n break;\n\n default:\n throw new Error(`Unknown event: ${eventName}`);\n }\n}\n"]}
1
+ {"version":3,"file":"eventPayloadValidator.js","sourceRoot":"","sources":["../../src/utils/eventPayloadValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAEL,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAElC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;CAClD,CAAC,CAAC;AAEH,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;CAC9D,CAAC,CAAC;AAEH,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC;IAClD,cAAc,EAAE,uBAAuB,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;CAC1D,CAAC,CAAC;AAEH,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE;IACvB,aAAa,EAAE,YAAY,CAAC,QAAQ,EAAE;CACvC,CAAC,CAAC;AAEH,MAAM,kCAAkC,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;CACxB,CAAC,CAAC;AAEH,MAAM,UAAU,0BAA0B,CAExC,SAAY,EAAE,OAAmC;IACjD,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,gBAAgB,CAAC,cAAc,CAAC;QACrC,KAAK,gBAAgB,CAAC,eAAe,CAAC;QACtC,KAAK,gBAAgB,CAAC,kBAAkB;YACtC,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3B,MAAM;QAER,KAAK,gBAAgB,CAAC,qBAAqB;YACzC,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACrC,MAAM;QAER,KAAK,gBAAgB,CAAC,WAAW;YAC/B,MAAM;QAER,KAAK,gBAAgB,CAAC,iBAAiB;YACrC,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACtC,MAAM;QAER,KAAK,gBAAgB,CAAC,mBAAmB;YACvC,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACrC,MAAM;QAER,KAAK,gBAAgB,CAAC,+BAA+B,CAAC;QACtD,KAAK,gBAAgB,CAAC,mBAAmB,CAAC;QAC1C,KAAK,gBAAgB,CAAC,WAAW;YAC/B,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,MAAM;QAER,KAAK,gBAAgB,CAAC,OAAO;YAC3B,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC1B,MAAM;QAER,KAAK,gBAAgB,CAAC,iBAAiB;YACrC,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACpE,MAAM;QAER,KAAK,gBAAgB,CAAC,yBAAyB;YAC7C,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,CAChE,OAAO,CACR,CAAC;YACF,MAAM;QAER,KAAK,gBAAgB,CAAC,oBAAoB;YACxC,wBAAwB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM;QAER,KAAK,gBAAgB,CAAC,uBAAuB;YAC3C,kCAAkC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAClD,MAAM;QAER;YACE,MAAM,IAAI,KAAK,CAAC,kBAAkB,SAAS,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC","sourcesContent":["import { z } from 'zod';\nimport {\n ReceivableEventPayloads,\n ReceivableEvents,\n} from '../RNFishjamClientModule';\n\nconst SimulcastConfigSchema = z.object({\n enabled: z.boolean(),\n activeEncodings: z.array(z.enum(['l', 'm', 'h'])),\n});\n\nconst AudioOutputDeviceSchema = z.object({\n name: z.string(),\n type: z.enum(['bluetooth', 'headset', 'speaker', 'earpiece']),\n});\n\nconst AudioDeviceEventSchema = z.object({\n availableDevices: z.array(AudioOutputDeviceSchema),\n selectedDevice: AudioOutputDeviceSchema.nullable(),\n});\n\nconst CameraSchema = z.object({\n id: z.string(),\n name: z.string(),\n facingDirection: z.enum(['front', 'back', 'unspecified']),\n});\n\nconst CameraChangedEventSchema = z.object({\n isCameraOn: z.boolean(),\n currentCamera: CameraSchema.nullable(),\n});\n\nconst TrackAspectRatioUpdatedEventSchema = z.object({\n trackId: z.string(),\n aspectRatio: z.number(),\n});\n\nexport function validateNativeEventPayload<\n T extends keyof typeof ReceivableEvents,\n>(eventName: T, payload: ReceivableEventPayloads[T]): void {\n switch (eventName) {\n case ReceivableEvents.IsMicrophoneOn:\n case ReceivableEvents.IsScreenShareOn:\n case ReceivableEvents.IsAppScreenShareOn:\n z.boolean().parse(payload);\n break;\n\n case ReceivableEvents.SimulcastConfigUpdate:\n SimulcastConfigSchema.parse(payload);\n break;\n\n case ReceivableEvents.PeersUpdate:\n break;\n\n case ReceivableEvents.AudioDeviceUpdate:\n AudioDeviceEventSchema.parse(payload);\n break;\n\n case ReceivableEvents.BandwidthEstimation:\n z.number().nullable().parse(payload);\n break;\n\n case ReceivableEvents.ReconnectionRetriesLimitReached:\n case ReceivableEvents.ReconnectionStarted:\n case ReceivableEvents.Reconnected:\n z.undefined().parse(payload);\n break;\n\n case ReceivableEvents.Warning:\n z.string().parse(payload);\n break;\n\n case ReceivableEvents.PeerStatusChanged:\n z.enum(['connecting', 'connected', 'error', 'idle']).parse(payload);\n break;\n\n case ReceivableEvents.ReconnectionStatusChanged:\n z.enum(['connecting', 'connected', 'error', 'reconnecting']).parse(\n payload,\n );\n break;\n\n case ReceivableEvents.CurrentCameraChanged:\n CameraChangedEventSchema.parse(payload);\n break;\n\n case ReceivableEvents.TrackAspectRatioUpdated:\n TrackAspectRatioUpdatedEventSchema.parse(payload);\n break;\n\n default:\n throw new Error(`Unknown event: ${eventName}`);\n }\n}\n"]}
@@ -1,17 +1,9 @@
1
1
  import ExpoModulesCore
2
2
  import FishjamCloudClient
3
3
 
4
- class VideoPreviewView: ExpoView, LocalCameraTrackChangedListener {
5
- var videoView: VideoView!
4
+ class VideoPreviewView: VideoRendererView, LocalCameraTrackChangedListener {
6
5
  private var localVideoTrack: LocalCameraTrack?
7
6
 
8
- required init(appContext: AppContext? = nil) {
9
- super.init(appContext: appContext)
10
- videoView = VideoView()
11
- videoView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
12
- videoView.clipsToBounds = true
13
- }
14
-
15
7
  private func trySetLocalCameraTrack() {
16
8
  DispatchQueue.main.async { [weak self] in
17
9
  guard let self else { return }
@@ -23,50 +15,28 @@ class VideoPreviewView: ExpoView, LocalCameraTrackChangedListener {
23
15
  return
24
16
  }
25
17
 
26
- self.localVideoTrack =
27
- tracks.first(where: { (key, track) in
18
+ guard
19
+ let localVideoTrack = tracks.first(where: { (key, track) in
28
20
  track is LocalCameraTrack
29
- })?.value as? LocalCameraTrack
30
- self.localVideoTrack?.start()
31
- self.videoView.track = self.localVideoTrack
21
+ })?.value as? LocalCameraTrack, localVideoTrack.id != trackId
22
+ else { return }
23
+
24
+ self.localVideoTrack = localVideoTrack
25
+ trackId = localVideoTrack.id
26
+ localVideoTrack.start()
32
27
  }
33
28
  }
34
29
 
35
30
  override func willMove(toSuperview newSuperview: UIView?) {
36
- super.willMove(toSuperview: newSuperview)
37
31
  if newSuperview == nil {
38
- videoView.removeFromSuperview()
39
32
  RNFishjamClient.localCameraTracksChangedListenersManager.remove(self)
40
33
  localVideoTrack?.stop()
41
34
  } else {
42
- addSubview(videoView)
43
35
  RNFishjamClient.localCameraTracksChangedListenersManager.add(self)
44
36
  trySetLocalCameraTrack()
45
37
  }
46
- }
47
-
48
- override func layoutSubviews() {
49
- super.layoutSubviews()
50
- videoView.frame = bounds
51
- }
52
38
 
53
- var videoLayout: String = "FILL" {
54
- didSet {
55
- switch videoLayout {
56
- case "FIT":
57
- videoView.layout = .fit
58
- case "FILL":
59
- videoView.layout = .fill
60
- default:
61
- videoView.layout = .fill
62
- }
63
- }
64
- }
65
-
66
- var mirrorVideo: Bool = false {
67
- didSet {
68
- videoView.mirror = mirrorVideo
69
- }
39
+ super.willMove(toSuperview: newSuperview)
70
40
  }
71
41
 
72
42
  var captureDeviceId: String? = nil {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fishjam-cloud/react-native-client",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "A React Native client for Fishjam",
5
5
  "author": "Fishjam Team",
6
6
  "license": "Apache-2.0",
@@ -58,7 +58,7 @@
58
58
  "jest-websocket-mock": "^2.4.0",
59
59
  "pod-install": "^0.3.4",
60
60
  "react-dom": "^18.3.1",
61
- "ts-proto": "^2.6.1",
61
+ "ts-proto": "^2.7.0",
62
62
  "typedoc": "^0.28.1",
63
63
  "typedoc-plugin-mark-react-functional-components": "^0.2.2",
64
64
  "typescript": "^5.8.2"