feat(filmstrip) Updated filmstrip design (#10791)
Added background on hover Updated toggle button Made vertical filmstrip full height on desktop
This commit is contained in:
parent
7e9e5e258f
commit
820ff8473c
|
@ -30,7 +30,7 @@
|
||||||
transition: bottom .3s ease-in;
|
transition: bottom .3s ease-in;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
z-index: $toolbarZ + 2;
|
||||||
|
|
||||||
&.visible {
|
&.visible {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
.filmstrip__toolbar {
|
|
||||||
@include flex();
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
position: relative;
|
|
||||||
width: $filmstripToggleButtonWidth;
|
|
||||||
|
|
||||||
button {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.2;
|
|
||||||
text-align: center;
|
|
||||||
background: transparent;
|
|
||||||
opacity: 0.7;
|
|
||||||
height: auto;
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
border: none;
|
|
||||||
|
|
||||||
-webkit-appearance: none;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,11 +6,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.horizontal-filmstrip .filmstrip {
|
.horizontal-filmstrip .filmstrip {
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 10px 5px;
|
padding: 10px 5px;
|
||||||
@extend %align-right;
|
@extend %align-right;
|
||||||
transition: bottom .3s;
|
|
||||||
z-index: $filmstripVideosZ;
|
z-index: $filmstripVideosZ;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -58,7 +55,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.hidden {
|
&.hidden {
|
||||||
bottom: calc(-196px - #{$newToolbarSizeWithPadding});
|
bottom: calc(-196px - #{$newToolbarSizeWithPadding} + 50px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
#dominantSpeaker,
|
#dominantSpeaker,
|
||||||
#filmstripLocalVideoThumbnail,
|
#filmstripLocalVideoThumbnail,
|
||||||
#largeVideoElementsContainer,
|
#largeVideoElementsContainer,
|
||||||
#sharedVideo,
|
#sharedVideo {
|
||||||
.filmstrip__toolbar {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
*/
|
*/
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
transition: height .3s ease-in;
|
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: $filmstripVideosZ;
|
z-index: $filmstripVideosZ;
|
||||||
|
|
||||||
|
@ -52,11 +51,6 @@
|
||||||
right: 0;
|
right: 0;
|
||||||
width: auto;
|
width: auto;
|
||||||
|
|
||||||
&.hidden {
|
|
||||||
bottom: auto;
|
|
||||||
right: -196px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An id selector is used to match id specificity with existing
|
* An id selector is used to match id specificity with existing
|
||||||
* filmstrip styles.
|
* filmstrip styles.
|
||||||
|
@ -64,7 +58,6 @@
|
||||||
&#remoteVideos {
|
&#remoteVideos {
|
||||||
border: $thumbnailsBorder solid transparent;
|
border: $thumbnailsBorder solid transparent;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
transition: right 2s;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,3 @@
|
||||||
/**
|
|
||||||
* Rotate the hide filmstrip icon so it points towards the right edge
|
|
||||||
* of the screen.
|
|
||||||
*/
|
|
||||||
.vertical-filmstrip .filmstrip__toolbar {
|
|
||||||
transform: rotate(-90deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides for video containers that should not be centered aligned to avoid=
|
* Overrides for video containers that should not be centered aligned to avoid=
|
||||||
* clashing with the filmstrip.
|
* clashing with the filmstrip.
|
||||||
|
|
|
@ -69,7 +69,6 @@ $flagsImagePath: "../images/";
|
||||||
@import '404';
|
@import '404';
|
||||||
@import 'policy';
|
@import 'policy';
|
||||||
@import 'popover';
|
@import 'popover';
|
||||||
@import 'filmstrip/filmstrip_toolbar';
|
|
||||||
@import 'filmstrip/horizontal_filmstrip';
|
@import 'filmstrip/horizontal_filmstrip';
|
||||||
@import 'filmstrip/small_video';
|
@import 'filmstrip/small_video';
|
||||||
@import 'filmstrip/tile_view';
|
@import 'filmstrip/tile_view';
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
|
import { withStyles } from '@material-ui/styles';
|
||||||
|
import clsx from 'clsx';
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { FixedSizeList, FixedSizeGrid } from 'react-window';
|
import { FixedSizeList, FixedSizeGrid } from 'react-window';
|
||||||
import type { Dispatch } from 'redux';
|
import type { Dispatch } from 'redux';
|
||||||
|
@ -80,6 +82,11 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
_isFilmstripButtonEnabled: boolean,
|
_isFilmstripButtonEnabled: boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the current layout is vertical filmstrip.
|
||||||
|
*/
|
||||||
|
_isVerticalFilmstrip: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The participants in the call.
|
* The participants in the call.
|
||||||
*/
|
*/
|
||||||
|
@ -125,6 +132,11 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
_isToolboxVisible: Boolean,
|
_isToolboxVisible: Boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object containing the CSS classes.
|
||||||
|
*/
|
||||||
|
classes: Object,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The redux {@code dispatch} function.
|
* The redux {@code dispatch} function.
|
||||||
*/
|
*/
|
||||||
|
@ -136,6 +148,84 @@ type Props = {
|
||||||
t: Function
|
t: Function
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the styles for the component.
|
||||||
|
*
|
||||||
|
* @param {Object} theme - The current theme.
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
const styles = theme => {
|
||||||
|
return {
|
||||||
|
toggleFilmstripContainer: {
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'nowrap',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, .6)',
|
||||||
|
width: '32px',
|
||||||
|
height: '24px',
|
||||||
|
position: 'absolute',
|
||||||
|
borderRadius: '4px',
|
||||||
|
top: 'calc(-24px - 2px)',
|
||||||
|
left: 'calc(50% - 16px)',
|
||||||
|
opacity: 0,
|
||||||
|
transition: 'opacity .3s'
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleFilmstripButton: {
|
||||||
|
fontSize: '14px',
|
||||||
|
lineHeight: 1.2,
|
||||||
|
textAlign: 'center',
|
||||||
|
background: 'transparent',
|
||||||
|
height: 'auto',
|
||||||
|
width: '100%',
|
||||||
|
padding: 0,
|
||||||
|
margin: 0,
|
||||||
|
border: 'none',
|
||||||
|
|
||||||
|
'-webkit-appearance': 'none',
|
||||||
|
|
||||||
|
'& svg': {
|
||||||
|
fill: theme.palette.icon02
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleVerticalFilmstripContainer: {
|
||||||
|
transform: 'rotate(-90deg)',
|
||||||
|
left: 'calc(-24px - 2px - 5px)',
|
||||||
|
top: 'calc(50% - 16px)'
|
||||||
|
},
|
||||||
|
|
||||||
|
filmstrip: {
|
||||||
|
transition: 'background .2s ease-in-out, right 1s, bottom 1s, height .3s ease-in',
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, .6)',
|
||||||
|
|
||||||
|
'& .toggleFilmstripContainer': {
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'.horizontal-filmstrip &.hidden': {
|
||||||
|
bottom: '-50px',
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: 'transparent'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'&.hidden': {
|
||||||
|
'& .toggleFilmstripContainer': {
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements a React {@link Component} which represents the filmstrip on
|
* Implements a React {@link Component} which represents the filmstrip on
|
||||||
* Web/React.
|
* Web/React.
|
||||||
|
@ -195,7 +285,7 @@ class Filmstrip extends PureComponent <Props> {
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const filmstripStyle = { };
|
const filmstripStyle = { };
|
||||||
const { _currentLayout, _disableSelfView } = this.props;
|
const { _currentLayout, _disableSelfView, classes, _visible } = this.props;
|
||||||
const tileViewActive = _currentLayout === LAYOUTS.TILE_VIEW;
|
const tileViewActive = _currentLayout === LAYOUTS.TILE_VIEW;
|
||||||
|
|
||||||
switch (_currentLayout) {
|
switch (_currentLayout) {
|
||||||
|
@ -203,18 +293,24 @@ class Filmstrip extends PureComponent <Props> {
|
||||||
// Adding 18px for the 2px margins, 2px borders on the left and right and 5px padding on the left and right.
|
// Adding 18px for the 2px margins, 2px borders on the left and right and 5px padding on the left and right.
|
||||||
// Also adding 7px for the scrollbar.
|
// Also adding 7px for the scrollbar.
|
||||||
filmstripStyle.maxWidth = (interfaceConfig.FILM_STRIP_MAX_HEIGHT || 120) + 25;
|
filmstripStyle.maxWidth = (interfaceConfig.FILM_STRIP_MAX_HEIGHT || 120) + 25;
|
||||||
|
|
||||||
|
if (!_visible) {
|
||||||
|
filmstripStyle.right = `-${filmstripStyle.maxWidth + 2}px`;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let toolbar = null;
|
let toolbar = null;
|
||||||
|
|
||||||
if (!this.props._iAmRecorder && this.props._isFilmstripButtonEnabled) {
|
if (!this.props._iAmRecorder && this.props._isFilmstripButtonEnabled && _currentLayout !== LAYOUTS.TILE_VIEW) {
|
||||||
toolbar = this._renderToggleButton();
|
toolbar = this._renderToggleButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className = { `filmstrip ${this.props._className}` }
|
className = { clsx('filmstrip',
|
||||||
|
this.props._className,
|
||||||
|
classes.filmstrip) }
|
||||||
style = { filmstripStyle }>
|
style = { filmstripStyle }>
|
||||||
{ toolbar }
|
{ toolbar }
|
||||||
<div
|
<div
|
||||||
|
@ -534,17 +630,20 @@ class Filmstrip extends PureComponent <Props> {
|
||||||
*/
|
*/
|
||||||
_renderToggleButton() {
|
_renderToggleButton() {
|
||||||
const icon = this.props._visible ? IconMenuDown : IconMenuUp;
|
const icon = this.props._visible ? IconMenuDown : IconMenuUp;
|
||||||
const { t } = this.props;
|
const { t, classes, _isVerticalFilmstrip } = this.props;
|
||||||
const actions = isMobileBrowser()
|
const actions = isMobileBrowser()
|
||||||
? { onTouchStart: this._onToggleButtonTouch }
|
? { onTouchStart: this._onToggleButtonTouch }
|
||||||
: { onClick: this._onToolbarToggleFilmstrip };
|
: { onClick: this._onToolbarToggleFilmstrip };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className = 'filmstrip__toolbar'>
|
className = { clsx(classes.toggleFilmstripContainer,
|
||||||
|
_isVerticalFilmstrip && classes.toggleVerticalFilmstripContainer,
|
||||||
|
'toggleFilmstripContainer') }>
|
||||||
<button
|
<button
|
||||||
aria-expanded = { this.props._visible }
|
aria-expanded = { this.props._visible }
|
||||||
aria-label = { t('toolbar.accessibilityLabel.toggleFilmstrip') }
|
aria-label = { t('toolbar.accessibilityLabel.toggleFilmstrip') }
|
||||||
|
className = { classes.toggleFilmstripButton }
|
||||||
id = 'toggleFilmstripButton'
|
id = 'toggleFilmstripButton'
|
||||||
onFocus = { this._onTabIn }
|
onFocus = { this._onTabIn }
|
||||||
tabIndex = { 0 }
|
tabIndex = { 0 }
|
||||||
|
@ -600,10 +699,13 @@ function _mapStateToProps(state) {
|
||||||
&& isMobileBrowser()
|
&& isMobileBrowser()
|
||||||
&& clientWidth <= ASPECT_RATIO_BREAKPOINT;
|
&& clientWidth <= ASPECT_RATIO_BREAKPOINT;
|
||||||
|
|
||||||
const className = `${remoteVideosVisible ? '' : 'hide-videos'} ${
|
const shouldReduceHeight = reduceHeight && (
|
||||||
reduceHeight ? 'reduce-height' : ''
|
isMobileBrowser() || _currentLayout !== LAYOUTS.VERTICAL_FILMSTRIP_VIEW);
|
||||||
} ${shiftRight ? 'shift-right' : ''} ${collapseTileView ? 'collapse' : ''}`.trim();
|
|
||||||
const videosClassName = `filmstrip__videos${visible ? '' : ' hidden'}`;
|
const videosClassName = `filmstrip__videos${visible ? '' : ' hidden'}`;
|
||||||
|
const className = `${remoteVideosVisible ? '' : 'hide-videos'} ${
|
||||||
|
shouldReduceHeight ? 'reduce-height' : ''
|
||||||
|
} ${shiftRight ? 'shift-right' : ''} ${collapseTileView ? 'collapse' : ''} ${visible ? '' : 'hidden'}`.trim();
|
||||||
let _thumbnailSize, remoteFilmstripHeight, remoteFilmstripWidth;
|
let _thumbnailSize, remoteFilmstripHeight, remoteFilmstripWidth;
|
||||||
|
|
||||||
switch (_currentLayout) {
|
switch (_currentLayout) {
|
||||||
|
@ -616,7 +718,7 @@ function _mapStateToProps(state) {
|
||||||
const { remote, remoteVideosContainer } = state['features/filmstrip'].verticalViewDimensions;
|
const { remote, remoteVideosContainer } = state['features/filmstrip'].verticalViewDimensions;
|
||||||
|
|
||||||
_thumbnailSize = remote;
|
_thumbnailSize = remote;
|
||||||
remoteFilmstripHeight = remoteVideosContainer?.height - (reduceHeight ? TOOLBAR_HEIGHT : 0);
|
remoteFilmstripHeight = remoteVideosContainer?.height - (shouldReduceHeight ? TOOLBAR_HEIGHT : 0);
|
||||||
remoteFilmstripWidth = remoteVideosContainer?.width;
|
remoteFilmstripWidth = remoteVideosContainer?.width;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -647,8 +749,9 @@ function _mapStateToProps(state) {
|
||||||
_thumbnailsReordered: enableThumbnailReordering,
|
_thumbnailsReordered: enableThumbnailReordering,
|
||||||
_videosClassName: videosClassName,
|
_videosClassName: videosClassName,
|
||||||
_visible: visible,
|
_visible: visible,
|
||||||
_isToolboxVisible: isToolboxVisible(state)
|
_isToolboxVisible: isToolboxVisible(state),
|
||||||
|
_isVerticalFilmstrip: _currentLayout === LAYOUTS.VERTICAL_FILMSTRIP_VIEW
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect(_mapStateToProps)(Filmstrip));
|
export default withStyles(styles)(translate(connect(_mapStateToProps)(Filmstrip)));
|
||||||
|
|
Loading…
Reference in New Issue