@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.
- package/CHANGELOG.md +95 -0
- package/README.md +15 -0
- package/android/build.gradle +7 -1
- package/android/src/main/java/com/streamvideo/reactnative/audio/AudioDeviceManager.kt +110 -58
- package/android/src/main/java/com/streamvideo/reactnative/audio/CommunicationModeKeepAlive.kt +247 -0
- package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt +16 -5
- package/dist/commonjs/components/Call/CallContent/CallContent.js +1 -1
- package/dist/commonjs/components/Call/CallContent/CallContent.js.map +1 -1
- package/dist/commonjs/components/Call/CallContent/RTCViewPipIOS.js +78 -7
- package/dist/commonjs/components/Call/CallContent/RTCViewPipIOS.js.map +1 -1
- package/dist/commonjs/components/Call/CallContent/RTCViewPipNative.js +3 -0
- package/dist/commonjs/components/Call/CallContent/RTCViewPipNative.js.map +1 -1
- package/dist/commonjs/components/Call/Lobby/JoinCallButton.js +3 -2
- package/dist/commonjs/components/Call/Lobby/JoinCallButton.js.map +1 -1
- package/dist/commonjs/components/Call/Lobby/Lobby.js +4 -3
- package/dist/commonjs/components/Call/Lobby/Lobby.js.map +1 -1
- package/dist/commonjs/components/Call/Lobby/LobbyFooter.js +10 -10
- package/dist/commonjs/components/Call/Lobby/LobbyFooter.js.map +1 -1
- package/dist/commonjs/components/Call/RingingCallContent/CallLeftIndicator.js +3 -3
- package/dist/commonjs/components/Call/RingingCallContent/CallLeftIndicator.js.map +1 -1
- package/dist/commonjs/components/Call/RingingCallContent/CallPreparingIndicator.js +3 -3
- package/dist/commonjs/components/Call/RingingCallContent/CallPreparingIndicator.js.map +1 -1
- package/dist/commonjs/components/Call/RingingCallContent/IncomingCall.js +3 -2
- package/dist/commonjs/components/Call/RingingCallContent/IncomingCall.js.map +1 -1
- package/dist/commonjs/components/Call/RingingCallContent/OutgoingCall.js +7 -14
- package/dist/commonjs/components/Call/RingingCallContent/OutgoingCall.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamControls/HostStartStreamButton.js +3 -2
- package/dist/commonjs/components/Livestream/LivestreamControls/HostStartStreamButton.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamPlayer/LivestreamEnded.js +4 -3
- package/dist/commonjs/components/Livestream/LivestreamPlayer/LivestreamEnded.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamTopView/LiveIndicator.js +3 -3
- package/dist/commonjs/components/Livestream/LivestreamTopView/LiveIndicator.js.map +1 -1
- package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLobby.js +9 -4
- package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLobby.js.map +1 -1
- package/dist/commonjs/components/Participant/ParticipantView/ParticipantLabel.js +4 -3
- package/dist/commonjs/components/Participant/ParticipantView/ParticipantLabel.js.map +1 -1
- package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.js +27 -4
- package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.js.map +1 -1
- package/dist/commonjs/components/utility/ScreenShareOverlay.js +4 -3
- package/dist/commonjs/components/utility/ScreenShareOverlay.js.map +1 -1
- package/dist/commonjs/i18n/Streami18n.js +77 -0
- package/dist/commonjs/i18n/Streami18n.js.map +1 -0
- package/dist/commonjs/i18n/TranslationContext.js +52 -0
- package/dist/commonjs/i18n/TranslationContext.js.map +1 -0
- package/dist/commonjs/i18n/index.js +85 -0
- package/dist/commonjs/i18n/index.js.map +1 -0
- package/dist/commonjs/i18n/keys.js +2 -0
- package/dist/commonjs/i18n/keys.js.map +1 -0
- package/dist/commonjs/i18n/runtimeDefaults.js +24 -0
- package/dist/commonjs/i18n/runtimeDefaults.js.map +1 -0
- package/dist/commonjs/i18n/types.js +6 -0
- package/dist/commonjs/i18n/types.js.map +1 -0
- package/dist/commonjs/i18n/useStreami18n.js +61 -0
- package/dist/commonjs/i18n/useStreami18n.js.map +1 -0
- package/dist/commonjs/index.js +18 -5
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/modules/encryption/EncryptionManager.js +305 -0
- package/dist/commonjs/modules/encryption/EncryptionManager.js.map +1 -0
- package/dist/commonjs/modules/encryption/eventMapping.js +143 -0
- package/dist/commonjs/modules/encryption/eventMapping.js.map +1 -0
- package/dist/commonjs/modules/encryption/index.js +13 -0
- package/dist/commonjs/modules/encryption/index.js.map +1 -0
- package/dist/commonjs/modules/encryption/parity.js +6 -0
- package/dist/commonjs/modules/encryption/parity.js.map +1 -0
- package/dist/commonjs/providers/NoiseCancellation/NoiseCancellationProvider.js +6 -2
- package/dist/commonjs/providers/NoiseCancellation/NoiseCancellationProvider.js.map +1 -1
- package/dist/commonjs/providers/StreamVideo.js +28 -12
- package/dist/commonjs/providers/StreamVideo.js.map +1 -1
- package/dist/commonjs/utils/StreamVideoRN/index.js +46 -0
- package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/commonjs/utils/internal/callingx/callingx.js +29 -4
- package/dist/commonjs/utils/internal/callingx/callingx.js.map +1 -1
- package/dist/commonjs/utils/internal/iosPipTrack.js +41 -0
- package/dist/commonjs/utils/internal/iosPipTrack.js.map +1 -0
- package/dist/commonjs/utils/internal/registerSDKGlobals.js +6 -0
- package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/commonjs/utils/internal/ringingCallLifecycle.js +142 -0
- package/dist/commonjs/utils/internal/ringingCallLifecycle.js.map +1 -0
- package/dist/commonjs/utils/push/internal/utils.js +4 -0
- package/dist/commonjs/utils/push/internal/utils.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/module/components/Call/CallContent/CallContent.js +1 -1
- package/dist/module/components/Call/CallContent/CallContent.js.map +1 -1
- package/dist/module/components/Call/CallContent/RTCViewPipIOS.js +80 -9
- package/dist/module/components/Call/CallContent/RTCViewPipIOS.js.map +1 -1
- package/dist/module/components/Call/CallContent/RTCViewPipNative.js +3 -0
- package/dist/module/components/Call/CallContent/RTCViewPipNative.js.map +1 -1
- package/dist/module/components/Call/Lobby/JoinCallButton.js +3 -2
- package/dist/module/components/Call/Lobby/JoinCallButton.js.map +1 -1
- package/dist/module/components/Call/Lobby/Lobby.js +4 -3
- package/dist/module/components/Call/Lobby/Lobby.js.map +1 -1
- package/dist/module/components/Call/Lobby/LobbyFooter.js +10 -10
- package/dist/module/components/Call/Lobby/LobbyFooter.js.map +1 -1
- package/dist/module/components/Call/RingingCallContent/CallLeftIndicator.js +2 -2
- package/dist/module/components/Call/RingingCallContent/CallLeftIndicator.js.map +1 -1
- package/dist/module/components/Call/RingingCallContent/CallPreparingIndicator.js +2 -2
- package/dist/module/components/Call/RingingCallContent/CallPreparingIndicator.js.map +1 -1
- package/dist/module/components/Call/RingingCallContent/IncomingCall.js +3 -2
- package/dist/module/components/Call/RingingCallContent/IncomingCall.js.map +1 -1
- package/dist/module/components/Call/RingingCallContent/OutgoingCall.js +7 -14
- package/dist/module/components/Call/RingingCallContent/OutgoingCall.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamControls/HostStartStreamButton.js +3 -2
- package/dist/module/components/Livestream/LivestreamControls/HostStartStreamButton.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamPlayer/LivestreamEnded.js +4 -3
- package/dist/module/components/Livestream/LivestreamPlayer/LivestreamEnded.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamTopView/LiveIndicator.js +2 -2
- package/dist/module/components/Livestream/LivestreamTopView/LiveIndicator.js.map +1 -1
- package/dist/module/components/Livestream/ViewerLivestream/ViewerLobby.js +9 -4
- package/dist/module/components/Livestream/ViewerLivestream/ViewerLobby.js.map +1 -1
- package/dist/module/components/Participant/ParticipantView/ParticipantLabel.js +4 -3
- package/dist/module/components/Participant/ParticipantView/ParticipantLabel.js.map +1 -1
- package/dist/module/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.js +28 -5
- package/dist/module/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.js.map +1 -1
- package/dist/module/components/utility/ScreenShareOverlay.js +4 -3
- package/dist/module/components/utility/ScreenShareOverlay.js.map +1 -1
- package/dist/module/i18n/Streami18n.js +73 -0
- package/dist/module/i18n/Streami18n.js.map +1 -0
- package/dist/module/i18n/TranslationContext.js +48 -0
- package/dist/module/i18n/TranslationContext.js.map +1 -0
- package/dist/module/i18n/index.js +20 -0
- package/dist/module/i18n/index.js.map +1 -0
- package/dist/module/i18n/keys.js +2 -0
- package/dist/module/i18n/keys.js.map +1 -0
- package/dist/module/i18n/runtimeDefaults.js +20 -0
- package/dist/module/i18n/runtimeDefaults.js.map +1 -0
- package/dist/module/i18n/types.js +4 -0
- package/dist/module/i18n/types.js.map +1 -0
- package/dist/module/i18n/useStreami18n.js +56 -0
- package/dist/module/i18n/useStreami18n.js.map +1 -0
- package/dist/module/index.js +6 -1
- package/dist/module/index.js.map +1 -1
- package/dist/module/modules/encryption/EncryptionManager.js +301 -0
- package/dist/module/modules/encryption/EncryptionManager.js.map +1 -0
- package/dist/module/modules/encryption/eventMapping.js +135 -0
- package/dist/module/modules/encryption/eventMapping.js.map +1 -0
- package/dist/module/modules/encryption/index.js +4 -0
- package/dist/module/modules/encryption/index.js.map +1 -0
- package/dist/module/modules/encryption/parity.js +4 -0
- package/dist/module/modules/encryption/parity.js.map +1 -0
- package/dist/module/providers/NoiseCancellation/NoiseCancellationProvider.js +6 -2
- package/dist/module/providers/NoiseCancellation/NoiseCancellationProvider.js.map +1 -1
- package/dist/module/providers/StreamVideo.js +29 -14
- package/dist/module/providers/StreamVideo.js.map +1 -1
- package/dist/module/utils/StreamVideoRN/index.js +46 -0
- package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/module/utils/internal/callingx/callingx.js +29 -4
- package/dist/module/utils/internal/callingx/callingx.js.map +1 -1
- package/dist/module/utils/internal/iosPipTrack.js +35 -0
- package/dist/module/utils/internal/iosPipTrack.js.map +1 -0
- package/dist/module/utils/internal/registerSDKGlobals.js +6 -0
- package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/module/utils/internal/ringingCallLifecycle.js +134 -0
- package/dist/module/utils/internal/ringingCallLifecycle.js.map +1 -0
- package/dist/module/utils/push/internal/utils.js +4 -0
- package/dist/module/utils/push/internal/utils.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/components/Call/CallContent/RTCViewPipIOS.d.ts.map +1 -1
- package/dist/typescript/components/Call/CallContent/RTCViewPipNative.d.ts +12 -0
- package/dist/typescript/components/Call/CallContent/RTCViewPipNative.d.ts.map +1 -1
- package/dist/typescript/components/Call/Lobby/JoinCallButton.d.ts.map +1 -1
- package/dist/typescript/components/Call/Lobby/Lobby.d.ts.map +1 -1
- package/dist/typescript/components/Call/Lobby/LobbyFooter.d.ts.map +1 -1
- package/dist/typescript/components/Call/RingingCallContent/OutgoingCall.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamControls/HostStartStreamButton.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamPlayer/LivestreamEnded.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/ViewerLivestream/ViewerLobby.d.ts.map +1 -1
- package/dist/typescript/components/Participant/ParticipantView/ParticipantLabel.d.ts.map +1 -1
- package/dist/typescript/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.d.ts +11 -0
- package/dist/typescript/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.d.ts.map +1 -1
- package/dist/typescript/components/utility/ScreenShareOverlay.d.ts.map +1 -1
- package/dist/typescript/i18n/Streami18n.d.ts +61 -0
- package/dist/typescript/i18n/Streami18n.d.ts.map +1 -0
- package/dist/typescript/i18n/TranslationContext.d.ts +31 -0
- package/dist/typescript/i18n/TranslationContext.d.ts.map +1 -0
- package/dist/typescript/i18n/index.d.ts +17 -0
- package/dist/typescript/i18n/index.d.ts.map +1 -0
- package/dist/typescript/i18n/keys.d.ts +38 -0
- package/dist/typescript/i18n/keys.d.ts.map +1 -0
- package/dist/typescript/i18n/runtimeDefaults.d.ts +18 -0
- package/dist/typescript/i18n/runtimeDefaults.d.ts.map +1 -0
- package/dist/typescript/i18n/types.d.ts +46 -0
- package/dist/typescript/i18n/types.d.ts.map +1 -0
- package/dist/typescript/i18n/useStreami18n.d.ts +20 -0
- package/dist/typescript/i18n/useStreami18n.d.ts.map +1 -0
- package/dist/typescript/index.d.ts +2 -1
- package/dist/typescript/index.d.ts.map +1 -1
- package/dist/typescript/modules/encryption/EncryptionManager.d.ts +190 -0
- package/dist/typescript/modules/encryption/EncryptionManager.d.ts.map +1 -0
- package/dist/typescript/modules/encryption/eventMapping.d.ts +38 -0
- package/dist/typescript/modules/encryption/eventMapping.d.ts.map +1 -0
- package/dist/typescript/modules/encryption/index.d.ts +2 -0
- package/dist/typescript/modules/encryption/index.d.ts.map +1 -0
- package/dist/typescript/modules/encryption/parity.d.ts +55 -0
- package/dist/typescript/modules/encryption/parity.d.ts.map +1 -0
- package/dist/typescript/providers/NoiseCancellation/NoiseCancellationProvider.d.ts.map +1 -1
- package/dist/typescript/providers/StreamVideo.d.ts +17 -4
- package/dist/typescript/providers/StreamVideo.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/index.d.ts +33 -1
- package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/types.d.ts +67 -0
- package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
- package/dist/typescript/utils/internal/callingx/callingx.d.ts +1 -1
- package/dist/typescript/utils/internal/callingx/callingx.d.ts.map +1 -1
- package/dist/typescript/utils/internal/iosPipTrack.d.ts +9 -0
- package/dist/typescript/utils/internal/iosPipTrack.d.ts.map +1 -0
- package/dist/typescript/utils/internal/registerSDKGlobals.d.ts.map +1 -1
- package/dist/typescript/utils/internal/ringingCallLifecycle.d.ts +27 -0
- package/dist/typescript/utils/internal/ringingCallLifecycle.d.ts.map +1 -0
- package/dist/typescript/utils/push/internal/utils.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/ios/RTCViewPip.swift +33 -8
- package/ios/RTCViewPipManager.mm +1 -0
- package/package.json +17 -13
- package/src/components/Call/CallContent/CallContent.tsx +1 -1
- package/src/components/Call/CallContent/RTCViewPipIOS.tsx +92 -10
- package/src/components/Call/CallContent/RTCViewPipNative.tsx +13 -0
- package/src/components/Call/Lobby/JoinCallButton.tsx +5 -2
- package/src/components/Call/Lobby/Lobby.tsx +6 -3
- package/src/components/Call/Lobby/LobbyFooter.tsx +15 -10
- package/src/components/Call/RingingCallContent/CallLeftIndicator.tsx +2 -2
- package/src/components/Call/RingingCallContent/CallPreparingIndicator.tsx +2 -2
- package/src/components/Call/RingingCallContent/IncomingCall.tsx +2 -2
- package/src/components/Call/RingingCallContent/OutgoingCall.tsx +7 -14
- package/src/components/Livestream/LivestreamControls/HostStartStreamButton.tsx +5 -8
- package/src/components/Livestream/LivestreamPlayer/LivestreamEnded.tsx +11 -3
- package/src/components/Livestream/LivestreamTopView/LiveIndicator.tsx +2 -2
- package/src/components/Livestream/ViewerLivestream/ViewerLobby.tsx +23 -10
- package/src/components/Participant/ParticipantView/ParticipantLabel.tsx +15 -6
- package/src/components/Participant/ParticipantView/VideoRenderer/TrackSubscriber.tsx +58 -5
- package/src/components/utility/ScreenShareOverlay.tsx +7 -3
- package/src/i18n/Streami18n.ts +71 -0
- package/src/i18n/TranslationContext.tsx +55 -0
- package/src/i18n/index.ts +22 -0
- package/src/i18n/keys.ts +42 -0
- package/src/i18n/runtimeDefaults.ts +17 -0
- package/src/i18n/types.ts +78 -0
- package/src/i18n/useStreami18n.ts +66 -0
- package/src/index.ts +6 -1
- package/src/modules/call-manager/native-module.d.ts +14 -0
- package/src/modules/encryption/EncryptionManager.ts +360 -0
- package/src/modules/encryption/eventMapping.ts +151 -0
- package/src/modules/encryption/index.ts +1 -0
- package/src/modules/encryption/parity.ts +83 -0
- package/src/providers/NoiseCancellation/NoiseCancellationProvider.tsx +8 -4
- package/src/providers/StreamVideo.tsx +39 -28
- package/src/utils/StreamVideoRN/index.ts +51 -1
- package/src/utils/StreamVideoRN/types.ts +68 -0
- package/src/utils/internal/callingx/callingx.ts +37 -2
- package/src/utils/internal/iosPipTrack.ts +39 -0
- package/src/utils/internal/registerSDKGlobals.ts +2 -0
- package/src/utils/internal/ringingCallLifecycle.ts +148 -0
- package/src/utils/push/internal/utils.ts +4 -0
- package/src/version.ts +1 -1
- package/dist/commonjs/translations/en.json +0 -32
- package/dist/commonjs/translations/index.js +0 -12
- package/dist/commonjs/translations/index.js.map +0 -1
- package/dist/module/translations/en.json +0 -32
- package/dist/module/translations/index.js +0 -7
- package/dist/module/translations/index.js.map +0 -1
- package/dist/typescript/translations/index.d.ts +0 -35
- package/dist/typescript/translations/index.d.ts.map +0 -1
- package/src/translations/en.json +0 -32
- package/src/translations/index.ts +0 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type Call,
|
|
2
3
|
CallingState,
|
|
3
4
|
SfuModels,
|
|
4
5
|
hasAudio,
|
|
@@ -12,17 +13,35 @@ import {
|
|
|
12
13
|
} from '@stream-io/video-client';
|
|
13
14
|
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
14
15
|
import type { MediaStream } from '@stream-io/react-native-webrtc';
|
|
15
|
-
import React, { useEffect, useCallback, useState } from 'react';
|
|
16
|
+
import React, { useEffect, useCallback, useRef, useState } from 'react';
|
|
16
17
|
import { findNodeHandle } from 'react-native';
|
|
17
18
|
import {
|
|
18
19
|
onNativeCallClosed,
|
|
19
20
|
onNativeDimensionsUpdated,
|
|
21
|
+
type PiPBoundsChangeEvent,
|
|
22
|
+
type PiPChangeEvent,
|
|
20
23
|
RTCViewPipNative,
|
|
21
24
|
} from './RTCViewPipNative';
|
|
22
|
-
import { debounceTime } from 'rxjs';
|
|
25
|
+
import { BehaviorSubject, debounceTime } from 'rxjs';
|
|
23
26
|
import { shouldDisableIOSLocalVideoOnBackgroundRef } from '../../../utils/internal/shouldDisableIOSLocalVideoOnBackground';
|
|
24
27
|
import { useTrackDimensions } from '../../../hooks/useTrackDimensions';
|
|
25
28
|
import { isInPiPMode$ } from '../../../utils/internal/rxSubjects';
|
|
29
|
+
import TrackSubscriber from '../../Participant/ParticipantView/VideoRenderer/TrackSubscriber';
|
|
30
|
+
|
|
31
|
+
// One native view per Call instance. React Native drops the events of an
|
|
32
|
+
// unmounted view, so an event the previous call's controller queued before
|
|
33
|
+
// the replacement cannot reach the view of its successor.
|
|
34
|
+
const nativeViewKeys = new WeakMap<Call, number>();
|
|
35
|
+
let nextNativeViewKey = 0;
|
|
36
|
+
const nativeViewKeyOf = (call: Call | undefined) => {
|
|
37
|
+
if (!call) return 0;
|
|
38
|
+
let key = nativeViewKeys.get(call);
|
|
39
|
+
if (key === undefined) {
|
|
40
|
+
key = ++nextNativeViewKey;
|
|
41
|
+
nativeViewKeys.set(call, key);
|
|
42
|
+
}
|
|
43
|
+
return key;
|
|
44
|
+
};
|
|
26
45
|
|
|
27
46
|
type Props = {
|
|
28
47
|
includeLocalParticipantVideo?: boolean;
|
|
@@ -52,6 +71,39 @@ export const RTCViewPipIOS = React.memo((props: Props) => {
|
|
|
52
71
|
StreamVideoParticipant[]
|
|
53
72
|
>(call?.state.participants ?? []);
|
|
54
73
|
|
|
74
|
+
// bounds of the native window, in logical points. While the window is on
|
|
75
|
+
// screen they are the demand of the track it renders.
|
|
76
|
+
const [pipDimensions$] = useState(
|
|
77
|
+
() => new BehaviorSubject<SfuModels.VideoDimension | undefined>(undefined),
|
|
78
|
+
);
|
|
79
|
+
const [isPipActive, setIsPipActive] = useState(false);
|
|
80
|
+
// synchronous mirror of isPipActive: native may emit the same lifecycle
|
|
81
|
+
// state twice (e.g. failedToStart after didStop) before React re-renders.
|
|
82
|
+
const isPipActiveRef = useRef(false);
|
|
83
|
+
// set once the call is closed: later native events describe a disposed window.
|
|
84
|
+
const isClosedRef = useRef(false);
|
|
85
|
+
// the handlers below are bound to the view they were rendered for; an event
|
|
86
|
+
// of a replaced view is rejected even if it were delivered.
|
|
87
|
+
const nativeViewKey = nativeViewKeyOf(call);
|
|
88
|
+
const activeNativeViewKeyRef = useRef(nativeViewKey);
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
activeNativeViewKeyRef.current = nativeViewKey;
|
|
91
|
+
}, [nativeViewKey]);
|
|
92
|
+
const isStaleNativeEvent = () =>
|
|
93
|
+
isClosedRef.current || nativeViewKey !== activeNativeViewKeyRef.current;
|
|
94
|
+
const onPiPChangeRef = useRef(onPiPChange);
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
onPiPChangeRef.current = onPiPChange;
|
|
97
|
+
}, [onPiPChange]);
|
|
98
|
+
|
|
99
|
+
const updatePipState = useCallback((active: boolean) => {
|
|
100
|
+
if (isPipActiveRef.current === active) return;
|
|
101
|
+
isPipActiveRef.current = active;
|
|
102
|
+
setIsPipActive(active);
|
|
103
|
+
isInPiPMode$.next(active);
|
|
104
|
+
onPiPChangeRef.current?.(active);
|
|
105
|
+
}, []);
|
|
106
|
+
|
|
55
107
|
// we debounce the participants to avoid unnecessary rerenders
|
|
56
108
|
// that happen when participant tracks are all subscribed simultaneously
|
|
57
109
|
useEffect(() => {
|
|
@@ -86,17 +138,19 @@ export const RTCViewPipIOS = React.memo((props: Props) => {
|
|
|
86
138
|
const nativeRef = React.useRef<any>(null);
|
|
87
139
|
|
|
88
140
|
React.useEffect(() => {
|
|
89
|
-
|
|
141
|
+
const node = findNodeHandle(nativeRef.current);
|
|
142
|
+
isClosedRef.current = false;
|
|
90
143
|
const onCallClosed = () => {
|
|
91
|
-
if (
|
|
144
|
+
if (isClosedRef.current) {
|
|
92
145
|
return;
|
|
93
146
|
}
|
|
94
|
-
|
|
95
|
-
const node = findNodeHandle(nativeRef.current);
|
|
147
|
+
isClosedRef.current = true;
|
|
96
148
|
if (node !== null) {
|
|
97
149
|
onNativeCallClosed(node);
|
|
98
150
|
}
|
|
99
151
|
shouldDisableIOSLocalVideoOnBackgroundRef.current = true;
|
|
152
|
+
pipDimensions$.next(undefined);
|
|
153
|
+
updatePipState(false);
|
|
100
154
|
};
|
|
101
155
|
const unsubFunc = call?.on('call.ended', () => {
|
|
102
156
|
videoLoggerSystem
|
|
@@ -117,7 +171,7 @@ export const RTCViewPipIOS = React.memo((props: Props) => {
|
|
|
117
171
|
unsubFunc?.();
|
|
118
172
|
subscription?.unsubscribe();
|
|
119
173
|
};
|
|
120
|
-
}, [call]);
|
|
174
|
+
}, [call, pipDimensions$, updatePipState]);
|
|
121
175
|
|
|
122
176
|
const onDimensionsUpdated = useCallback((width: number, height: number) => {
|
|
123
177
|
const node = findNodeHandle(nativeRef.current);
|
|
@@ -150,9 +204,17 @@ export const RTCViewPipIOS = React.memo((props: Props) => {
|
|
|
150
204
|
? mirrorOverride
|
|
151
205
|
: !!participantInSpotlight?.isLocalParticipant && direction === 'front';
|
|
152
206
|
|
|
153
|
-
const handlePiPChange = (event: { nativeEvent:
|
|
154
|
-
|
|
155
|
-
|
|
207
|
+
const handlePiPChange = (event: { nativeEvent: PiPChangeEvent }) => {
|
|
208
|
+
if (isStaleNativeEvent()) return;
|
|
209
|
+
updatePipState(event.nativeEvent.active);
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const handlePiPBoundsChange = (event: {
|
|
213
|
+
nativeEvent: PiPBoundsChangeEvent;
|
|
214
|
+
}) => {
|
|
215
|
+
if (isStaleNativeEvent()) return;
|
|
216
|
+
const { width, height } = event.nativeEvent;
|
|
217
|
+
pipDimensions$.next({ width, height });
|
|
156
218
|
};
|
|
157
219
|
|
|
158
220
|
// Get participant info for avatar placeholder
|
|
@@ -193,13 +255,23 @@ export const RTCViewPipIOS = React.memo((props: Props) => {
|
|
|
193
255
|
participantInSpotlight?.connectionQuality ??
|
|
194
256
|
SfuModels.ConnectionQuality.UNSPECIFIED;
|
|
195
257
|
|
|
258
|
+
// while the native window is on screen, its bounds - and not the hidden
|
|
259
|
+
// inline layout behind it - are the demand of the track it renders. The local
|
|
260
|
+
// preview is never subscribed to.
|
|
261
|
+
const pipTrackOwner =
|
|
262
|
+
isPipActive && participantInSpotlight?.isLocalParticipant !== true
|
|
263
|
+
? participantInSpotlight
|
|
264
|
+
: undefined;
|
|
265
|
+
|
|
196
266
|
return (
|
|
197
267
|
<>
|
|
198
268
|
<RTCViewPipNative
|
|
269
|
+
key={nativeViewKey}
|
|
199
270
|
streamURL={streamURL}
|
|
200
271
|
mirror={mirror}
|
|
201
272
|
ref={nativeRef}
|
|
202
273
|
onPiPChange={handlePiPChange}
|
|
274
|
+
onPiPBoundsChange={handlePiPBoundsChange}
|
|
203
275
|
participantName={participantName}
|
|
204
276
|
participantImageURL={participantImageURL}
|
|
205
277
|
isReconnecting={isReconnecting}
|
|
@@ -210,6 +282,16 @@ export const RTCViewPipIOS = React.memo((props: Props) => {
|
|
|
210
282
|
isSpeaking={participantIsSpeaking}
|
|
211
283
|
connectionQuality={participantConnectionQuality}
|
|
212
284
|
/>
|
|
285
|
+
{pipTrackOwner && call && (
|
|
286
|
+
<TrackSubscriber
|
|
287
|
+
call={call}
|
|
288
|
+
participantSessionId={pipTrackOwner.sessionId}
|
|
289
|
+
trackType={trackType}
|
|
290
|
+
isVisible={true}
|
|
291
|
+
dimensions$={pipDimensions$}
|
|
292
|
+
isPipWriter
|
|
293
|
+
/>
|
|
294
|
+
)}
|
|
213
295
|
{participantInSpotlight && (
|
|
214
296
|
<DimensionsUpdatedRenderless
|
|
215
297
|
participant={participantInSpotlight}
|
|
@@ -14,10 +14,21 @@ export type PiPChangeEvent = {
|
|
|
14
14
|
active: boolean;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
export type PiPBoundsChangeEvent = {
|
|
18
|
+
/** the laid out width of the native window, in logical points */
|
|
19
|
+
width: number;
|
|
20
|
+
/** the laid out height of the native window, in logical points */
|
|
21
|
+
height: number;
|
|
22
|
+
};
|
|
23
|
+
|
|
17
24
|
type RTCViewPipNativeProps = {
|
|
18
25
|
streamURL?: string;
|
|
19
26
|
mirror?: boolean;
|
|
20
27
|
onPiPChange?: (event: { nativeEvent: PiPChangeEvent }) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Reports the actual laid out bounds of the native Picture in Picture window.
|
|
30
|
+
*/
|
|
31
|
+
onPiPBoundsChange?: (event: { nativeEvent: PiPBoundsChangeEvent }) => void;
|
|
21
32
|
/** The participant's name for the avatar placeholder when video is disabled */
|
|
22
33
|
participantName?: string;
|
|
23
34
|
/** The URL string for the participant's profile image */
|
|
@@ -84,6 +95,8 @@ export const RTCViewPipNative = React.memo(
|
|
|
84
95
|
// eslint-disable-next-line react/prop-types
|
|
85
96
|
onPiPChange={props.onPiPChange}
|
|
86
97
|
// eslint-disable-next-line react/prop-types
|
|
98
|
+
onPiPBoundsChange={props.onPiPBoundsChange}
|
|
99
|
+
// eslint-disable-next-line react/prop-types
|
|
87
100
|
participantName={props.participantName}
|
|
88
101
|
// eslint-disable-next-line react/prop-types
|
|
89
102
|
participantImageURL={props.participantImageURL}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React, { useMemo, useState } from 'react';
|
|
2
2
|
import { type LobbyProps } from './Lobby';
|
|
3
3
|
import { Pressable, StyleSheet, Text } from 'react-native';
|
|
4
|
-
import { useCall
|
|
4
|
+
import { useCall } from '@stream-io/video-react-bindings';
|
|
5
|
+
import { useI18n } from '../../../i18n';
|
|
5
6
|
import { useTheme } from '../../../contexts/ThemeContext';
|
|
6
7
|
import { videoLoggerSystem } from '@stream-io/video-client';
|
|
7
8
|
|
|
@@ -64,7 +65,9 @@ export const JoinCallButton = ({
|
|
|
64
65
|
joinCallButton.label,
|
|
65
66
|
]}
|
|
66
67
|
>
|
|
67
|
-
{isLoading
|
|
68
|
+
{isLoading
|
|
69
|
+
? t('common.joining.text', 'Joining...')
|
|
70
|
+
: t('common.join.label', 'Join')}
|
|
68
71
|
</Text>
|
|
69
72
|
</Pressable>
|
|
70
73
|
);
|
|
@@ -3,8 +3,8 @@ import { StyleSheet, Text, View } from 'react-native';
|
|
|
3
3
|
import {
|
|
4
4
|
useCallStateHooks,
|
|
5
5
|
useConnectedUser,
|
|
6
|
-
useI18n,
|
|
7
6
|
} from '@stream-io/video-react-bindings';
|
|
7
|
+
import { useI18n } from '../../../i18n';
|
|
8
8
|
import { Avatar } from '../../utility/Avatar';
|
|
9
9
|
import type { StreamVideoParticipant } from '@stream-io/video-client';
|
|
10
10
|
import { LobbyControls as DefaultLobbyControls } from '../CallControls/LobbyControls';
|
|
@@ -82,10 +82,13 @@ export const Lobby = ({
|
|
|
82
82
|
{connectedUser && (
|
|
83
83
|
<>
|
|
84
84
|
<Text style={[styles.heading, typefaces.heading5, lobby.heading]}>
|
|
85
|
-
{t('Before joining')}
|
|
85
|
+
{t('lobby.beforeJoining.title', 'Before joining')}
|
|
86
86
|
</Text>
|
|
87
87
|
<Text style={[styles.subHeading, lobby.subHeading]}>
|
|
88
|
-
{t(
|
|
88
|
+
{t(
|
|
89
|
+
'lobby.setupAudioVideo.description',
|
|
90
|
+
'Setup your audio and video',
|
|
91
|
+
)}
|
|
89
92
|
</Text>
|
|
90
93
|
{isVideoEnabledInCall && (
|
|
91
94
|
<View
|
|
@@ -2,7 +2,8 @@ import React, { useMemo } from 'react';
|
|
|
2
2
|
import { type LobbyProps } from './Lobby';
|
|
3
3
|
import { StyleSheet, Text, View } from 'react-native';
|
|
4
4
|
import { useTheme } from '../../../contexts/ThemeContext';
|
|
5
|
-
import { useCallStateHooks
|
|
5
|
+
import { useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
6
|
+
import { useI18n } from '../../../i18n';
|
|
6
7
|
import { Lock } from '../../../icons/Lock';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -31,15 +32,17 @@ export const LobbyFooter = ({
|
|
|
31
32
|
|
|
32
33
|
const participantsText = useMemo(() => {
|
|
33
34
|
if (!numberOfParticipants) {
|
|
34
|
-
return t(
|
|
35
|
+
return t(
|
|
36
|
+
'lobby.footer.noOtherParticipants.text',
|
|
37
|
+
'Currently there are no other participants in the call.',
|
|
38
|
+
);
|
|
35
39
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
numberOfParticipants,
|
|
40
|
+
// i18next picks the singular/plural form for the active language via
|
|
41
|
+
// Intl.PluralRules, so no `=== 1` branch is needed here.
|
|
42
|
+
return t('lobby.footer.otherParticipants.text', {
|
|
43
|
+
count: numberOfParticipants,
|
|
44
|
+
defaultValue_one: 'There is {{ count }} more person in the call.',
|
|
45
|
+
defaultValue_other: 'There are {{ count }} more people in the call.',
|
|
43
46
|
});
|
|
44
47
|
}, [numberOfParticipants, t]);
|
|
45
48
|
|
|
@@ -56,7 +59,9 @@ export const LobbyFooter = ({
|
|
|
56
59
|
lobby.infoText,
|
|
57
60
|
]}
|
|
58
61
|
>
|
|
59
|
-
{t('You are about to join a call.') +
|
|
62
|
+
{t('lobby.footer.aboutToJoin.text', 'You are about to join a call.') +
|
|
63
|
+
' ' +
|
|
64
|
+
participantsText}
|
|
60
65
|
</Text>
|
|
61
66
|
</View>
|
|
62
67
|
{JoinCallButton && (
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useI18n } from '
|
|
1
|
+
import { useI18n } from '../../../i18n';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import {
|
|
4
4
|
TextBasedIndicator,
|
|
@@ -14,7 +14,7 @@ export const CallLeftIndicator = (props: CallLeftIndicatorProps) => {
|
|
|
14
14
|
const { t } = useI18n();
|
|
15
15
|
return (
|
|
16
16
|
<TextBasedIndicator
|
|
17
|
-
text={t('You have left the call')}
|
|
17
|
+
text={t('ringingCall.leftCall.title', 'You have left the call')}
|
|
18
18
|
onBackPress={props.onBackPress}
|
|
19
19
|
/>
|
|
20
20
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useI18n } from '
|
|
1
|
+
import { useI18n } from '../../../i18n';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import {
|
|
4
4
|
TextBasedIndicator,
|
|
@@ -14,7 +14,7 @@ export const CallPreparingIndicator = (props: CallPreparingIndicatorProps) => {
|
|
|
14
14
|
const { t } = useI18n();
|
|
15
15
|
return (
|
|
16
16
|
<TextBasedIndicator
|
|
17
|
-
text={t('Preparing call')}
|
|
17
|
+
text={t('ringingCall.preparing.title', 'Preparing call')}
|
|
18
18
|
onBackPress={props.onBackPress}
|
|
19
19
|
/>
|
|
20
20
|
);
|
|
@@ -3,8 +3,8 @@ import { Image, StyleSheet, Text, View, type ViewStyle } from 'react-native';
|
|
|
3
3
|
import {
|
|
4
4
|
useCallStateHooks,
|
|
5
5
|
useConnectedUser,
|
|
6
|
-
useI18n,
|
|
7
6
|
} from '@stream-io/video-react-bindings';
|
|
7
|
+
import { useI18n } from '../../../i18n';
|
|
8
8
|
import { UserInfo } from './UserInfo';
|
|
9
9
|
import {
|
|
10
10
|
IncomingCallControls as DefaultIncomingCallControls,
|
|
@@ -73,7 +73,7 @@ export const IncomingCall = ({
|
|
|
73
73
|
incomingCall.incomingCallText,
|
|
74
74
|
]}
|
|
75
75
|
>
|
|
76
|
-
{t('Incoming Call...')}
|
|
76
|
+
{t('ringingCall.incoming.title', 'Incoming Call...')}
|
|
77
77
|
</Text>
|
|
78
78
|
</View>
|
|
79
79
|
<View style={[styles.bottomContainer, incomingCall.bottomContainer]}>
|
|
@@ -2,13 +2,14 @@ import React from 'react';
|
|
|
2
2
|
import { StyleSheet, Text, View, type ViewStyle } from 'react-native';
|
|
3
3
|
import { UserInfo } from './UserInfo';
|
|
4
4
|
import { Z_INDEX } from '../../../constants';
|
|
5
|
-
import { useCallStateHooks
|
|
6
|
-
import {
|
|
5
|
+
import { useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
6
|
+
import { useI18n } from '../../../i18n';
|
|
7
7
|
import { useTheme } from '../../../contexts/ThemeContext';
|
|
8
8
|
import {
|
|
9
9
|
OutgoingCallControls as DefaultOutgoingCallControls,
|
|
10
10
|
type OutgoingCallControlsProps,
|
|
11
11
|
} from '../CallControls';
|
|
12
|
+
import { LobbyCameraPreview } from '../Lobby';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Props for the OutgoingCall Component.
|
|
@@ -77,7 +78,7 @@ export const OutgoingCall = ({
|
|
|
77
78
|
outgoingCall.callingText,
|
|
78
79
|
]}
|
|
79
80
|
>
|
|
80
|
-
{t('Calling...')}
|
|
81
|
+
{t('ringingCall.outgoing.title', 'Calling...')}
|
|
81
82
|
</Text>
|
|
82
83
|
</View>
|
|
83
84
|
<View style={[styles.bottomContainer, outgoingCall.bottomContainer]}>
|
|
@@ -107,11 +108,9 @@ const Background = () => {
|
|
|
107
108
|
theme: { colors, outgoingCall },
|
|
108
109
|
} = useTheme();
|
|
109
110
|
const { useCameraState } = useCallStateHooks();
|
|
110
|
-
const {
|
|
111
|
-
const localVideoStream = camera.state.mediaStream as unknown as
|
|
112
|
-
MediaStream | undefined;
|
|
111
|
+
const { optimisticIsMute } = useCameraState();
|
|
113
112
|
|
|
114
|
-
if (
|
|
113
|
+
if (optimisticIsMute) {
|
|
115
114
|
return (
|
|
116
115
|
<View
|
|
117
116
|
style={[
|
|
@@ -130,13 +129,7 @@ const Background = () => {
|
|
|
130
129
|
outgoingCall.background,
|
|
131
130
|
]}
|
|
132
131
|
>
|
|
133
|
-
<
|
|
134
|
-
streamURL={localVideoStream.toURL()}
|
|
135
|
-
zOrder={Z_INDEX.IN_BACK}
|
|
136
|
-
style={StyleSheet.absoluteFill}
|
|
137
|
-
mirror
|
|
138
|
-
objectFit="cover"
|
|
139
|
-
/>
|
|
132
|
+
<LobbyCameraPreview />
|
|
140
133
|
</View>
|
|
141
134
|
);
|
|
142
135
|
};
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
useCallStateHooks,
|
|
4
|
-
useI18n,
|
|
5
|
-
} from '@stream-io/video-react-bindings';
|
|
1
|
+
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
2
|
+
import { useI18n } from '../../../i18n';
|
|
6
3
|
import React, { useState } from 'react';
|
|
7
4
|
import {
|
|
8
5
|
ActivityIndicator,
|
|
@@ -149,10 +146,10 @@ export const HostStartStreamButton = ({
|
|
|
149
146
|
]}
|
|
150
147
|
>
|
|
151
148
|
{isAwaitingResponse
|
|
152
|
-
? t('Loading...')
|
|
149
|
+
? t('common.loading.text', 'Loading...')
|
|
153
150
|
: liveOrBroadcasting
|
|
154
|
-
? t('Stop Livestream')
|
|
155
|
-
: t('Start Livestream')}
|
|
151
|
+
? t('livestreamControls.stop.label', 'Stop Livestream')
|
|
152
|
+
: t('livestreamControls.start.label', 'Start Livestream')}
|
|
156
153
|
</Text>
|
|
157
154
|
</Pressable>
|
|
158
155
|
);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
-
import { useCall
|
|
2
|
+
import { useCall } from '@stream-io/video-react-bindings';
|
|
3
|
+
import { useI18n } from '../../../i18n';
|
|
3
4
|
import { useTheme } from '../../../contexts';
|
|
4
5
|
import { ListRecordingsResponse } from '@stream-io/video-client';
|
|
5
6
|
import {
|
|
@@ -106,11 +107,18 @@ export const CallEndedView = () => {
|
|
|
106
107
|
|
|
107
108
|
return (
|
|
108
109
|
<View style={styles.container}>
|
|
109
|
-
<Text style={styles.title}>
|
|
110
|
+
<Text style={styles.title}>
|
|
111
|
+
{t('livestreamPlayer.ended.title', 'The livestream has ended.')}
|
|
112
|
+
</Text>
|
|
110
113
|
|
|
111
114
|
{showRecordings && (
|
|
112
115
|
<>
|
|
113
|
-
<Text style={styles.subtitle}>
|
|
116
|
+
<Text style={styles.subtitle}>
|
|
117
|
+
{t(
|
|
118
|
+
'livestreamPlayer.ended.watchRecordings.title',
|
|
119
|
+
'Watch recordings:',
|
|
120
|
+
)}
|
|
121
|
+
</Text>
|
|
114
122
|
<View style={styles.recordingsContainer}>
|
|
115
123
|
<FlatList
|
|
116
124
|
data={recordingsResponse.recordings}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import { StyleSheet, Text, View } from 'react-native';
|
|
3
3
|
import { useTheme } from '../../../contexts';
|
|
4
|
-
import { useI18n } from '
|
|
4
|
+
import { useI18n } from '../../../i18n';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Props for the LiveIndicator component.
|
|
@@ -33,7 +33,7 @@ export const LiveIndicator = ({}: LiveIndicatorProps) => {
|
|
|
33
33
|
liveIndicator.label,
|
|
34
34
|
]}
|
|
35
35
|
>
|
|
36
|
-
{t('Live')}
|
|
36
|
+
{t('common.live.label', 'Live')}
|
|
37
37
|
</Text>
|
|
38
38
|
</View>
|
|
39
39
|
);
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
useCallStateHooks,
|
|
4
|
-
useI18n,
|
|
5
|
-
} from '@stream-io/video-react-bindings';
|
|
1
|
+
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
2
|
+
import { useI18n } from '../../../i18n';
|
|
6
3
|
import React, { useEffect, useMemo, useState } from 'react';
|
|
7
4
|
import {
|
|
8
5
|
ActivityIndicator,
|
|
@@ -99,10 +96,19 @@ export const ViewerLobby = ({ isLive }: LobbyProps) => {
|
|
|
99
96
|
<View style={styles.container}>
|
|
100
97
|
<Text style={styles.text}>
|
|
101
98
|
{isLive
|
|
102
|
-
? t(
|
|
99
|
+
? t(
|
|
100
|
+
'livestreamViewer.stillInProgress.text',
|
|
101
|
+
'Livestream is still in progress',
|
|
102
|
+
)
|
|
103
103
|
: startsAt
|
|
104
|
-
? t(
|
|
105
|
-
|
|
104
|
+
? t(
|
|
105
|
+
'livestreamViewer.willStartIn.text',
|
|
106
|
+
'Livestream will start in:',
|
|
107
|
+
)
|
|
108
|
+
: t(
|
|
109
|
+
'livestreamViewer.willStartSoon.text',
|
|
110
|
+
'Livestream will start soon',
|
|
111
|
+
)}
|
|
106
112
|
</Text>
|
|
107
113
|
{startsAt && !isLive && (
|
|
108
114
|
<Text style={styles.countdownText}>{countdown}</Text>
|
|
@@ -110,12 +116,19 @@ export const ViewerLobby = ({ isLive }: LobbyProps) => {
|
|
|
110
116
|
{!isLive && participants.length > 0 && (
|
|
111
117
|
<>
|
|
112
118
|
<Text style={styles.participantsText}>
|
|
113
|
-
{
|
|
119
|
+
{t('livestreamViewer.earlyParticipants.text', {
|
|
120
|
+
count: participants.length,
|
|
121
|
+
defaultValue_one: '{{ count }} participant has joined early',
|
|
122
|
+
defaultValue_other: '{{ count }} participants have joined early',
|
|
123
|
+
})}
|
|
114
124
|
</Text>
|
|
115
125
|
</>
|
|
116
126
|
)}
|
|
117
127
|
{isLive && (
|
|
118
|
-
<Button
|
|
128
|
+
<Button
|
|
129
|
+
title={t('livestreamViewer.join.label', 'Join Livestream')}
|
|
130
|
+
onPress={() => call?.join()}
|
|
131
|
+
/>
|
|
119
132
|
)}
|
|
120
133
|
</View>
|
|
121
134
|
);
|
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
} from '../../../icons';
|
|
16
16
|
import {
|
|
17
17
|
useCall,
|
|
18
|
-
useI18n,
|
|
19
18
|
useIsAudioConnecting,
|
|
20
19
|
useIsVideoConnecting,
|
|
21
20
|
} from '@stream-io/video-react-bindings';
|
|
21
|
+
import { useI18n } from '../../../i18n';
|
|
22
22
|
import { ComponentTestIds } from '../../../constants/TestIds';
|
|
23
23
|
import { type ParticipantViewProps } from './ParticipantView';
|
|
24
24
|
import { Z_INDEX } from '../../../constants';
|
|
@@ -62,7 +62,9 @@ export const ParticipantLabel = ({
|
|
|
62
62
|
const { t } = useI18n();
|
|
63
63
|
const participantName = name ?? userId;
|
|
64
64
|
|
|
65
|
-
const participantLabel = isLocalParticipant
|
|
65
|
+
const participantLabel = isLocalParticipant
|
|
66
|
+
? t('common.you.label', 'You')
|
|
67
|
+
: participantName;
|
|
66
68
|
const isAudioMuted = !hasAudio(participant);
|
|
67
69
|
const isVideoMuted = !hasVideo(participant);
|
|
68
70
|
const isTrackPaused = trackType && hasPausedTrack(participant, trackType);
|
|
@@ -71,10 +73,17 @@ export const ParticipantLabel = ({
|
|
|
71
73
|
|
|
72
74
|
if (trackType === 'screenShareTrack') {
|
|
73
75
|
const screenShareText = isLocalParticipant
|
|
74
|
-
? t(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
? t(
|
|
77
|
+
'participantView.screenShare.byYou.text',
|
|
78
|
+
'You are sharing your screen',
|
|
79
|
+
)
|
|
80
|
+
: t(
|
|
81
|
+
'participantView.screenShare.byUser.text',
|
|
82
|
+
'{{ userName }} is sharing their screen',
|
|
83
|
+
{
|
|
84
|
+
userName: participantName,
|
|
85
|
+
},
|
|
86
|
+
);
|
|
78
87
|
return (
|
|
79
88
|
<View
|
|
80
89
|
style={[
|