Merge pull request #20495 from germanocaumo/new-video-preview-design
feat(video-preview): new modal design
This commit is contained in:
commit
6581ed1f11
@ -21,6 +21,7 @@ import {
|
||||
} from '/imports/ui/services/virtual-background/service';
|
||||
import { getSettingsSingletonInstance } from '/imports/ui/services/settings';
|
||||
import Checkbox from '/imports/ui/components/common/checkbox/component'
|
||||
import AppService from '/imports/ui/components/app/service';
|
||||
|
||||
const VIEW_STATES = {
|
||||
finding: 'finding',
|
||||
@ -48,9 +49,9 @@ const defaultProps = {
|
||||
};
|
||||
|
||||
const intlMessages = defineMessages({
|
||||
webcamEffectsTitle: {
|
||||
id: 'app.videoPreview.webcamEffectsTitle',
|
||||
description: 'Title for the video effects modal',
|
||||
webcamVirtualBackgroundTitle: {
|
||||
id: 'app.videoPreview.webcamVirtualBackgroundLabel',
|
||||
description: 'Title for the virtual background modal',
|
||||
},
|
||||
webcamSettingsTitle: {
|
||||
id: 'app.videoPreview.webcamSettingsTitle',
|
||||
@ -60,6 +61,10 @@ const intlMessages = defineMessages({
|
||||
id: 'app.videoPreview.closeLabel',
|
||||
description: 'Close button label',
|
||||
},
|
||||
cancelLabel: {
|
||||
id: 'app.mobileAppModal.dismissLabel',
|
||||
description: 'Close button label',
|
||||
},
|
||||
webcamPreviewLabel: {
|
||||
id: 'app.videoPreview.webcamPreviewLabel',
|
||||
description: 'Webcam preview label',
|
||||
@ -227,11 +232,13 @@ class VideoPreview extends Component {
|
||||
this.handleVirtualBgSelected = this.handleVirtualBgSelected.bind(this);
|
||||
this.handleLocalStreamInactive = this.handleLocalStreamInactive.bind(this);
|
||||
this.handleBrightnessAreaChange = this.handleBrightnessAreaChange.bind(this);
|
||||
this.handleSelectTab = this.handleSelectTab.bind(this);
|
||||
|
||||
this._isMounted = false;
|
||||
|
||||
this.state = {
|
||||
webcamDeviceId,
|
||||
selectedTab: 0,
|
||||
availableWebcams: null,
|
||||
selectedProfile: null,
|
||||
isStartSharingDisabled: true,
|
||||
@ -542,12 +549,12 @@ class VideoPreview extends Component {
|
||||
}
|
||||
|
||||
handleProceed() {
|
||||
const { resolve, closeModal, sharedDevices, isVisualEffects } = this.props;
|
||||
const { resolve, closeModal, sharedDevices } = this.props;
|
||||
const { webcamDeviceId, brightness } = this.state;
|
||||
const shared = sharedDevices.includes(webcamDeviceId);
|
||||
|
||||
if (
|
||||
(shared || isVisualEffects)
|
||||
(shared)
|
||||
&& this.currentVideoStream.virtualBgService
|
||||
&& brightness === 100
|
||||
&& this.currentVideoStream.virtualBgType === EFFECT_TYPES.NONE_TYPE
|
||||
@ -740,9 +747,7 @@ class VideoPreview extends Component {
|
||||
const {
|
||||
intl,
|
||||
sharedDevices,
|
||||
isVisualEffects,
|
||||
cameraAsContent,
|
||||
isVirtualBackgroundsEnabled,
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
@ -751,120 +756,95 @@ class VideoPreview extends Component {
|
||||
selectedProfile,
|
||||
} = this.state;
|
||||
|
||||
const shared = sharedDevices.includes(webcamDeviceId);
|
||||
const shouldShowVirtualBackgrounds = isVirtualBackgroundsEnabled && !cameraAsContent;
|
||||
return (
|
||||
<Styled.InternCol>
|
||||
<Styled.Label htmlFor="setCam">
|
||||
{intl.formatMessage(intlMessages.cameraLabel)}
|
||||
</Styled.Label>
|
||||
{ availableWebcams && availableWebcams.length > 0
|
||||
? (
|
||||
<Styled.Select
|
||||
id="setCam"
|
||||
value={webcamDeviceId || ''}
|
||||
onChange={this.handleSelectWebcam}
|
||||
>
|
||||
{availableWebcams.map((webcam, index) => (
|
||||
<option key={webcam.deviceId} value={webcam.deviceId}>
|
||||
{webcam.label || this.getFallbackLabel(webcam, index)}
|
||||
</option>
|
||||
))}
|
||||
</Styled.Select>
|
||||
)
|
||||
: (
|
||||
<span>
|
||||
{intl.formatMessage(intlMessages.webcamNotFoundLabel)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
{this.renderQualitySelector()}
|
||||
</Styled.InternCol>
|
||||
);
|
||||
}
|
||||
|
||||
renderQualitySelector() {
|
||||
const {
|
||||
intl,
|
||||
cameraAsContent,
|
||||
} = this.props
|
||||
|
||||
const {
|
||||
selectedProfile,
|
||||
availableWebcams,
|
||||
webcamDeviceId,
|
||||
} = this.state;
|
||||
|
||||
const shared = this.isAlreadyShared(webcamDeviceId);
|
||||
|
||||
if (shared) {
|
||||
return (
|
||||
<Styled.Label>
|
||||
{intl.formatMessage(intlMessages.sharedCameraLabel)}
|
||||
</Styled.Label>
|
||||
);
|
||||
}
|
||||
|
||||
if (cameraAsContent) return;
|
||||
|
||||
const CAMERA_PROFILES = window.meetingClientSettings.public.kurento.cameraProfiles || [];
|
||||
// Filtered, without hidden profiles
|
||||
const PREVIEW_CAMERA_PROFILES = CAMERA_PROFILES.filter(p => !p.hidden);
|
||||
|
||||
if (isVisualEffects) {
|
||||
return (
|
||||
<>
|
||||
{isVirtualBackgroundsEnabled && this.renderVirtualBgSelector()}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Styled.Label htmlFor="setQuality">
|
||||
{intl.formatMessage(intlMessages.qualityLabel)}
|
||||
</Styled.Label>
|
||||
{PREVIEW_CAMERA_PROFILES.length > 0
|
||||
? (
|
||||
<Styled.Select
|
||||
id="setQuality"
|
||||
value={selectedProfile || ''}
|
||||
onChange={this.handleSelectProfile}
|
||||
>
|
||||
{PREVIEW_CAMERA_PROFILES.map((profile) => {
|
||||
const label = intlMessages[`${profile.id}`]
|
||||
? intl.formatMessage(intlMessages[`${profile.id}`])
|
||||
: profile.name;
|
||||
|
||||
{ cameraAsContent
|
||||
? (
|
||||
<>
|
||||
<Styled.Label htmlFor="setCam">
|
||||
{intl.formatMessage(intlMessages.cameraLabel)}
|
||||
</Styled.Label>
|
||||
{ availableWebcams && availableWebcams.length > 0
|
||||
? (
|
||||
<Styled.Select
|
||||
id="setCam"
|
||||
value={webcamDeviceId || ''}
|
||||
onChange={this.handleSelectWebcam}
|
||||
>
|
||||
{availableWebcams.map((webcam, index) => (
|
||||
<option key={webcam.deviceId} value={webcam.deviceId}>
|
||||
{webcam.label || this.getFallbackLabel(webcam, index)}
|
||||
</option>
|
||||
))}
|
||||
</Styled.Select>
|
||||
)
|
||||
: (
|
||||
<span>
|
||||
{intl.formatMessage(intlMessages.webcamNotFoundLabel)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
</>
|
||||
)
|
||||
:
|
||||
<>
|
||||
<Styled.Label htmlFor="setCam">
|
||||
{intl.formatMessage(intlMessages.cameraLabel)}
|
||||
</Styled.Label>
|
||||
{ availableWebcams && availableWebcams.length > 0
|
||||
? (
|
||||
<Styled.Select
|
||||
id="setCam"
|
||||
value={webcamDeviceId || ''}
|
||||
onChange={this.handleSelectWebcam}
|
||||
>
|
||||
{availableWebcams.map((webcam, index) => (
|
||||
<option key={webcam.deviceId} value={webcam.deviceId}>
|
||||
{webcam.label || this.getFallbackLabel(webcam, index)}
|
||||
return (
|
||||
<option key={profile.id} value={profile.id}>
|
||||
{`${label}`}
|
||||
</option>
|
||||
))}
|
||||
</Styled.Select>
|
||||
)
|
||||
: (
|
||||
<span>
|
||||
{intl.formatMessage(intlMessages.webcamNotFoundLabel)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
{ shared
|
||||
? (
|
||||
<Styled.Label>
|
||||
{intl.formatMessage(intlMessages.sharedCameraLabel)}
|
||||
</Styled.Label>
|
||||
)
|
||||
: (
|
||||
<>
|
||||
<Styled.Label htmlFor="setQuality">
|
||||
{intl.formatMessage(intlMessages.qualityLabel)}
|
||||
</Styled.Label>
|
||||
{PREVIEW_CAMERA_PROFILES.length > 0
|
||||
? (
|
||||
<Styled.Select
|
||||
id="setQuality"
|
||||
value={selectedProfile || ''}
|
||||
onChange={this.handleSelectProfile}
|
||||
>
|
||||
{PREVIEW_CAMERA_PROFILES.map((profile) => {
|
||||
const label = intlMessages[`${profile.id}`]
|
||||
? intl.formatMessage(intlMessages[`${profile.id}`])
|
||||
: profile.name;
|
||||
|
||||
return (
|
||||
<option key={profile.id} value={profile.id}>
|
||||
{`${label}`}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</Styled.Select>
|
||||
)
|
||||
: (
|
||||
<span>
|
||||
{intl.formatMessage(intlMessages.profileNotFoundLabel)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
{shouldShowVirtualBackgrounds && this.renderVirtualBgSelector()}
|
||||
</>
|
||||
}
|
||||
);
|
||||
})}
|
||||
</Styled.Select>
|
||||
)
|
||||
: (
|
||||
<span>
|
||||
{intl.formatMessage(intlMessages.profileNotFoundLabel)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -878,6 +858,7 @@ class VideoPreview extends Component {
|
||||
renderBrightnessInput() {
|
||||
const {
|
||||
cameraAsContent,
|
||||
cameraAsContentDeviceId,
|
||||
} = this.props;
|
||||
const {
|
||||
webcamDeviceId,
|
||||
@ -896,10 +877,10 @@ class VideoPreview extends Component {
|
||||
? (brightness * 100) / 200
|
||||
: ((200 - brightness) * 100) / 200;
|
||||
|
||||
if(cameraAsContent){ return null }
|
||||
if(cameraAsContent || webcamDeviceId === cameraAsContentDeviceId){ return null }
|
||||
|
||||
return (
|
||||
<>
|
||||
<Styled.InternCol>
|
||||
<Styled.Label htmlFor="brightness">
|
||||
{intl.formatMessage(intlMessages.brightness)}
|
||||
</Styled.Label>
|
||||
@ -947,12 +928,12 @@ class VideoPreview extends Component {
|
||||
label={intl.formatMessage(intlMessages.wholeImageBrightnessLabel)}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
</Styled.InternCol>
|
||||
);
|
||||
}
|
||||
|
||||
renderVirtualBgSelector() {
|
||||
const { isVisualEffects, isCustomVirtualBackgroundsEnabled } = this.props;
|
||||
const { isCustomVirtualBackgroundsEnabled } = this.props;
|
||||
const { isStartSharingDisabled, webcamDeviceId } = this.state;
|
||||
const initialVirtualBgState = this.currentVideoStream ? {
|
||||
type: this.currentVideoStream.virtualBgType,
|
||||
@ -969,13 +950,37 @@ class VideoPreview extends Component {
|
||||
locked={isStartSharingDisabled}
|
||||
showThumbnails={SHOW_THUMBNAILS}
|
||||
initialVirtualBgState={initialVirtualBgState}
|
||||
isVisualEffects={isVisualEffects}
|
||||
isCustomVirtualBackgroundsEnabled={isCustomVirtualBackgroundsEnabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
renderTabsContent(tabNumber) {
|
||||
const {
|
||||
cameraAsContent,
|
||||
isVirtualBackgroundsEnabled,
|
||||
} = this.props;
|
||||
|
||||
const shouldShowVirtualBackgrounds = isVirtualBackgroundsEnabled && !cameraAsContent;
|
||||
|
||||
return (
|
||||
<Styled.ContentCol>
|
||||
{tabNumber === 0 && (
|
||||
<Styled.Col>
|
||||
{this.renderDeviceSelectors()}
|
||||
{this.renderBrightnessInput()}
|
||||
</Styled.Col>
|
||||
)}
|
||||
{tabNumber === 1 && shouldShowVirtualBackgrounds && (
|
||||
<Styled.BgnCol>
|
||||
{this.renderVirtualBgSelector()}
|
||||
</Styled.BgnCol>
|
||||
)}
|
||||
</Styled.ContentCol>
|
||||
);
|
||||
}
|
||||
|
||||
renderContent(selectedTab) {
|
||||
const {
|
||||
intl,
|
||||
} = this.props;
|
||||
@ -989,12 +994,20 @@ class VideoPreview extends Component {
|
||||
const Settings = getSettingsSingletonInstance();
|
||||
const { animations } = Settings.application;
|
||||
|
||||
const containerStyle = {
|
||||
width: '60%',
|
||||
height: '25vh',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
};
|
||||
|
||||
switch (viewState) {
|
||||
case VIEW_STATES.finding:
|
||||
return (
|
||||
<Styled.Content>
|
||||
<Styled.VideoCol>
|
||||
<div>
|
||||
<div style={containerStyle}>
|
||||
<span>{intl.formatMessage(intlMessages.findingWebcamsLabel)}</span>
|
||||
<Styled.FetchingAnimation animations={animations} />
|
||||
</div>
|
||||
@ -1030,10 +1043,7 @@ class VideoPreview extends Component {
|
||||
)
|
||||
}
|
||||
</Styled.VideoCol>
|
||||
<Styled.Col>
|
||||
{this.renderDeviceSelectors()}
|
||||
{this.renderBrightnessInput()}
|
||||
</Styled.Col>
|
||||
{this.renderTabsContent(selectedTab)}
|
||||
</Styled.Content>
|
||||
);
|
||||
}
|
||||
@ -1045,13 +1055,13 @@ class VideoPreview extends Component {
|
||||
return intl.formatMessage(intlMessages.webcamSettingsTitle);
|
||||
}
|
||||
|
||||
renderModalContent() {
|
||||
renderModalContent(selectedTab) {
|
||||
const {
|
||||
intl,
|
||||
hasVideoStream,
|
||||
forceOpen,
|
||||
camCapReached,
|
||||
isVisualEffects,
|
||||
closeModal,
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
@ -1066,6 +1076,8 @@ class VideoPreview extends Component {
|
||||
|
||||
const shared = this.isAlreadyShared(webcamDeviceId);
|
||||
|
||||
const showStopAllButton = hasVideoStream && VideoService.isMultipleCamerasEnabled();
|
||||
|
||||
const { isIe } = browserInfo;
|
||||
|
||||
return (
|
||||
@ -1083,50 +1095,72 @@ class VideoPreview extends Component {
|
||||
</Styled.BrowserWarning>
|
||||
) : null}
|
||||
|
||||
{this.renderContent()}
|
||||
{this.renderContent(selectedTab)}
|
||||
|
||||
{!isVisualEffects ? (
|
||||
<Styled.Footer>
|
||||
{hasVideoStream && VideoService.isMultipleCamerasEnabled()
|
||||
? (
|
||||
<Styled.Footer>
|
||||
<Styled.BottomSeparator />
|
||||
<Styled.FooterContainer>
|
||||
{showStopAllButton ? (
|
||||
<Styled.ExtraActions>
|
||||
<Button
|
||||
<Styled.StopAllButton
|
||||
color="danger"
|
||||
label={intl.formatMessage(intlMessages.stopSharingAllLabel)}
|
||||
onClick={this.handleStopSharingAll}
|
||||
disabled={shouldDisableButtons}
|
||||
/>
|
||||
</Styled.ExtraActions>
|
||||
)
|
||||
: null
|
||||
}
|
||||
<Styled.Actions>
|
||||
{!shared && camCapReached ? (
|
||||
<span>{intl.formatMessage(intlMessages.camCapReached)}</span>
|
||||
) : (<Button
|
||||
data-test="startSharingWebcam"
|
||||
color={shared ? 'danger' : 'primary'}
|
||||
label={intl.formatMessage(shared ? intlMessages.stopSharingLabel : intlMessages.startSharingLabel)}
|
||||
onClick={shared ? this.handleStopSharing : this.handleStartSharing}
|
||||
disabled={isStartSharingDisabled || isStartSharingDisabled === null || shouldDisableButtons}
|
||||
/>)}
|
||||
</Styled.Actions>
|
||||
</Styled.Footer>
|
||||
) : null }
|
||||
) : null}
|
||||
{!shared && camCapReached ? (
|
||||
<span>{intl.formatMessage(intlMessages.camCapReached)}</span>
|
||||
) : (
|
||||
<div style={{ display: 'flex' }}>
|
||||
<Styled.CancelButton
|
||||
data-test="cancelSharingWebcam"
|
||||
label={intl.formatMessage(intlMessages.cancelLabel)}
|
||||
onClick={closeModal}
|
||||
/>
|
||||
<Styled.SharingButton
|
||||
data-test="startSharingWebcam"
|
||||
color={shared ? 'danger' : 'primary'}
|
||||
label={intl.formatMessage(shared ? intlMessages.stopSharingLabel : intlMessages.startSharingLabel)}
|
||||
onClick={shared ? this.handleStopSharing : this.handleStartSharing}
|
||||
disabled={isStartSharingDisabled || isStartSharingDisabled === null || shouldDisableButtons}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</Styled.FooterContainer>
|
||||
</Styled.Footer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
handleSelectTab(tab) {
|
||||
this.setState({
|
||||
selectedTab: tab,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
intl,
|
||||
isCamLocked,
|
||||
forceOpen,
|
||||
isVisualEffects,
|
||||
isOpen,
|
||||
priority,
|
||||
cameraAsContent,
|
||||
cameraAsContentDeviceId,
|
||||
isVirtualBackgroundsEnabled,
|
||||
} = this.props;
|
||||
|
||||
const { selectedTab, webcamDeviceId } = this.state;
|
||||
|
||||
const BASE_NAME = window.meetingClientSettings.public.app.basename;
|
||||
const WebcamSettingsImg = `${BASE_NAME}/resources/images/webcam_settings.svg`;
|
||||
const WebcamBackgroundImg = `${BASE_NAME}/resources/images/webcam_background.svg`;
|
||||
|
||||
const darkThemeState = AppService.isDarkThemeEnabled();
|
||||
|
||||
if (isCamLocked === true) {
|
||||
this.handleProceed();
|
||||
return null;
|
||||
@ -1145,9 +1179,9 @@ class VideoPreview extends Component {
|
||||
|| !PreviewService.getSkipVideoPreview()
|
||||
|| forceOpen;
|
||||
|
||||
const title = isVisualEffects
|
||||
? intl.formatMessage(intlMessages.webcamEffectsTitle)
|
||||
: intl.formatMessage(intlMessages.webcamSettingsTitle);
|
||||
const shouldShowVirtualBackgroundsTab = isVirtualBackgroundsEnabled
|
||||
&& !cameraAsContent
|
||||
&& !(webcamDeviceId === cameraAsContentDeviceId)
|
||||
|
||||
return (
|
||||
<Styled.VideoPreviewModal
|
||||
@ -1157,16 +1191,50 @@ class VideoPreview extends Component {
|
||||
shouldCloseOnOverlayClick={allowCloseModal}
|
||||
isPhone={deviceInfo.isPhone}
|
||||
data-test="webcamSettingsModal"
|
||||
title={title}
|
||||
{...{
|
||||
isOpen,
|
||||
priority,
|
||||
}}
|
||||
>
|
||||
{deviceInfo.hasMediaDevices
|
||||
? this.renderModalContent()
|
||||
: this.supportWarning()
|
||||
}
|
||||
<Styled.Container>
|
||||
<Styled.Header>
|
||||
<Styled.WebcamTabs
|
||||
onSelect={this.handleSelectTab}
|
||||
selectedIndex={selectedTab}
|
||||
>
|
||||
<Styled.WebcamTabList>
|
||||
<Styled.WebcamTabSelector selectedClassName="is-selected">
|
||||
<Styled.IconSvg
|
||||
src={WebcamSettingsImg}
|
||||
darkThemeState={darkThemeState}
|
||||
/>
|
||||
<span
|
||||
id="webcam-settings-title">{this.getModalTitle()}
|
||||
</span>
|
||||
</Styled.WebcamTabSelector>
|
||||
{shouldShowVirtualBackgroundsTab && (
|
||||
<>
|
||||
<Styled.HeaderSeparator />
|
||||
<Styled.WebcamTabSelector selectedClassName="is-selected">
|
||||
<Styled.IconSvg
|
||||
src={WebcamBackgroundImg}
|
||||
darkThemeState={darkThemeState}
|
||||
/>
|
||||
<span id="backgrounds-title">{intl.formatMessage(intlMessages.webcamVirtualBackgroundTitle)}</span>
|
||||
</Styled.WebcamTabSelector>
|
||||
</>
|
||||
)}
|
||||
</Styled.WebcamTabList>
|
||||
|
||||
</Styled.WebcamTabs>
|
||||
</Styled.Header>
|
||||
|
||||
{deviceInfo.hasMediaDevices
|
||||
? this.renderModalContent(selectedTab)
|
||||
: this.supportWarning()
|
||||
}
|
||||
|
||||
</Styled.Container>
|
||||
</Styled.VideoPreviewModal>
|
||||
);
|
||||
}
|
||||
|
@ -30,7 +30,8 @@ const VideoPreviewContainer = (props) => {
|
||||
const hasVideoStream = useHasVideoStream();
|
||||
const camCapReached = useHasCapReached();
|
||||
const isCamLocked = useIsUserLocked();
|
||||
const webcamDeviceId = useStorageKey('WebcamDeviceId');
|
||||
const settingsStorage = window.meetingClientSettings.public.app.userSettingsStorage;
|
||||
const webcamDeviceId = useStorageKey('WebcamDeviceId', settingsStorage);
|
||||
const isVirtualBackgroundsEnabled = useIsVirtualBackgroundsEnabled();
|
||||
const isCustomVirtualBackgroundsEnabled = useIsCustomVirtualBackgroundsEnabled();
|
||||
const isCameraAsContentBroadcasting = ScreenShareService.useIsCameraAsContentBroadcasting();
|
||||
|
@ -1,12 +1,18 @@
|
||||
import styled, { css, keyframes } from 'styled-components';
|
||||
import {
|
||||
borderSizeSmall,
|
||||
borderSize,
|
||||
borderSizeLarge,
|
||||
mdPaddingX,
|
||||
titlePositionLeft,
|
||||
lgPaddingY,
|
||||
} from '/imports/ui/stylesheets/styled-components/general';
|
||||
import {
|
||||
colorGrayLabel,
|
||||
colorWhite,
|
||||
colorBlack,
|
||||
colorGrayLighter,
|
||||
colorGrayLightest,
|
||||
colorPrimary,
|
||||
colorText,
|
||||
} from '/imports/ui/stylesheets/styled-components/palette';
|
||||
@ -14,10 +20,16 @@ import {
|
||||
fontSizeLarge,
|
||||
lineHeightComputed,
|
||||
headingsFontWeight,
|
||||
fontSizeLarger,
|
||||
fontSizeSmall,
|
||||
} from '/imports/ui/stylesheets/styled-components/typography';
|
||||
import { smallOnly, landscape } from '/imports/ui/stylesheets/styled-components/breakpoints';
|
||||
import { smallOnly, mediumOnly, landscape } from '/imports/ui/stylesheets/styled-components/breakpoints';
|
||||
import ModalSimple from '/imports/ui/components/common/modal/simple/component';
|
||||
import ModalStyles from '/imports/ui/components/common/modal/simple/styles';
|
||||
import Button from '/imports/ui/components/common/button/component';
|
||||
import {
|
||||
Tab, Tabs, TabList,
|
||||
} from 'react-tabs';
|
||||
|
||||
const Warning = styled.div`
|
||||
text-align: center;
|
||||
@ -44,18 +56,59 @@ const Col = styled.div`
|
||||
justify-content: center;
|
||||
margin: 0 0.5rem 0 0.5rem;
|
||||
|
||||
width: 50%;
|
||||
@media ${smallOnly}, ${mediumOnly} {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
overflow: auto;
|
||||
margin: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const BgnCol = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
margin: 0 0.5rem 0 0.5rem;
|
||||
|
||||
@media ${smallOnly} {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const InternCol = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
margin: 0 0.5rem 0 0.5rem;
|
||||
|
||||
@media ${smallOnly} {
|
||||
width: 90%;
|
||||
height: unset;
|
||||
}
|
||||
`;
|
||||
|
||||
const ContentCol = styled.div`
|
||||
width: 60%;
|
||||
height: 25vh;
|
||||
|
||||
@media ${smallOnly} {
|
||||
width: 90%;
|
||||
}
|
||||
`;
|
||||
|
||||
const BackgroundCol = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const VideoCol = styled(Col)`
|
||||
align-items: center;
|
||||
|
||||
@media ${landscape} {
|
||||
width: 33.3%;
|
||||
width: 50%;
|
||||
}
|
||||
`;
|
||||
|
||||
@ -94,14 +147,15 @@ const Content = styled.div`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: auto;
|
||||
|
||||
color: ${colorText};
|
||||
font-weight: normal;
|
||||
padding: ${lineHeightComputed} 0;
|
||||
|
||||
@media ${smallOnly} {
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
margin: 5px;
|
||||
}
|
||||
`;
|
||||
|
||||
@ -116,11 +170,23 @@ const BrowserWarning = styled.p`
|
||||
|
||||
const Footer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const FooterContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: ${({ showStopAllButton }) => (showStopAllButton ? 'flex-start' : 'flex-end')};
|
||||
|
||||
@media ${smallOnly} {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
`;
|
||||
|
||||
const Actions = styled.div`
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
[dir="rtl"] & {
|
||||
margin-right: auto;
|
||||
@ -167,7 +233,6 @@ const VideoPreviewModal = styled(ModalSimple)`
|
||||
@media ${smallOnly} {
|
||||
height: unset;
|
||||
min-height: 22.5rem;
|
||||
max-height: unset;
|
||||
}
|
||||
|
||||
${({ isPhone }) => isPhone && `
|
||||
@ -244,17 +309,120 @@ const MarkerDynamicWrapper = styled.div`
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
const Container = styled.div`
|
||||
padding: 0 calc(${mdPaddingX} / 2 + ${borderSize});
|
||||
`;
|
||||
|
||||
const Header = styled.div`
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
line-height: ${titlePositionLeft};
|
||||
margin-bottom: ${lgPaddingY};
|
||||
`;
|
||||
|
||||
const WebcamTabs = styled(Tabs)`
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
`;
|
||||
|
||||
const WebcamTabList = styled(TabList)`
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
`;
|
||||
|
||||
const WebcamTabSelector = styled(Tab)`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
color: ${colorGrayLighter};
|
||||
|
||||
&.is-selected {
|
||||
border: none;
|
||||
color: ${colorBlack};
|
||||
}
|
||||
`;
|
||||
|
||||
const HeaderSeparator = styled.div`
|
||||
border-left: 1px solid ${colorText};
|
||||
content: '|';
|
||||
margin: 0 1.5rem;
|
||||
height: 1.5rem;
|
||||
align-self: center;
|
||||
opacity: 0.75;
|
||||
`;
|
||||
|
||||
const BottomSeparator = styled.div`
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: ${borderSizeSmall};
|
||||
background-color: ${colorGrayLightest};
|
||||
margin-top: calc(${lineHeightComputed} * 1.25);
|
||||
margin-bottom: calc(${lineHeightComputed} * 1.25);
|
||||
`;
|
||||
|
||||
const IconSvg = styled.img`
|
||||
height: ${fontSizeLarger};
|
||||
border-radius: 5px;
|
||||
margin: 5px;
|
||||
|
||||
${({ darkThemeState }) => darkThemeState && css`
|
||||
filter: invert(1);
|
||||
`}
|
||||
|
||||
`;
|
||||
|
||||
const SharingButton = styled(Button)`
|
||||
margin: 0 0.5rem;
|
||||
height: 2.5rem;
|
||||
`;
|
||||
|
||||
const CancelButton = styled(Button)`
|
||||
margin: 0 0.5rem;
|
||||
height: 2.5rem;
|
||||
`;
|
||||
|
||||
const StopAllButton = styled(Button)`
|
||||
margin: 0 0.5rem;
|
||||
height: 2.5rem;
|
||||
`;
|
||||
|
||||
export default {
|
||||
Warning,
|
||||
Main,
|
||||
Text,
|
||||
Col,
|
||||
BgnCol,
|
||||
ContentCol,
|
||||
InternCol,
|
||||
Container,
|
||||
Header,
|
||||
WebcamTabs,
|
||||
WebcamTabList,
|
||||
WebcamTabSelector,
|
||||
HeaderSeparator,
|
||||
BottomSeparator,
|
||||
VideoCol,
|
||||
BackgroundCol,
|
||||
IconSvg,
|
||||
SharingButton,
|
||||
CancelButton,
|
||||
StopAllButton,
|
||||
Label,
|
||||
Select,
|
||||
Content,
|
||||
BrowserWarning,
|
||||
Footer,
|
||||
FooterContainer,
|
||||
Actions,
|
||||
ExtraActions,
|
||||
VideoPreviewModal,
|
||||
|
@ -51,7 +51,6 @@ const VirtualBgSelector = ({
|
||||
locked,
|
||||
showThumbnails = false,
|
||||
initialVirtualBgState = defaultInitialVirtualBgState,
|
||||
isVisualEffects,
|
||||
readFile,
|
||||
isCustomVirtualBackgroundsEnabled,
|
||||
}) => {
|
||||
@ -269,7 +268,6 @@ const VirtualBgSelector = ({
|
||||
return (
|
||||
<Styled.ThumbnailButtonWrapper
|
||||
key={`blur-${index}`}
|
||||
isVisualEffects={isVisualEffects}
|
||||
>
|
||||
<Styled.ThumbnailButton
|
||||
background={getVirtualBackgroundThumbnail(BLUR_FILENAME)}
|
||||
@ -282,7 +280,6 @@ const VirtualBgSelector = ({
|
||||
disabled={disabled}
|
||||
ref={ref => { inputElementsRef.current[index] = ref; }}
|
||||
onClick={() => _virtualBgSelected(EFFECT_TYPES.BLUR_TYPE, 'Blur', index)}
|
||||
isVisualEffects={isVisualEffects}
|
||||
/>
|
||||
<div aria-hidden className="sr-only" id={`vr-cam-btn-blur`}>
|
||||
{intl.formatMessage(intlMessages.camBgAriaDesc, { 0: EFFECT_TYPES.BLUR_TYPE })}
|
||||
@ -300,7 +297,6 @@ const VirtualBgSelector = ({
|
||||
return (
|
||||
<Styled.ThumbnailButtonWrapper
|
||||
key={`${imageName}-${index + 1}`}
|
||||
isVisualEffects={isVisualEffects}
|
||||
>
|
||||
<Styled.ThumbnailButton
|
||||
id={`${imageName}-${index + 1}`}
|
||||
@ -314,7 +310,6 @@ const VirtualBgSelector = ({
|
||||
ref={ref => inputElementsRef.current[index] = ref}
|
||||
onClick={() => _virtualBgSelected(EFFECT_TYPES.IMAGE_TYPE, imageName, index)}
|
||||
disabled={disabled}
|
||||
isVisualEffects={isVisualEffects}
|
||||
background={getVirtualBackgroundThumbnail(imageName)}
|
||||
data-test="selectDefaultBackground"
|
||||
/>
|
||||
@ -334,7 +329,6 @@ const VirtualBgSelector = ({
|
||||
return (
|
||||
<Styled.ThumbnailButtonWrapper
|
||||
key={`${filename}-${index + 1}`}
|
||||
isVisualEffects={isVisualEffects}
|
||||
>
|
||||
<Styled.ThumbnailButton
|
||||
id={`${filename}-${index + 1}`}
|
||||
@ -353,7 +347,6 @@ const VirtualBgSelector = ({
|
||||
{ file: data, uniqueId },
|
||||
)}
|
||||
disabled={disabled}
|
||||
isVisualEffects={isVisualEffects}
|
||||
background={data}
|
||||
data-test="selectCustomBackground"
|
||||
/>
|
||||
@ -399,7 +392,6 @@ const VirtualBgSelector = ({
|
||||
customBgSelectorRef.current.click();
|
||||
}
|
||||
}}
|
||||
isVisualEffects={isVisualEffects}
|
||||
data-test="inputBackgroundButton"
|
||||
/>
|
||||
<input
|
||||
@ -427,7 +419,6 @@ const VirtualBgSelector = ({
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
disabled={disabled}
|
||||
onClick={() => _virtualBgSelected(EFFECT_TYPES.NONE_TYPE)}
|
||||
isVisualEffects={isVisualEffects}
|
||||
data-test="noneBackgroundButton"
|
||||
/>
|
||||
<div aria-hidden className="sr-only" id={`vr-cam-btn-none`}>
|
||||
@ -454,7 +445,6 @@ const VirtualBgSelector = ({
|
||||
<Styled.BgWrapper
|
||||
role="group"
|
||||
aria-label={intl.formatMessage(intlMessages.virtualBackgroundSettingsLabel)}
|
||||
isVisualEffects={isVisualEffects}
|
||||
brightnessEnabled={ENABLE_CAMERA_BRIGHTNESS}
|
||||
data-test="virtualBackground"
|
||||
>
|
||||
@ -507,13 +497,13 @@ const VirtualBgSelector = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isVisualEffects && (
|
||||
<Styled.Label>
|
||||
{!isVirtualBackgroundSupported()
|
||||
? intl.formatMessage(intlMessages.virtualBackgroundSettingsDisabledLabel)
|
||||
: intl.formatMessage(intlMessages.virtualBackgroundSettingsLabel)}
|
||||
</Styled.Label>
|
||||
)}
|
||||
<Styled.Label>
|
||||
{intl.formatMessage(
|
||||
isVirtualBackgroundSupported()
|
||||
? intlMessages.virtualBackgroundSettingsLabel
|
||||
: intlMessages.virtualBackgroundSettingsDisabledLabel,
|
||||
)}
|
||||
</Styled.Label>
|
||||
|
||||
{renderSelector()}
|
||||
</>
|
||||
|
@ -16,28 +16,27 @@ import {
|
||||
} from '/imports/ui/stylesheets/styled-components/palette';
|
||||
import { ScrollboxVertical } from '/imports/ui/stylesheets/styled-components/scrollable';
|
||||
import { fontSizeSmallest } from '/imports/ui/stylesheets/styled-components/typography';
|
||||
import { smallOnly, mediumOnly } from '/imports/ui/stylesheets/styled-components/breakpoints';
|
||||
import Button from '/imports/ui/components/common/button/component';
|
||||
|
||||
const VirtualBackgroundRowThumbnail = styled.div`
|
||||
margin-top: 0.4rem;
|
||||
margin: 0.4rem;
|
||||
`;
|
||||
|
||||
const BgWrapper = styled(ScrollboxVertical)`
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
overflow-x: auto;
|
||||
max-width: 272px;
|
||||
max-height: 216px;
|
||||
flex-wrap: wrap;
|
||||
overflow-y: auto;
|
||||
margin: ${borderSizeLarge};
|
||||
padding: ${borderSizeLarge};
|
||||
|
||||
${({ isVisualEffects }) => isVisualEffects && `
|
||||
height: 15rem;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
`}
|
||||
|
||||
${({ brightnessEnabled, isVisualEffects }) => brightnessEnabled && isVisualEffects && `
|
||||
height: 10rem;
|
||||
`}
|
||||
@media ${smallOnly}, ${mediumOnly} {
|
||||
justify-content: center;
|
||||
max-height: 22vh;
|
||||
}
|
||||
`;
|
||||
|
||||
const BgNoneButton = styled(Button)`
|
||||
@ -45,12 +44,8 @@ const BgNoneButton = styled(Button)`
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
border: ${borderSizeSmall} solid ${userThumbnailBorder};
|
||||
margin: 0 0.15rem;
|
||||
margin: 0.5rem 0.5rem;
|
||||
flex-shrink: 0;
|
||||
|
||||
${({ isVisualEffects }) => isVisualEffects && `
|
||||
margin: 0.15rem;
|
||||
`}
|
||||
`;
|
||||
|
||||
const ThumbnailButton = styled(Button)`
|
||||
@ -131,11 +126,7 @@ const Label = styled.label`
|
||||
|
||||
const ThumbnailButtonWrapper = styled.div`
|
||||
position: relative;
|
||||
margin: 0 0.15rem;
|
||||
|
||||
${({ isVisualEffects }) => isVisualEffects && `
|
||||
margin: 0.15rem;
|
||||
`}
|
||||
margin: 0.5rem 0.5rem;
|
||||
`;
|
||||
|
||||
const ButtonWrapper = styled.div`
|
||||
@ -177,4 +168,4 @@ export default {
|
||||
ButtonRemove,
|
||||
BgCustomButton,
|
||||
SkeletonWrapper,
|
||||
};
|
||||
};
|
||||
|
@ -5,7 +5,6 @@ import { IntlShape, defineMessages, injectIntl } from 'react-intl';
|
||||
import deviceInfo from '/imports/utils/deviceInfo';
|
||||
import { debounce } from '/imports/utils/debounce';
|
||||
import BBBMenu from '/imports/ui/components/common/menu/component';
|
||||
import { useIsVirtualBackgroundsEnabled } from '/imports/ui/services/features';
|
||||
import Button from '/imports/ui/components/common/button/component';
|
||||
import VideoPreviewContainer from '/imports/ui/components/video-preview/container';
|
||||
import { CameraSettingsDropdownItemType } from 'bigbluebutton-html-plugin-sdk/dist/cjs/extensible-areas/camera-settings-dropdown-item/enums';
|
||||
@ -87,15 +86,9 @@ const JoinVideoButton: React.FC<JoinVideoButtonProps> = ({
|
||||
const isDesktopSharingCamera = hasVideoStream && !isMobile;
|
||||
|
||||
const ENABLE_WEBCAM_SELECTOR_BUTTON = window.meetingClientSettings.public.app.enableWebcamSelectorButton;
|
||||
const ENABLE_CAMERA_BRIGHTNESS = window.meetingClientSettings.public.app.enableCameraBrightness;
|
||||
|
||||
const shouldEnableWebcamSelectorButton = ENABLE_WEBCAM_SELECTOR_BUTTON
|
||||
&& isDesktopSharingCamera;
|
||||
const isVirtualBackgroundsEnabled = useIsVirtualBackgroundsEnabled();
|
||||
const shouldEnableWebcamVisualEffectsButton = (isVirtualBackgroundsEnabled
|
||||
|| ENABLE_CAMERA_BRIGHTNESS)
|
||||
&& hasVideoStream
|
||||
&& !isMobile;
|
||||
const exitVideo = () => isDesktopSharingCamera && (!VideoService.isMultipleCamerasEnabled()
|
||||
|| shouldEnableWebcamSelectorButton);
|
||||
|
||||
@ -168,16 +161,6 @@ const JoinVideoButton: React.FC<JoinVideoButtonProps> = ({
|
||||
);
|
||||
}
|
||||
|
||||
if (shouldEnableWebcamVisualEffectsButton) {
|
||||
actions.push(
|
||||
{
|
||||
key: 'virtualBgSelection',
|
||||
label: intl.formatMessage(intlMessages.visualEffects),
|
||||
onClick: () => handleOpenAdvancedOptions(() => setPropsToPassModal({ isVisualEffects: true })),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (actions.length === 0) return null;
|
||||
const customStyles = { top: '-3.6rem' };
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M120-574v-85l181-181h85L120-574Zm0-196v-70h70l-70 70Zm527 67q-10-11-21.5-21.5T602-743l97-97h85L647-703ZM220-361l77-77q7 11 14.5 20t16.5 17q-28 7-56.5 17.5T220-361Zm480-197v-2q0-19-3-37t-9-35l152-152v86L700-558ZM436-776l65-64h85l-64 64q-11-2-21-3t-21-1q-11 0-22 1t-22 3ZM120-375v-85l144-144q-2 11-3 22t-1 22q0 11 1 21t3 20L120-375Zm709 83q-8-12-18.5-23T788-335l52-52v85l-11 10Zm-116-82q-7-3-14-5.5t-14-4.5q-9-3-17.5-6t-17.5-5l190-191v86L713-374Zm-233-26q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47ZM160-120v-71q0-34 17-63t47-44q51-26 115.5-44T480-360q76 0 140.5 18T736-298q30 15 47 44t17 63v71H160Z"/></svg>
|
After Width: | Height: | Size: 738 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h480q33 0 56.5 23.5T720-720v180l126-126q10-10 22-5t12 19v344q0 14-12 19t-22-5L720-420v180q0 33-23.5 56.5T640-160H160Z"/></svg>
|
After Width: | Height: | Size: 282 B |
@ -429,7 +429,9 @@ exports.advancedVideoSettingsBtn = 'li[data-test="advancedVideoSettingsButton"]'
|
||||
exports.mirrorWebcamBtn = 'li[data-test="mirrorWebcamBtn"]';
|
||||
exports.focusWebcamBtn = 'li[data-test="focusWebcamBtn"]';
|
||||
exports.pinWebcamBtn = 'li[data-test="pinWebcamBtn"]';
|
||||
exports.webcamFullscreenButton = 'button[data-test="webcamFullscreenButton"]';
|
||||
exports.webcamsFullscreenButton = 'li[data-test="webcamsFullscreenButton"]';
|
||||
exports.webcamSettingsTitle = 'span[id="webcam-settings-title"]';
|
||||
exports.backgroundSettingsTitle = 'span[id="backgrounds-title"]';
|
||||
exports.selectDefaultBackground = 'button[data-test="selectDefaultBackground"]';
|
||||
exports.selectCustomBackground = 'button[data-test="selectCustomBackground"]';
|
||||
exports.removeCustomBackground = 'button[data-test="removeCustomBackground"]';
|
||||
|
@ -18,7 +18,7 @@ class DisabledFeatures extends MultiUsers {
|
||||
|
||||
await this.modPage.waitForSelector(e.audioModal, ELEMENT_WAIT_LONGER_TIME);
|
||||
|
||||
if(speechRecognitionEnabled) {
|
||||
if (speechRecognitionEnabled) {
|
||||
await this.modPage.wasRemoved(e.speechRecognition);
|
||||
} else {
|
||||
await this.modPage.wasRemoved(e.speechRecognitionUnsupported);
|
||||
@ -64,7 +64,7 @@ class DisabledFeatures extends MultiUsers {
|
||||
|
||||
async virtualBackgrounds() {
|
||||
await this.modPage.waitAndClick(e.joinVideo);
|
||||
await this.modPage.wasRemoved(e.virtualBackgrounds);
|
||||
await this.modPage.wasRemoved(e.backgroundSettingsTitle);
|
||||
}
|
||||
|
||||
async downloadPresentationWithAnnotations() {
|
||||
@ -93,8 +93,8 @@ class DisabledFeatures extends MultiUsers {
|
||||
}
|
||||
|
||||
async customVirtualBackground() {
|
||||
await this.modPage.waitAndClick (e.joinVideo);
|
||||
await this.modPage.waitForSelector(e.webcamSettingsModal);
|
||||
await this.modPage.waitAndClick(e.joinVideo);
|
||||
await this.modPage.waitAndClick(e.backgroundSettingsTitle);
|
||||
await this.modPage.wasRemoved(e.inputBackgroundButton);
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ class DisabledFeatures extends MultiUsers {
|
||||
|
||||
await this.modPage.waitForSelector(e.audioModal, ELEMENT_WAIT_LONGER_TIME);
|
||||
|
||||
if(speechRecognitionEnabled) {
|
||||
if (speechRecognitionEnabled) {
|
||||
await this.modPage.wasRemoved(e.speechRecognition);
|
||||
} else {
|
||||
await this.modPage.wasRemoved(e.speechRecognitionUnsupported);
|
||||
@ -169,6 +169,7 @@ class DisabledFeatures extends MultiUsers {
|
||||
|
||||
async virtualBackgroundsExclude() {
|
||||
await this.modPage.waitAndClick(e.joinVideo);
|
||||
await this.modPage.waitAndClick(e.backgroundSettingsTitle);
|
||||
await this.modPage.hasElement(e.virtualBackgrounds);
|
||||
}
|
||||
|
||||
@ -199,8 +200,8 @@ class DisabledFeatures extends MultiUsers {
|
||||
}
|
||||
|
||||
async customVirtualBackgroundExclude() {
|
||||
await this.modPage.waitAndClick (e.joinVideo);
|
||||
await this.modPage.waitForSelector(e.webcamSettingsModal);
|
||||
await this.modPage.waitAndClick(e.joinVideo);
|
||||
await this.modPage.waitAndClick(e.backgroundSettingsTitle);
|
||||
await this.modPage.hasElement(e.inputBackgroundButton);
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ class Webcam extends Page {
|
||||
|
||||
async applyBackground() {
|
||||
await this.waitAndClick(e.joinVideo);
|
||||
await this.waitAndClick(e.backgroundSettingsTitle);
|
||||
await this.waitForSelector(e.noneBackgroundButton);
|
||||
await this.waitAndClick(`${e.selectDefaultBackground}[aria-label="Home"]`);
|
||||
await sleep(1000);
|
||||
@ -75,11 +76,14 @@ class Webcam extends Page {
|
||||
async webcamFullscreen() {
|
||||
await this.shareWebcam();
|
||||
// get default viewport sizes
|
||||
const { windowWidth, windowHeight } = await this.page.evaluate(() => { return {
|
||||
windowWidth: window.innerWidth,
|
||||
windowHeight: window.innerHeight,
|
||||
}});
|
||||
await this.waitAndClick(e.webcamFullscreenButton);
|
||||
const { windowWidth, windowHeight } = await this.page.evaluate(() => {
|
||||
return {
|
||||
windowWidth: window.innerWidth,
|
||||
windowHeight: window.innerHeight,
|
||||
}
|
||||
});
|
||||
await this.waitAndClick(e.dropdownWebcamButton);
|
||||
await this.waitAndClick(e.webcamsFullscreenButton);
|
||||
// get fullscreen webcam size
|
||||
const { width, height } = await this.getLocator('video').boundingBox();
|
||||
await expect(width + 1).toBe(windowWidth); // not sure why there is a difference of 1 pixel
|
||||
@ -88,6 +92,7 @@ class Webcam extends Page {
|
||||
|
||||
async disableSelfView() {
|
||||
await this.waitAndClick(e.joinVideo);
|
||||
await this.waitAndClick(e.backgroundSettingsTitle);
|
||||
await this.waitForSelector(e.noneBackgroundButton);
|
||||
|
||||
await uploadBackgroundVideoImage(this);
|
||||
@ -105,6 +110,7 @@ class Webcam extends Page {
|
||||
|
||||
async managingNewBackground() {
|
||||
await this.waitAndClick(e.joinVideo);
|
||||
await this.waitAndClick(e.backgroundSettingsTitle);
|
||||
await this.waitForSelector(e.noneBackgroundButton);
|
||||
|
||||
// Upload
|
||||
@ -121,12 +127,14 @@ class Webcam extends Page {
|
||||
// Remove
|
||||
await this.waitAndClick(e.videoDropdownMenu);
|
||||
await this.waitAndClick(e.advancedVideoSettingsBtn);
|
||||
await this.waitAndClick(e.backgroundSettingsTitle);
|
||||
await this.waitAndClick(e.removeCustomBackground);
|
||||
await this.wasRemoved(e.selectCustomBackground);
|
||||
}
|
||||
|
||||
async keepBackgroundWhenRejoin(context) {
|
||||
await this.waitAndClick(e.joinVideo);
|
||||
await this.waitAndClick(e.backgroundSettingsTitle);
|
||||
await this.waitForSelector(e.noneBackgroundButton);
|
||||
await uploadBackgroundVideoImage(this);
|
||||
// Create a new page before closing the previous to not close the current context
|
||||
@ -135,6 +143,7 @@ class Webcam extends Page {
|
||||
const openedPage = await this.getLastTargetPage(context);
|
||||
await openedPage.init(true, true, { meetingId: this.meetingId });
|
||||
await openedPage.waitAndClick(e.joinVideo);
|
||||
await openedPage.waitAndClick(e.backgroundSettingsTitle);
|
||||
await openedPage.hasElement(e.selectCustomBackground);
|
||||
}
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Loading…
Reference in New Issue
Block a user