浏览代码

fix(large-video): do not show avatar if no url (#3871)

* fix(large-video): do not show avatar if no url

By default the large video dominant speaker avatar
has an empty src, which will result in a broken
image displaying. There is also disconnect with
non-react code trying to set an undefined src.
To prevent such until local avatar generation
work is done in the future, just don't show the
avatar.

* fix(conference): set the room instance earlier

Set the room instance on APP.conference before triggering
a redux update of the conference being set,, because
middleware can then fire and call methods on APP.conference
that depend on the room being set.

* get local participant directly from store instead of from global
j8
virtuacoplenny 6 年前
父节点
当前提交
b7133f5717
没有帐户链接到提交者的电子邮件

+ 1
- 0
conference.js 查看文件

1237
             = connection.initJitsiConference(
1237
             = connection.initJitsiConference(
1238
                 APP.conference.roomName,
1238
                 APP.conference.roomName,
1239
                 this._getConferenceOptions());
1239
                 this._getConferenceOptions());
1240
+
1240
         APP.store.dispatch(conferenceWillJoin(room));
1241
         APP.store.dispatch(conferenceWillJoin(room));
1241
         this._setLocalAudioVideoStreams(localTracks);
1242
         this._setLocalAudioVideoStreams(localTracks);
1242
         this._room = room; // FIXME do not use this
1243
         this._room = room; // FIXME do not use this

+ 5
- 1
css/_videolayout_default.scss 查看文件

496
     display:none !important;
496
     display:none !important;
497
 }
497
 }
498
 
498
 
499
+#dominantSpeakerAvatarContainer,
499
 #dominantSpeakerAvatar,
500
 #dominantSpeakerAvatar,
500
 .dynamic-shadow {
501
 .dynamic-shadow {
501
     width: 200px;
502
     width: 200px;
502
     height: 200px;
503
     height: 200px;
503
 }
504
 }
504
 
505
 
505
-#dominantSpeakerAvatar {
506
+#dominantSpeakerAvatarContainer {
506
     top: 50px;
507
     top: 50px;
507
     margin: auto;
508
     margin: auto;
508
     position: relative;
509
     position: relative;
509
     border-radius: 100px;
510
     border-radius: 100px;
511
+    overflow: hidden;
510
     visibility: inherit;
512
     visibility: inherit;
513
+}
514
+#dominantSpeakerAvatar {
511
     background-color: #000000;
515
     background-color: #000000;
512
 }
516
 }
513
 
517
 

+ 20
- 4
modules/UI/videolayout/LargeVideoManager.js 查看文件

6
 import { Provider } from 'react-redux';
6
 import { Provider } from 'react-redux';
7
 
7
 
8
 import { i18next } from '../../../react/features/base/i18n';
8
 import { i18next } from '../../../react/features/base/i18n';
9
+import {
10
+    Avatar,
11
+    getAvatarURLByParticipantId
12
+} from '../../../react/features/base/participants';
9
 import { PresenceLabel } from '../../../react/features/presence-status';
13
 import { PresenceLabel } from '../../../react/features/presence-status';
10
 /* eslint-enable no-unused-vars */
14
 /* eslint-enable no-unused-vars */
11
 
15
 
14
 import {
18
 import {
15
     JitsiParticipantConnectionStatus
19
     JitsiParticipantConnectionStatus
16
 } from '../../../react/features/base/lib-jitsi-meet';
20
 } from '../../../react/features/base/lib-jitsi-meet';
17
-import {
18
-    getAvatarURLByParticipantId
19
-} from '../../../react/features/base/participants';
20
 import {
21
 import {
21
     updateKnownLargeVideoResolution
22
     updateKnownLargeVideoResolution
22
 } from '../../../react/features/large-video';
23
 } from '../../../react/features/large-video';
95
             = this._onVideoResolutionUpdate.bind(this);
96
             = this._onVideoResolutionUpdate.bind(this);
96
 
97
 
97
         this.videoContainer.addResizeListener(this._onVideoResolutionUpdate);
98
         this.videoContainer.addResizeListener(this._onVideoResolutionUpdate);
99
+
100
+        this._dominantSpeakerAvatarContainer
101
+            = document.getElementById('dominantSpeakerAvatarContainer');
98
     }
102
     }
99
 
103
 
100
     /**
104
     /**
109
 
113
 
110
         this.removePresenceLabel();
114
         this.removePresenceLabel();
111
 
115
 
116
+        ReactDOM.unmountComponentAtNode(this._dominantSpeakerAvatarContainer);
117
+
112
         this.$container.css({ display: 'none' });
118
         this.$container.css({ display: 'none' });
113
     }
119
     }
114
 
120
 
394
      * Updates the src of the dominant speaker avatar
400
      * Updates the src of the dominant speaker avatar
395
      */
401
      */
396
     updateAvatar(avatarUrl) {
402
     updateAvatar(avatarUrl) {
397
-        $('#dominantSpeakerAvatar').attr('src', avatarUrl);
403
+        if (avatarUrl) {
404
+            ReactDOM.render(
405
+                <Avatar
406
+                    id = "dominantSpeakerAvatar"
407
+                    uri = { avatarUrl } />,
408
+                this._dominantSpeakerAvatarContainer
409
+            );
410
+        } else {
411
+            ReactDOM.unmountComponentAtNode(
412
+                this._dominantSpeakerAvatarContainer);
413
+        }
398
     }
414
     }
399
 
415
 
400
     /**
416
     /**

+ 2
- 2
modules/UI/videolayout/VideoContainer.js 查看文件

265
          */
265
          */
266
         this.$wrapperParent = this.$wrapper.parent();
266
         this.$wrapperParent = this.$wrapper.parent();
267
 
267
 
268
-        this.avatarHeight = $('#dominantSpeakerAvatar').height();
268
+        this.avatarHeight = $('#dominantSpeakerAvatarContainer').height();
269
 
269
 
270
         const onPlayingCallback = function(event) {
270
         const onPlayingCallback = function(event) {
271
             if (typeof resizeContainer === 'function') {
271
             if (typeof resizeContainer === 'function') {
408
      */
408
      */
409
     _positionParticipantStatus($element) {
409
     _positionParticipantStatus($element) {
410
         if (this.avatarDisplayed) {
410
         if (this.avatarDisplayed) {
411
-            const $avatarImage = $('#dominantSpeakerAvatar');
411
+            const $avatarImage = $('#dominantSpeakerAvatarContainer');
412
 
412
 
413
             $element.css(
413
             $element.css(
414
                 'top',
414
                 'top',

+ 14
- 3
modules/UI/videolayout/VideoLayout.js 查看文件

10
 } from '../../../react/features/base/lib-jitsi-meet';
10
 } from '../../../react/features/base/lib-jitsi-meet';
11
 import { VIDEO_TYPE } from '../../../react/features/base/media';
11
 import { VIDEO_TYPE } from '../../../react/features/base/media';
12
 import {
12
 import {
13
+    getLocalParticipant as getLocalParticipantFromStore,
13
     getPinnedParticipant,
14
     getPinnedParticipant,
14
     pinParticipant
15
     pinParticipant
15
 } from '../../../react/features/base/participants';
16
 } from '../../../react/features/base/participants';
75
     ];
76
     ];
76
 }
77
 }
77
 
78
 
79
+/**
80
+ * Private helper to get the redux representation of the local participant.
81
+ *
82
+ * @private
83
+ * @returns {Object}
84
+ */
85
+function getLocalParticipant() {
86
+    return getLocalParticipantFromStore(APP.store.getState());
87
+}
88
+
78
 /**
89
 /**
79
  * Returns the user ID of the remote participant that is current the dominant
90
  * Returns the user ID of the remote participant that is current the dominant
80
  * speaker.
91
  * speaker.
181
     },
192
     },
182
 
193
 
183
     changeLocalVideo(stream) {
194
     changeLocalVideo(stream) {
184
-        const localId = APP.conference.getMyUserId();
195
+        const localId = getLocalParticipant().id;
185
 
196
 
186
         this.onVideoTypeChanged(localId, stream.videoType);
197
         this.onVideoTypeChanged(localId, stream.videoType);
187
 
198
 
198
      */
209
      */
199
     mucJoined() {
210
     mucJoined() {
200
         if (largeVideo && !largeVideo.id) {
211
         if (largeVideo && !largeVideo.id) {
201
-            this.updateLargeVideo(APP.conference.getMyUserId(), true);
212
+            this.updateLargeVideo(getLocalParticipant().id, true);
202
         }
213
         }
203
 
214
 
204
         // FIXME: replace this call with a generic update call once SmallVideo
215
         // FIXME: replace this call with a generic update call once SmallVideo
302
         // Go with local video
313
         // Go with local video
303
         logger.info('Fallback to local video...');
314
         logger.info('Fallback to local video...');
304
 
315
 
305
-        const id = APP.conference.getMyUserId();
316
+        const { id } = getLocalParticipant();
306
 
317
 
307
         logger.info(`electLastVisibleVideo: ${id}`);
318
         logger.info(`electLastVisibleVideo: ${id}`);
308
 
319
 

+ 1
- 3
react/features/large-video/components/LargeVideo.web.js 查看文件

34
 
34
 
35
                 <div id = 'dominantSpeaker'>
35
                 <div id = 'dominantSpeaker'>
36
                     <div className = 'dynamic-shadow' />
36
                     <div className = 'dynamic-shadow' />
37
-                    <img
38
-                        id = 'dominantSpeakerAvatar'
39
-                        src = '' />
37
+                    <div id = 'dominantSpeakerAvatarContainer' />
40
                 </div>
38
                 </div>
41
                 <div id = 'remotePresenceMessage' />
39
                 <div id = 'remotePresenceMessage' />
42
                 <span id = 'remoteConnectionMessage' />
40
                 <span id = 'remoteConnectionMessage' />

正在加载...
取消
保存