|
@@ -1,14 +1,20 @@
|
1
|
1
|
// @flow
|
2
|
2
|
|
3
|
3
|
import React, { PureComponent } from 'react';
|
|
4
|
+import type { Dispatch } from 'redux';
|
4
|
5
|
|
|
6
|
+import { getSourceNameSignalingFeatureFlag } from '../../base/config/functions.any';
|
|
7
|
+import { JitsiTrackEvents } from '../../base/lib-jitsi-meet';
|
5
|
8
|
import { ParticipantView, getParticipantById } from '../../base/participants';
|
6
|
9
|
import { connect } from '../../base/redux';
|
7
|
|
-import { isLocalVideoTrackDesktop } from '../../base/tracks/functions';
|
|
10
|
+import {
|
|
11
|
+ getVideoTrackByParticipant,
|
|
12
|
+ isLocalVideoTrackDesktop,
|
|
13
|
+ trackStreamingStatusChanged
|
|
14
|
+} from '../../base/tracks';
|
8
|
15
|
|
9
|
16
|
import { AVATAR_SIZE } from './styles';
|
10
|
17
|
|
11
|
|
-
|
12
|
18
|
/**
|
13
|
19
|
* The type of the React {@link Component} props of {@link LargeVideo}.
|
14
|
20
|
*/
|
|
@@ -31,11 +37,26 @@ type Props = {
|
31
|
37
|
*/
|
32
|
38
|
_participantId: string,
|
33
|
39
|
|
|
40
|
+ /**
|
|
41
|
+ * Whether source name signaling is enabled.
|
|
42
|
+ */
|
|
43
|
+ _sourceNameSignalingEnabled: boolean,
|
|
44
|
+
|
|
45
|
+ /**
|
|
46
|
+ * The video track that will be displayed in the thumbnail.
|
|
47
|
+ */
|
|
48
|
+ _videoTrack: ?Object,
|
|
49
|
+
|
34
|
50
|
/**
|
35
|
51
|
* Application's viewport height.
|
36
|
52
|
*/
|
37
|
53
|
_width: number,
|
38
|
54
|
|
|
55
|
+ /**
|
|
56
|
+ * Invoked to trigger state changes in Redux.
|
|
57
|
+ */
|
|
58
|
+ dispatch: Dispatch<any>,
|
|
59
|
+
|
39
|
60
|
/**
|
40
|
61
|
* Callback to invoke when the {@code LargeVideo} is clicked/pressed.
|
41
|
62
|
*/
|
|
@@ -72,6 +93,18 @@ const DEFAULT_STATE = {
|
72
|
93
|
* @augments Component
|
73
|
94
|
*/
|
74
|
95
|
class LargeVideo extends PureComponent<Props, State> {
|
|
96
|
+ /**
|
|
97
|
+ * Creates new LargeVideo component.
|
|
98
|
+ *
|
|
99
|
+ * @param {Props} props - The props of the component.
|
|
100
|
+ * @returns {LargeVideo}
|
|
101
|
+ */
|
|
102
|
+ constructor(props: Props) {
|
|
103
|
+ super(props);
|
|
104
|
+
|
|
105
|
+ this.handleTrackStreamingStatusChanged = this.handleTrackStreamingStatusChanged.bind(this);
|
|
106
|
+ }
|
|
107
|
+
|
75
|
108
|
state = {
|
76
|
109
|
...DEFAULT_STATE
|
77
|
110
|
};
|
|
@@ -100,6 +133,86 @@ class LargeVideo extends PureComponent<Props, State> {
|
100
|
133
|
|
101
|
134
|
}
|
102
|
135
|
|
|
136
|
+ /**
|
|
137
|
+ * Starts listening for track streaming status updates after the initial render.
|
|
138
|
+ *
|
|
139
|
+ * @inheritdoc
|
|
140
|
+ * @returns {void}
|
|
141
|
+ */
|
|
142
|
+ componentDidMount() {
|
|
143
|
+ // Listen to track streaming status changed event to keep it updated.
|
|
144
|
+ // TODO: after converting this component to a react function component,
|
|
145
|
+ // use a custom hook to update local track streaming status.
|
|
146
|
+ const { _videoTrack, dispatch, _sourceNameSignalingEnabled } = this.props;
|
|
147
|
+
|
|
148
|
+ if (_sourceNameSignalingEnabled && _videoTrack && !_videoTrack.local) {
|
|
149
|
+ _videoTrack.jitsiTrack.on(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
|
|
150
|
+ this.handleTrackStreamingStatusChanged);
|
|
151
|
+ dispatch(trackStreamingStatusChanged(_videoTrack.jitsiTrack,
|
|
152
|
+ _videoTrack.jitsiTrack.getTrackStreamingStatus()));
|
|
153
|
+ }
|
|
154
|
+ }
|
|
155
|
+
|
|
156
|
+ /**
|
|
157
|
+ * Stops listening for track streaming status updates on the old track and starts listening instead on the new
|
|
158
|
+ * track.
|
|
159
|
+ *
|
|
160
|
+ * @inheritdoc
|
|
161
|
+ * @returns {void}
|
|
162
|
+ */
|
|
163
|
+ componentDidUpdate(prevProps: Props) {
|
|
164
|
+ // TODO: after converting this component to a react function component,
|
|
165
|
+ // use a custom hook to update local track streaming status.
|
|
166
|
+ const { _videoTrack, dispatch, _sourceNameSignalingEnabled } = this.props;
|
|
167
|
+
|
|
168
|
+ if (_sourceNameSignalingEnabled
|
|
169
|
+ && prevProps._videoTrack?.jitsiTrack?.getSourceName() !== _videoTrack?.jitsiTrack?.getSourceName()) {
|
|
170
|
+ if (prevProps._videoTrack && !prevProps._videoTrack.local) {
|
|
171
|
+ prevProps._videoTrack.jitsiTrack.off(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
|
|
172
|
+ this.handleTrackStreamingStatusChanged);
|
|
173
|
+ dispatch(trackStreamingStatusChanged(prevProps._videoTrack.jitsiTrack,
|
|
174
|
+ prevProps._videoTrack.jitsiTrack.getTrackStreamingStatus()));
|
|
175
|
+ }
|
|
176
|
+ if (_videoTrack && !_videoTrack.local) {
|
|
177
|
+ _videoTrack.jitsiTrack.on(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
|
|
178
|
+ this.handleTrackStreamingStatusChanged);
|
|
179
|
+ dispatch(trackStreamingStatusChanged(_videoTrack.jitsiTrack,
|
|
180
|
+ _videoTrack.jitsiTrack.getTrackStreamingStatus()));
|
|
181
|
+ }
|
|
182
|
+ }
|
|
183
|
+ }
|
|
184
|
+
|
|
185
|
+ /**
|
|
186
|
+ * Remove listeners for track streaming status update.
|
|
187
|
+ *
|
|
188
|
+ * @inheritdoc
|
|
189
|
+ * @returns {void}
|
|
190
|
+ */
|
|
191
|
+ componentWillUnmount() {
|
|
192
|
+ // TODO: after converting this component to a react function component,
|
|
193
|
+ // use a custom hook to update local track streaming status.
|
|
194
|
+ const { _videoTrack, dispatch, _sourceNameSignalingEnabled } = this.props;
|
|
195
|
+
|
|
196
|
+ if (_sourceNameSignalingEnabled && _videoTrack && !_videoTrack.local) {
|
|
197
|
+ _videoTrack.jitsiTrack.off(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
|
|
198
|
+ this.handleTrackStreamingStatusChanged);
|
|
199
|
+ dispatch(trackStreamingStatusChanged(_videoTrack.jitsiTrack,
|
|
200
|
+ _videoTrack.jitsiTrack.getTrackStreamingStatus()));
|
|
201
|
+ }
|
|
202
|
+ }
|
|
203
|
+
|
|
204
|
+ /**
|
|
205
|
+ * Handle track streaming status change event by by dispatching an action to update track streaming status for the
|
|
206
|
+ * given track in app state.
|
|
207
|
+ *
|
|
208
|
+ * @param {JitsiTrack} jitsiTrack - The track with streaming status updated.
|
|
209
|
+ * @param {JitsiTrackStreamingStatus} streamingStatus - The updated track streaming status.
|
|
210
|
+ * @returns {void}
|
|
211
|
+ */
|
|
212
|
+ handleTrackStreamingStatusChanged(jitsiTrack, streamingStatus) {
|
|
213
|
+ this.props.dispatch(trackStreamingStatusChanged(jitsiTrack, streamingStatus));
|
|
214
|
+ }
|
|
215
|
+
|
103
|
216
|
/**
|
104
|
217
|
* Implements React's {@link Component#render()}.
|
105
|
218
|
*
|
|
@@ -142,6 +255,7 @@ function _mapStateToProps(state) {
|
142
|
255
|
const { participantId } = state['features/large-video'];
|
143
|
256
|
const participant = getParticipantById(state, participantId);
|
144
|
257
|
const { clientHeight: height, clientWidth: width } = state['features/base/responsive-ui'];
|
|
258
|
+ const videoTrack = getVideoTrackByParticipant(state['features/base/tracks'], participant);
|
145
|
259
|
let disableVideo = false;
|
146
|
260
|
|
147
|
261
|
if (participant?.local) {
|
|
@@ -152,6 +266,8 @@ function _mapStateToProps(state) {
|
152
|
266
|
_disableVideo: disableVideo,
|
153
|
267
|
_height: height,
|
154
|
268
|
_participantId: participantId,
|
|
269
|
+ _sourceNameSignalingEnabled: getSourceNameSignalingFeatureFlag(state),
|
|
270
|
+ _videoTrack: videoTrack,
|
155
|
271
|
_width: width
|
156
|
272
|
};
|
157
|
273
|
}
|