@fishjam-cloud/react-native-client 0.24.0 → 0.25.0-rc.1

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 (266) hide show
  1. package/README.md +56 -15
  2. package/dist/index.d.ts +13 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +19 -0
  5. package/dist/overrides/RTCPeerConnection.d.ts +8 -0
  6. package/dist/overrides/RTCPeerConnection.d.ts.map +1 -0
  7. package/dist/overrides/RTCPeerConnection.js +16 -0
  8. package/dist/overrides/RTCView.d.ts +11 -0
  9. package/dist/overrides/RTCView.d.ts.map +1 -0
  10. package/dist/overrides/RTCView.js +21 -0
  11. package/dist/polyfills/local-storage.d.ts +10 -0
  12. package/dist/polyfills/local-storage.d.ts.map +1 -0
  13. package/dist/polyfills/local-storage.js +24 -0
  14. package/{build/hooks → dist}/useForegroundService.d.ts +10 -10
  15. package/dist/useForegroundService.d.ts.map +1 -0
  16. package/dist/useForegroundService.js +10 -0
  17. package/dist/webrtc-polyfill.d.ts +2 -0
  18. package/dist/webrtc-polyfill.d.ts.map +1 -0
  19. package/dist/webrtc-polyfill.js +14 -0
  20. package/package.json +44 -92
  21. package/plugin/broadcastExtensionFiles/Atomic.swift +37 -0
  22. package/plugin/broadcastExtensionFiles/DarwinNotificationCenter.swift +29 -0
  23. package/plugin/broadcastExtensionFiles/Info.plist +1 -1
  24. package/plugin/broadcastExtensionFiles/SampleHandler.swift +104 -0
  25. package/plugin/broadcastExtensionFiles/SampleUploader.swift +146 -0
  26. package/plugin/broadcastExtensionFiles/SocketConnection.swift +198 -0
  27. package/plugin/build/types.d.ts +5 -4
  28. package/plugin/build/withFishjam.d.ts +31 -2
  29. package/plugin/build/withFishjam.js +31 -5
  30. package/plugin/build/withFishjamAndroid.d.ts +2 -2
  31. package/plugin/build/withFishjamAndroid.js +48 -40
  32. package/plugin/build/withFishjamIos.d.ts +3 -8
  33. package/plugin/build/withFishjamIos.js +52 -72
  34. package/plugin/src/types.ts +19 -0
  35. package/plugin/src/withFishjam.ts +42 -0
  36. package/plugin/src/withFishjamAndroid.ts +112 -0
  37. package/plugin/src/withFishjamIos.ts +336 -0
  38. package/plugin/tsconfig.json +9 -0
  39. package/plugin/tsconfig.tsbuildinfo +1 -0
  40. package/LICENSE.txt +0 -201
  41. package/android/build.gradle +0 -95
  42. package/android/src/main/AndroidManifest.xml +0 -2
  43. package/android/src/main/java/io/fishjam/reactnative/AudioDeviceKind.kt +0 -34
  44. package/android/src/main/java/io/fishjam/reactnative/AudioSwitchManager.kt +0 -61
  45. package/android/src/main/java/io/fishjam/reactnative/EmitableEvents.kt +0 -126
  46. package/android/src/main/java/io/fishjam/reactnative/Errors.kt +0 -31
  47. package/android/src/main/java/io/fishjam/reactnative/PipContainerView.kt +0 -282
  48. package/android/src/main/java/io/fishjam/reactnative/PipContainerViewModule.kt +0 -41
  49. package/android/src/main/java/io/fishjam/reactnative/PipTrackSelector.kt +0 -98
  50. package/android/src/main/java/io/fishjam/reactnative/PipViewFactory.kt +0 -186
  51. package/android/src/main/java/io/fishjam/reactnative/RNFishjamClient.kt +0 -1001
  52. package/android/src/main/java/io/fishjam/reactnative/RNFishjamClientModule.kt +0 -358
  53. package/android/src/main/java/io/fishjam/reactnative/Utils.kt +0 -11
  54. package/android/src/main/java/io/fishjam/reactnative/VideoPreviewView.kt +0 -40
  55. package/android/src/main/java/io/fishjam/reactnative/VideoPreviewViewModule.kt +0 -22
  56. package/android/src/main/java/io/fishjam/reactnative/VideoRendererView.kt +0 -76
  57. package/android/src/main/java/io/fishjam/reactnative/VideoRendererViewModule.kt +0 -33
  58. package/android/src/main/java/io/fishjam/reactnative/VideoView.kt +0 -257
  59. package/android/src/main/java/io/fishjam/reactnative/extensions/CaptureDevice.kt +0 -17
  60. package/android/src/main/java/io/fishjam/reactnative/foregroundService/FishjamForegroundService.kt +0 -101
  61. package/android/src/main/java/io/fishjam/reactnative/foregroundService/ForegroundServiceManager.kt +0 -118
  62. package/android/src/main/java/io/fishjam/reactnative/foregroundService/ForegroundServiceState.kt +0 -46
  63. package/android/src/main/java/io/fishjam/reactnative/helpers/PictureInPictureHelperFragment.kt +0 -20
  64. package/android/src/main/java/io/fishjam/reactnative/managers/ListenerManager.kt +0 -24
  65. package/android/src/main/java/io/fishjam/reactnative/managers/LocalCameraTracksChangedListenersManager.kt +0 -8
  66. package/android/src/main/java/io/fishjam/reactnative/managers/LocalTracksSwitchListenersManager.kt +0 -17
  67. package/android/src/main/java/io/fishjam/reactnative/managers/TracksUpdateListenersManager.kt +0 -7
  68. package/android/src/main/java/io/fishjam/reactnative/utils/PermissionUtils.kt +0 -45
  69. package/build/RNFishjamClientModule.d.ts +0 -106
  70. package/build/RNFishjamClientModule.d.ts.map +0 -1
  71. package/build/RNFishjamClientModule.js +0 -21
  72. package/build/RNFishjamClientModule.js.map +0 -1
  73. package/build/common/metadata.d.ts +0 -9
  74. package/build/common/metadata.d.ts.map +0 -1
  75. package/build/common/metadata.js +0 -11
  76. package/build/common/metadata.js.map +0 -1
  77. package/build/components/FishjamRoom/GridTrackItem.d.ts +0 -12
  78. package/build/components/FishjamRoom/GridTrackItem.d.ts.map +0 -1
  79. package/build/components/FishjamRoom/GridTrackItem.js +0 -56
  80. package/build/components/FishjamRoom/GridTrackItem.js.map +0 -1
  81. package/build/components/FishjamRoom/VideosGrid.d.ts +0 -3
  82. package/build/components/FishjamRoom/VideosGrid.d.ts.map +0 -1
  83. package/build/components/FishjamRoom/VideosGrid.js +0 -20
  84. package/build/components/FishjamRoom/VideosGrid.js.map +0 -1
  85. package/build/components/FishjamRoom/index.d.ts +0 -33
  86. package/build/components/FishjamRoom/index.d.ts.map +0 -1
  87. package/build/components/FishjamRoom/index.js +0 -52
  88. package/build/components/FishjamRoom/index.js.map +0 -1
  89. package/build/components/FishjamRoom/parsePeersToTracks.d.ts +0 -4
  90. package/build/components/FishjamRoom/parsePeersToTracks.d.ts.map +0 -1
  91. package/build/components/FishjamRoom/parsePeersToTracks.js +0 -37
  92. package/build/components/FishjamRoom/parsePeersToTracks.js.map +0 -1
  93. package/build/components/PipContainerView.d.ts +0 -48
  94. package/build/components/PipContainerView.d.ts.map +0 -1
  95. package/build/components/PipContainerView.js +0 -34
  96. package/build/components/PipContainerView.js.map +0 -1
  97. package/build/components/VideoPreviewView.d.ts +0 -28
  98. package/build/components/VideoPreviewView.d.ts.map +0 -1
  99. package/build/components/VideoPreviewView.js +0 -17
  100. package/build/components/VideoPreviewView.js.map +0 -1
  101. package/build/components/VideoRendererView.d.ts +0 -39
  102. package/build/components/VideoRendererView.d.ts.map +0 -1
  103. package/build/components/VideoRendererView.js +0 -25
  104. package/build/components/VideoRendererView.js.map +0 -1
  105. package/build/consts/index.d.ts +0 -5
  106. package/build/consts/index.d.ts.map +0 -1
  107. package/build/consts/index.js +0 -8
  108. package/build/consts/index.js.map +0 -1
  109. package/build/debug/common/webRTC.d.ts +0 -9
  110. package/build/debug/common/webRTC.d.ts.map +0 -1
  111. package/build/debug/common/webRTC.js +0 -11
  112. package/build/debug/common/webRTC.js.map +0 -1
  113. package/build/debug/index.d.ts +0 -4
  114. package/build/debug/index.d.ts.map +0 -1
  115. package/build/debug/index.js +0 -3
  116. package/build/debug/index.js.map +0 -1
  117. package/build/debug/stats/types.d.ts +0 -55
  118. package/build/debug/stats/types.d.ts.map +0 -1
  119. package/build/debug/stats/types.js +0 -2
  120. package/build/debug/stats/types.js.map +0 -1
  121. package/build/debug/stats/useRTCStatistics.d.ts +0 -9
  122. package/build/debug/stats/useRTCStatistics.d.ts.map +0 -1
  123. package/build/debug/stats/useRTCStatistics.js +0 -79
  124. package/build/debug/stats/useRTCStatistics.js.map +0 -1
  125. package/build/hooks/internal/useFishjamEvent.d.ts +0 -4
  126. package/build/hooks/internal/useFishjamEvent.d.ts.map +0 -1
  127. package/build/hooks/internal/useFishjamEvent.js +0 -38
  128. package/build/hooks/internal/useFishjamEvent.js.map +0 -1
  129. package/build/hooks/internal/useFishjamEventState.d.ts +0 -3
  130. package/build/hooks/internal/useFishjamEventState.d.ts.map +0 -1
  131. package/build/hooks/internal/useFishjamEventState.js +0 -18
  132. package/build/hooks/internal/useFishjamEventState.js.map +0 -1
  133. package/build/hooks/useAppScreenShare.d.ts +0 -18
  134. package/build/hooks/useAppScreenShare.d.ts.map +0 -1
  135. package/build/hooks/useAppScreenShare.js +0 -46
  136. package/build/hooks/useAppScreenShare.js.map +0 -1
  137. package/build/hooks/useAudioSettings.d.ts +0 -49
  138. package/build/hooks/useAudioSettings.d.ts.map +0 -1
  139. package/build/hooks/useAudioSettings.js +0 -70
  140. package/build/hooks/useAudioSettings.js.map +0 -1
  141. package/build/hooks/useBandwidthEstimation.d.ts +0 -14
  142. package/build/hooks/useBandwidthEstimation.d.ts.map +0 -1
  143. package/build/hooks/useBandwidthEstimation.js +0 -19
  144. package/build/hooks/useBandwidthEstimation.js.map +0 -1
  145. package/build/hooks/useCallKit.d.ts +0 -121
  146. package/build/hooks/useCallKit.d.ts.map +0 -1
  147. package/build/hooks/useCallKit.js +0 -142
  148. package/build/hooks/useCallKit.js.map +0 -1
  149. package/build/hooks/useCamera.d.ts +0 -113
  150. package/build/hooks/useCamera.d.ts.map +0 -1
  151. package/build/hooks/useCamera.js +0 -93
  152. package/build/hooks/useCamera.js.map +0 -1
  153. package/build/hooks/useConnection.d.ts +0 -73
  154. package/build/hooks/useConnection.d.ts.map +0 -1
  155. package/build/hooks/useConnection.js +0 -46
  156. package/build/hooks/useConnection.js.map +0 -1
  157. package/build/hooks/useForegroundService.d.ts.map +0 -1
  158. package/build/hooks/useForegroundService.js +0 -66
  159. package/build/hooks/useForegroundService.js.map +0 -1
  160. package/build/hooks/useMicrophone.d.ts +0 -16
  161. package/build/hooks/useMicrophone.d.ts.map +0 -1
  162. package/build/hooks/useMicrophone.js +0 -31
  163. package/build/hooks/useMicrophone.js.map +0 -1
  164. package/build/hooks/usePeerStatus.d.ts +0 -10
  165. package/build/hooks/usePeerStatus.d.ts.map +0 -1
  166. package/build/hooks/usePeerStatus.js +0 -13
  167. package/build/hooks/usePeerStatus.js.map +0 -1
  168. package/build/hooks/usePeers.d.ts +0 -98
  169. package/build/hooks/usePeers.d.ts.map +0 -1
  170. package/build/hooks/usePeers.js +0 -81
  171. package/build/hooks/usePeers.js.map +0 -1
  172. package/build/hooks/usePermissions.d.ts +0 -24
  173. package/build/hooks/usePermissions.d.ts.map +0 -1
  174. package/build/hooks/usePermissions.js +0 -61
  175. package/build/hooks/usePermissions.js.map +0 -1
  176. package/build/hooks/useReconnection.d.ts +0 -11
  177. package/build/hooks/useReconnection.d.ts.map +0 -1
  178. package/build/hooks/useReconnection.js +0 -14
  179. package/build/hooks/useReconnection.js.map +0 -1
  180. package/build/hooks/useSandbox.d.ts +0 -20
  181. package/build/hooks/useSandbox.d.ts.map +0 -1
  182. package/build/hooks/useSandbox.js +0 -54
  183. package/build/hooks/useSandbox.js.map +0 -1
  184. package/build/hooks/useScreenShare.d.ts +0 -36
  185. package/build/hooks/useScreenShare.d.ts.map +0 -1
  186. package/build/hooks/useScreenShare.js +0 -45
  187. package/build/hooks/useScreenShare.js.map +0 -1
  188. package/build/hooks/useUpdatePeerMetadata.d.ts +0 -15
  189. package/build/hooks/useUpdatePeerMetadata.d.ts.map +0 -1
  190. package/build/hooks/useUpdatePeerMetadata.js +0 -21
  191. package/build/hooks/useUpdatePeerMetadata.js.map +0 -1
  192. package/build/index.d.ts +0 -36
  193. package/build/index.d.ts.map +0 -1
  194. package/build/index.js +0 -30
  195. package/build/index.js.map +0 -1
  196. package/build/livestream/components/LivestreamStreamer.d.ts +0 -24
  197. package/build/livestream/components/LivestreamStreamer.d.ts.map +0 -1
  198. package/build/livestream/components/LivestreamStreamer.js +0 -12
  199. package/build/livestream/components/LivestreamStreamer.js.map +0 -1
  200. package/build/livestream/components/LivestreamViewer.d.ts +0 -46
  201. package/build/livestream/components/LivestreamViewer.d.ts.map +0 -1
  202. package/build/livestream/components/LivestreamViewer.js +0 -10
  203. package/build/livestream/components/LivestreamViewer.js.map +0 -1
  204. package/build/livestream/hooks/useLivestreamScreenSharingStreamer.d.ts +0 -49
  205. package/build/livestream/hooks/useLivestreamScreenSharingStreamer.d.ts.map +0 -1
  206. package/build/livestream/hooks/useLivestreamScreenSharingStreamer.js +0 -58
  207. package/build/livestream/hooks/useLivestreamScreenSharingStreamer.js.map +0 -1
  208. package/build/livestream/hooks/useLivestreamStreamer.d.ts +0 -65
  209. package/build/livestream/hooks/useLivestreamStreamer.d.ts.map +0 -1
  210. package/build/livestream/hooks/useLivestreamStreamer.js +0 -71
  211. package/build/livestream/hooks/useLivestreamStreamer.js.map +0 -1
  212. package/build/livestream/hooks/useLivestreamViewer.d.ts +0 -36
  213. package/build/livestream/hooks/useLivestreamViewer.d.ts.map +0 -1
  214. package/build/livestream/hooks/useLivestreamViewer.js +0 -73
  215. package/build/livestream/hooks/useLivestreamViewer.js.map +0 -1
  216. package/build/livestream/index.d.ts +0 -12
  217. package/build/livestream/index.d.ts.map +0 -1
  218. package/build/livestream/index.js +0 -7
  219. package/build/livestream/index.js.map +0 -1
  220. package/build/protos/fishjam/peer_notifications.d.ts +0 -63
  221. package/build/protos/fishjam/peer_notifications.d.ts.map +0 -1
  222. package/build/protos/fishjam/peer_notifications.js +0 -235
  223. package/build/protos/fishjam/peer_notifications.js.map +0 -1
  224. package/build/types.d.ts +0 -34
  225. package/build/types.d.ts.map +0 -1
  226. package/build/types.js +0 -2
  227. package/build/types.js.map +0 -1
  228. package/build/utils/config.d.ts +0 -6
  229. package/build/utils/config.d.ts.map +0 -1
  230. package/build/utils/config.js +0 -10
  231. package/build/utils/config.js.map +0 -1
  232. package/build/utils/errorListener.d.ts +0 -2
  233. package/build/utils/errorListener.d.ts.map +0 -1
  234. package/build/utils/errorListener.js +0 -15
  235. package/build/utils/errorListener.js.map +0 -1
  236. package/build/utils/eventPayloadValidator.d.ts +0 -3
  237. package/build/utils/eventPayloadValidator.d.ts.map +0 -1
  238. package/build/utils/eventPayloadValidator.js +0 -86
  239. package/build/utils/eventPayloadValidator.js.map +0 -1
  240. package/build/utils/getFishjamUrl.d.ts +0 -2
  241. package/build/utils/getFishjamUrl.d.ts.map +0 -1
  242. package/build/utils/getFishjamUrl.js +0 -10
  243. package/build/utils/getFishjamUrl.js.map +0 -1
  244. package/debug/package.json +0 -4
  245. package/expo-module.config.json +0 -19
  246. package/ios/CameraPermissionsRequester.swift +0 -117
  247. package/ios/Events.swift +0 -152
  248. package/ios/PictureInPictureManager.swift +0 -215
  249. package/ios/PipContainerView.swift +0 -56
  250. package/ios/PipContainerViewModule.swift +0 -48
  251. package/ios/RNFishjamClient.podspec +0 -30
  252. package/ios/RNFishjamClient.swift +0 -995
  253. package/ios/RNFishjamClientModule.swift +0 -289
  254. package/ios/RNFishjamProxy.swift +0 -12
  255. package/ios/Utils/PermissionUtils.swift +0 -16
  256. package/ios/Utils.swift +0 -23
  257. package/ios/VideoPreviewView.swift +0 -54
  258. package/ios/VideoPreviewViewModule.swift +0 -21
  259. package/ios/VideoRendererView.swift +0 -98
  260. package/ios/VideoRendererViewModule.swift +0 -23
  261. package/ios/extensions/AVCaptureDevice.swift +0 -20
  262. package/ios/managers/LocalCameraTracksChangedListenersManager.swift +0 -23
  263. package/ios/managers/TracksUpdateListenersManager.swift +0 -21
  264. package/livestream/package.json +0 -4
  265. package/plugin/broadcastExtensionFiles/FishjamBroadcastSampleHandler.swift +0 -50
  266. /package/plugin/broadcastExtensionFiles/{FishjamScreenBroadcastExtension.entitlements → ScreenBroadcastExtension.entitlements} +0 -0
@@ -1,257 +0,0 @@
1
- package io.fishjam.reactnative
2
-
3
- import android.animation.ValueAnimator
4
- import android.annotation.SuppressLint
5
- import android.content.Context
6
- import android.content.res.Resources
7
- import android.graphics.Color
8
- import android.graphics.Rect
9
- import android.graphics.drawable.ColorDrawable
10
- import android.os.Handler
11
- import android.os.Looper
12
- import android.view.animation.LinearInterpolator
13
- import androidx.core.view.ViewCompat
14
- import com.fishjamcloud.client.media.LocalVideoTrack
15
- import com.fishjamcloud.client.media.VideoTrack
16
- import com.fishjamcloud.client.models.Dimensions
17
- import com.fishjamcloud.client.ui.VideoSurfaceViewRenderer
18
- import com.fishjamcloud.client.ui.VideoSurfaceViewRendererListener
19
- import expo.modules.kotlin.AppContext
20
- import expo.modules.kotlin.views.ExpoView
21
- import io.fishjam.reactnative.managers.LocalTrackSwitchListener
22
- import kotlinx.coroutines.delay
23
- import org.webrtc.RendererCommon
24
-
25
- abstract class VideoView(
26
- context: Context,
27
- appContext: AppContext
28
- ) : ExpoView(context, appContext),
29
- LocalTrackSwitchListener, VideoSurfaceViewRendererListener {
30
- protected val videoView: VideoSurfaceViewRenderer = RNFishjamClient.fishjamClient.createVideoViewRenderer().also {
31
- it.setEnableHardwareScaler(true)
32
- addView(it)
33
- }
34
-
35
- private var frameHeight: Int = 0
36
- private var frameWidth: Int = 0
37
-
38
- private var scalingType = RendererCommon.ScalingType.SCALE_ASPECT_FIT
39
- set(value) {
40
- field = value
41
- videoView.setScalingType(scalingType)
42
- post(requestSurfaceViewRendererLayoutRunnable)
43
- }
44
-
45
-
46
- private val fadeAnimation: ValueAnimator =
47
- ValueAnimator.ofArgb(Color.TRANSPARENT, Color.BLACK).apply {
48
- duration = 200
49
- interpolator = LinearInterpolator()
50
- addUpdateListener {
51
- val colorValue = it.animatedValue as Int
52
- foreground = ColorDrawable(colorValue)
53
- }
54
- }
55
-
56
- private val checkVisibilityHandler: Handler = Handler(Looper.getMainLooper())
57
-
58
- // If set to `null` the view will always be rendered
59
- var checkVisibilityDelayMillis: Long? = null
60
- set(value) {
61
- field = value
62
- if (value == null) {
63
- getVideoTrack()?.shouldReceive(true)
64
- } else {
65
- checkVisibilityHandler.post(checkVisibility)
66
- }
67
- }
68
-
69
- private val checkVisibility =
70
- object : Runnable {
71
- override fun run() {
72
- checkVisibilityDelayMillis?.let {
73
- getVideoTrack()?.shouldReceive(isVisibleOnScreen)
74
- checkVisibilityHandler.postDelayed(this, it)
75
- }
76
- }
77
- }
78
-
79
- private val isVisibleOnScreen: Boolean
80
- get() {
81
- if (!isShown) {
82
- return false
83
- }
84
-
85
- val globalVisibleRect = Rect()
86
- getGlobalVisibleRect(globalVisibleRect)
87
- val displayMetrics = Resources.getSystem().displayMetrics
88
- val screen = Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)
89
- return screen.intersect(globalVisibleRect)
90
- }
91
-
92
- fun setVideoLayout(videoLayout: String) {
93
- scalingType =
94
- when (videoLayout) {
95
- "FILL" -> RendererCommon.ScalingType.SCALE_ASPECT_FILL
96
- "FIT" -> RendererCommon.ScalingType.SCALE_ASPECT_FIT
97
- else -> RendererCommon.ScalingType.SCALE_ASPECT_FILL
98
- }
99
- }
100
-
101
- val dimensionsListener = object : VideoSurfaceViewRendererListener {
102
- override fun onDimensionsChanged(dimensions: Dimensions) {
103
- if (dimensions.height == frameHeight && dimensions.width == frameWidth) {
104
- return
105
- }
106
- frameWidth = dimensions.width
107
- frameHeight = dimensions.height
108
-
109
- post(requestSurfaceViewRendererLayoutRunnable);
110
- }
111
- }
112
-
113
- init {
114
- RNFishjamClient.localTracksSwitchListenerManager.add(this)
115
- videoView.addDimensionsListener(dimensionsListener)
116
- }
117
-
118
- open fun dispose() {
119
- checkVisibilityHandler.removeCallbacksAndMessages(null)
120
- videoView.removeDimensionsListener(dimensionsListener)
121
- videoView.release()
122
- }
123
-
124
- protected abstract fun getVideoTrack(): VideoTrack?
125
-
126
- override suspend fun onLocalTrackWillSwitch() {
127
- if (getVideoTrack() is LocalVideoTrack) {
128
- fadeAnimation.start()
129
- }
130
- }
131
-
132
- override suspend fun onLocalTrackSwitched() {
133
- if (getVideoTrack() is LocalVideoTrack) {
134
- videoView.setMirror((getVideoTrack() as? LocalVideoTrack)?.isFrontCamera() ?: false)
135
- delay(500)
136
- fadeAnimation.reverse()
137
- }
138
- }
139
-
140
- private val requestSurfaceViewRendererLayoutRunnable: Runnable = object : Runnable {
141
- override fun run() {
142
- requestSurfaceViewRendererLayout()
143
- }
144
- }
145
-
146
- /**
147
- * Inspired by:
148
- * https://github.com/react-native-webrtc/react-native-webrtc/blob/5ecc86111c2f8e0d152d719f8b7b357a601150b6/android/src/main/java/com/oney/WebRTCModule/WebRTCView.java#L292
149
- */
150
- override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
151
- super.onLayout(changed, l, t, r, b)
152
-
153
- var left = l
154
- var top = t
155
- var right = r
156
- var bottom = b
157
-
158
- val height = b - t
159
- val width = r - l
160
-
161
- if (height == 0 || width == 0) {
162
- left = 0
163
- top = 0
164
- right = 0
165
- bottom = 0
166
- } else {
167
- when (scalingType) {
168
- RendererCommon.ScalingType.SCALE_ASPECT_FILL -> {
169
- // Fill this ViewGroup with videoView and the latter
170
- // will take care of filling itself with the video similarly to
171
- // the cover value the CSS property object-fit.
172
- left = 0
173
- top = 0
174
- right = width
175
- bottom = height
176
- }
177
- RendererCommon.ScalingType.SCALE_ASPECT_FIT -> {
178
- // Lay videoView out inside this ViewGroup in accord
179
- // with the contain value of the CSS property object-fit.
180
- // VideoView will fill itself with the video similarly
181
- // to the cover or contain value of the CSS property object-fit
182
- // (which will not matter, eventually).
183
- if (frameHeight == 0 || frameWidth == 0) {
184
- // If frame dimensions are not yet available, fill the container
185
- // to ensure the view is visible. It will re-layout once dimensions arrive.
186
- left = 0
187
- top = 0
188
- right = width
189
- bottom = height
190
- } else {
191
- val frameAspectRatio = frameWidth.toFloat() / frameHeight.toFloat()
192
- val frameDisplaySize = RendererCommon.getDisplaySize(
193
- scalingType,
194
- frameAspectRatio,
195
- width,
196
- height
197
- )
198
-
199
- left = (width - frameDisplaySize.x) / 2
200
- top = (height - frameDisplaySize.y) / 2
201
- right = left + frameDisplaySize.x
202
- bottom = top + frameDisplaySize.y
203
- }
204
- }
205
- else -> {
206
- // Default to SCALE_ASPECT_FIT behavior
207
- if (frameHeight == 0 || frameWidth == 0) {
208
- // If frame dimensions are not yet available, fill the container
209
- // to ensure the view is visible. It will re-layout once dimensions arrive.
210
- left = 0
211
- top = 0
212
- right = width
213
- bottom = height
214
- } else {
215
- val frameAspectRatio = frameWidth.toFloat() / frameHeight.toFloat()
216
- val frameDisplaySize = RendererCommon.getDisplaySize(
217
- scalingType,
218
- frameAspectRatio,
219
- width,
220
- height
221
- )
222
-
223
- left = (width - frameDisplaySize.x) / 2
224
- top = (height - frameDisplaySize.y) / 2
225
- right = left + frameDisplaySize.x
226
- bottom = top + frameDisplaySize.y
227
- }
228
- }
229
- }
230
- }
231
-
232
- videoView.layout(left, top, right, bottom)
233
- }
234
-
235
- /**
236
- * Inspired by:
237
- * https://github.com/react-native-webrtc/react-native-webrtc/blob/5ecc86111c2f8e0d152d719f8b7b357a601150b6/android/src/main/java/com/oney/WebRTCModule/WebRTCView.java#L386
238
- */
239
- @SuppressLint("WrongCall")
240
- public fun requestSurfaceViewRendererLayout() {
241
- // Google/WebRTC just call requestLayout() on surfaceViewRenderer when
242
- // they change the value of its mirror or surfaceType property.
243
- videoView.requestLayout()
244
- // The above is not enough though when the video frame's dimensions or
245
- // rotation change. The following will suffice.
246
- if (!ViewCompat.isInLayout(this)) {
247
- onLayout( /* changed */
248
- false, left, top, right, bottom
249
- )
250
- }
251
- }
252
-
253
- fun setupTrack() {
254
- videoView.setMirror((getVideoTrack() as? LocalVideoTrack)?.isFrontCamera() ?: false)
255
- checkVisibilityHandler.post(checkVisibility)
256
- }
257
- }
@@ -1,17 +0,0 @@
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
- )
@@ -1,101 +0,0 @@
1
- package io.fishjam.reactnative.foregroundService
2
-
3
- import android.app.Notification
4
- import android.app.NotificationChannel
5
- import android.app.NotificationManager
6
- import android.app.PendingIntent
7
- import android.app.Service
8
- import android.content.Intent
9
- import android.os.Binder
10
- import android.os.Build
11
- import android.os.IBinder
12
- import androidx.core.app.NotificationCompat
13
-
14
- class FishjamForegroundService : Service() {
15
- companion object {
16
- private const val FOREGROUND_SERVICE_ID = 1668
17
- }
18
-
19
- private val binder = LocalBinder()
20
-
21
- inner class LocalBinder : Binder() {
22
- fun getService(): FishjamForegroundService = this@FishjamForegroundService
23
- }
24
-
25
- override fun onBind(intent: Intent): IBinder = binder
26
-
27
- override fun onStartCommand(
28
- intent: Intent?,
29
- flags: Int,
30
- startId: Int
31
- ): Int {
32
- restartService(intent)
33
- return START_NOT_STICKY
34
- }
35
-
36
- fun restartService(intent: Intent?) {
37
- val channelId = intent!!.getStringExtra("channelId")!!
38
- val channelName = intent.getStringExtra("channelName")!!
39
- val notificationTitle = intent.getStringExtra("notificationTitle")!!
40
- val notificationContent = intent.getStringExtra("notificationContent")!!
41
- val foregroundServiceTypesArray = intent.getIntArrayExtra("foregroundServiceTypes")!!
42
- // Create "bitwise or" of foregroundServiceTypesArray
43
- val foregroundServiceType = foregroundServiceTypesArray.reduce { acc, value -> acc or value }
44
-
45
- val pendingIntent =
46
- PendingIntent.getActivity(
47
- this,
48
- 0,
49
- intent,
50
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
51
- )
52
-
53
- val notification: Notification =
54
- NotificationCompat
55
- .Builder(this, channelId)
56
- .setContentTitle(notificationTitle)
57
- .setContentText(notificationContent)
58
- .setContentIntent(pendingIntent)
59
- .setSmallIcon(android.R.drawable.ic_dialog_info)
60
- .build()
61
-
62
- createNotificationChannel(channelId, channelName)
63
- startForegroundWithNotification(notification, foregroundServiceType)
64
- }
65
-
66
- private fun startForegroundWithNotification(
67
- notification: Notification,
68
- foregroundServiceType: Int
69
- ) {
70
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
71
- startForeground(
72
- FOREGROUND_SERVICE_ID,
73
- notification,
74
- foregroundServiceType
75
- )
76
- } else {
77
- startForeground(
78
- FOREGROUND_SERVICE_ID,
79
- notification
80
- )
81
- }
82
- }
83
-
84
- private fun createNotificationChannel(
85
- channelId: String,
86
- channelName: String
87
- ) {
88
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
89
- return
90
- }
91
-
92
- val serviceChannel =
93
- NotificationChannel(
94
- channelId,
95
- channelName,
96
- NotificationManager.IMPORTANCE_HIGH
97
- )
98
- val notificationManager = getSystemService(NOTIFICATION_SERVICE) as? NotificationManager
99
- notificationManager?.createNotificationChannel(serviceChannel)
100
- }
101
- }
@@ -1,118 +0,0 @@
1
- package io.fishjam.reactnative.foregroundService
2
-
3
- import android.content.ComponentName
4
- import android.content.Context
5
- import android.content.Intent
6
- import android.content.ServiceConnection
7
- import android.os.Build
8
- import android.os.IBinder
9
- import expo.modules.kotlin.AppContext
10
- import expo.modules.kotlin.exception.CodedException
11
- import io.fishjam.reactnative.ForegroundServiceConfig
12
- import kotlinx.coroutines.CancellableContinuation
13
- import kotlinx.coroutines.suspendCancellableCoroutine
14
- import kotlin.coroutines.resume
15
-
16
- class ForegroundServiceManager(
17
- private val appContext: AppContext
18
- ) {
19
- private val reactContext by lazy {
20
- appContext.reactContext ?: throw CodedException("reactContext not found")
21
- }
22
-
23
- private var serviceState = ForegroundServiceState()
24
- private var serviceInstance: FishjamForegroundService? = null
25
- private var serviceConnectedContinuation: CancellableContinuation<Unit>? = null
26
- private val serviceIntent =
27
- Intent(
28
- appContext.reactContext,
29
- FishjamForegroundService::class.java
30
- )
31
-
32
- private val connection =
33
- object : ServiceConnection {
34
- override fun onServiceConnected(
35
- className: ComponentName,
36
- service: IBinder
37
- ) {
38
- serviceInstance = (service as FishjamForegroundService.LocalBinder).getService()
39
- serviceConnectedContinuation?.resume(Unit)
40
- serviceConnectedContinuation = null
41
- }
42
-
43
- override fun onServiceDisconnected(arg0: ComponentName) {
44
- serviceInstance = null
45
- serviceConnectedContinuation?.cancel()
46
- serviceConnectedContinuation = null
47
- }
48
- }
49
-
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)
65
-
66
- if (foregroundServiceTypes.isEmpty()) {
67
- stop()
68
- return
69
- }
70
-
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
- }
78
-
79
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
80
- reactContext.startForegroundService(serviceIntent)
81
- } else {
82
- reactContext.startService(serviceIntent)
83
- }
84
-
85
- bindServiceIfNeededAndAwait()
86
- }
87
-
88
- fun stop() {
89
- if (serviceInstance != null) {
90
- appContext.currentActivity?.unbindService(connection)
91
- ?: throw CodedException("Current activity not found")
92
- serviceInstance = null
93
- }
94
- reactContext.stopService(serviceIntent)
95
- serviceConnectedContinuation?.cancel()
96
- serviceConnectedContinuation = null
97
- }
98
-
99
- private suspend fun bindServiceIfNeededAndAwait() =
100
- suspendCancellableCoroutine { continuation ->
101
- if (serviceInstance == null) {
102
- serviceConnectedContinuation = continuation
103
- runCatching {
104
- appContext.currentActivity?.bindService(
105
- serviceIntent,
106
- connection,
107
- Context.BIND_AUTO_CREATE
108
- )
109
- }.onFailure { error ->
110
- continuation.cancel(CodedException("Failed to bind service: ${error.message}"))
111
- }
112
- } else {
113
- serviceInstance?.restartService(serviceIntent)
114
- continuation.resume(Unit)
115
- serviceConnectedContinuation = null
116
- }
117
- }
118
- }
@@ -1,46 +0,0 @@
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
- }
@@ -1,20 +0,0 @@
1
- package io.fishjam.reactnative.helpers
2
-
3
- import androidx.fragment.app.Fragment
4
- import io.fishjam.reactnative.PipContainerView
5
- import java.util.UUID
6
-
7
- class PictureInPictureHelperFragment(private val containerView: PipContainerView) : Fragment() {
8
- val id = "${PictureInPictureHelperFragment::class.java.simpleName}_${UUID.randomUUID()}"
9
-
10
- override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
11
- super.onPictureInPictureModeChanged(isInPictureInPictureMode)
12
-
13
- if (isInPictureInPictureMode) {
14
- containerView.layoutForPiPEnter()
15
- } else {
16
- containerView.layoutForPiPExit()
17
- }
18
- }
19
- }
20
-
@@ -1,24 +0,0 @@
1
- package io.fishjam.reactnative.managers
2
-
3
- import java.util.concurrent.CopyOnWriteArrayList
4
-
5
- abstract class ListenerManager<T> {
6
- protected var listeners = CopyOnWriteArrayList<T>()
7
- private set
8
-
9
- fun add(listener: T) {
10
- listeners.add(listener)
11
- }
12
-
13
- fun remove(listener: T) {
14
- listeners.remove(listener)
15
- }
16
- }
17
-
18
- open class SingleListenerManager<T>(
19
- private val notify: (T) -> Unit
20
- ) : ListenerManager<T>() {
21
- fun notifyListeners() {
22
- for (listener in listeners) notify(listener)
23
- }
24
- }
@@ -1,8 +0,0 @@
1
- package io.fishjam.reactnative.managers
2
-
3
- interface LocalCameraTrackChangedListener {
4
- fun onLocalCameraTrackChanged()
5
- }
6
-
7
- class LocalCameraTracksChangedListenersManager :
8
- SingleListenerManager<LocalCameraTrackChangedListener>(LocalCameraTrackChangedListener::onLocalCameraTrackChanged)
@@ -1,17 +0,0 @@
1
- package io.fishjam.reactnative.managers
2
-
3
- interface LocalTrackSwitchListener {
4
- suspend fun onLocalTrackWillSwitch()
5
-
6
- suspend fun onLocalTrackSwitched()
7
- }
8
-
9
- class LocalTracksSwitchListenersManager : ListenerManager<LocalTrackSwitchListener>() {
10
- suspend fun notifyWillSwitch() {
11
- for (listener in listeners) listener.onLocalTrackWillSwitch()
12
- }
13
-
14
- suspend fun notifySwitched() {
15
- for (listener in listeners) listener.onLocalTrackSwitched()
16
- }
17
- }
@@ -1,7 +0,0 @@
1
- package io.fishjam.reactnative.managers
2
-
3
- interface TrackUpdateListener {
4
- fun onTracksUpdate()
5
- }
6
-
7
- class TracksUpdateListenersManager : SingleListenerManager<TrackUpdateListener>(TrackUpdateListener::onTracksUpdate)
@@ -1,45 +0,0 @@
1
- package io.fishjam.reactnative.utils
2
-
3
- import android.Manifest
4
- import android.content.pm.PackageManager
5
- import expo.modules.interfaces.permissions.Permissions
6
- import expo.modules.interfaces.permissions.PermissionsStatus
7
- import expo.modules.kotlin.AppContext
8
- import expo.modules.kotlin.exception.Exceptions
9
- import kotlin.coroutines.resume
10
- import kotlin.coroutines.suspendCoroutine
11
-
12
- object PermissionUtils {
13
- fun hasCameraPermission(appContext: AppContext?): Boolean = hasPermission(appContext, Manifest.permission.CAMERA)
14
-
15
- fun hasMicrophonePermission(appContext: AppContext?): Boolean = hasPermission(appContext, Manifest.permission.RECORD_AUDIO)
16
-
17
- suspend fun requestCameraPermission(appContext: AppContext?): Boolean = requestAccessIfNeeded(appContext, Manifest.permission.CAMERA)
18
-
19
- suspend fun requestMicrophonePermission(appContext: AppContext?): Boolean =
20
- requestAccessIfNeeded(appContext, Manifest.permission.RECORD_AUDIO)
21
-
22
- private suspend fun requestAccessIfNeeded(
23
- appContext: AppContext?,
24
- permission: String
25
- ): Boolean {
26
- val permissionsManager: Permissions =
27
- appContext?.permissions
28
- ?: throw Exceptions.PermissionsModuleNotFound()
29
-
30
- if (hasPermission(appContext, permission)) {
31
- return true
32
- }
33
-
34
- return suspendCoroutine { continuation ->
35
- permissionsManager.askForPermissions({ result ->
36
- continuation.resume(result[permission]?.status == PermissionsStatus.GRANTED)
37
- }, permission)
38
- }
39
- }
40
-
41
- private fun hasPermission(
42
- appContext: AppContext?,
43
- permission: String
44
- ): Boolean = appContext?.reactContext?.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED
45
- }