@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,15 +2,14 @@ import ExpoModulesCore
2
2
  import FishjamCloudClient
3
3
 
4
4
  class VideoPreviewView: ExpoView, LocalCameraTrackChangedListener {
5
- var videoView: VideoView? = nil
6
- private var localVideoTrack: LocalCameraTrack? = nil
5
+ var videoView: VideoView!
6
+ private var localVideoTrack: LocalCameraTrack?
7
7
 
8
8
  required init(appContext: AppContext? = nil) {
9
9
  super.init(appContext: appContext)
10
10
  videoView = VideoView()
11
- videoView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
12
- videoView?.clipsToBounds = true
13
- addSubview(videoView!)
11
+ videoView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
12
+ videoView.clipsToBounds = true
14
13
  }
15
14
 
16
15
  private func trySetLocalCameraTrack() {
@@ -29,16 +28,18 @@ class VideoPreviewView: ExpoView, LocalCameraTrackChangedListener {
29
28
  track is LocalCameraTrack
30
29
  })?.value as? LocalCameraTrack
31
30
  self.localVideoTrack?.start()
32
- self.videoView?.track = self.localVideoTrack
31
+ self.videoView.track = self.localVideoTrack
33
32
  }
34
33
  }
35
34
 
36
35
  override func willMove(toSuperview newSuperview: UIView?) {
37
36
  super.willMove(toSuperview: newSuperview)
38
37
  if newSuperview == nil {
38
+ videoView.removeFromSuperview()
39
39
  RNFishjamClient.localCameraTracksChangedListenersManager.remove(self)
40
40
  localVideoTrack?.stop()
41
41
  } else {
42
+ addSubview(videoView)
42
43
  RNFishjamClient.localCameraTracksChangedListenersManager.add(self)
43
44
  trySetLocalCameraTrack()
44
45
  }
@@ -48,26 +49,25 @@ class VideoPreviewView: ExpoView, LocalCameraTrackChangedListener {
48
49
  didSet {
49
50
  switch videoLayout {
50
51
  case "FIT":
51
- self.videoView?.layout = .fit
52
+ videoView.layout = .fit
52
53
  case "FILL":
53
- self.videoView?.layout = .fill
54
+ videoView.layout = .fill
54
55
  default:
55
- self.videoView?.layout = .fill
56
+ videoView.layout = .fill
56
57
  }
57
58
  }
58
59
  }
59
60
 
60
61
  var mirrorVideo: Bool = false {
61
62
  didSet {
62
- self.videoView?.mirror = mirrorVideo
63
+ videoView.mirror = mirrorVideo
63
64
  }
64
65
  }
65
66
 
66
67
  var captureDeviceId: String? = nil {
67
68
  didSet {
68
- if let captureDeviceId = captureDeviceId {
69
- localVideoTrack?.switchCamera(deviceId: captureDeviceId)
70
- }
69
+ guard let captureDeviceId else { return }
70
+ localVideoTrack?.switchCamera(deviceId: captureDeviceId)
71
71
  }
72
72
  }
73
73
 
@@ -3,42 +3,39 @@ import ExpoModulesCore
3
3
  import FishjamCloudClient
4
4
 
5
5
  class VideoRendererView: ExpoView, TrackUpdateListener {
6
- var videoView: VideoView? = nil
7
- var cancellableEndpoints: Cancellable? = nil
6
+ var videoView: VideoView!
7
+ var cancellableEndpoints: Cancellable?
8
8
 
9
9
  required init(appContext: AppContext? = nil) {
10
10
  super.init(appContext: appContext)
11
- RNFishjamClient.tracksUpdateListenersManager.add(self)
12
11
  videoView = VideoView()
13
- videoView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
14
- videoView?.clipsToBounds = true
15
- addSubview(videoView!)
16
- }
17
-
18
- deinit {
19
- RNFishjamClient.tracksUpdateListenersManager.remove(self)
12
+ videoView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
13
+ videoView.clipsToBounds = true
20
14
  }
21
15
 
22
16
  override func willMove(toSuperview newSuperview: UIView?) {
23
17
  super.willMove(toSuperview: newSuperview)
24
18
 
25
- if newSuperview != nil {
19
+ if newSuperview == nil {
20
+ videoView.removeFromSuperview()
21
+ RNFishjamClient.tracksUpdateListenersManager.remove(self)
22
+ } else {
23
+ addSubview(videoView)
24
+ RNFishjamClient.tracksUpdateListenersManager.add(self)
26
25
  updateVideoTrack()
27
26
  }
28
27
  }
29
28
 
30
29
  func updateVideoTrack() {
31
- DispatchQueue.main.async {
32
- if self.superview != nil {
33
- for endpoint in RNFishjamClient.getLocalAndRemoteEndpoints() {
34
- if let track = endpoint.tracks[self.trackId] as? VideoTrack {
35
- if let track = track as? LocalCameraTrack {
36
- self.mirrorVideo = track.isFrontCamera
37
- }
38
- self.videoView?.track = track
39
- return
40
- }
30
+ DispatchQueue.main.async { [weak self] in
31
+ guard let self, self.superview != nil else { return }
32
+ for endpoint in RNFishjamClient.getLocalAndRemoteEndpoints() {
33
+ guard let track = endpoint.tracks[self.trackId] as? VideoTrack else { continue }
34
+ if let track = track as? LocalCameraTrack {
35
+ self.mirrorVideo = track.isFrontCamera
41
36
  }
37
+ self.videoView.track = track
38
+ return
42
39
  }
43
40
  }
44
41
  }
@@ -57,11 +54,11 @@ class VideoRendererView: ExpoView, TrackUpdateListener {
57
54
  didSet {
58
55
  switch videoLayout {
59
56
  case "FIT":
60
- self.videoView?.layout = .fit
57
+ videoView.layout = .fit
61
58
  case "FILL":
62
- self.videoView?.layout = .fill
59
+ videoView.layout = .fill
63
60
  default:
64
- self.videoView?.layout = .fill
61
+ videoView.layout = .fill
65
62
  }
66
63
 
67
64
  }
@@ -69,7 +66,13 @@ class VideoRendererView: ExpoView, TrackUpdateListener {
69
66
 
70
67
  var mirrorVideo: Bool = false {
71
68
  didSet {
72
- self.videoView?.mirror = mirrorVideo
69
+ videoView.mirror = mirrorVideo
70
+ }
71
+ }
72
+
73
+ var checkVisibilityTimeInterval: TimeInterval? {
74
+ didSet {
75
+ videoView.checkVisibilityTimeInterval = checkVisibilityTimeInterval
73
76
  }
74
77
  }
75
78
  }
@@ -5,12 +5,16 @@ public class VideoRendererViewModule: Module {
5
5
  Name("VideoRendererViewModule")
6
6
 
7
7
  View(VideoRendererView.self) {
8
- Prop("trackId") { (view: VideoRendererView, prop: String) in
9
- view.trackId = prop
8
+ Prop("trackId") { (view, trackId) in
9
+ view.trackId = trackId
10
10
  }
11
11
 
12
- Prop("videoLayout") { (view: VideoRendererView, prop: String) in
13
- view.videoLayout = prop
12
+ Prop("videoLayout") { (view, videoLayout) in
13
+ view.videoLayout = videoLayout
14
+ }
15
+
16
+ Prop("skipRenderOutsideVisibleArea") { (view, skipRenderOutsideVisibleArea) in
17
+ view.checkVisibilityTimeInterval = skipRenderOutsideVisibleArea ? 1 : nil
14
18
  }
15
19
  }
16
20
  }
@@ -0,0 +1,20 @@
1
+ import AVKit
2
+ import FishjamCloudClient
3
+
4
+ public typealias LocalCamera = [String: Any]
5
+
6
+ extension AVCaptureDevice {
7
+ func toLocalCamera() -> LocalCamera {
8
+ let facingDirection =
9
+ switch position {
10
+ case .front: "front"
11
+ case .back: "back"
12
+ default: "unspecified"
13
+ }
14
+ return [
15
+ "id": uniqueID,
16
+ "name": localizedName,
17
+ "facingDirection": facingDirection,
18
+ ]
19
+ }
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fishjam-cloud/react-native-client",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "A React Native client for Fishjam Cloud",
5
5
  "author": "Fishjam Cloud Team",
6
6
  "license": "Apache-2.0",
@@ -44,25 +44,22 @@
44
44
  "protobufjs": "^7.4.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@testing-library/react": "^15.0.7",
48
- "@types/lodash": "^4.17.10",
47
+ "@testing-library/dom": "^10.4.0",
48
+ "@testing-library/react": "^16.0.1",
49
+ "@types/lodash": "^4.17.13",
49
50
  "@types/phoenix": "^1.6.5",
50
51
  "@types/promise-fs": "^2.1.2",
51
- "@types/react": "^18.3.11",
52
- "expo": "^51.0.32",
53
- "expo-module-scripts": "^3.5.2",
54
- "expo-modules-core": "^1.12.24",
55
- "husky": "^9.1.6",
52
+ "@types/react": "^18.3.12",
53
+ "expo-module-scripts": "^4.0.2",
54
+ "husky": "^9.1.7",
56
55
  "jest": "^29.6.1",
57
56
  "jest-environment-jsdom": "^29.6.1",
58
- "jest-expo": "^51.0.4",
57
+ "jest-expo": "^52.0.0",
59
58
  "jest-websocket-mock": "^2.4.0",
60
- "pod-install": "^0.2.0",
61
- "react": "^18.2.0",
59
+ "pod-install": "^0.3.2",
62
60
  "react-dom": "^18.3.1",
63
- "react-native": "^0.75.2",
64
- "ts-proto": "^2.2.3",
65
- "typedoc": "^0.26.8",
61
+ "ts-proto": "^2.3.0",
62
+ "typedoc": "^0.26.11",
66
63
  "typedoc-plugin-mark-react-functional-components": "^0.2.2",
67
64
  "typescript": "^5.6.3"
68
65
  },
@@ -3,26 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.withFishjamAndroid = void 0;
4
4
  const config_plugins_1 = require("@expo/config-plugins");
5
5
  const Manifest_1 = require("@expo/config-plugins/build/android/Manifest");
6
- const withFishjamForegroundService = (config) => {
7
- return (0, config_plugins_1.withAndroidManifest)(config, async (config) => {
8
- const mainApplication = (0, Manifest_1.getMainApplicationOrThrow)(config.modResults);
9
- mainApplication.service = mainApplication.service || [];
10
- const newService = {
11
- $: {
12
- 'android:name': 'io.fishjam.reactnative.foregroundService.FishjamForegroundService',
13
- 'android:foregroundServiceType': 'camera|microphone|mediaProjection',
14
- },
15
- };
16
- const existingServiceIndex = mainApplication.service.findIndex((service) => service.$['android:name'] === newService.$['android:name']);
17
- if (existingServiceIndex !== -1) {
18
- mainApplication.service[existingServiceIndex] = newService;
19
- }
20
- else {
21
- mainApplication.service.push(newService);
22
- }
23
- return config;
24
- });
25
- };
6
+ const withFishjamForegroundService = (config) => (0, config_plugins_1.withAndroidManifest)(config, async (configuration) => {
7
+ const mainApplication = (0, Manifest_1.getMainApplicationOrThrow)(configuration.modResults);
8
+ mainApplication.service = mainApplication.service || [];
9
+ const newService = {
10
+ $: {
11
+ 'android:name': 'io.fishjam.reactnative.foregroundService.FishjamForegroundService',
12
+ 'android:foregroundServiceType': 'camera|microphone|mediaProjection',
13
+ },
14
+ };
15
+ const existingServiceIndex = mainApplication.service.findIndex((service) => service.$['android:name'] === newService.$['android:name']);
16
+ if (existingServiceIndex !== -1) {
17
+ mainApplication.service[existingServiceIndex] = newService;
18
+ }
19
+ else {
20
+ mainApplication.service.push(newService);
21
+ }
22
+ return configuration;
23
+ });
26
24
  const withFishjamAndroid = (config, props) => {
27
25
  if (props?.android?.enableForegroundService) {
28
26
  config = withFishjamForegroundService(config);
@@ -34,7 +34,7 @@ target '${SBE_TARGET_NAME}' do
34
34
  pod 'FishjamCloudClient/Broadcast'
35
35
  end`;
36
36
  const TARGETED_DEVICE_FAMILY = `"1,2"`;
37
- const IPHONEOS_DEPLOYMENT_TARGET = '13.4';
37
+ const IPHONEOS_DEPLOYMENT_TARGET = '15.1';
38
38
  const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
39
39
  const BUNDLE_IDENTIFIER_TEMPLATE_REGEX = /{{BUNDLE_IDENTIFIER}}/gm;
40
40
  /**
@@ -95,113 +95,109 @@ const withAppGroupPermissions = (config) => {
95
95
  * Adds constants to Info.plist
96
96
  * In other to dynamically retreive extension's bundleId and group name we need to store it in Info.plist.
97
97
  */
98
- const withInfoPlistConstants = (config) => {
99
- return (0, config_plugins_1.withInfoPlist)(config, (config) => {
100
- const bundleIdentifier = config.ios?.bundleIdentifier || '';
101
- config.modResults['AppGroupName'] = `group.${bundleIdentifier}`;
102
- config.modResults['ScreenShareExtensionBundleId'] =
103
- `${bundleIdentifier}.${SBE_TARGET_NAME}`;
104
- return config;
105
- });
106
- };
98
+ const withInfoPlistConstants = (config) => (0, config_plugins_1.withInfoPlist)(config, (configuration) => {
99
+ const bundleIdentifier = configuration.ios?.bundleIdentifier || '';
100
+ configuration.modResults['AppGroupName'] = `group.${bundleIdentifier}`;
101
+ configuration.modResults['ScreenShareExtensionBundleId'] =
102
+ `${bundleIdentifier}.${SBE_TARGET_NAME}`;
103
+ return configuration;
104
+ });
107
105
  /**
108
106
  * Updates and copies required extension files.
109
107
  * Our extension needs to be properly setup inside the Xcode project. In order to do that we need to copy the files and update the pbxproj.
110
108
  */
111
- const withFishjamSBE = (config, options) => {
112
- return (0, config_plugins_1.withXcodeProject)(config, async (props) => {
113
- const appName = props.modRequest.projectName || '';
114
- const iosPath = props.modRequest.platformProjectRoot;
115
- const bundleIdentifier = props.ios?.bundleIdentifier;
116
- const xcodeProject = props.modResults;
117
- const pluginDir = require.resolve('@fishjam-cloud/react-native-client/package.json');
118
- const extensionSourceDir = path.join(pluginDir, '../plugin/broadcastExtensionFiles/');
119
- await updatePodfile(iosPath);
120
- const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
121
- const extFiles = [
122
- 'FishjamBroadcastSampleHandler.swift',
123
- `${SBE_TARGET_NAME}.entitlements`,
124
- `Info.plist`,
125
- ];
126
- await xcodeProject.parse(async function (err) {
127
- if (err) {
128
- console.error(`Error parsing iOS project: ${JSON.stringify(err)}`);
129
- return;
130
- }
131
- if (xcodeProject.pbxTargetByName(SBE_TARGET_NAME)) {
132
- console.log(`${SBE_TARGET_NAME} already exists in project. Skipping...`);
133
- return;
134
- }
135
- try {
136
- // copy extension files
137
- await fs.mkdir(`${iosPath}/${SBE_TARGET_NAME}`, { recursive: true });
138
- for (let i = 0; i < extFiles.length; i++) {
139
- const extFile = extFiles[i];
140
- const targetFile = `${iosPath}/${SBE_TARGET_NAME}/${extFile}`;
141
- await fs.copyFile(`${extensionSourceDir}${extFile}`, targetFile);
142
- }
143
- }
144
- catch (e) {
145
- console.error('Error copying extension files: ', e);
109
+ const withFishjamSBE = (config, options) => (0, config_plugins_1.withXcodeProject)(config, async (props) => {
110
+ const appName = props.modRequest.projectName || '';
111
+ const iosPath = props.modRequest.platformProjectRoot;
112
+ const bundleIdentifier = props.ios?.bundleIdentifier;
113
+ const xcodeProject = props.modResults;
114
+ const pluginDir = require.resolve('@fishjam-cloud/react-native-client/package.json');
115
+ const extensionSourceDir = path.join(pluginDir, '../plugin/broadcastExtensionFiles/');
116
+ await updatePodfile(iosPath);
117
+ const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
118
+ const extFiles = [
119
+ 'FishjamBroadcastSampleHandler.swift',
120
+ `${SBE_TARGET_NAME}.entitlements`,
121
+ `Info.plist`,
122
+ ];
123
+ await xcodeProject.parse(async function (err) {
124
+ if (err) {
125
+ console.error(`Error parsing iOS project: ${JSON.stringify(err)}`);
126
+ return;
127
+ }
128
+ if (xcodeProject.pbxTargetByName(SBE_TARGET_NAME)) {
129
+ console.log(`${SBE_TARGET_NAME} already exists in project. Skipping...`);
130
+ return;
131
+ }
132
+ try {
133
+ // copy extension files
134
+ await fs.mkdir(`${iosPath}/${SBE_TARGET_NAME}`, { recursive: true });
135
+ for (let i = 0; i < extFiles.length; i++) {
136
+ const extFile = extFiles[i];
137
+ const targetFile = `${iosPath}/${SBE_TARGET_NAME}/${extFile}`;
138
+ await fs.copyFile(`${extensionSourceDir}${extFile}`, targetFile);
146
139
  }
147
- // update extension files
148
- await updateFileWithRegex(iosPath, `${SBE_TARGET_NAME}.entitlements`, GROUP_IDENTIFIER_TEMPLATE_REGEX, `group.${bundleIdentifier}`);
149
- await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift', GROUP_IDENTIFIER_TEMPLATE_REGEX, `group.${bundleIdentifier}`);
150
- await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift', BUNDLE_IDENTIFIER_TEMPLATE_REGEX, bundleIdentifier || '');
151
- // Create new PBXGroup for the extension
152
- const extGroup = xcodeProject.addPbxGroup(extFiles, SBE_TARGET_NAME, SBE_TARGET_NAME);
153
- // Add the new PBXGroup to the top level group. This makes the
154
- // files / folder appear in the file explorer in Xcode.
155
- const groups = xcodeProject.hash.project.objects['PBXGroup'];
156
- Object.keys(groups).forEach(function (key) {
157
- if (groups[key].name === undefined) {
158
- xcodeProject.addToPbxGroup(extGroup.uuid, key);
159
- }
160
- });
161
- // WORK AROUND for codeProject.addTarget BUG
162
- // Xcode projects don't contain these if there is only one target
163
- // An upstream fix should be made to the code referenced in this link:
164
- // - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
165
- const projObjects = xcodeProject.hash.project.objects;
166
- projObjects['PBXTargetDependency'] =
167
- projObjects['PBXTargetDependency'] || {};
168
- projObjects['PBXContainerItemProxy'] =
169
- projObjects['PBXTargetDependency'] || {};
170
- // Add the SBE target
171
- // This adds PBXTargetDependency and PBXContainerItemProxy for you
172
- const sbeTarget = xcodeProject.addTarget(SBE_TARGET_NAME, 'app_extension', SBE_TARGET_NAME, `${bundleIdentifier}.${SBE_TARGET_NAME}`);
173
- // Add build phases to the new target
174
- xcodeProject.addBuildPhase(['FishjamBroadcastSampleHandler.swift'], 'PBXSourcesBuildPhase', 'Sources', sbeTarget.uuid);
175
- xcodeProject.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', sbeTarget.uuid);
176
- xcodeProject.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', sbeTarget.uuid);
177
- xcodeProject.addFramework('ReplayKit.framework', {
178
- target: sbeTarget.uuid,
179
- });
180
- // Edit the Deployment info of the new Target, only IphoneOS and Targeted Device Family
181
- // However, can be more
182
- const configurations = xcodeProject.pbxXCBuildConfigurationSection();
183
- for (const key in configurations) {
184
- if (typeof configurations[key].buildSettings !== 'undefined' &&
185
- configurations[key].buildSettings.PRODUCT_NAME ===
186
- `"${SBE_TARGET_NAME}"`) {
187
- const buildSettingsObj = configurations[key].buildSettings;
188
- buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET =
189
- options?.ios?.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
190
- buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;
191
- buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${SBE_TARGET_NAME}/${SBE_TARGET_NAME}.entitlements`;
192
- buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
193
- buildSettingsObj.INFOPLIST_FILE = `${SBE_TARGET_NAME}/Info.plist`;
194
- buildSettingsObj.SWIFT_VERSION = '5.0';
195
- buildSettingsObj.MARKETING_VERSION = '1.0.0';
196
- buildSettingsObj.CURRENT_PROJECT_VERSION = '1';
197
- buildSettingsObj.ENABLE_BITCODE = 'NO';
198
- }
140
+ }
141
+ catch (e) {
142
+ console.error('Error copying extension files: ', e);
143
+ }
144
+ // update extension files
145
+ await updateFileWithRegex(iosPath, `${SBE_TARGET_NAME}.entitlements`, GROUP_IDENTIFIER_TEMPLATE_REGEX, `group.${bundleIdentifier}`);
146
+ await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift', GROUP_IDENTIFIER_TEMPLATE_REGEX, `group.${bundleIdentifier}`);
147
+ await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift', BUNDLE_IDENTIFIER_TEMPLATE_REGEX, bundleIdentifier || '');
148
+ // Create new PBXGroup for the extension
149
+ const extGroup = xcodeProject.addPbxGroup(extFiles, SBE_TARGET_NAME, SBE_TARGET_NAME);
150
+ // Add the new PBXGroup to the top level group. This makes the
151
+ // files / folder appear in the file explorer in Xcode.
152
+ const groups = xcodeProject.hash.project.objects['PBXGroup'];
153
+ Object.keys(groups).forEach(function (key) {
154
+ if (groups[key].name === undefined) {
155
+ xcodeProject.addToPbxGroup(extGroup.uuid, key);
199
156
  }
200
- await fs.writeFile(projPath, xcodeProject.writeSync());
201
157
  });
202
- return props;
158
+ // WORK AROUND for codeProject.addTarget BUG
159
+ // Xcode projects don't contain these if there is only one target
160
+ // An upstream fix should be made to the code referenced in this link:
161
+ // - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
162
+ const projObjects = xcodeProject.hash.project.objects;
163
+ projObjects['PBXTargetDependency'] =
164
+ projObjects['PBXTargetDependency'] || {};
165
+ projObjects['PBXContainerItemProxy'] =
166
+ projObjects['PBXTargetDependency'] || {};
167
+ // Add the SBE target
168
+ // This adds PBXTargetDependency and PBXContainerItemProxy for you
169
+ const sbeTarget = xcodeProject.addTarget(SBE_TARGET_NAME, 'app_extension', SBE_TARGET_NAME, `${bundleIdentifier}.${SBE_TARGET_NAME}`);
170
+ // Add build phases to the new target
171
+ xcodeProject.addBuildPhase(['FishjamBroadcastSampleHandler.swift'], 'PBXSourcesBuildPhase', 'Sources', sbeTarget.uuid);
172
+ xcodeProject.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', sbeTarget.uuid);
173
+ xcodeProject.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', sbeTarget.uuid);
174
+ xcodeProject.addFramework('ReplayKit.framework', {
175
+ target: sbeTarget.uuid,
176
+ });
177
+ // Edit the Deployment info of the new Target, only IphoneOS and Targeted Device Family
178
+ // However, can be more
179
+ const configurations = xcodeProject.pbxXCBuildConfigurationSection();
180
+ for (const key in configurations) {
181
+ if (typeof configurations[key].buildSettings !== 'undefined' &&
182
+ configurations[key].buildSettings.PRODUCT_NAME ===
183
+ `"${SBE_TARGET_NAME}"`) {
184
+ const buildSettingsObj = configurations[key].buildSettings;
185
+ buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET =
186
+ options?.ios?.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
187
+ buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;
188
+ buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${SBE_TARGET_NAME}/${SBE_TARGET_NAME}.entitlements`;
189
+ buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
190
+ buildSettingsObj.INFOPLIST_FILE = `${SBE_TARGET_NAME}/Info.plist`;
191
+ buildSettingsObj.SWIFT_VERSION = '5.0';
192
+ buildSettingsObj.MARKETING_VERSION = '1.0.0';
193
+ buildSettingsObj.CURRENT_PROJECT_VERSION = '1';
194
+ buildSettingsObj.ENABLE_BITCODE = 'NO';
195
+ }
196
+ }
197
+ await fs.writeFile(projPath, xcodeProject.writeSync());
203
198
  });
204
- };
199
+ return props;
200
+ });
205
201
  /**
206
202
  * Applies screen sharing plugin if enabled. In order for screensharing to work, we need to copy extension files to your iOS project.
207
203
  * Allows for dynamically changing deploymentTarget.
@@ -212,10 +208,10 @@ const withFishjamIos = (config, props) => {
212
208
  withInfoPlistConstants(config);
213
209
  withFishjamSBE(config, props);
214
210
  }
215
- (0, config_plugins_1.withPodfileProperties)(config, (config) => {
216
- config.modResults['ios.deploymentTarget'] =
211
+ (0, config_plugins_1.withPodfileProperties)(config, (configuration) => {
212
+ configuration.modResults['ios.deploymentTarget'] =
217
213
  props?.ios?.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
218
- return config;
214
+ return configuration;
219
215
  });
220
216
  return config;
221
217
  };
@@ -1,18 +0,0 @@
1
- export declare const ReceivableEvents: {
2
- readonly IsCameraOn: "IsCameraOn";
3
- readonly IsMicrophoneOn: "IsMicrophoneOn";
4
- readonly IsScreenShareOn: "IsScreenShareOn";
5
- readonly IsAppScreenShareOn: "IsAppScreenShareOn";
6
- readonly SimulcastConfigUpdate: "SimulcastConfigUpdate";
7
- readonly PeersUpdate: "PeersUpdate";
8
- readonly AudioDeviceUpdate: "AudioDeviceUpdate";
9
- readonly SendMediaEvent: "SendMediaEvent";
10
- readonly BandwidthEstimation: "BandwidthEstimation";
11
- readonly ReconnectionRetriesLimitReached: "ReconnectionRetriesLimitReached";
12
- readonly ReconnectionStarted: "ReconnectionStarted";
13
- readonly Reconnected: "Reconnected";
14
- readonly Warning: "Warning";
15
- readonly PeerStatusChanged: "PeerStatusChanged";
16
- };
17
- export declare function useFishjamEvent<T>(eventName: keyof typeof ReceivableEvents, callback: (event: T) => void): void;
18
- //# sourceMappingURL=useFishjamEvent.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useFishjamEvent.d.ts","sourceRoot":"","sources":["../../src/hooks/useFishjamEvent.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;CAenB,CAAC;AAEX,wBAAgB,eAAe,CAAC,CAAC,EAC/B,SAAS,EAAE,MAAM,OAAO,gBAAgB,EACxC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,QAU7B"}
@@ -1,27 +0,0 @@
1
- import { useEffect } from 'react';
2
- import { nativeModuleEventEmitter } from '../RNFishjamClientModule';
3
- export const ReceivableEvents = {
4
- IsCameraOn: 'IsCameraOn',
5
- IsMicrophoneOn: 'IsMicrophoneOn',
6
- IsScreenShareOn: 'IsScreenShareOn',
7
- IsAppScreenShareOn: 'IsAppScreenShareOn', // only for iOS
8
- SimulcastConfigUpdate: 'SimulcastConfigUpdate',
9
- PeersUpdate: 'PeersUpdate',
10
- AudioDeviceUpdate: 'AudioDeviceUpdate',
11
- SendMediaEvent: 'SendMediaEvent',
12
- BandwidthEstimation: 'BandwidthEstimation',
13
- ReconnectionRetriesLimitReached: 'ReconnectionRetriesLimitReached',
14
- ReconnectionStarted: 'ReconnectionStarted',
15
- Reconnected: 'Reconnected',
16
- Warning: 'Warning',
17
- PeerStatusChanged: 'PeerStatusChanged',
18
- };
19
- export function useFishjamEvent(eventName, callback) {
20
- useEffect(() => {
21
- const eventListener = nativeModuleEventEmitter.addListener(eventName, (event) => {
22
- callback(event[eventName]);
23
- });
24
- return () => eventListener.remove();
25
- }, [callback, eventName]);
26
- }
27
- //# sourceMappingURL=useFishjamEvent.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useFishjamEvent.js","sourceRoot":"","sources":["../../src/hooks/useFishjamEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,UAAU,EAAE,YAAY;IACxB,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;CAC9B,CAAC;AAEX,MAAM,UAAU,eAAe,CAC7B,SAAwC,EACxC,QAA4B;IAE5B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,aAAa,GAAG,wBAAwB,CAAC,WAAW,CAExD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YACrB,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;IACtC,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAC5B,CAAC","sourcesContent":["import { useEffect } from 'react';\nimport { nativeModuleEventEmitter } from '../RNFishjamClientModule';\n\nexport const ReceivableEvents = {\n IsCameraOn: 'IsCameraOn',\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} as const;\n\nexport function useFishjamEvent<T>(\n eventName: keyof typeof ReceivableEvents,\n callback: (event: T) => void,\n) {\n useEffect(() => {\n const eventListener = nativeModuleEventEmitter.addListener<\n Record<keyof typeof ReceivableEvents, T>\n >(eventName, (event) => {\n callback(event[eventName]);\n });\n return () => eventListener.remove();\n }, [callback, eventName]);\n}\n"]}