@stream-io/video-react-native-sdk 2.0.0-beta.0 → 2.0.0-beta.2

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 (263) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/README.md +15 -0
  3. package/android/build.gradle +7 -1
  4. package/android/src/main/java/com/streamvideo/reactnative/audio/AudioDeviceManager.kt +110 -58
  5. package/android/src/main/java/com/streamvideo/reactnative/audio/CommunicationModeKeepAlive.kt +247 -0
  6. package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt +16 -5
  7. package/dist/commonjs/components/Call/CallContent/CallContent.js +1 -1
  8. package/dist/commonjs/components/Call/CallContent/CallContent.js.map +1 -1
  9. package/dist/commonjs/components/Call/CallContent/RTCViewPipIOS.js +78 -7
  10. package/dist/commonjs/components/Call/CallContent/RTCViewPipIOS.js.map +1 -1
  11. package/dist/commonjs/components/Call/CallContent/RTCViewPipNative.js +3 -0
  12. package/dist/commonjs/components/Call/CallContent/RTCViewPipNative.js.map +1 -1
  13. package/dist/commonjs/components/Call/Lobby/JoinCallButton.js +3 -2
  14. package/dist/commonjs/components/Call/Lobby/JoinCallButton.js.map +1 -1
  15. package/dist/commonjs/components/Call/Lobby/Lobby.js +4 -3
  16. package/dist/commonjs/components/Call/Lobby/Lobby.js.map +1 -1
  17. package/dist/commonjs/components/Call/Lobby/LobbyFooter.js +10 -10
  18. package/dist/commonjs/components/Call/Lobby/LobbyFooter.js.map +1 -1
  19. package/dist/commonjs/components/Call/RingingCallContent/CallLeftIndicator.js +3 -3
  20. package/dist/commonjs/components/Call/RingingCallContent/CallLeftIndicator.js.map +1 -1
  21. package/dist/commonjs/components/Call/RingingCallContent/CallPreparingIndicator.js +3 -3
  22. package/dist/commonjs/components/Call/RingingCallContent/CallPreparingIndicator.js.map +1 -1
  23. package/dist/commonjs/components/Call/RingingCallContent/IncomingCall.js +3 -2
  24. package/dist/commonjs/components/Call/RingingCallContent/IncomingCall.js.map +1 -1
  25. package/dist/commonjs/components/Call/RingingCallContent/OutgoingCall.js +7 -14
  26. package/dist/commonjs/components/Call/RingingCallContent/OutgoingCall.js.map +1 -1
  27. package/dist/commonjs/components/Livestream/LivestreamControls/HostStartStreamButton.js +3 -2
  28. package/dist/commonjs/components/Livestream/LivestreamControls/HostStartStreamButton.js.map +1 -1
  29. package/dist/commonjs/components/Livestream/LivestreamPlayer/LivestreamEnded.js +4 -3
  30. package/dist/commonjs/components/Livestream/LivestreamPlayer/LivestreamEnded.js.map +1 -1
  31. package/dist/commonjs/components/Livestream/LivestreamTopView/LiveIndicator.js +3 -3
  32. package/dist/commonjs/components/Livestream/LivestreamTopView/LiveIndicator.js.map +1 -1
  33. package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLobby.js +9 -4
  34. package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLobby.js.map +1 -1
  35. package/dist/commonjs/components/Participant/ParticipantView/ParticipantLabel.js +4 -3
  36. package/dist/commonjs/components/Participant/ParticipantView/ParticipantLabel.js.map +1 -1
  37. package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.js +27 -4
  38. package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.js.map +1 -1
  39. package/dist/commonjs/components/utility/ScreenShareOverlay.js +4 -3
  40. package/dist/commonjs/components/utility/ScreenShareOverlay.js.map +1 -1
  41. package/dist/commonjs/i18n/Streami18n.js +77 -0
  42. package/dist/commonjs/i18n/Streami18n.js.map +1 -0
  43. package/dist/commonjs/i18n/TranslationContext.js +52 -0
  44. package/dist/commonjs/i18n/TranslationContext.js.map +1 -0
  45. package/dist/commonjs/i18n/index.js +85 -0
  46. package/dist/commonjs/i18n/index.js.map +1 -0
  47. package/dist/commonjs/i18n/keys.js +2 -0
  48. package/dist/commonjs/i18n/keys.js.map +1 -0
  49. package/dist/commonjs/i18n/runtimeDefaults.js +24 -0
  50. package/dist/commonjs/i18n/runtimeDefaults.js.map +1 -0
  51. package/dist/commonjs/i18n/types.js +6 -0
  52. package/dist/commonjs/i18n/types.js.map +1 -0
  53. package/dist/commonjs/i18n/useStreami18n.js +61 -0
  54. package/dist/commonjs/i18n/useStreami18n.js.map +1 -0
  55. package/dist/commonjs/index.js +18 -5
  56. package/dist/commonjs/index.js.map +1 -1
  57. package/dist/commonjs/modules/encryption/EncryptionManager.js +305 -0
  58. package/dist/commonjs/modules/encryption/EncryptionManager.js.map +1 -0
  59. package/dist/commonjs/modules/encryption/eventMapping.js +143 -0
  60. package/dist/commonjs/modules/encryption/eventMapping.js.map +1 -0
  61. package/dist/commonjs/modules/encryption/index.js +13 -0
  62. package/dist/commonjs/modules/encryption/index.js.map +1 -0
  63. package/dist/commonjs/modules/encryption/parity.js +6 -0
  64. package/dist/commonjs/modules/encryption/parity.js.map +1 -0
  65. package/dist/commonjs/providers/NoiseCancellation/NoiseCancellationProvider.js +6 -2
  66. package/dist/commonjs/providers/NoiseCancellation/NoiseCancellationProvider.js.map +1 -1
  67. package/dist/commonjs/providers/StreamVideo.js +28 -12
  68. package/dist/commonjs/providers/StreamVideo.js.map +1 -1
  69. package/dist/commonjs/utils/StreamVideoRN/index.js +46 -0
  70. package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
  71. package/dist/commonjs/utils/internal/callingx/callingx.js +29 -4
  72. package/dist/commonjs/utils/internal/callingx/callingx.js.map +1 -1
  73. package/dist/commonjs/utils/internal/iosPipTrack.js +41 -0
  74. package/dist/commonjs/utils/internal/iosPipTrack.js.map +1 -0
  75. package/dist/commonjs/utils/internal/registerSDKGlobals.js +6 -0
  76. package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
  77. package/dist/commonjs/utils/internal/ringingCallLifecycle.js +142 -0
  78. package/dist/commonjs/utils/internal/ringingCallLifecycle.js.map +1 -0
  79. package/dist/commonjs/utils/push/internal/utils.js +4 -0
  80. package/dist/commonjs/utils/push/internal/utils.js.map +1 -1
  81. package/dist/commonjs/version.js +1 -1
  82. package/dist/module/components/Call/CallContent/CallContent.js +1 -1
  83. package/dist/module/components/Call/CallContent/CallContent.js.map +1 -1
  84. package/dist/module/components/Call/CallContent/RTCViewPipIOS.js +80 -9
  85. package/dist/module/components/Call/CallContent/RTCViewPipIOS.js.map +1 -1
  86. package/dist/module/components/Call/CallContent/RTCViewPipNative.js +3 -0
  87. package/dist/module/components/Call/CallContent/RTCViewPipNative.js.map +1 -1
  88. package/dist/module/components/Call/Lobby/JoinCallButton.js +3 -2
  89. package/dist/module/components/Call/Lobby/JoinCallButton.js.map +1 -1
  90. package/dist/module/components/Call/Lobby/Lobby.js +4 -3
  91. package/dist/module/components/Call/Lobby/Lobby.js.map +1 -1
  92. package/dist/module/components/Call/Lobby/LobbyFooter.js +10 -10
  93. package/dist/module/components/Call/Lobby/LobbyFooter.js.map +1 -1
  94. package/dist/module/components/Call/RingingCallContent/CallLeftIndicator.js +2 -2
  95. package/dist/module/components/Call/RingingCallContent/CallLeftIndicator.js.map +1 -1
  96. package/dist/module/components/Call/RingingCallContent/CallPreparingIndicator.js +2 -2
  97. package/dist/module/components/Call/RingingCallContent/CallPreparingIndicator.js.map +1 -1
  98. package/dist/module/components/Call/RingingCallContent/IncomingCall.js +3 -2
  99. package/dist/module/components/Call/RingingCallContent/IncomingCall.js.map +1 -1
  100. package/dist/module/components/Call/RingingCallContent/OutgoingCall.js +7 -14
  101. package/dist/module/components/Call/RingingCallContent/OutgoingCall.js.map +1 -1
  102. package/dist/module/components/Livestream/LivestreamControls/HostStartStreamButton.js +3 -2
  103. package/dist/module/components/Livestream/LivestreamControls/HostStartStreamButton.js.map +1 -1
  104. package/dist/module/components/Livestream/LivestreamPlayer/LivestreamEnded.js +4 -3
  105. package/dist/module/components/Livestream/LivestreamPlayer/LivestreamEnded.js.map +1 -1
  106. package/dist/module/components/Livestream/LivestreamTopView/LiveIndicator.js +2 -2
  107. package/dist/module/components/Livestream/LivestreamTopView/LiveIndicator.js.map +1 -1
  108. package/dist/module/components/Livestream/ViewerLivestream/ViewerLobby.js +9 -4
  109. package/dist/module/components/Livestream/ViewerLivestream/ViewerLobby.js.map +1 -1
  110. package/dist/module/components/Participant/ParticipantView/ParticipantLabel.js +4 -3
  111. package/dist/module/components/Participant/ParticipantView/ParticipantLabel.js.map +1 -1
  112. package/dist/module/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.js +28 -5
  113. package/dist/module/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.js.map +1 -1
  114. package/dist/module/components/utility/ScreenShareOverlay.js +4 -3
  115. package/dist/module/components/utility/ScreenShareOverlay.js.map +1 -1
  116. package/dist/module/i18n/Streami18n.js +73 -0
  117. package/dist/module/i18n/Streami18n.js.map +1 -0
  118. package/dist/module/i18n/TranslationContext.js +48 -0
  119. package/dist/module/i18n/TranslationContext.js.map +1 -0
  120. package/dist/module/i18n/index.js +20 -0
  121. package/dist/module/i18n/index.js.map +1 -0
  122. package/dist/module/i18n/keys.js +2 -0
  123. package/dist/module/i18n/keys.js.map +1 -0
  124. package/dist/module/i18n/runtimeDefaults.js +20 -0
  125. package/dist/module/i18n/runtimeDefaults.js.map +1 -0
  126. package/dist/module/i18n/types.js +4 -0
  127. package/dist/module/i18n/types.js.map +1 -0
  128. package/dist/module/i18n/useStreami18n.js +56 -0
  129. package/dist/module/i18n/useStreami18n.js.map +1 -0
  130. package/dist/module/index.js +6 -1
  131. package/dist/module/index.js.map +1 -1
  132. package/dist/module/modules/encryption/EncryptionManager.js +301 -0
  133. package/dist/module/modules/encryption/EncryptionManager.js.map +1 -0
  134. package/dist/module/modules/encryption/eventMapping.js +135 -0
  135. package/dist/module/modules/encryption/eventMapping.js.map +1 -0
  136. package/dist/module/modules/encryption/index.js +4 -0
  137. package/dist/module/modules/encryption/index.js.map +1 -0
  138. package/dist/module/modules/encryption/parity.js +4 -0
  139. package/dist/module/modules/encryption/parity.js.map +1 -0
  140. package/dist/module/providers/NoiseCancellation/NoiseCancellationProvider.js +6 -2
  141. package/dist/module/providers/NoiseCancellation/NoiseCancellationProvider.js.map +1 -1
  142. package/dist/module/providers/StreamVideo.js +29 -14
  143. package/dist/module/providers/StreamVideo.js.map +1 -1
  144. package/dist/module/utils/StreamVideoRN/index.js +46 -0
  145. package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
  146. package/dist/module/utils/internal/callingx/callingx.js +29 -4
  147. package/dist/module/utils/internal/callingx/callingx.js.map +1 -1
  148. package/dist/module/utils/internal/iosPipTrack.js +35 -0
  149. package/dist/module/utils/internal/iosPipTrack.js.map +1 -0
  150. package/dist/module/utils/internal/registerSDKGlobals.js +6 -0
  151. package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
  152. package/dist/module/utils/internal/ringingCallLifecycle.js +134 -0
  153. package/dist/module/utils/internal/ringingCallLifecycle.js.map +1 -0
  154. package/dist/module/utils/push/internal/utils.js +4 -0
  155. package/dist/module/utils/push/internal/utils.js.map +1 -1
  156. package/dist/module/version.js +1 -1
  157. package/dist/typescript/components/Call/CallContent/RTCViewPipIOS.d.ts.map +1 -1
  158. package/dist/typescript/components/Call/CallContent/RTCViewPipNative.d.ts +12 -0
  159. package/dist/typescript/components/Call/CallContent/RTCViewPipNative.d.ts.map +1 -1
  160. package/dist/typescript/components/Call/Lobby/JoinCallButton.d.ts.map +1 -1
  161. package/dist/typescript/components/Call/Lobby/Lobby.d.ts.map +1 -1
  162. package/dist/typescript/components/Call/Lobby/LobbyFooter.d.ts.map +1 -1
  163. package/dist/typescript/components/Call/RingingCallContent/OutgoingCall.d.ts.map +1 -1
  164. package/dist/typescript/components/Livestream/LivestreamControls/HostStartStreamButton.d.ts.map +1 -1
  165. package/dist/typescript/components/Livestream/LivestreamPlayer/LivestreamEnded.d.ts.map +1 -1
  166. package/dist/typescript/components/Livestream/ViewerLivestream/ViewerLobby.d.ts.map +1 -1
  167. package/dist/typescript/components/Participant/ParticipantView/ParticipantLabel.d.ts.map +1 -1
  168. package/dist/typescript/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.d.ts +11 -0
  169. package/dist/typescript/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.d.ts.map +1 -1
  170. package/dist/typescript/components/utility/ScreenShareOverlay.d.ts.map +1 -1
  171. package/dist/typescript/i18n/Streami18n.d.ts +61 -0
  172. package/dist/typescript/i18n/Streami18n.d.ts.map +1 -0
  173. package/dist/typescript/i18n/TranslationContext.d.ts +31 -0
  174. package/dist/typescript/i18n/TranslationContext.d.ts.map +1 -0
  175. package/dist/typescript/i18n/index.d.ts +17 -0
  176. package/dist/typescript/i18n/index.d.ts.map +1 -0
  177. package/dist/typescript/i18n/keys.d.ts +38 -0
  178. package/dist/typescript/i18n/keys.d.ts.map +1 -0
  179. package/dist/typescript/i18n/runtimeDefaults.d.ts +18 -0
  180. package/dist/typescript/i18n/runtimeDefaults.d.ts.map +1 -0
  181. package/dist/typescript/i18n/types.d.ts +46 -0
  182. package/dist/typescript/i18n/types.d.ts.map +1 -0
  183. package/dist/typescript/i18n/useStreami18n.d.ts +20 -0
  184. package/dist/typescript/i18n/useStreami18n.d.ts.map +1 -0
  185. package/dist/typescript/index.d.ts +2 -1
  186. package/dist/typescript/index.d.ts.map +1 -1
  187. package/dist/typescript/modules/encryption/EncryptionManager.d.ts +190 -0
  188. package/dist/typescript/modules/encryption/EncryptionManager.d.ts.map +1 -0
  189. package/dist/typescript/modules/encryption/eventMapping.d.ts +38 -0
  190. package/dist/typescript/modules/encryption/eventMapping.d.ts.map +1 -0
  191. package/dist/typescript/modules/encryption/index.d.ts +2 -0
  192. package/dist/typescript/modules/encryption/index.d.ts.map +1 -0
  193. package/dist/typescript/modules/encryption/parity.d.ts +55 -0
  194. package/dist/typescript/modules/encryption/parity.d.ts.map +1 -0
  195. package/dist/typescript/providers/NoiseCancellation/NoiseCancellationProvider.d.ts.map +1 -1
  196. package/dist/typescript/providers/StreamVideo.d.ts +17 -4
  197. package/dist/typescript/providers/StreamVideo.d.ts.map +1 -1
  198. package/dist/typescript/utils/StreamVideoRN/index.d.ts +33 -1
  199. package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
  200. package/dist/typescript/utils/StreamVideoRN/types.d.ts +67 -0
  201. package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
  202. package/dist/typescript/utils/internal/callingx/callingx.d.ts +1 -1
  203. package/dist/typescript/utils/internal/callingx/callingx.d.ts.map +1 -1
  204. package/dist/typescript/utils/internal/iosPipTrack.d.ts +9 -0
  205. package/dist/typescript/utils/internal/iosPipTrack.d.ts.map +1 -0
  206. package/dist/typescript/utils/internal/registerSDKGlobals.d.ts.map +1 -1
  207. package/dist/typescript/utils/internal/ringingCallLifecycle.d.ts +27 -0
  208. package/dist/typescript/utils/internal/ringingCallLifecycle.d.ts.map +1 -0
  209. package/dist/typescript/utils/push/internal/utils.d.ts.map +1 -1
  210. package/dist/typescript/version.d.ts +1 -1
  211. package/ios/RTCViewPip.swift +33 -8
  212. package/ios/RTCViewPipManager.mm +1 -0
  213. package/package.json +17 -13
  214. package/src/components/Call/CallContent/CallContent.tsx +1 -1
  215. package/src/components/Call/CallContent/RTCViewPipIOS.tsx +92 -10
  216. package/src/components/Call/CallContent/RTCViewPipNative.tsx +13 -0
  217. package/src/components/Call/Lobby/JoinCallButton.tsx +5 -2
  218. package/src/components/Call/Lobby/Lobby.tsx +6 -3
  219. package/src/components/Call/Lobby/LobbyFooter.tsx +15 -10
  220. package/src/components/Call/RingingCallContent/CallLeftIndicator.tsx +2 -2
  221. package/src/components/Call/RingingCallContent/CallPreparingIndicator.tsx +2 -2
  222. package/src/components/Call/RingingCallContent/IncomingCall.tsx +2 -2
  223. package/src/components/Call/RingingCallContent/OutgoingCall.tsx +7 -14
  224. package/src/components/Livestream/LivestreamControls/HostStartStreamButton.tsx +5 -8
  225. package/src/components/Livestream/LivestreamPlayer/LivestreamEnded.tsx +11 -3
  226. package/src/components/Livestream/LivestreamTopView/LiveIndicator.tsx +2 -2
  227. package/src/components/Livestream/ViewerLivestream/ViewerLobby.tsx +23 -10
  228. package/src/components/Participant/ParticipantView/ParticipantLabel.tsx +15 -6
  229. package/src/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.tsx +58 -5
  230. package/src/components/utility/ScreenShareOverlay.tsx +7 -3
  231. package/src/i18n/Streami18n.ts +71 -0
  232. package/src/i18n/TranslationContext.tsx +55 -0
  233. package/src/i18n/index.ts +22 -0
  234. package/src/i18n/keys.ts +42 -0
  235. package/src/i18n/runtimeDefaults.ts +17 -0
  236. package/src/i18n/types.ts +78 -0
  237. package/src/i18n/useStreami18n.ts +66 -0
  238. package/src/index.ts +6 -1
  239. package/src/modules/call-manager/native-module.d.ts +14 -0
  240. package/src/modules/encryption/EncryptionManager.ts +360 -0
  241. package/src/modules/encryption/eventMapping.ts +151 -0
  242. package/src/modules/encryption/index.ts +1 -0
  243. package/src/modules/encryption/parity.ts +83 -0
  244. package/src/providers/NoiseCancellation/NoiseCancellationProvider.tsx +8 -4
  245. package/src/providers/StreamVideo.tsx +39 -28
  246. package/src/utils/StreamVideoRN/index.ts +51 -1
  247. package/src/utils/StreamVideoRN/types.ts +68 -0
  248. package/src/utils/internal/callingx/callingx.ts +37 -2
  249. package/src/utils/internal/iosPipTrack.ts +39 -0
  250. package/src/utils/internal/registerSDKGlobals.ts +2 -0
  251. package/src/utils/internal/ringingCallLifecycle.ts +148 -0
  252. package/src/utils/push/internal/utils.ts +4 -0
  253. package/src/version.ts +1 -1
  254. package/dist/commonjs/translations/en.json +0 -32
  255. package/dist/commonjs/translations/index.js +0 -12
  256. package/dist/commonjs/translations/index.js.map +0 -1
  257. package/dist/module/translations/en.json +0 -32
  258. package/dist/module/translations/index.js +0 -7
  259. package/dist/module/translations/index.js.map +0 -1
  260. package/dist/typescript/translations/index.d.ts +0 -35
  261. package/dist/typescript/translations/index.d.ts.map +0 -1
  262. package/src/translations/en.json +0 -32
  263. package/src/translations/index.ts +0 -3
@@ -1,4 +1,5 @@
1
1
  import { useEffect } from 'react';
2
+ import { Platform } from 'react-native';
2
3
  import {
3
4
  Call,
4
5
  CallingState,
@@ -16,7 +17,12 @@ import {
16
17
  distinctUntilKeyChanged,
17
18
  filter,
18
19
  map,
20
+ of,
19
21
  } from 'rxjs';
22
+ import {
23
+ getIosPipTrack$,
24
+ setIosPipTrack,
25
+ } from '../../../../utils/internal/iosPipTrack';
20
26
 
21
27
  type TrackSubscriberProps = {
22
28
  participantSessionId: string;
@@ -28,6 +34,13 @@ type TrackSubscriberProps = {
28
34
  * the last reported layout survives a remount of this component.
29
35
  */
30
36
  dimensions$: BehaviorSubject<SfuModels.VideoDimension | undefined>;
37
+ /**
38
+ * Set by the native iOS Picture in Picture window, whose bounds this
39
+ * subscriber requests. While it does, the inline views of the same track
40
+ * stop requesting their own, hidden layout. Only rendered on iOS; on other
41
+ * platforms the gate is always open.
42
+ */
43
+ isPipWriter?: boolean;
31
44
  };
32
45
 
33
46
  /**
@@ -40,10 +53,20 @@ type TrackSubscriberProps = {
40
53
  * This component is used to unsubscribe to video track and subscribe only to the audio track of the participant (by passing undefined dimensions) in the following cases:
41
54
  * 1. When the participant stops publishing the video track
42
55
  * 2. When the participant becomes invisible
56
+ *
57
+ * The same component serves the native iOS Picture in Picture window, which
58
+ * renders one of the tracks too. Its bounds take precedence over the inline
59
+ * views of that track for as long as it is on screen.
43
60
  */
44
61
  const TrackSubscriber = (props: TrackSubscriberProps) => {
45
- const { call, participantSessionId, trackType, isVisible, dimensions$ } =
46
- props;
62
+ const {
63
+ call,
64
+ participantSessionId,
65
+ trackType,
66
+ isVisible,
67
+ dimensions$,
68
+ isPipWriter,
69
+ } = props;
47
70
 
48
71
  useEffect(() => {
49
72
  const requestTrackWithDimensions = (
@@ -75,12 +98,28 @@ const TrackSubscriber = (props: TrackSubscriberProps) => {
75
98
  map((callingState) => callingState === CallingState.JOINED),
76
99
  );
77
100
 
101
+ const trackKey = { sessionId: participantSessionId, trackType };
102
+ const pipTrack$ = Platform.OS === 'ios' ? getIosPipTrack$(call) : undefined;
103
+ if (isPipWriter && pipTrack$) setIosPipTrack(call, trackKey);
104
+ const canWrite$ = pipTrack$
105
+ ? pipTrack$.pipe(
106
+ map((track) => {
107
+ const sameTrack =
108
+ track?.sessionId === participantSessionId &&
109
+ track?.trackType === trackType;
110
+ return isPipWriter ? sameTrack : !sameTrack;
111
+ }),
112
+ distinctUntilChanged(),
113
+ )
114
+ : of(true);
115
+
78
116
  const subscription = combineLatest([
79
117
  dimensions$,
80
118
  isPublishingTrack$,
81
119
  isJoinedState$,
82
- ]).subscribe(([dimension, isPublishing, isJoined]) => {
83
- if (isJoined) {
120
+ canWrite$,
121
+ ]).subscribe(([dimension, isPublishing, isJoined, canWrite]) => {
122
+ if (isJoined && canWrite) {
84
123
  if (!isVisible || !isPublishing) {
85
124
  requestTrackWithDimensions(DebounceType.MEDIUM, undefined);
86
125
  } else if (dimension) {
@@ -91,8 +130,22 @@ const TrackSubscriber = (props: TrackSubscriberProps) => {
91
130
 
92
131
  return () => {
93
132
  subscription.unsubscribe();
133
+ if (isPipWriter && pipTrack$) {
134
+ // Let sibling inline views finish unmounting before handing back demand.
135
+ queueMicrotask(() => {
136
+ if (pipTrack$.getValue() === trackKey)
137
+ setIosPipTrack(call, undefined);
138
+ });
139
+ }
94
140
  };
95
- }, [call, participantSessionId, trackType, isVisible, dimensions$]);
141
+ }, [
142
+ call,
143
+ participantSessionId,
144
+ trackType,
145
+ isVisible,
146
+ dimensions$,
147
+ isPipWriter,
148
+ ]);
96
149
 
97
150
  return null;
98
151
  };
@@ -2,7 +2,8 @@ import React from 'react';
2
2
  import { Pressable, StyleSheet, Text, View } from 'react-native';
3
3
  import { StopScreenShare } from '../../icons';
4
4
  import { useTheme } from '../../contexts';
5
- import { useCall, useI18n } from '@stream-io/video-react-bindings';
5
+ import { useCall } from '@stream-io/video-react-bindings';
6
+ import { useI18n } from '../../i18n';
6
7
 
7
8
  /**
8
9
  * Props for the ScreenShareOverlay component
@@ -45,7 +46,10 @@ export const ScreenShareOverlay = ({}: ScreenShareOverlayProps) => {
45
46
  screenshareOverlay.text,
46
47
  ]}
47
48
  >
48
- {t('You are sharing your screen with everyone')}
49
+ {t(
50
+ 'screenShare.sharingWithEveryone.text',
51
+ 'You are sharing your screen with everyone',
52
+ )}
49
53
  </Text>
50
54
  <Pressable
51
55
  onPress={onStopScreenshareHandler}
@@ -76,7 +80,7 @@ export const ScreenShareOverlay = ({}: ScreenShareOverlayProps) => {
76
80
  screenshareOverlay.buttonText,
77
81
  ]}
78
82
  >
79
- {t('Stop Screen Sharing')}
83
+ {t('participantView.screenShare.stop.label', 'Stop Screen Sharing')}
80
84
  </Text>
81
85
  </Pressable>
82
86
  </View>
@@ -0,0 +1,71 @@
1
+ import { Streami18n as CoreStreami18n } from '@stream-io/i18n';
2
+ import type { Streami18nOptions as CoreStreami18nOptions } from '@stream-io/i18n';
3
+
4
+ import { runtimeDefaults } from './runtimeDefaults';
5
+ import type { BundledKey, TranslationCatalog } from './types';
6
+
7
+ /**
8
+ * Options for {@link Streami18n}.
9
+ *
10
+ * Core's options, narrowed to this SDK's catalog so `translationsForLanguage` is key-checked.
11
+ * `runtimeDefaults` is *merged* over the SDK's own rather than replacing it, so supplying it adds to
12
+ * what the SDK ships.
13
+ */
14
+ export type Streami18nOptions = CoreStreami18nOptions<TranslationCatalog>;
15
+
16
+ /**
17
+ * Wrapper around [i18next](https://www.i18next.com/) for this SDK's translations. Pass an instance
18
+ * to `<StreamVideo i18nInstance={…}>` to control the language and the copy.
19
+ *
20
+ * The implementation lives in `@stream-io/i18n`, shared with the web SDK and with Chat. This
21
+ * subclass exists even though {@link runtimeDefaults} is currently empty: its job is to bind the
22
+ * two type parameters, so `new Streami18n()` and its `t` are checked against *this* package's
23
+ * catalog rather than against core's `Record<string, string>` fallback, which would accept any key.
24
+ *
25
+ * ## Overriding some of the English copy
26
+ *
27
+ * ```ts
28
+ * const i18n = new Streami18n({
29
+ * translationsForLanguage: {
30
+ * 'common.you.label': 'Jij',
31
+ * },
32
+ * });
33
+ * ```
34
+ *
35
+ * ## Adding a language
36
+ *
37
+ * ```ts
38
+ * import 'dayjs/locale/nl';
39
+ *
40
+ * const i18n = new Streami18n({ language: 'nl' });
41
+ * i18n.registerTranslation('nl', {
42
+ * 'common.join.label': 'Deelnemen',
43
+ * });
44
+ * ```
45
+ *
46
+ * No dayjs locale file defines `calendar` — that field belongs to the calendar plugin — so a
47
+ * language whose relative dates must read natively needs the locale import *and* a `calendar`
48
+ * config passed as the third argument.
49
+ *
50
+ * Type your dictionary as `TranslationDictionary` to turn a typo or a key removed in a later major
51
+ * into a compile error. A **partial dictionary is safe**: any key you leave out renders the English
52
+ * copy that ships inline at each call site, never a raw dotted path — so there is no need to
53
+ * translate everything before shipping a language.
54
+ *
55
+ * Hermes ships a partial ICU, so `Intl.PluralRules` has no data for most locales and every count
56
+ * would select the `_other` form. Import `intl-pluralrules` before anything else in your entry
57
+ * file; core warns when it is missing.
58
+ *
59
+ * Reactivity goes through `i18n.state`, a `StateStore`. `setLanguage()` returns nothing — the new
60
+ * `t` is published to that store, which the provider subscribes to.
61
+ */
62
+ export class Streami18n extends CoreStreami18n<TranslationCatalog, BundledKey> {
63
+ constructor(options: Streami18nOptions = {}) {
64
+ super({
65
+ ...options,
66
+ // Merged, not replaced. Spreading `options` over a literal would let an integrator supplying
67
+ // one entry silently drop the SDK's own bundled data, which then renders as raw keys.
68
+ runtimeDefaults: { ...runtimeDefaults, ...options.runtimeDefaults },
69
+ });
70
+ }
71
+ }
@@ -0,0 +1,55 @@
1
+ import {
2
+ createDefaultTranslatorFunction,
3
+ defaultDateTimeParser,
4
+ } from '@stream-io/i18n';
5
+ import { createTranslationContext } from '@stream-io/i18n/react';
6
+
7
+ import type { StreamTFunction, TDateTimeParser } from './types';
8
+
9
+ export type TranslationContextValue = {
10
+ t: StreamTFunction;
11
+ tDateTimeParser: TDateTimeParser;
12
+ };
13
+
14
+ /**
15
+ * The `t` in force before i18next has initialized, and the context's default.
16
+ *
17
+ * Core's factory, instantiated against this SDK's catalog so it is typed exactly like the real `t`.
18
+ * It honours the inline `defaultValue` each prose call site passes, which is what stops raw dotted
19
+ * keys flashing on the first frame.
20
+ */
21
+ const defaultTranslatorFunction =
22
+ createDefaultTranslatorFunction() as StreamTFunction;
23
+
24
+ /**
25
+ * Built from the shared factory in `@stream-io/i18n/react`.
26
+ *
27
+ * A **default value** is supplied rather than making the hook throw, and that is deliberate: it
28
+ * matches what `useI18n` did before this module existed, so a component rendered outside the
29
+ * provider keeps showing correct English instead of crashing. Chat's React Native SDK throws
30
+ * instead; hence core exposes this as a factory rather than one exported context.
31
+ */
32
+ const { TranslationContext, TranslationProvider, useTranslationContext } =
33
+ createTranslationContext<TranslationContextValue>({
34
+ defaultValue: {
35
+ t: defaultTranslatorFunction,
36
+ tDateTimeParser: defaultDateTimeParser,
37
+ },
38
+ displayName: 'StreamVideoTranslationContext',
39
+ });
40
+
41
+ export { TranslationContext, TranslationProvider };
42
+
43
+ /**
44
+ * Reads `t` and `tDateTimeParser` from the closest provider.
45
+ *
46
+ * Works outside a provider too — the default translator renders each call site's inline English.
47
+ *
48
+ * The name is `useI18n` rather than core's `useTranslationContext` because ~500 call sites across
49
+ * the video SDKs already import it; renaming them is churn with no payoff.
50
+ *
51
+ * @example
52
+ * const { t } = useI18n();
53
+ * const label = t('common.join.label', 'Join');
54
+ */
55
+ export const useI18n = useTranslationContext;
@@ -0,0 +1,22 @@
1
+ export * from './Streami18n';
2
+ export * from './TranslationContext';
3
+ export * from './types';
4
+ export * from './useStreami18n';
5
+
6
+ /**
7
+ * Core helpers re-exported so an integrator never needs a direct dependency on `@stream-io/i18n`:
8
+ * that package is an implementation detail of this SDK, and a second copy resolved from their
9
+ * `node_modules` would register dayjs plugins on the wrong module.
10
+ *
11
+ * - `asDynamicKey` — brands a runtime-resolved string as a translation key, the one sanctioned way
12
+ * past the compile-time key check.
13
+ * - `getDateString` — the timestamp renderer, for a custom component formatting dates itself.
14
+ * - `predefinedFormatters` — the built-in i18next formatters, to spread over when adding one.
15
+ * - `defaultDateTimeParser` — the dayjs-backed parser, with the required plugins already applied.
16
+ */
17
+ export {
18
+ asDynamicKey,
19
+ defaultDateTimeParser,
20
+ getDateString,
21
+ predefinedFormatters,
22
+ } from '@stream-io/i18n';
@@ -0,0 +1,42 @@
1
+ // AUTO-GENERATED — do not edit by hand.
2
+ // Regenerate with `yarn build-translations`. CI fails if this file is out of sync.
3
+ //
4
+ // Type-only: no runtime value is emitted, so this adds nothing to the bundle.
5
+
6
+ /**
7
+ * Every translation entry shipped with the SDK, mapped to its English copy.
8
+ *
9
+ * Plural entries appear as `<key>_one` / `<key>_other`; call sites use the bare `<key>` and
10
+ * pass `count`.
11
+ */
12
+ export type TranslationCatalog = {
13
+ 'common.join.label': 'Join';
14
+ 'common.joining.text': 'Joining...';
15
+ 'common.live.label': 'Live';
16
+ 'common.loading.text': 'Loading...';
17
+ 'common.you.label': 'You';
18
+ 'livestreamControls.start.label': 'Start Livestream';
19
+ 'livestreamControls.stop.label': 'Stop Livestream';
20
+ 'livestreamPlayer.ended.title': 'The livestream has ended.';
21
+ 'livestreamPlayer.ended.watchRecordings.title': 'Watch recordings:';
22
+ 'livestreamViewer.earlyParticipants.text_one': '{{ count }} participant has joined early';
23
+ 'livestreamViewer.earlyParticipants.text_other': '{{ count }} participants have joined early';
24
+ 'livestreamViewer.join.label': 'Join Livestream';
25
+ 'livestreamViewer.stillInProgress.text': 'Livestream is still in progress';
26
+ 'livestreamViewer.willStartIn.text': 'Livestream will start in:';
27
+ 'livestreamViewer.willStartSoon.text': 'Livestream will start soon';
28
+ 'lobby.beforeJoining.title': 'Before joining';
29
+ 'lobby.footer.aboutToJoin.text': 'You are about to join a call.';
30
+ 'lobby.footer.noOtherParticipants.text': 'Currently there are no other participants in the call.';
31
+ 'lobby.footer.otherParticipants.text_one': 'There is {{ count }} more person in the call.';
32
+ 'lobby.footer.otherParticipants.text_other': 'There are {{ count }} more people in the call.';
33
+ 'lobby.setupAudioVideo.description': 'Setup your audio and video';
34
+ 'participantView.screenShare.byUser.text': '{{ userName }} is sharing their screen';
35
+ 'participantView.screenShare.byYou.text': 'You are sharing your screen';
36
+ 'participantView.screenShare.stop.label': 'Stop Screen Sharing';
37
+ 'ringingCall.incoming.title': 'Incoming Call...';
38
+ 'ringingCall.leftCall.title': 'You have left the call';
39
+ 'ringingCall.outgoing.title': 'Calling...';
40
+ 'ringingCall.preparing.title': 'Preparing call';
41
+ 'screenShare.sharingWithEveryone.text': 'You are sharing your screen with everyone';
42
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The SDK's bundled translation data: the keys that cannot carry an inline `defaultValue` at their
3
+ * call site. `Streami18n` layers it under *every* language, so a partial dictionary never knocks
4
+ * these out.
5
+ *
6
+ * Empty, and that is the intended steady state. The four lookups this SDK resolved from a runtime
7
+ * value — the only candidates for an entry here — are written as `switch` statements over literal
8
+ * `t()` calls instead, so every branch carries its own English copy inline and the codegen reads it
9
+ * straight off the call site. Nothing is left without a default. `timestamp.*` / `duration.*`
10
+ * formatter expressions would also live here; this SDK has none yet.
11
+ *
12
+ * Adding an entry later needs no wiring. `Streami18n` already spreads this into the core options and
13
+ * `scripts/generate-i18n-keys.mts` already reads this path, so a new key reaches `keys.ts` on the
14
+ * next `build-translations` run — where a key nothing references, or one that shadows an inline
15
+ * default, fails a codegen guard.
16
+ */
17
+ export const runtimeDefaults = {};
@@ -0,0 +1,78 @@
1
+ import type {
2
+ Streami18nState as CoreStreami18nState,
3
+ LooseTranslationDictionaryOf,
4
+ RelativeTimeCatalog,
5
+ StreamTFunctionFor,
6
+ TranslationDictionaryOf,
7
+ TranslationKeyOf,
8
+ } from '@stream-io/i18n';
9
+
10
+ import type { TranslationCatalog as GeneratedCatalog } from './keys';
11
+
12
+ /**
13
+ * The SDK's i18n types, instantiated from the generic helpers in `@stream-io/i18n`.
14
+ *
15
+ * The derivations live in core so both video SDKs (and Chat) share one implementation; the *catalog*
16
+ * stays here, because it is generated from this package's own `t()` call sites — which are not the
17
+ * web SDK's. That split is why core's helpers are generic over the catalog rather than driven by
18
+ * module augmentation: two catalogs have to be able to coexist in one TypeScript program, which a
19
+ * monorepo typechecking the web and React Native SDKs in one pass does.
20
+ *
21
+ * `relativeTime.*` is intersected in because it is core's copy, not ours: `timestampFormatter`
22
+ * renders "Today" / "3d ago" through `t()`, and without these keys in the catalog an integrator
23
+ * could not type a dictionary that translates them.
24
+ */
25
+ export type TranslationCatalog = GeneratedCatalog & RelativeTimeCatalog;
26
+
27
+ /**
28
+ * Keys resolved from bundled data rather than from an inline `defaultValue`.
29
+ *
30
+ * `never`, because `runtimeDefaults.ts` is empty — every key this SDK uses is written literally
31
+ * with its English copy at the call site. `timestamp.*` / `duration.*` are matched by prefix inside
32
+ * core and need no entry here.
33
+ *
34
+ * **It must never become `string`.** `string` collapses the prose overload in `StreamTFunctionFor`,
35
+ * which silently disables all key checking: every `t('typo.key', 'copy')` would compile. Widen it
36
+ * only to a literal prefix template (`` `foo.${string}` ``) when a real bundled key appears.
37
+ */
38
+ export type BundledKey = never;
39
+
40
+ export type TranslationKey = TranslationKeyOf<TranslationCatalog>;
41
+ export type TranslationDictionary = TranslationDictionaryOf<TranslationCatalog>;
42
+ export type LooseTranslationDictionary =
43
+ LooseTranslationDictionaryOf<TranslationCatalog>;
44
+ export type StreamTFunction = StreamTFunctionFor<
45
+ TranslationCatalog,
46
+ BundledKey
47
+ >;
48
+
49
+ /**
50
+ * The value held by `Streami18n.state`, parameterized for this SDK's catalog.
51
+ *
52
+ * Exported because `state` is public: a consumer subscribing to it needs to name the type for a
53
+ * module-scope selector. Core's default-parameterized `Streami18nState` is not a substitute — `t` is
54
+ * contravariant in its key parameter, so that one is not assignable to this.
55
+ */
56
+ export type Streami18nState = CoreStreami18nState<
57
+ TranslationCatalog,
58
+ BundledKey
59
+ >;
60
+
61
+ /**
62
+ * Re-exported so an integrator can type a formatter, a locale config or a date parser without
63
+ * taking a direct dependency on `@stream-io/i18n`.
64
+ */
65
+ export type {
66
+ CustomFormatters,
67
+ DateTimeParserModule,
68
+ DayjsLocaleConfig,
69
+ DurationFormatterOptions,
70
+ DynamicTranslationKey,
71
+ FormatterFactory,
72
+ LooseTranslateFunction,
73
+ PredefinedFormatters,
74
+ TDateTimeParser,
75
+ TDateTimeParserInput,
76
+ TDateTimeParserOutput,
77
+ TimestampFormatterOptions,
78
+ } from '@stream-io/i18n';
@@ -0,0 +1,66 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { useStreami18nState } from '@stream-io/i18n/react';
3
+
4
+ import { Streami18n } from './Streami18n';
5
+ import type { TranslationContextValue } from './TranslationContext';
6
+ import type { LooseTranslationDictionary } from './types';
7
+
8
+ export type UseStreami18nParams = {
9
+ /** An instance the integrator configured. One is created when absent. */
10
+ i18nInstance?: Streami18n;
11
+ /** The language the SDK's copy renders in. Changing it switches languages in place. */
12
+ language?: string;
13
+ /** Dictionaries to register, keyed by language code. Partial dictionaries are safe. */
14
+ translations?: Record<string, LooseTranslationDictionary>;
15
+ };
16
+
17
+ /**
18
+ * Resolves the translation context value: creates or adopts a {@link Streami18n} instance,
19
+ * registers the supplied dictionaries, initializes it and keeps `t` fresh across language changes.
20
+ *
21
+ * `init()` and the store subscription belong to `useStreami18nState` in `@stream-io/i18n/react`,
22
+ * shared with the web SDK.
23
+ */
24
+ export const useStreami18n = ({
25
+ i18nInstance,
26
+ language,
27
+ translations,
28
+ }: UseStreami18nParams): TranslationContextValue => {
29
+ // Lazy `useState`, not `useMemo`: `new Streami18n()` is a real allocation with identity that must
30
+ // survive a re-render, and this repo lints `react-hooks/purity` as an error — `useMemo` is a
31
+ // cache React is free to drop, so constructing there is a purity violation. A later change to
32
+ // `i18nInstance` is ignored on purpose; swapping the instance mid-tree is not a supported move.
33
+ const [i18n] = useState(() => {
34
+ const instance = i18nInstance ?? new Streami18n({ language });
35
+
36
+ // Registered here rather than in an effect. `useStreami18nState` calls `init()` from its own
37
+ // effect, which runs *before* any effect declared below it in this hook — so a dictionary
38
+ // registered in an effect would arrive after i18next was already initialized, and the first
39
+ // `init()` would warn that the language has no dictionary.
40
+ if (translations) {
41
+ for (const [code, dictionary] of Object.entries(translations)) {
42
+ instance.registerTranslation(code, dictionary);
43
+ }
44
+ }
45
+
46
+ return instance;
47
+ });
48
+
49
+ // No `onInitError` handler: core already logs a warning and leaves the instance usable, with `t`
50
+ // still rendering each call site's inline English. Pass one only to surface init failures
51
+ // somewhere other than the console.
52
+ const translators = useStreami18nState(i18n);
53
+
54
+ useEffect(() => {
55
+ // Guarded on the current value: `setLanguage` re-runs the formatter factories and a full
56
+ // i18next `changeLanguage`, and the first render already constructed the instance with
57
+ // `language`. Undefined means "leave whatever the instance was configured with".
58
+ if (!language || i18n.currentLanguage === language) return;
59
+ i18n.setLanguage(language);
60
+ }, [i18n, language]);
61
+
62
+ // Returned as-is: `useStreami18nState` already caches this object and only produces a new one
63
+ // when `t` or `tDateTimeParser` actually changes, so wrapping it in a `useMemo` would add a
64
+ // second cache over a stable value.
65
+ return translators;
66
+ };
package/src/index.ts CHANGED
@@ -29,13 +29,18 @@ export * from './contexts';
29
29
  export * from './hooks';
30
30
  export * from './theme';
31
31
  export * from './utils';
32
- export * from './translations';
32
+ export * from './i18n';
33
33
  export * from './modules/call-manager';
34
34
 
35
35
  // Overriding 'StreamVideo' and 'StreamCall' from '@stream-io/video-react-bindings'
36
36
  // Explicitly re-exporting to resolve ambiguity.
37
37
  export { StreamVideo } from './providers/StreamVideo';
38
38
  export { StreamCall } from './providers/StreamCall';
39
+ // Overriding 'EncryptionManager' from '@stream-io/video-client' with the React
40
+ // Native implementation, which is backed by the native WebRTC transform. React
41
+ // Native Web is not supported: `isSupported()` returns false there rather than
42
+ // falling back to the web manager.
43
+ export { EncryptionManager } from './modules/encryption';
39
44
  export * from './providers/NoiseCancellation';
40
45
 
41
46
  setClientDetails();
@@ -32,6 +32,20 @@ export interface CallManager extends NativeModule {
32
32
  */
33
33
  setTelecomManagedMode: (enabled: boolean) => void;
34
34
 
35
+ /**
36
+ * Opt out of the Android 11+ communication-mode keep-alive workaround.
37
+ *
38
+ * On Android 11+ (API 30) the OS resets `MODE_IN_COMMUNICATION` ~6s after it is
39
+ * set when there is no active voice-communication playback/recording, which
40
+ * breaks audio routing and AEC. By default the SDK plays a silent
41
+ * voice-communication track for the duration of a communicator-role call to
42
+ * prevent this. Pass `true` to disable it. Sticky for the process lifetime.
43
+ *
44
+ * No-op on iOS and on Android below API 30. See
45
+ * https://issuetracker.google.com/issues/209493718
46
+ */
47
+ setDisableCommunicationModeWorkaround: (disabled: boolean) => void;
48
+
35
49
  /**
36
50
  * Choose an audio device endpoint by its stable id.
37
51
  * @param deviceId - The id of the audio device to choose (`AudioDevice.id`).