Kaynağa Gözat

Merge pull request #1110 from jitsi/filmstrip-button-editions

Filmstrip button editions
j8
yanas 8 yıl önce
ebeveyn
işleme
101c413a3c
6 değiştirilmiş dosya ile 243 ekleme ve 169 silme
  1. 120
    0
      css/_filmstrip.scss
  2. 1
    1
      css/_toastr.scss
  3. 0
    122
      css/_videolayout_default.scss
  4. 1
    0
      css/main.scss
  5. 15
    13
      index.html
  6. 106
    33
      modules/UI/videolayout/FilmStrip.js

+ 120
- 0
css/_filmstrip.scss Dosyayı Görüntüle

@@ -0,0 +1,120 @@
1
+%align-right {
2
+    @include flex();
3
+    flex-direction: row-reverse;
4
+    flex-wrap: nowrap;
5
+    justify-content: flex-start;
6
+}
7
+
8
+.filmstrip {
9
+    position: absolute;
10
+    bottom: 0;
11
+    right: 0;
12
+    padding: 10px 5px;
13
+    @extend %align-right;
14
+
15
+    &__toolbar {
16
+        @include flex();
17
+        flex-direction: column-reverse;
18
+        flex-wrap: nowrap;
19
+        position: relative;
20
+        z-index: 1;                     // Set z-index to make element visible
21
+        width: 17px;
22
+
23
+        button {
24
+            font-size: 14px;
25
+            line-height: 1.2;
26
+            text-align: center;
27
+            background: transparent;
28
+            opacity: 0.7;
29
+            height: auto;
30
+            width: 100%;
31
+            padding: 0;
32
+            margin: 0;
33
+            border: none;
34
+            outline: none;
35
+
36
+            -webkit-appearance: none;
37
+
38
+            &:hover {
39
+                opacity: 1;
40
+            }
41
+
42
+            i {
43
+                cursor: pointer;
44
+            }
45
+        }
46
+    }
47
+
48
+    &__videos {
49
+        @extend %align-right;
50
+        position:relative;
51
+        height:196px;
52
+        padding: 0;
53
+        bottom: 0;
54
+        width:auto;
55
+        border: 2px solid transparent;
56
+        z-index: 5;
57
+        transition: bottom 2s;
58
+        overflow: visible !important;
59
+        font-size: 0pt; /*!!!Removes the gap between the local video container and the remote videos.*/
60
+
61
+        &.hidden {
62
+            bottom: -196px;
63
+        }
64
+
65
+        .videocontainer {
66
+            display: none;
67
+            position: relative;
68
+            background-size: contain;
69
+            border: 2px solid transparent;
70
+            border-radius:1px;
71
+            margin: 0 $thumbnailVideoMargin;
72
+
73
+            &.videoContainerFocused, &:hover {
74
+                cursor: hand;
75
+            }
76
+
77
+            /**
78
+            * Focused video thumbnail.
79
+            */
80
+            &.videoContainerFocused {
81
+                transition-duration: 0.5s;
82
+                -webkit-transition-duration: 0.5s;
83
+                -webkit-animation-name: greyPulse;
84
+                -webkit-animation-duration: 2s;
85
+                -webkit-animation-iteration-count: 1;
86
+                border: 2px solid $videoThumbnailSelected !important;
87
+                box-shadow: inset 0 0 3px $videoThumbnailSelected,
88
+                0 0 3px $videoThumbnailSelected !important;
89
+            }
90
+
91
+            .remotevideomenu {
92
+                display: none;
93
+            }
94
+
95
+            /**
96
+            * Hovered video thumbnail.
97
+            */
98
+            &:hover {
99
+                cursor: hand;
100
+                border: 2px solid $videoThumbnailHovered;
101
+                box-shadow: inset 0 0 3px $videoThumbnailHovered,
102
+                0 0 3px $videoThumbnailHovered;
103
+
104
+                .remotevideomenu {
105
+                    display: inline-block;
106
+                }
107
+            }
108
+
109
+            /* With TemasysWebRTC plugin <object/> element is used
110
+            instead of <video/> */
111
+            & > video,
112
+            & > object {
113
+                cursor: hand;
114
+                border-radius:1px;
115
+                object-fit: cover;
116
+                overflow: hidden;
117
+            }
118
+        }
119
+    }
120
+}

+ 1
- 1
css/_toastr.scss Dosyayı Görüntüle

@@ -93,7 +93,7 @@
93 93
 
94 94
 #toast-container.notification-bottom-right {
95 95
   bottom: 135px;
96
-  right: 13px;
96
+  right: 28px;
97 97
 }
98 98
 
99 99
 #toast-container * {

+ 0
- 122
css/_videolayout_default.scss Dosyayı Görüntüle

@@ -12,34 +12,6 @@
12 12
     overflow: hidden;
13 13
 }
14 14
 
15
-#remoteVideos {
16
-    display: -webkit-box;
17
-    display: -moz-box;
18
-    display: -ms-flexbox;
19
-    display: -webkit-flex;
20
-    display: flex;
21
-    flex-direction: row-reverse;
22
-    flex-wrap: nowrap;
23
-    justify-content: flex-start;
24
-
25
-    position:absolute;
26
-    text-align:right;
27
-    height:196px;
28
-    padding: 10px 10px 17px 5px;
29
-    bottom: 0;
30
-    right: 0;
31
-    width:auto;
32
-    border: 2px solid transparent;
33
-    z-index: 5;
34
-    transition: bottom 2s;
35
-    overflow: visible !important;
36
-    font-size: 0pt; /*!!!Removes the gap between the local video container and the remote videos.*/
37
-}
38
-
39
-#remotevideos.hidden {
40
-    bottom: -196px;
41
-}
42
-
43 15
 .videocontainer {
44 16
     position: relative;
45 17
     text-align: center;
@@ -52,15 +24,6 @@
52 24
     }
53 25
 }
54 26
 
55
-#remoteVideos .videocontainer {
56
-    display: none;
57
-    position: relative;
58
-    background-size: contain;
59
-    border: 2px solid transparent;
60
-    border-radius:1px;
61
-    margin: 0 $thumbnailVideoMargin;
62
-}
63
-
64 27
 /**
65 28
  * The toolbar of the video thumbnail.
66 29
  */
@@ -96,60 +59,10 @@
96 59
     z-index: 2;
97 60
 }
98 61
 
99
-#remoteVideos .videocontainer.videoContainerFocused,
100
-#remoteVideos .videocontainer:hover {
101
-    cursor: hand;
102
-}
103
-/**
104
- * Focused video thumbnail.
105
- */
106
-#remoteVideos .videocontainer.videoContainerFocused {
107
-    transition-duration: 0.5s;
108
-    -webkit-transition-duration: 0.5s;
109
-    -webkit-animation-name: greyPulse;
110
-    -webkit-animation-duration: 2s;
111
-    -webkit-animation-iteration-count: 1;
112
-    border: 2px solid $videoThumbnailSelected !important;
113
-    box-shadow: inset 0 0 3px $videoThumbnailSelected,
114
-                0 0 3px $videoThumbnailSelected !important;
115
-}
116
-
117
-/**
118
- * Hovered video thumbnail.
119
- */
120
-#remoteVideos .videocontainer {
121
-    .remotevideomenu {
122
-        display: none;
123
-    }
124
-
125
-    /**
126
-     * Show/hide items for hover event here
127
-     */
128
-    &:hover {
129
-        cursor: hand;
130
-        border: 2px solid $videoThumbnailHovered;
131
-        box-shadow: inset 0 0 3px $videoThumbnailHovered,
132
-            0 0 3px $videoThumbnailHovered;
133
-        .remotevideomenu {
134
-            display: inline-block;
135
-        }
136
-    }
137
-}
138
-
139 62
 #localVideoWrapper {
140 63
     display:inline-block;
141 64
 }
142 65
 
143
-/* With TemasysWebRTC plugin <object/> element is used
144
-   instead of <video/> */
145
-#remoteVideos .videocontainer>video,
146
-#remoteVideos .videocontainer>object {
147
-    cursor: hand;
148
-    border-radius:1px;
149
-    object-fit: cover;
150
-    overflow: hidden;
151
-}
152
-
153 66
 .flipVideoX {
154 67
     transform: scale(-1, 1);
155 68
     -moz-transform: scale(-1, 1);
@@ -618,39 +531,4 @@
618 531
 
619 532
 .moveToCorner + .moveToCorner {
620 533
     right: 80px;
621
-}
622
-
623
-.filmstripToolbar {
624
-    width: 20px;
625
-    position: absolute;
626
-    right: 4px;
627
-    bottom: 20px;
628
-    z-index: 6;
629
-
630
-    button {
631
-        font-size: 14px;
632
-        line-height: 1.2;
633
-        text-align: center;
634
-        background: transparent;
635
-        opacity: 0.7;
636
-        height: auto;
637
-        width: 100%;
638
-        padding: 0;
639
-        margin: 0 1px;
640
-        border: none;
641
-
642
-        -webkit-appearance: none;
643
-
644
-        &:hover {
645
-            opacity: 1;
646
-        }
647
-
648
-        i {
649
-            cursor: pointer;
650
-        }
651
-    }
652
-}
653
-
654
-.filmstripToolbar + #remoteVideos {
655
-    padding-right: 24px;
656 534
 }

+ 1
- 0
css/main.scss Dosyayı Görüntüle

@@ -63,5 +63,6 @@
63 63
 @import 'aui-components/dropdown';
64 64
 @import '404';
65 65
 @import 'policy';
66
+@import 'filmstrip';
66 67
 
67 68
 /* Modules END */

+ 15
- 13
index.html Dosyayı Görüntüle

@@ -166,21 +166,23 @@
166 166
                     <img id="recordingSpinner" class="recordingSpinner" src="images/spin.svg"></img>
167 167
                 </span>
168 168
             </div>
169
-
170
-            <div id="remoteVideos">
171
-                <span id="localVideoContainer" class="videocontainer videocontainer_small">
172
-                    <div class="videocontainer__background"></div>
173
-                    <span id="localVideoWrapper">
174
-                        <!--<video id="localVideo" autoplay muted></video> - is now per stream generated -->
169
+            <div class="filmstrip">
170
+                <div class="filmstrip__videos" id="remoteVideos">
171
+                    <span id="localVideoContainer" class="videocontainer videocontainer_small">
172
+                        <div class="videocontainer__background"></div>
173
+                        <span id="localVideoWrapper">
174
+                            <!--<video id="localVideo" autoplay muted></video> - is now per stream generated -->
175
+                        </span>
176
+                        <audio id="localAudio" autoplay muted></audio>
177
+                        <div class="videocontainer__toolbar"></div>
178
+                        <div class="videocontainer__toptoolbar"></div>
179
+                        <div class="videocontainer__hoverOverlay"></div>
175 180
                     </span>
176
-                    <audio id="localAudio" autoplay muted></audio>
177
-                    <div class="videocontainer__toolbar"></div>
178
-                    <div class="videocontainer__toptoolbar"></div>
179
-                    <div class="videocontainer__hoverOverlay"></div>
180
-                </span>
181
-                <audio id="userJoined" src="sounds/joined.wav" preload="auto"></audio>
182
-                <audio id="userLeft" src="sounds/left.wav" preload="auto"></audio>
181
+                    <audio id="userJoined" src="sounds/joined.wav" preload="auto"></audio>
182
+                    <audio id="userLeft" src="sounds/left.wav" preload="auto"></audio>
183
+                </div>
183 184
             </div>
185
+
184 186
         </div>
185 187
     </div>
186 188
     <div id="keyboard-shortcuts" class="keyboard-shortcuts" style="display:none;">

+ 106
- 33
modules/UI/videolayout/FilmStrip.js Dosyayı Görüntüle

@@ -10,48 +10,72 @@ const FilmStrip = {
10 10
      * emit/fire {UIEvents} (such as {UIEvents.TOGGLED_FILM_STRIP}).
11 11
      */
12 12
     init (eventEmitter) {
13
+        this.iconMenuDownClassName = 'icon-menu-down';
14
+        this.iconMenuUpClassName = 'icon-menu-up';
13 15
         this.filmStrip = $('#remoteVideos');
14 16
         this.eventEmitter = eventEmitter;
15
-        this.filmStripIsVisible = true;
16
-        this.renderFilmstripToolbar();
17
-        this.activateHideButton();
17
+        this._initFilmStripToolbar();
18
+        this.registerListeners();
18 19
     },
19 20
 
20 21
     /**
21
-     * Attach 'click' listener to "hide filmstrip" button
22
+     * Initializes the filmstrip toolbar
22 23
      */
23
-    activateHideButton () {
24
-        $('#videospace').on('click', '#hideVideoToolbar', () => {
25
-            var icon = document.querySelector('#hideVideoToolbar i');
24
+    _initFilmStripToolbar() {
25
+        let toolbar = this._generateFilmStripToolbar();
26
+        let container = document.querySelector('.filmstrip');
26 27
 
27
-            this.filmStripIsVisible = !this.filmStripIsVisible;
28
-            this.toggleFilmStrip(this.filmStripIsVisible);
28
+        UIUtil.prependChild(container, toolbar);
29 29
 
30
-            icon.classList.remove(
31
-                this.filmStripIsVisible ? 'icon-menu-up' : 'icon-menu-down');
32
-            icon.classList.add(
33
-                this.filmStripIsVisible ? 'icon-menu-down' : 'icon-menu-up');
34
-        });
30
+        let iconSelector = '#hideVideoToolbar i';
31
+        this.toggleFilmStripIcon = document.querySelector(iconSelector);
35 32
     },
36 33
 
37 34
     /**
38
-     * Shows toolbar on the right of the filmstrip
35
+     * Generates HTML layout for filmstrip toolbar
36
+     * @returns {HTMLElement}
37
+     * @private
39 38
      */
40
-    renderFilmstripToolbar () {
41
-        // create toolbar
42
-        var container = document.createElement('div');
43
-        container.className = 'filmstripToolbar';
39
+    _generateFilmStripToolbar() {
40
+        let container = document.createElement('div');
41
+        let isVisible = this.isFilmStripVisible();
42
+        container.className = 'filmstrip__toolbar';
44 43
 
45 44
         container.innerHTML = `
46 45
             <button id="hideVideoToolbar">
47
-                <i class="icon-menu-${this.filmStripIsVisible ? 'down' : 'up'}">
46
+                <i class="icon-menu-${isVisible ? 'down' : 'up'}">
48 47
                 </i>
49 48
             </button>
50 49
         `;
51 50
 
52
-        // show toolbar
53
-        document.querySelector('#videospace')
54
-            .insertBefore(container, document.querySelector('#remoteVideos'));
51
+        return container;
52
+    },
53
+
54
+    /**
55
+     * Attach 'click' listener to "hide filmstrip" button
56
+     */
57
+    registerListeners() {
58
+        let toggleFilmstripMethod = this.toggleFilmStrip.bind(this);
59
+        let selector = '#hideVideoToolbar';
60
+        $('#videospace').on('click', selector, toggleFilmstripMethod);
61
+    },
62
+
63
+    /**
64
+     * Changes classes of icon for showing down state
65
+     */
66
+    showMenuDownIcon() {
67
+        let icon = this.toggleFilmStripIcon;
68
+        icon.classList.add(this.iconMenuDownClassName);
69
+        icon.classList.remove(this.iconMenuUpClassName);
70
+    },
71
+
72
+    /**
73
+     * Changes classes of icon for showing up state
74
+     */
75
+    showMenuUpIcon() {
76
+        let icon = this.toggleFilmStripIcon;
77
+        icon.classList.add(this.iconMenuUpClassName);
78
+        icon.classList.remove(this.iconMenuDownClassName);
55 79
     },
56 80
 
57 81
     /**
@@ -62,14 +86,22 @@ const FilmStrip = {
62 86
      * (i.e. toggled); otherwise, the visibility will be set to the specified
63 87
      * value.
64 88
      */
65
-    toggleFilmStrip (visible) {
66
-        if (typeof visible === 'boolean'
67
-            && this.isFilmStripVisible() == visible) {
89
+    toggleFilmStrip(visible) {
90
+        let isVisibleDefined = typeof visible === 'boolean';
91
+        if (!isVisibleDefined) {
92
+            visible = this.isFilmStripVisible();
93
+        } else if (this.isFilmStripVisible() === visible) {
68 94
             return;
69 95
         }
70 96
 
71 97
         this.filmStrip.toggleClass("hidden");
72 98
 
99
+        if (!visible) {
100
+            this.showMenuDownIcon();
101
+        } else {
102
+            this.showMenuUpIcon();
103
+        }
104
+
73 105
         // Emit/fire UIEvents.TOGGLED_FILM_STRIP.
74 106
         var eventEmitter = this.eventEmitter;
75 107
         if (eventEmitter) {
@@ -79,18 +111,26 @@ const FilmStrip = {
79 111
         }
80 112
     },
81 113
 
82
-    isFilmStripVisible () {
114
+    /**
115
+     * Shows if filmstrip is visible
116
+     * @returns {boolean}
117
+     */
118
+    isFilmStripVisible() {
83 119
         return !this.filmStrip.hasClass('hidden');
84 120
     },
85 121
 
86
-    setupFilmStripOnly () {
122
+    setupFilmStripOnly() {
87 123
         this.filmStrip.css({
88 124
             padding: "0px 0px 18px 0px",
89 125
             right: 0
90 126
         });
91 127
     },
92 128
 
93
-    getFilmStripHeight () {
129
+    /**
130
+     * Returns the height of filmstrip
131
+     * @returns {number} height
132
+     */
133
+    getFilmStripHeight() {
94 134
         if (this.isFilmStripVisible()) {
95 135
             return this.filmStrip.outerHeight();
96 136
         } else {
@@ -98,12 +138,20 @@ const FilmStrip = {
98 138
         }
99 139
     },
100 140
 
101
-    getFilmStripWidth () {
141
+    /**
142
+     * Returns the width of filmstip
143
+     * @returns {number} width
144
+     */
145
+    getFilmStripWidth() {
102 146
         return this.filmStrip.innerWidth()
103 147
             - parseInt(this.filmStrip.css('paddingLeft'), 10)
104 148
             - parseInt(this.filmStrip.css('paddingRight'), 10);
105 149
     },
106 150
 
151
+    /**
152
+     * Calculates the size for thumbnails: local and remote one
153
+     * @returns {*|{localVideo, remoteVideo}}
154
+     */
107 155
     calculateThumbnailSize() {
108 156
         let availableSizes = this.calculateAvailableSize();
109 157
         let width = availableSizes.availableWidth;
@@ -115,7 +163,7 @@ const FilmStrip = {
115 163
     /**
116 164
      * Normalizes local and remote thumbnail ratios
117 165
      */
118
-    normalizeThumbnailRatio () {
166
+    normalizeThumbnailRatio() {
119 167
         let remoteHeightRatio = interfaceConfig.REMOTE_THUMBNAIL_RATIO_HEIGHT;
120 168
         let remoteWidthRatio = interfaceConfig.REMOTE_THUMBNAIL_RATIO_WIDTH;
121 169
 
@@ -146,6 +194,11 @@ const FilmStrip = {
146 194
         return { localRatio, remoteRatio };
147 195
     },
148 196
 
197
+    /**
198
+     * Calculates available size for one thumbnail according to
199
+     * the current window size
200
+     * @returns {{availableWidth: number, availableHeight: number}}
201
+     */
149 202
     calculateAvailableSize() {
150 203
         let availableHeight = interfaceConfig.FILM_STRIP_MAX_HEIGHT;
151 204
         let thumbs = this.getThumbs(true);
@@ -221,6 +274,13 @@ const FilmStrip = {
221 274
         return { availableWidth, availableHeight };
222 275
     },
223 276
 
277
+    /**
278
+     * Takes the available size for thumbnail and calculates
279
+     * final size of thumbnails
280
+     * @param availableWidth
281
+     * @param availableHeight
282
+     * @returns {{localVideo, remoteVideo}}
283
+     */
224 284
     calculateThumbnailSizeFromAvailable(availableWidth, availableHeight) {
225 285
         let { localRatio, remoteRatio } = this.normalizeThumbnailRatio();
226 286
         let { remoteThumbs } = this.getThumbs(true);
@@ -251,7 +311,15 @@ const FilmStrip = {
251 311
         };
252 312
     },
253 313
 
254
-    resizeThumbnails (local, remote,
314
+    /**
315
+     * Resizes thumbnails
316
+     * @param local
317
+     * @param remote
318
+     * @param animate
319
+     * @param forceUpdate
320
+     * @returns {Promise}
321
+     */
322
+    resizeThumbnails(local, remote,
255 323
                       animate = false, forceUpdate = false) {
256 324
 
257 325
         return new Promise(resolve => {
@@ -289,7 +357,12 @@ const FilmStrip = {
289 357
         });
290 358
     },
291 359
 
292
-    getThumbs (only_visible = false) {
360
+    /**
361
+     * Returns thumbnails of the filmstrip
362
+     * @param only_visible
363
+     * @returns {object} thumbnails
364
+     */
365
+    getThumbs(only_visible = false) {
293 366
         let selector = 'span';
294 367
         if (only_visible) {
295 368
             selector += ':visible';

Loading…
İptal
Kaydet