refactor(virtual-background): use jss instead of sass (#11152)

This commit is contained in:
Shahab 2022-03-29 13:37:55 +04:30 committed by GitHub
parent 3eafaeeedd
commit 70efa31c16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 246 additions and 230 deletions

View File

@ -40,7 +40,6 @@ $flagsImagePath: "../images/";
@import 'modals/invite/info';
@import 'modals/screen-share/share-audio';
@import 'modals/screen-share/share-screen-warning';
@import 'modals/virtual-background/virtual-background';
@import 'modals/local-recording/local-recording';
@import 'videolayout_default';
@import 'notice';

View File

@ -1,207 +0,0 @@
.virtual-background-dialog {
margin-left: -10px;
position: relative;
max-height: 300px;
color: white;
display: inline-grid;
grid-template-columns: auto auto auto auto auto;
column-gap: 9px;
cursor: pointer;
.desktop-share:hover,
.thumbnail:hover,
.blur:hover,
.slight-blur:hover,
.virtual-background-none:hover {
opacity: 0.5;
border: 2px solid #99bbf3;
@media (max-width: 632px) {
height: 60px;
width: 60px;
}
}
.background-option {
margin-top: 8px;
border-radius: 6px;
height: 60px;
width: 107px;
text-align: center;
justify-content: center;
font-weight: bold;
box-sizing: border-box;
display: flex;
align-items: center;
}
.thumbnail {
object-fit: cover;
}
.thumbnail:hover ~ .delete-image-icon {
display: block;
}
.thumbnail-selected {
object-fit: cover;
border: 2px solid #246fe5;
}
.blur {
box-shadow: inset 0 0 12px #000000;
background: #7e8287;
padding: 0 10px;
}
.blur-selected {
box-shadow: inset 0 0 12px #000000;
background: #7e8287;
border: 2px solid #246fe5;
padding: 0 10px;
}
.slight-blur {
box-shadow: inset 0 0 12px #000000;
background: #a4a4a4;
padding: 0 10px;
}
.slight-blur-selected {
box-shadow: inset 0 0 12px #000000;
background: #a4a4a4;
border: 2px solid #246fe5;
padding: 0 10px;
}
.virtual-background-none {
background: #525252;
padding: 0 10px;
}
.none-selected {
background: #525252;
border: 2px solid #246fe5;
padding: 0 10px;
}
.desktop-share {
background: #525252;
}
.desktop-share-selected {
background: #525252;
border: 2px solid #246fe5;
padding: 0 10px;
}
@media (max-width: 632px) {
font-size: 1.5vw;
.desktop-share,
.virtual-background-none,
.thumbnail,
.blur,
.slight-blur {
height: 60px;
width: 60px;
}
.desktop-share-selected,
.thumbnail-selected,
.none-selected,
.blur-selected,
.slight-blur-selected {
height: 60px;
width: 60px;
}
}
@media (max-width: 360px) {
grid-template-columns: auto auto auto;
}
}
.modal-dialog-form .virtual-background-loading {
overflow: hidden;
position: fixed;
left: 50%;
margin-top: 10px;
transform: translateX(-50%);
}
.modal-dialog-form .video-preview {
height: 250px;
}
.file-upload-btn {
display: none;
}
.file-upload-label {
font-size: 14px;
font-weight: 600;
line-height: 20px;
margin-left: -10px;
margin-top: 16px;
margin-bottom: 8px;
color: #669aec;
display: inline-flex;
cursor: pointer;
}
.delete-image-icon {
background: #3d3d3d;
position: absolute;
display: none;
left: 96;
bottom: 51;
@media (max-width: 632px) {
left: 51px;
}
}
.delete-image-icon:hover {
display: block;
}
.thumbnail-container {
position: relative;
&:focus-within {
.thumbnail ~ .delete-image-icon {
display: block;
}
}
}
.add-background {
margin-right: 8px;
}
.apply-background-btn {
margin-top: 16px;
float: right;
}
.video-background-preview-entry {
margin-left: -10px;
height: 250px;
width: 570px;
margin-bottom: 8px;
z-index: 2;
@media (max-width: 632px) {
max-width: 336;
}
}
.virtual-background-preview-video {
margin-left: -10;
border-radius: 6px;
height: 100%;
object-fit: cover;
width: 100%;
}
.video-preview-loader {
border-radius: 6px;
background-color: transparent;
height: 250px;
margin-bottom: 8px;
width: 572px;
position: fixed;
z-index: 2;
@media (min-width: 432px) and (max-width: 632px) {
width: 340px;
}
}
.video-preview-loader svg {
position: absolute;
top: 40%;
left: 45%;
}
.dialog-margin-top{
margin-top: 44px;
}

View File

@ -1,5 +1,6 @@
// @flow
import { makeStyles } from '@material-ui/styles';
import React, { useCallback, useRef } from 'react';
import { v4 as uuidv4 } from 'uuid';
@ -42,6 +43,28 @@ type Props = {
t: Function
}
const useStyles = makeStyles(theme => {
return {
addBackground: {
marginRight: `${theme.spacing(2)}px`
},
button: {
display: 'none'
},
label: {
fontSize: '14px',
fontWeight: '600',
lineHeight: '20px',
marginLeft: '-10px',
marginTop: `${theme.spacing(3)}px`,
marginBottom: `${theme.spacing(2)}px`,
color: '#669aec',
display: 'inline-flex',
cursor: 'pointer'
}
};
});
/**
* Component used to upload an image.
*
@ -56,6 +79,7 @@ function UploadImageButton({
storedImages,
t
}: Props) {
const classes = useStyles();
const uploadImageButton: Object = useRef(null);
const uploadImageKeyPress = useCallback(e => {
if (uploadImageButton.current && (e.key === ' ' || e.key === 'Enter')) {
@ -100,12 +124,12 @@ function UploadImageButton({
<>
{showLabel && <label
aria-label = { t('virtualBackground.uploadImage') }
className = 'file-upload-label'
className = { classes.label }
htmlFor = 'file-upload'
onKeyPress = { uploadImageKeyPress }
tabIndex = { 0 } >
<Icon
className = { 'add-background' }
className = { classes.addBackground }
size = { 20 }
src = { IconPlusCircle } />
{t('virtualBackground.addBackground')}
@ -113,7 +137,7 @@ function UploadImageButton({
<input
accept = 'image/*'
className = 'file-upload-btn'
className = { classes.button }
id = 'file-upload'
onChange = { uploadImage }
ref = { uploadImageButton }

View File

@ -3,6 +3,8 @@
import Spinner from '@atlaskit/spinner';
import Bourne from '@hapi/bourne';
import { jitsiLocalStorage } from '@jitsi/js-utils/jitsi-local-storage';
import { makeStyles } from '@material-ui/styles';
import clsx from 'clsx';
import React, { useState, useEffect, useCallback } from 'react';
import { useSelector } from 'react-redux';
@ -106,6 +108,142 @@ function _mapStateToProps(state): Object {
const VirtualBackgroundDialog = translate(connect(_mapStateToProps)(VirtualBackground));
const useStyles = makeStyles(theme => {
return {
dialog: {
marginLeft: '-10px',
position: 'relative',
maxHeight: '300px',
color: 'white',
display: 'inline-grid',
gridTemplateColumns: 'auto auto auto auto auto',
columnGap: '9px',
cursor: 'pointer',
[[ '& .desktop-share:hover',
'& .thumbnail:hover',
'& .blur:hover',
'& .slight-blur:hover',
'& .virtual-background-none:hover' ]]: {
opacity: 0.5,
border: '2px solid #99bbf3'
},
'& .background-option': {
marginTop: `${theme.spacing(2)}px`,
borderRadius: `${theme.shape.borderRadius}px`,
height: '60px',
width: '107px',
textAlign: 'center',
justifyContent: 'center',
fontWeight: 'bold',
boxSizing: 'border-box',
display: 'flex',
alignItems: 'center'
},
'& thumbnail-container': {
position: 'relative',
'&:focus-within .thumbnail ~ .delete-image-icon': {
display: 'block'
}
},
'& .thumbnail': {
objectFit: 'cover'
},
'& .thumbnail:hover ~ .delete-image-icon': {
display: 'block'
},
'& .thumbnail-selected': {
objectFit: 'cover',
border: '2px solid #246fe5'
},
'& .blur': {
boxShadow: 'inset 0 0 12px #000000',
background: '#7e8287',
padding: '0 10px'
},
'& .blur-selected': {
border: '2px solid #246fe5'
},
'& .slight-blur': {
boxShadow: 'inset 0 0 12px #000000',
background: '#a4a4a4',
padding: '0 10px'
},
'& .slight-blur-selected': {
border: '2px solid #246fe5'
},
'& .virtual-background-none': {
background: '#525252',
padding: '0 10px'
},
'& .none-selected': {
border: '2px solid #246fe5'
},
'& .desktop-share': {
background: '#525252'
},
'& .desktop-share-selected': {
border: '2px solid #246fe5',
padding: '0 10px'
},
'& delete-image-icon': {
background: '#3d3d3d',
position: 'absolute',
display: 'none',
left: '96px',
bottom: '51px',
'&:hover': {
display: 'block'
},
'@media (max-width: 632px)': {
left: '51px'
}
},
'@media (max-width: 360px)': {
gridTemplateColumns: 'auto auto auto'
},
'@media (max-width: 632px)': {
fontSize: '1.5vw',
[[ '& .desktop-share:hover',
'& .thumbnail:hover',
'& .blur:hover',
'& .slight-blur:hover',
'& .virtual-background-none:hover' ]]: {
height: '60px',
width: '60px'
},
[[ '& .desktop-share',
'& .virtual-background-none,',
'& .thumbnail,',
'& .blur,',
'& .slight-blur' ]]: {
height: '60px',
width: '60px'
},
[[ '& .desktop-share-selected',
'& .thumbnail-selected',
'& .none-selected',
'& .blur-selected',
'& .slight-blur-selected' ]]: {
height: '60px',
width: '60px'
}
}
},
dialogMarginTop: {
marginTop: '44px'
},
virtualBackgroundLoading: {
overflow: 'hidden',
position: 'fixed',
left: '50%',
marginTop: '10px',
transform: 'translateX(-50%)'
}
};
});
/**
* Renders virtual background dialog.
*
@ -122,6 +260,7 @@ function VirtualBackground({
initialOptions,
t
}: Props) {
const classes = useStyles();
const [ previewIsLoaded, setPreviewIsLoaded ] = useState(false);
const [ options, setOptions ] = useState({ ...initialOptions });
const localImages = jitsiLocalStorage.getItem('virtualBackgrounds');
@ -382,7 +521,7 @@ function VirtualBackground({
loadedPreview = { loadedPreviewState }
options = { options } />
{loading ? (
<div className = 'virtual-background-loading'>
<div className = { classes.virtualBackgroundLoading }>
<Spinner
isCompleting = { false }
size = 'medium' />
@ -397,7 +536,7 @@ function VirtualBackground({
showLabel = { previewIsLoaded }
storedImages = { storedImages } />}
<div
className = { `virtual-background-dialog${previewIsLoaded ? '' : ' dialog-margin-top'}` }
className = { clsx(classes.dialog, { [classes.dialogMarginTop]: previewIsLoaded }) }
role = 'radiogroup'
tabIndex = '-1'>
<Tooltip
@ -406,8 +545,9 @@ function VirtualBackground({
<div
aria-checked = { _selectedThumbnail === 'none' }
aria-label = { t('virtualBackground.removeBackground') }
className = { _selectedThumbnail === 'none' ? 'background-option none-selected'
: 'background-option virtual-background-none' }
className = { clsx('background-option', 'virtual-background-none', {
'none-selected': _selectedThumbnail === 'none'
}) }
onClick = { removeBackground }
onKeyPress = { removeBackgroundKeyPress }
role = 'radio'
@ -421,8 +561,9 @@ function VirtualBackground({
<div
aria-checked = { _selectedThumbnail === 'slight-blur' }
aria-label = { t('virtualBackground.slightBlur') }
className = { _selectedThumbnail === 'slight-blur'
? 'background-option slight-blur-selected' : 'background-option slight-blur' }
className = { clsx('background-option', 'slight-blur', {
'slight-blur-selected': _selectedThumbnail === 'slight-blur'
}) }
onClick = { enableSlideBlur }
onKeyPress = { enableSlideBlurKeyPress }
role = 'radio'
@ -436,8 +577,9 @@ function VirtualBackground({
<div
aria-checked = { _selectedThumbnail === 'blur' }
aria-label = { t('virtualBackground.blur') }
className = { _selectedThumbnail === 'blur' ? 'background-option blur-selected'
: 'background-option blur' }
className = { clsx('background-option', 'blur', {
'blur-selected': _selectedThumbnail === 'blur'
}) }
onClick = { enableBlur }
onKeyPress = { enableBlurKeyPress }
role = 'radio'
@ -452,9 +594,9 @@ function VirtualBackground({
<div
aria-checked = { _selectedThumbnail === 'desktop-share' }
aria-label = { t('virtualBackground.desktopShare') }
className = { _selectedThumbnail === 'desktop-share'
? 'background-option desktop-share-selected'
: 'background-option desktop-share' }
className = { clsx('background-option', 'desktop-share', {
'desktop-share-selected': _selectedThumbnail === 'desktop-share'
}) }
onClick = { shareDesktop }
onKeyPress = { shareDesktopKeyPress }
role = 'radio'
@ -494,8 +636,10 @@ function VirtualBackground({
<img
alt = { t('virtualBackground.uploadedImage', { index: index + 1 }) }
aria-checked = { _selectedThumbnail === image.id }
className = { _selectedThumbnail === image.id
? 'background-option thumbnail-selected' : 'background-option thumbnail' }
className = { clsx('background-option', {
'thumbnail-selected': _selectedThumbnail === image.id,
'thumbnail': _selectedThumbnail !== image.id
}) }
data-imageid = { image.id }
onClick = { setUploadedImageBackground }
onError = { onError }

View File

@ -1,6 +1,7 @@
// @flow
import Spinner from '@atlaskit/spinner';
import { withStyles } from '@material-ui/core/styles';
import React, { PureComponent } from 'react';
import { hideDialog } from '../../base/dialog';
@ -29,6 +30,11 @@ export type Props = {
*/
_currentCameraDeviceId: string,
/**
* An object containing the CSS classes.
*/
classes: Object,
/**
* The redux {@code dispatch} function.
*/
@ -71,6 +77,55 @@ type State = {
jitsiTrack: Object
};
/**
* Creates the styles for the component.
*
* @param {Object} theme - The current UI theme.
*
* @returns {Object}
*/
const styles = theme => {
return {
virtualBackgroundPreview: {
'& .video-preview': {
height: '250px'
},
'& .video-background-preview-entry': {
marginLeft: '-10px',
height: '250px',
width: '570px',
marginBottom: `${theme.spacing(2)}px`,
zIndex: 2,
'@media (max-width: 632px)': {
maxWidth: '336px'
}
},
'& .video-preview-loader': {
borderRadius: '6px',
backgroundColor: 'transparent',
height: '250px',
marginBottom: `${theme.spacing(2)}px`,
width: '572px',
position: 'fixed',
zIndex: 2,
'& svg': {
position: 'absolute',
top: '40%',
left: '45%'
},
'@media (min-width: 432px) and (max-width: 632px)': {
width: '340px'
}
}
}
};
};
/**
* Implements a React {@link PureComponent} which displays the virtual
* background preview.
@ -264,12 +319,13 @@ class VirtualBackgroundPreview extends PureComponent<Props, State> {
* @inheritdoc
*/
render() {
const { jitsiTrack } = this.state;
const { classes, jitsiTrack } = this.state;
return jitsiTrack
? <div className = 'video-preview'>{this._renderPreviewEntry(jitsiTrack)}</div>
: <div className = 'video-preview-loader'>{this._loadVideoPreview()}</div>
;
return (<div className = { classes.virtualBackgroundPreview }>
{jitsiTrack
? <div className = 'video-preview'>{this._renderPreviewEntry(jitsiTrack)}</div>
: <div className = 'video-preview-loader'>{this._loadVideoPreview()}</div>
}</div>);
}
}
@ -287,4 +343,4 @@ function _mapStateToProps(state): Object {
};
}
export default translate(connect(_mapStateToProps)(VirtualBackgroundPreview));
export default translate(connect(_mapStateToProps)(withStyles(styles)(VirtualBackgroundPreview)));