Ver código fonte

fix(vertical-filmstrip): move video status labels back to top right

The video status labels, which include recording and hd status,
have been moved back to the top left while in vertical filmstrip
mode. The following had to be done:
- Remove styling to move the labels to the bottom left
- For VideoStatusLabel, move filmstrip remote video count, toggle
  state, and 1:1 state into redux.
- Use middleware to emit out to the Recording label when the
  filmstrip changes.
- Create an empty Filmstrip file for web and identify the existing
  Filmstrip component as native.
j8
Leonard Kim 8 anos atrás
pai
commit
56b12bd969

+ 11
- 43
css/_vertical_filmstrip_overrides.scss Ver arquivo

87
         }
87
         }
88
     }
88
     }
89
 
89
 
90
+    /**
91
+     * For video labels that display on the top right to adjust its position as
92
+     * the filmstrip itself or filmstrip remote videos appear and disappear.
93
+     */
90
     .video-state-indicator {
94
     .video-state-indicator {
91
-        bottom: 30px;
92
-        left: 30px;
93
-        right: auto;
94
-        top: auto;
95
+        transition: right 2s;
95
 
96
 
96
-        /**
97
-         * Move the label to the bottom left of the screen
98
-         */
99
-        &#videoResolutionLabel {
100
-            left: 60px;
101
-            z-index: $poweredByZ;
102
-
103
-            /**
104
-             * Open the menu above the label.
105
-             */
106
-            .video-state-indicator-menu {
107
-                bottom: calc(100% - 15px);
108
-                left: -10px;
109
-
110
-                /**
111
-                 * Create padding for mouse travel on hover.
112
-                 */
113
-                padding-bottom: 20px;
114
-                right: auto;
115
-                top: auto;
116
-
117
-                .video-state-indicator-menu-options {
118
-                    margin: 0;
119
-
120
-                    /**
121
-                     * The menu arrow should point down
122
-                     */
123
-                    &::after {
124
-                        border-color: $popoverBg transparent transparent;
125
-                        bottom: -10px;
126
-                        left: 15px;
127
-                        right: auto;
128
-                        top: auto;
129
-                    }
130
-                }
97
+        &.with-filmstrip {
98
+            &#recordingLabel {
99
+                right: 200px;
131
             }
100
             }
132
-        }
133
 
101
 
134
-        &#recordingLabel {
135
-            left: 110px;
136
-            z-index: $poweredByZ;
102
+            &#videoResolutionLabel {
103
+                right: 150px;
104
+            }
137
         }
105
         }
138
     }
106
     }
139
 
107
 

+ 13
- 0
modules/UI/recording/Recording.js Ver arquivo

201
  * position
201
  * position
202
  */
202
  */
203
 function moveToCorner(selector, move) {
203
 function moveToCorner(selector, move) {
204
+    const {
205
+        remoteVideosCount,
206
+        remoteVideosVisible,
207
+        visible
208
+    } = APP.store.getState()['features/filmstrip'];
209
+    selector.toggleClass(
210
+        'with-filmstrip',
211
+        Boolean(remoteVideosCount && remoteVideosVisible && visible));
212
+
204
     let moveToCornerClass = "moveToCorner";
213
     let moveToCornerClass = "moveToCorner";
205
     let containsClass = selector.hasClass(moveToCornerClass);
214
     let containsClass = selector.hasClass(moveToCornerClass);
206
 
215
 
295
             APP.UI.messageHandler.enableNotifications(false);
304
             APP.UI.messageHandler.enableNotifications(false);
296
             APP.UI.messageHandler.enablePopups(false);
305
             APP.UI.messageHandler.enablePopups(false);
297
         }
306
         }
307
+
308
+        this.eventEmitter.addListener(UIEvents.UPDATED_FILMSTRIP_DISPLAY, () =>{
309
+            this._updateStatusLabel();
310
+        });
298
     },
311
     },
299
 
312
 
300
     /**
313
     /**

+ 9
- 0
modules/UI/videolayout/Filmstrip.js Ver arquivo

1
 /* global $, APP, config, JitsiMeetJS, interfaceConfig */
1
 /* global $, APP, config, JitsiMeetJS, interfaceConfig */
2
 
2
 
3
+import {
4
+    setFilmstripRemoteVideosVisibility,
5
+    setFilmstripVisibility
6
+} from '../../../react/features/filmstrip';
7
+
3
 import UIEvents from "../../../service/UI/UIEvents";
8
 import UIEvents from "../../../service/UI/UIEvents";
4
 import UIUtil from "../util/UIUtil";
9
 import UIUtil from "../util/UIUtil";
5
 
10
 
43
             return;
48
             return;
44
         }
49
         }
45
 
50
 
51
+        APP.store.dispatch(setFilmstripRemoteVideosVisibility(shouldShow));
46
         this.filmstripRemoteVideos.toggleClass('hide-videos', !shouldShow);
52
         this.filmstripRemoteVideos.toggleClass('hide-videos', !shouldShow);
47
     },
53
     },
48
 
54
 
172
 
178
 
173
         // Emit/fire UIEvents.TOGGLED_FILMSTRIP.
179
         // Emit/fire UIEvents.TOGGLED_FILMSTRIP.
174
         const eventEmitter = this.eventEmitter;
180
         const eventEmitter = this.eventEmitter;
181
+        const isFilmstripVisible = this.isFilmstripVisible();
182
+
175
         if (eventEmitter) {
183
         if (eventEmitter) {
176
             eventEmitter.emit(
184
             eventEmitter.emit(
177
                 UIEvents.TOGGLED_FILMSTRIP,
185
                 UIEvents.TOGGLED_FILMSTRIP,
178
                 this.isFilmstripVisible());
186
                 this.isFilmstripVisible());
179
         }
187
         }
188
+        APP.store.dispatch(setFilmstripVisibility(isFilmstripVisible));
180
     },
189
     },
181
 
190
 
182
     /**
191
     /**

+ 7
- 0
modules/UI/videolayout/VideoLayout.js Ver arquivo

1
 /* global APP, $, interfaceConfig */
1
 /* global APP, $, interfaceConfig */
2
 const logger = require("jitsi-meet-logger").getLogger(__filename);
2
 const logger = require("jitsi-meet-logger").getLogger(__filename);
3
 
3
 
4
+import {
5
+    setFilmstripRemoteVideosCount
6
+} from '../../../react/features/filmstrip';
7
+
4
 import Filmstrip from "./Filmstrip";
8
 import Filmstrip from "./Filmstrip";
5
 import UIEvents from "../../../service/UI/UIEvents";
9
 import UIEvents from "../../../service/UI/UIEvents";
6
 import UIUtil from "../util/UIUtil";
10
 import UIUtil from "../util/UIUtil";
550
                 if (onComplete && typeof onComplete === "function")
554
                 if (onComplete && typeof onComplete === "function")
551
                     onComplete();
555
                     onComplete();
552
             });
556
             });
557
+
558
+        APP.store.dispatch(
559
+            setFilmstripRemoteVideosCount(this.getRemoteVideosCount()));
553
         return { localVideo, remoteVideo };
560
         return { localVideo, remoteVideo };
554
     },
561
     },
555
 
562
 

+ 1
- 0
react/features/conference/components/Conference.web.js Ver arquivo

10
 import { Toolbox } from '../../toolbox';
10
 import { Toolbox } from '../../toolbox';
11
 import { HideNotificationBarStyle } from '../../unsupported-browser';
11
 import { HideNotificationBarStyle } from '../../unsupported-browser';
12
 import { VideoStatusLabel } from '../../video-status-label';
12
 import { VideoStatusLabel } from '../../video-status-label';
13
+import '../../filmstrip';
13
 
14
 
14
 declare var $: Function;
15
 declare var $: Function;
15
 declare var APP: Object;
16
 declare var APP: Object;

+ 35
- 0
react/features/filmstrip/actionTypes.js Ver arquivo

1
+import { Symbol } from '../base/react';
2
+
3
+/**
4
+ * The type of action which signals to change the count of known remote videos
5
+ * displayed in the filmstrip.
6
+ *
7
+ * {
8
+ *     type: SET_FILMSTRIP_REMOTE_VIDEOS_COUNT,
9
+ *     remoteVideosCount: number
10
+ * }
11
+ */
12
+export const SET_FILMSTRIP_REMOTE_VIDEOS_COUNT
13
+    = Symbol('SET_FILMSTRIP_REMOTE_VIDEOS_COUNT');
14
+
15
+/**
16
+ * The type of action which signals to change the visibility of remote videos in
17
+ * the filmstrip.
18
+ *
19
+ * {
20
+ *     type: SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
21
+ *     removeVideosVisible: boolean
22
+ * }
23
+ */
24
+export const SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY
25
+    = Symbol('SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY');
26
+
27
+/**
28
+ * The type of action sets the visibility of the entire filmstrip;
29
+ *
30
+ * {
31
+ *     type: SET_FILMSTRIP_VISIBILITY,
32
+ *     visible: boolean
33
+ * }
34
+ */
35
+export const SET_FILMSTRIP_VISIBILITY = Symbol('SET_FILMSTRIP_VISIBILITY');

+ 54
- 0
react/features/filmstrip/actions.js Ver arquivo

1
+import {
2
+    SET_FILMSTRIP_REMOTE_VIDEOS_COUNT,
3
+    SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
4
+    SET_FILMSTRIP_VISIBILITY
5
+} from './actionTypes';
6
+
7
+/**
8
+ * Sets the visibility of remote videos in the filmstrip.
9
+ *
10
+ * @param {boolean} remoteVideosVisible - Whether or not remote videos in the
11
+ * filmstrip should be visible.
12
+ * @returns {{
13
+ *     type: SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
14
+ *     remoteVideosVisible: boolean
15
+ * }}
16
+ */
17
+export function setFilmstripRemoteVideosVisibility(remoteVideosVisible) {
18
+    return {
19
+        type: SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
20
+        remoteVideosVisible
21
+    };
22
+}
23
+
24
+/**
25
+ * Sets how many remote videos are currently in the filmstrip.
26
+ *
27
+ * @param {number} remoteVideosCount - The number of remote videos.
28
+ * @returns {{
29
+ *     type: SET_FILMSTRIP_REMOTE_VIDEOS_COUNT,
30
+ *     remoteVideosCount: number
31
+ * }}
32
+ */
33
+export function setFilmstripRemoteVideosCount(remoteVideosCount) {
34
+    return {
35
+        type: SET_FILMSTRIP_REMOTE_VIDEOS_COUNT,
36
+        remoteVideosCount
37
+    };
38
+}
39
+
40
+/**
41
+ * Sets if the entire filmstrip should be visible.
42
+ *
43
+ * @param {boolean} visible - Whether not the filmstrip is visible.
44
+ * @returns {{
45
+ *     type: SET_FILMSTRIP_VISIBILITY,
46
+ *     visible: boolean
47
+ * }}
48
+ */
49
+export function setFilmstripVisibility(visible) {
50
+    return {
51
+        type: SET_FILMSTRIP_VISIBILITY,
52
+        visible
53
+    };
54
+}

react/features/filmstrip/components/Filmstrip.js → react/features/filmstrip/components/Filmstrip.native.js Ver arquivo


+ 0
- 0
react/features/filmstrip/components/Filmstrip.web.js Ver arquivo


+ 5
- 0
react/features/filmstrip/index.js Ver arquivo

1
+export * from './actions';
2
+export * from './actionTypes';
1
 export * from './components';
3
 export * from './components';
4
+
5
+import './middleware';
6
+import './reducer';

+ 30
- 0
react/features/filmstrip/middleware.js Ver arquivo

1
+import UIEvents from '../../../service/UI/UIEvents';
2
+
3
+import { MiddlewareRegistry } from '../base/redux';
4
+
5
+import {
6
+    SET_FILMSTRIP_REMOTE_VIDEOS_COUNT,
7
+    SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
8
+    SET_FILMSTRIP_VISIBILITY
9
+} from './actionTypes';
10
+
11
+declare var APP: Object;
12
+
13
+// eslint-disable-next-line no-unused-vars
14
+MiddlewareRegistry.register(store => next => action => {
15
+    const result = next(action);
16
+
17
+    switch (action.type) {
18
+    case SET_FILMSTRIP_REMOTE_VIDEOS_COUNT:
19
+    case SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY:
20
+    case SET_FILMSTRIP_VISIBILITY: {
21
+        if (typeof APP !== 'undefined') {
22
+            APP.UI.emitEvent(UIEvents.UPDATED_FILMSTRIP_DISPLAY);
23
+
24
+        }
25
+        break;
26
+    }
27
+    }
28
+
29
+    return result;
30
+});

+ 36
- 0
react/features/filmstrip/reducer.js Ver arquivo

1
+import { ReducerRegistry } from '../base/redux';
2
+import {
3
+    SET_FILMSTRIP_REMOTE_VIDEOS_COUNT,
4
+    SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
5
+    SET_FILMSTRIP_VISIBILITY
6
+} from './actionTypes';
7
+
8
+const DEFAULT_STATE = {
9
+    remoteVideosCount: 0,
10
+    remoteVideosVisible: true,
11
+    visible: true
12
+};
13
+
14
+ReducerRegistry.register(
15
+    'features/filmstrip',
16
+    (state = DEFAULT_STATE, action) => {
17
+        switch (action.type) {
18
+        case SET_FILMSTRIP_REMOTE_VIDEOS_COUNT:
19
+            return {
20
+                ...state,
21
+                remoteVideosCount: action.remoteVideosCount
22
+            };
23
+        case SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY:
24
+            return {
25
+                ...state,
26
+                remoteVideosVisible: action.remoteVideosVisible
27
+            };
28
+        case SET_FILMSTRIP_VISIBILITY:
29
+            return {
30
+                ...state,
31
+                visible: action.visible
32
+            };
33
+        }
34
+
35
+        return state;
36
+    });

+ 25
- 2
react/features/video-status-label/components/VideoStatusLabel.js Ver arquivo

28
          */
28
          */
29
         _conferenceStarted: React.PropTypes.bool,
29
         _conferenceStarted: React.PropTypes.bool,
30
 
30
 
31
+        /**
32
+         * Whether or not the filmstrip is displayed with remote videos.
33
+         */
34
+        _filmstripVisible: React.PropTypes.bool,
35
+
31
         /**
36
         /**
32
          * Whether or not a high-definition large video is displayed.
37
          * Whether or not a high-definition large video is displayed.
33
          */
38
          */
64
      * @returns {ReactElement}
69
      * @returns {ReactElement}
65
      */
70
      */
66
     render() {
71
     render() {
67
-        const { _audioOnly, _conferenceStarted, _largeVideoHD, t } = this.props;
72
+        const {
73
+            _audioOnly,
74
+            _conferenceStarted,
75
+            _filmstripVisible,
76
+            _largeVideoHD,
77
+            t
78
+        } = this.props;
68
 
79
 
69
         // FIXME The _conferenceStarted check is used to be defensive against
80
         // FIXME The _conferenceStarted check is used to be defensive against
70
         // toggling audio only mode while there is no conference and hides the
81
         // toggling audio only mode while there is no conference and hides the
82
                 ? t('videoStatus.hd') : t('videoStatus.sd');
93
                 ? t('videoStatus.hd') : t('videoStatus.sd');
83
         }
94
         }
84
 
95
 
96
+        const filmstripClassName
97
+            = _filmstripVisible ? 'with-filmstrip' : 'without-filmstrip';
98
+        const classNames
99
+            = `video-state-indicator moveToCorner ${filmstripClassName}`;
100
+
85
         return (
101
         return (
86
             <div
102
             <div
87
-                className = 'video-state-indicator moveToCorner'
103
+                className = { classNames }
88
                 id = 'videoResolutionLabel' >
104
                 id = 'videoResolutionLabel' >
89
                 { displayedLabel }
105
                 { displayedLabel }
90
                 { this._renderVideonMenu() }
106
                 { this._renderVideonMenu() }
152
         conference,
168
         conference,
153
         isLargeVideoHD
169
         isLargeVideoHD
154
     } = state['features/base/conference'];
170
     } = state['features/base/conference'];
171
+    const {
172
+        remoteVideosCount,
173
+        remoteVideosVisible,
174
+        visible
175
+    } = state['features/filmstrip'];
155
 
176
 
156
     return {
177
     return {
157
         _audioOnly: audioOnly,
178
         _audioOnly: audioOnly,
158
         _conferenceStarted: Boolean(conference),
179
         _conferenceStarted: Boolean(conference),
180
+        _filmstripVisible:
181
+            Boolean(remoteVideosCount && remoteVideosVisible && visible),
159
         _largeVideoHD: isLargeVideoHD
182
         _largeVideoHD: isLargeVideoHD
160
     };
183
     };
161
 }
184
 }

+ 6
- 0
service/UI/UIEvents.js Ver arquivo

65
      * @see {TOGGLE_FILMSTRIP}
65
      * @see {TOGGLE_FILMSTRIP}
66
      */
66
      */
67
     TOGGLED_FILMSTRIP: "UI.toggled_filmstrip",
67
     TOGGLED_FILMSTRIP: "UI.toggled_filmstrip",
68
+
69
+    /**
70
+     * Notifies that the filmstrip has updated its appearance, such as by
71
+     * toggling or removing videos or adding videos.
72
+     */
73
+    UPDATED_FILMSTRIP_DISPLAY: "UI.updated_filmstrip_display",
68
     TOGGLE_SCREENSHARING: "UI.toggle_screensharing",
74
     TOGGLE_SCREENSHARING: "UI.toggle_screensharing",
69
     TOGGLED_SHARED_DOCUMENT: "UI.toggled_shared_document",
75
     TOGGLED_SHARED_DOCUMENT: "UI.toggled_shared_document",
70
     CONTACT_CLICKED: "UI.contact_clicked",
76
     CONTACT_CLICKED: "UI.contact_clicked",

Carregando…
Cancelar
Salvar