feat: Drops filmStripOnly mode. (#8074)
* feat: Drops filmStripOnly mode. * squash: Let's make lint happy again. * squash: Drop some css.
This commit is contained in:
parent
f6127d45e9
commit
12c835dd91
|
@ -28,9 +28,6 @@ body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: $defaultColor;
|
color: $defaultColor;
|
||||||
background: $defaultBackground;
|
background: $defaultBackground;
|
||||||
&.filmstrip-only {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,16 +67,6 @@ body {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* AtlasKitThemeProvider sets a background color on an app-wrapping div, thereby
|
|
||||||
* preventing transparency in filmstrip-only mode. The selector chosen to
|
|
||||||
* override this behavior is specific to where the AtlasKitThemeProvider might
|
|
||||||
* be placed within the app hierarchy.
|
|
||||||
*/
|
|
||||||
.filmstrip-only #react > .ckAJgx {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,84 +27,4 @@
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-filmstrip-only {
|
|
||||||
background-color: $inlayFilmstripOnlyBg;
|
|
||||||
color: $inlayFilmstripOnlyColor;
|
|
||||||
margin-left: 20px;
|
|
||||||
margin-right: 20px;
|
|
||||||
margin-top: 20px;
|
|
||||||
bottom: 30px;
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
max-height: 120px;
|
|
||||||
height: 80%;
|
|
||||||
right: 0px;
|
|
||||||
border-radius: 4px;
|
|
||||||
overflow: hidden;
|
|
||||||
&__content {
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
position: relative;
|
|
||||||
> .button-control {
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
> #reloadProgressBar {
|
|
||||||
position: absolute;
|
|
||||||
left: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
margin-bottom: 0px;
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&__title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__container {
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__text {
|
|
||||||
margin-top: 10px;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon {
|
|
||||||
font-size: 50px;
|
|
||||||
align-self: center;
|
|
||||||
color: $inlayIconColor;
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
&__icon-container {
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__avatar-container {
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
> img {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon-background {
|
|
||||||
background: $inlayIconBg;
|
|
||||||
opacity: 0.6;
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,20 +67,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Style the filmstrip videos in filmstrip-only mode.
|
|
||||||
*/
|
|
||||||
&__videos-filmstripOnly {
|
|
||||||
margin-top: auto;
|
|
||||||
margin-bottom: auto;
|
|
||||||
|
|
||||||
.filmstrip__videos {
|
|
||||||
&#filmstripLocalVideo {
|
|
||||||
bottom: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.remote-videos-container {
|
.remote-videos-container {
|
||||||
transition: opacity 1s;
|
transition: opacity 1s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,26 +145,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Override other styles to support vertical filmstrip mode.
|
|
||||||
*/
|
|
||||||
.filmstrip-only .vertical-filmstrip {
|
|
||||||
.filmstrip {
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
}
|
|
||||||
.filmstrip__videos-filmstripOnly {
|
|
||||||
margin-top: auto;
|
|
||||||
margin-bottom: auto;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filmstrip__videos {
|
|
||||||
&#filmstripLocalVideo {
|
|
||||||
bottom: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Workarounds for Edge and Firefox not handling scrolling properly with
|
* Workarounds for Edge and Firefox not handling scrolling properly with
|
||||||
* flex-direction: column-reverse. The remove videos in filmstrip should
|
* flex-direction: column-reverse. The remove videos in filmstrip should
|
||||||
|
|
|
@ -8,16 +8,10 @@
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: $overlayZ;
|
z-index: $overlayZ;
|
||||||
background: $defaultBackground;
|
background: $defaultBackground;
|
||||||
&.filmstrip-only {
|
|
||||||
@include transparentBg($filmstripOnlyOverlayBg, 0.8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__container-light {
|
&__container-light {
|
||||||
@include transparentBg($defaultBackground, 0.7);
|
@include transparentBg($defaultBackground, 0.7);
|
||||||
&.filmstrip-only {
|
|
||||||
@include transparentBg($filmstripOnlyOverlayBg, 0.2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__content {
|
&__content {
|
||||||
|
@ -27,11 +21,6 @@
|
||||||
width: 56%;
|
width: 56%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
@include transform(translateX(-50%));
|
@include transform(translateX(-50%));
|
||||||
&.filmstrip-only {
|
|
||||||
left: 0px;
|
|
||||||
width: 100%;
|
|
||||||
@include transform(none);
|
|
||||||
}
|
|
||||||
|
|
||||||
&_bottom {
|
&_bottom {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -41,7 +41,6 @@ $overlayButtonBg: #0074E0;
|
||||||
* Color variables
|
* Color variables
|
||||||
**/
|
**/
|
||||||
$defaultBackground: #474747;
|
$defaultBackground: #474747;
|
||||||
$filmstripOnlyOverlayBg: #000;
|
|
||||||
$reloadProgressBarBg: #0074E0;
|
$reloadProgressBarBg: #0074E0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,10 +58,6 @@ $dialogErrorText: #344563;
|
||||||
**/
|
**/
|
||||||
$inlayColorBg: lighten($defaultBackground, 20%);
|
$inlayColorBg: lighten($defaultBackground, 20%);
|
||||||
$inlayBorderColor: lighten($baseLight, 10%);
|
$inlayBorderColor: lighten($baseLight, 10%);
|
||||||
$inlayIconBg: #000;
|
|
||||||
$inlayIconColor: #fff;
|
|
||||||
$inlayFilmstripOnlyColor: #474747;
|
|
||||||
$inlayFilmstripOnlyBg: #fff;
|
|
||||||
|
|
||||||
// Main controls
|
// Main controls
|
||||||
$placeHolderColor: #a7a7a7;
|
$placeHolderColor: #a7a7a7;
|
||||||
|
|
|
@ -13,9 +13,7 @@
|
||||||
height: 180,
|
height: 180,
|
||||||
parentNode: undefined,
|
parentNode: undefined,
|
||||||
configOverwrite: {},
|
configOverwrite: {},
|
||||||
interfaceConfigOverwrite: {
|
interfaceConfigOverwrite: {}
|
||||||
filmStripOnly: true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var api = new JitsiMeetExternalAPI(domain, options);
|
var api = new JitsiMeetExternalAPI(domain, options);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -97,11 +97,6 @@ var interfaceConfig = {
|
||||||
|
|
||||||
FILM_STRIP_MAX_HEIGHT: 120,
|
FILM_STRIP_MAX_HEIGHT: 120,
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to only show the filmstrip (and hide the toolbar).
|
|
||||||
*/
|
|
||||||
filmStripOnly: false,
|
|
||||||
|
|
||||||
GENERATE_ROOMNAMES_ON_WELCOME_PAGE: true,
|
GENERATE_ROOMNAMES_ON_WELCOME_PAGE: true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global APP, $, config, interfaceConfig */
|
/* global APP, $, config */
|
||||||
|
|
||||||
|
|
||||||
const UI = {};
|
const UI = {};
|
||||||
|
@ -143,9 +143,7 @@ UI.start = function() {
|
||||||
$.prompt.setDefaults({ persistent: false });
|
$.prompt.setDefaults({ persistent: false });
|
||||||
|
|
||||||
VideoLayout.init(eventEmitter);
|
VideoLayout.init(eventEmitter);
|
||||||
if (!interfaceConfig.filmStripOnly) {
|
VideoLayout.initLargeVideo();
|
||||||
VideoLayout.initLargeVideo();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not animate the video area on UI start (second argument passed into
|
// Do not animate the video area on UI start (second argument passed into
|
||||||
// resizeVideoArea) because the animation is not visible anyway. Plus with
|
// resizeVideoArea) because the animation is not visible anyway. Plus with
|
||||||
|
@ -161,10 +159,7 @@ UI.start = function() {
|
||||||
$('body').addClass('desktop-browser');
|
$('body').addClass('desktop-browser');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interfaceConfig.filmStripOnly) {
|
if (config.iAmRecorder) {
|
||||||
$('body').addClass('filmstrip-only');
|
|
||||||
APP.store.dispatch(setNotificationsEnabled(false));
|
|
||||||
} else if (config.iAmRecorder) {
|
|
||||||
// in case of iAmSipGateway keep local video visible
|
// in case of iAmSipGateway keep local video visible
|
||||||
if (!config.iAmSipGateway) {
|
if (!config.iAmSipGateway) {
|
||||||
VideoLayout.setLocalVideoVisible(false);
|
VideoLayout.setLocalVideoVisible(false);
|
||||||
|
|
|
@ -135,10 +135,6 @@ export default class RemoteVideo extends SmallVideo {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_generatePopupContent() {
|
_generatePopupContent() {
|
||||||
if (interfaceConfig.filmStripOnly) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const remoteVideoMenuContainer
|
const remoteVideoMenuContainer
|
||||||
= this.container.querySelector('.remotevideomenu');
|
= this.container.querySelector('.remotevideomenu');
|
||||||
|
|
||||||
|
|
|
@ -699,7 +699,7 @@ export default class SmallVideo {
|
||||||
alwaysVisible = { showConnectionIndicator }
|
alwaysVisible = { showConnectionIndicator }
|
||||||
iconSize = { iconSize }
|
iconSize = { iconSize }
|
||||||
isLocalVideo = { this.isLocal }
|
isLocalVideo = { this.isLocal }
|
||||||
enableStatsDisplay = { !interfaceConfig.filmStripOnly }
|
enableStatsDisplay = { true }
|
||||||
participantId = { this.id }
|
participantId = { this.id }
|
||||||
statsPopoverPosition = { statsPopoverPosition } />
|
statsPopoverPosition = { statsPopoverPosition } />
|
||||||
: null }
|
: null }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global APP, $, interfaceConfig */
|
/* global APP, $ */
|
||||||
|
|
||||||
import Logger from 'jitsi-meet-logger';
|
import Logger from 'jitsi-meet-logger';
|
||||||
|
|
||||||
|
@ -264,10 +264,6 @@ const VideoLayout = {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
onPinChange(pinnedParticipantID) {
|
onPinChange(pinnedParticipantID) {
|
||||||
if (interfaceConfig.filmStripOnly) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
getAllThumbnails().forEach(thumbnail =>
|
getAllThumbnails().forEach(thumbnail =>
|
||||||
thumbnail.focus(pinnedParticipantID === thumbnail.getId()));
|
thumbnail.focus(pinnedParticipantID === thumbnail.getId()));
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global APP, $, interfaceConfig */
|
/* global APP, $ */
|
||||||
|
|
||||||
import Logger from 'jitsi-meet-logger';
|
import Logger from 'jitsi-meet-logger';
|
||||||
|
|
||||||
|
@ -203,14 +203,12 @@ const KeyboardShortcut = {
|
||||||
});
|
});
|
||||||
this._addShortcutToHelp('SPACE', 'keyboardShortcuts.pushToTalk');
|
this._addShortcutToHelp('SPACE', 'keyboardShortcuts.pushToTalk');
|
||||||
|
|
||||||
if (!interfaceConfig.filmStripOnly) {
|
this.registerShortcut('T', null, () => {
|
||||||
this.registerShortcut('T', null, () => {
|
sendAnalytics(createShortcutEvent('speaker.stats'));
|
||||||
sendAnalytics(createShortcutEvent('speaker.stats'));
|
APP.store.dispatch(toggleDialog(SpeakerStats, {
|
||||||
APP.store.dispatch(toggleDialog(SpeakerStats, {
|
conference: APP.conference
|
||||||
conference: APP.conference
|
}));
|
||||||
}));
|
}, 'keyboardShortcuts.showSpeakerStats');
|
||||||
}, 'keyboardShortcuts.showSpeakerStats');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME: Currently focus keys are directly implemented below in
|
* FIXME: Currently focus keys are directly implemented below in
|
||||||
|
|
|
@ -54,6 +54,5 @@ export default [
|
||||||
'UNSUPPORTED_BROWSERS',
|
'UNSUPPORTED_BROWSERS',
|
||||||
'VERTICAL_FILMSTRIP',
|
'VERTICAL_FILMSTRIP',
|
||||||
'VIDEO_LAYOUT_FIT',
|
'VIDEO_LAYOUT_FIT',
|
||||||
'VIDEO_QUALITY_LABEL_DISABLED',
|
'VIDEO_QUALITY_LABEL_DISABLED'
|
||||||
'filmStripOnly'
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -84,13 +84,7 @@ class Watermarks extends Component<Props, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
let showBrandWatermark;
|
const showBrandWatermark = interfaceConfig.SHOW_BRAND_WATERMARK;
|
||||||
|
|
||||||
if (interfaceConfig.filmStripOnly) {
|
|
||||||
showBrandWatermark = false;
|
|
||||||
} else {
|
|
||||||
showBrandWatermark = interfaceConfig.SHOW_BRAND_WATERMARK;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
brandWatermarkLink:
|
brandWatermarkLink:
|
||||||
|
@ -237,12 +231,11 @@ function _mapStateToProps(state, ownProps) {
|
||||||
const {
|
const {
|
||||||
DEFAULT_LOGO_URL,
|
DEFAULT_LOGO_URL,
|
||||||
JITSI_WATERMARK_LINK,
|
JITSI_WATERMARK_LINK,
|
||||||
SHOW_JITSI_WATERMARK,
|
SHOW_JITSI_WATERMARK
|
||||||
filmStripOnly
|
|
||||||
} = interfaceConfig;
|
} = interfaceConfig;
|
||||||
let _showJitsiWatermark = (!filmStripOnly
|
let _showJitsiWatermark = (
|
||||||
&& (customizationReady && !customizationFailed)
|
customizationReady && !customizationFailed
|
||||||
&& SHOW_JITSI_WATERMARK)
|
&& SHOW_JITSI_WATERMARK)
|
||||||
|| !isValidRoom;
|
|| !isValidRoom;
|
||||||
let _logoUrl = logoImageUrl;
|
let _logoUrl = logoImageUrl;
|
||||||
let _logoLink = logoClickUrl;
|
let _logoLink = logoClickUrl;
|
||||||
|
|
|
@ -152,11 +152,9 @@ StateListenerRegistry.register(
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function _addChatMsgListener(conference, store) {
|
function _addChatMsgListener(conference, store) {
|
||||||
if ((typeof interfaceConfig === 'object' && interfaceConfig.filmStripOnly)
|
if ((typeof APP !== 'undefined' && !isButtonEnabled('chat'))
|
||||||
|| (typeof APP !== 'undefined' && !isButtonEnabled('chat'))
|
|
||||||
|| store.getState()['features/base/config'].iAmRecorder) {
|
|| store.getState()['features/base/config'].iAmRecorder) {
|
||||||
// We don't register anything on web if we're in filmStripOnly mode, or
|
// We don't register anything on web if the chat button is not enabled in interfaceConfig
|
||||||
// the chat button is not enabled in interfaceConfig.
|
|
||||||
// or we are in iAmRecorder mode
|
// or we are in iAmRecorder mode
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { CalleeInfoContainer } from '../../../invite';
|
||||||
import { LargeVideo } from '../../../large-video';
|
import { LargeVideo } from '../../../large-video';
|
||||||
import { KnockingParticipantList, LobbyScreen } from '../../../lobby';
|
import { KnockingParticipantList, LobbyScreen } from '../../../lobby';
|
||||||
import { Prejoin, isPrejoinPageVisible } from '../../../prejoin';
|
import { Prejoin, isPrejoinPageVisible } from '../../../prejoin';
|
||||||
import { fullScreenChanged, setToolboxAlwaysVisible, showToolbox } from '../../../toolbox/actions.web';
|
import { fullScreenChanged, showToolbox } from '../../../toolbox/actions.web';
|
||||||
import { Toolbox } from '../../../toolbox/components/web';
|
import { Toolbox } from '../../../toolbox/components/web';
|
||||||
import { LAYOUTS, getCurrentLayout } from '../../../video-layout';
|
import { LAYOUTS, getCurrentLayout } from '../../../video-layout';
|
||||||
import { maybeShowSuboptimalExperienceNotification } from '../../functions';
|
import { maybeShowSuboptimalExperienceNotification } from '../../functions';
|
||||||
|
@ -28,7 +28,6 @@ import Labels from './Labels';
|
||||||
import { default as Notice } from './Notice';
|
import { default as Notice } from './Notice';
|
||||||
|
|
||||||
declare var APP: Object;
|
declare var APP: Object;
|
||||||
declare var config: Object;
|
|
||||||
declare var interfaceConfig: Object;
|
declare var interfaceConfig: Object;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -175,18 +174,13 @@ class Conference extends AbstractConference<Props, *> {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const {
|
|
||||||
// XXX The character casing of the name filmStripOnly utilized by
|
|
||||||
// interfaceConfig is obsolete but legacy support is required.
|
|
||||||
filmStripOnly: filmstripOnly
|
|
||||||
} = interfaceConfig;
|
|
||||||
const {
|
const {
|
||||||
_iAmRecorder,
|
_iAmRecorder,
|
||||||
_isLobbyScreenVisible,
|
_isLobbyScreenVisible,
|
||||||
_layoutClassName,
|
_layoutClassName,
|
||||||
_showPrejoin
|
_showPrejoin
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const hideLabels = filmstripOnly || _iAmRecorder;
|
const hideLabels = _iAmRecorder;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -198,18 +192,18 @@ class Conference extends AbstractConference<Props, *> {
|
||||||
<div id = 'videospace'>
|
<div id = 'videospace'>
|
||||||
<LargeVideo />
|
<LargeVideo />
|
||||||
<KnockingParticipantList />
|
<KnockingParticipantList />
|
||||||
<Filmstrip filmstripOnly = { filmstripOnly } />
|
<Filmstrip />
|
||||||
{ hideLabels || <Labels /> }
|
{ hideLabels || <Labels /> }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ filmstripOnly || _showPrejoin || _isLobbyScreenVisible || <Toolbox /> }
|
{ _showPrejoin || _isLobbyScreenVisible || <Toolbox /> }
|
||||||
{ filmstripOnly || <Chat /> }
|
<Chat />
|
||||||
|
|
||||||
{ this.renderNotificationsContainer() }
|
{ this.renderNotificationsContainer() }
|
||||||
|
|
||||||
<CalleeInfoContainer />
|
<CalleeInfoContainer />
|
||||||
|
|
||||||
{ !filmstripOnly && _showPrejoin && <Prejoin />}
|
{ _showPrejoin && <Prejoin />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -256,9 +250,6 @@ class Conference extends AbstractConference<Props, *> {
|
||||||
dispatch(connect());
|
dispatch(connect());
|
||||||
|
|
||||||
maybeShowSuboptimalExperienceNotification(dispatch, t);
|
maybeShowSuboptimalExperienceNotification(dispatch, t);
|
||||||
|
|
||||||
interfaceConfig.filmStripOnly
|
|
||||||
&& dispatch(setToolboxAlwaysVisible(true));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ export function maybeOpenFeedbackDialog(conference: Object) {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const { feedbackPercentage = 100 } = state['features/base/config'];
|
const { feedbackPercentage = 100 } = state['features/base/config'];
|
||||||
|
|
||||||
if (interfaceConfig.filmStripOnly || config.iAmRecorder) {
|
if (config.iAmRecorder) {
|
||||||
// Intentionally fall through the if chain to prevent further action
|
// Intentionally fall through the if chain to prevent further action
|
||||||
// from being taken with regards to showing feedback.
|
// from being taken with regards to showing feedback.
|
||||||
} else if (state['features/base/dialog'].component === FeedbackDialog) {
|
} else if (state['features/base/dialog'].component === FeedbackDialog) {
|
||||||
|
|
|
@ -17,8 +17,6 @@ import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
|
||||||
import { setFilmstripHovered, setFilmstripVisible } from '../../actions';
|
import { setFilmstripHovered, setFilmstripVisible } from '../../actions';
|
||||||
import { shouldRemoteVideosBeVisible } from '../../functions';
|
import { shouldRemoteVideosBeVisible } from '../../functions';
|
||||||
|
|
||||||
import Toolbar from './Toolbar';
|
|
||||||
|
|
||||||
declare var APP: Object;
|
declare var APP: Object;
|
||||||
declare var interfaceConfig: Object;
|
declare var interfaceConfig: Object;
|
||||||
|
|
||||||
|
@ -42,11 +40,6 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
_columns: number,
|
_columns: number,
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the UI/UX is filmstrip-only.
|
|
||||||
*/
|
|
||||||
_filmstripOnly: boolean,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width of the filmstrip.
|
* The width of the filmstrip.
|
||||||
*/
|
*/
|
||||||
|
@ -142,14 +135,12 @@ class Filmstrip extends Component <Props> {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (!this.props._filmstripOnly) {
|
APP.keyboardshortcut.registerShortcut(
|
||||||
APP.keyboardshortcut.registerShortcut(
|
'F',
|
||||||
'F',
|
'filmstripPopover',
|
||||||
'filmstripPopover',
|
this._onShortcutToggleFilmstrip,
|
||||||
this._onShortcutToggleFilmstrip,
|
'keyboardShortcuts.toggleFilmstrip'
|
||||||
'keyboardShortcuts.toggleFilmstrip'
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -207,7 +198,7 @@ class Filmstrip extends Component <Props> {
|
||||||
let toolbar = null;
|
let toolbar = null;
|
||||||
|
|
||||||
if (!this.props._hideToolbar) {
|
if (!this.props._hideToolbar) {
|
||||||
toolbar = this.props._filmstripOnly ? <Toolbar /> : this._renderToggleButton();
|
toolbar = this._renderToggleButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -367,24 +358,20 @@ class Filmstrip extends Component <Props> {
|
||||||
function _mapStateToProps(state) {
|
function _mapStateToProps(state) {
|
||||||
const { iAmSipGateway } = state['features/base/config'];
|
const { iAmSipGateway } = state['features/base/config'];
|
||||||
const { hovered, visible } = state['features/filmstrip'];
|
const { hovered, visible } = state['features/filmstrip'];
|
||||||
const isFilmstripOnly = Boolean(interfaceConfig.filmStripOnly);
|
|
||||||
const reduceHeight
|
const reduceHeight
|
||||||
= !isFilmstripOnly && state['features/toolbox'].visible && interfaceConfig.TOOLBAR_BUTTONS.length;
|
= state['features/toolbox'].visible && interfaceConfig.TOOLBAR_BUTTONS.length;
|
||||||
const remoteVideosVisible = shouldRemoteVideosBeVisible(state);
|
const remoteVideosVisible = shouldRemoteVideosBeVisible(state);
|
||||||
const { isOpen: shiftRight } = state['features/chat'];
|
const { isOpen: shiftRight } = state['features/chat'];
|
||||||
const className = `${remoteVideosVisible ? '' : 'hide-videos'} ${
|
const className = `${remoteVideosVisible ? '' : 'hide-videos'} ${
|
||||||
reduceHeight ? 'reduce-height' : ''
|
reduceHeight ? 'reduce-height' : ''
|
||||||
} ${shiftRight ? 'shift-right' : ''}`.trim();
|
} ${shiftRight ? 'shift-right' : ''}`.trim();
|
||||||
const videosClassName = `filmstrip__videos${
|
const videosClassName = `filmstrip__videos${visible ? '' : ' hidden'}`;
|
||||||
isFilmstripOnly ? ' filmstrip__videos-filmstripOnly' : ''}${
|
|
||||||
visible ? '' : ' hidden'}`;
|
|
||||||
const { gridDimensions = {}, filmstripWidth } = state['features/filmstrip'].tileViewDimensions;
|
const { gridDimensions = {}, filmstripWidth } = state['features/filmstrip'].tileViewDimensions;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_className: className,
|
_className: className,
|
||||||
_columns: gridDimensions.columns,
|
_columns: gridDimensions.columns,
|
||||||
_currentLayout: getCurrentLayout(state),
|
_currentLayout: getCurrentLayout(state),
|
||||||
_filmstripOnly: isFilmstripOnly,
|
|
||||||
_filmstripWidth: filmstripWidth,
|
_filmstripWidth: filmstripWidth,
|
||||||
_hideScrollbar: Boolean(iAmSipGateway),
|
_hideScrollbar: Boolean(iAmSipGateway),
|
||||||
_hideToolbar: Boolean(iAmSipGateway),
|
_hideToolbar: Boolean(iAmSipGateway),
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
|
|
||||||
import { connect, equals } from '../../../base/redux';
|
|
||||||
import { SettingsButton } from '../../../settings';
|
|
||||||
import {
|
|
||||||
AudioMuteButton,
|
|
||||||
HangupButton,
|
|
||||||
VideoMuteButton
|
|
||||||
} from '../../../toolbox/components';
|
|
||||||
|
|
||||||
declare var interfaceConfig: Object;
|
|
||||||
|
|
||||||
// XXX: We are not currently using state here, but in the future, when
|
|
||||||
// interfaceConfig is part of redux we will. This has to be retrieved from the store.
|
|
||||||
const visibleButtons = new Set(interfaceConfig.TOOLBAR_BUTTONS);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of the React {@code Component} props of {@link Toolbar}.
|
|
||||||
*/
|
|
||||||
type Props = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The set of buttons which should be visible in this {@code Toolbar}.
|
|
||||||
*/
|
|
||||||
_visibleButtons: Set<string>
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the conference toolbar on React/Web for filmstrip-only mode.
|
|
||||||
*
|
|
||||||
* @extends Component
|
|
||||||
*/
|
|
||||||
class Toolbar extends Component<Props> {
|
|
||||||
/**
|
|
||||||
* Implements React's {@link Component#render()}.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {ReactElement}
|
|
||||||
*/
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className = 'filmstrip-toolbox'
|
|
||||||
id = 'new-toolbox'>
|
|
||||||
<HangupButton
|
|
||||||
tooltipPosition = 'left'
|
|
||||||
visible = { this._shouldShowButton('hangup') } />
|
|
||||||
<AudioMuteButton
|
|
||||||
tooltipPosition = 'left'
|
|
||||||
visible = { this._shouldShowButton('microphone') } />
|
|
||||||
<VideoMuteButton
|
|
||||||
tooltipPosition = 'left'
|
|
||||||
visible = { this._shouldShowButton('camera') } />
|
|
||||||
<SettingsButton
|
|
||||||
tooltipPosition = 'left'
|
|
||||||
visible = { this._shouldShowButton('fodeviceselection') } />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_shouldShowButton: (string) => boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if a button name has been explicitly configured to be displayed.
|
|
||||||
*
|
|
||||||
* @param {string} buttonName - The name of the button, as expected in
|
|
||||||
* {@link intefaceConfig}.
|
|
||||||
* @private
|
|
||||||
* @returns {boolean} True if the button should be displayed, false
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
_shouldShowButton(buttonName) {
|
|
||||||
return this.props._visibleButtons.has(buttonName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps (parts of) the redux state to the associated props for this component.
|
|
||||||
*
|
|
||||||
* @param {Object} state - The Redux state.
|
|
||||||
* @private
|
|
||||||
* @returns {{
|
|
||||||
* _visibleButtons: Set<string>
|
|
||||||
* }}
|
|
||||||
*/
|
|
||||||
function _mapStateToProps(state): Object { // eslint-disable-line no-unused-vars
|
|
||||||
// XXX: We are not currently using state here, but in the future, when
|
|
||||||
// interfaceConfig is part of redux we will.
|
|
||||||
//
|
|
||||||
// NB: We compute the buttons again here because if URL parameters were used to
|
|
||||||
// override them we'd miss it.
|
|
||||||
const buttons = new Set(interfaceConfig.TOOLBAR_BUTTONS);
|
|
||||||
|
|
||||||
return {
|
|
||||||
_visibleButtons: equals(visibleButtons, buttons) ? visibleButtons : buttons
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(_mapStateToProps)(Toolbar);
|
|
|
@ -56,9 +56,6 @@ export function shouldRemoteVideosBeVisible(state: Object) {
|
||||||
|| ((pinnedParticipant = getPinnedParticipant(state))
|
|| ((pinnedParticipant = getPinnedParticipant(state))
|
||||||
&& pinnedParticipant.local)))
|
&& pinnedParticipant.local)))
|
||||||
|
|
||||||
|| (typeof interfaceConfig === 'object'
|
|
||||||
&& interfaceConfig.filmStripOnly)
|
|
||||||
|
|
||||||
|| state['features/base/config'].disable1On1Mode);
|
|| state['features/base/config'].disable1On1Mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
|
|
||||||
import { Avatar } from '../../../base/avatar';
|
|
||||||
import { getLocalParticipant } from '../../../base/participants';
|
|
||||||
import { connect } from '../../../base/redux';
|
|
||||||
|
|
||||||
import OverlayFrame from './OverlayFrame';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of the React {@code Component} props of
|
|
||||||
* {@link FilmstripOnlyOverlayFrame}.
|
|
||||||
*/
|
|
||||||
type Props = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The ID of the local participant.
|
|
||||||
*/
|
|
||||||
_localParticipantId: string,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The children components to be displayed into the overlay frame for
|
|
||||||
* filmstrip only mode.
|
|
||||||
*/
|
|
||||||
children: React$Node,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The css class name for the icon that will be displayed over the avatar.
|
|
||||||
*/
|
|
||||||
icon: string,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates the css style of the overlay. If true, then lighter; darker,
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
isLightOverlay: boolean
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements a React Component for the frame of the overlays in filmstrip only
|
|
||||||
* mode.
|
|
||||||
*/
|
|
||||||
class FilmstripOnlyOverlayFrame extends Component<Props> {
|
|
||||||
/**
|
|
||||||
* Renders content related to the icon.
|
|
||||||
*
|
|
||||||
* @returns {ReactElement|null}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_renderIcon() {
|
|
||||||
if (!this.props.icon) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const iconClass = `inlay-filmstrip-only__icon ${this.props.icon}`;
|
|
||||||
const iconBGClass = 'inlay-filmstrip-only__icon-background';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div className = { iconBGClass } />
|
|
||||||
<div className = 'inlay-filmstrip-only__icon-container'>
|
|
||||||
<span className = { iconClass } />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements React's {@link Component#render()}.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {ReactElement}
|
|
||||||
*/
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<OverlayFrame isLightOverlay = { this.props.isLightOverlay }>
|
|
||||||
<div className = 'inlay-filmstrip-only'>
|
|
||||||
<div className = 'inlay-filmstrip-only__content'>
|
|
||||||
{
|
|
||||||
this.props.children
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div className = 'inlay-filmstrip-only__avatar-container'>
|
|
||||||
<Avatar participantId = { this.props._localParticipantId } />
|
|
||||||
{
|
|
||||||
this._renderIcon()
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</OverlayFrame>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps (parts of) the Redux state to the associated FilmstripOnlyOverlayFrame
|
|
||||||
* props.
|
|
||||||
*
|
|
||||||
* @param {Object} state - The Redux state.
|
|
||||||
* @private
|
|
||||||
* @returns {{
|
|
||||||
* _localParticipantId: string
|
|
||||||
* }}
|
|
||||||
*/
|
|
||||||
function _mapStateToProps(state) {
|
|
||||||
return {
|
|
||||||
_localParticipantId: (getLocalParticipant(state) || {}).id
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(_mapStateToProps)(FilmstripOnlyOverlayFrame);
|
|
|
@ -21,44 +21,10 @@ type Props = {
|
||||||
isLightOverlay?: boolean
|
isLightOverlay?: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of the React {@code Component} state of {@link OverlayFrame}.
|
|
||||||
*/
|
|
||||||
type State = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not the application is currently displaying in filmstrip only
|
|
||||||
* mode.
|
|
||||||
*/
|
|
||||||
filmstripOnly: boolean
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements a React {@link Component} for the frame of the overlays.
|
* Implements a React {@link Component} for the frame of the overlays.
|
||||||
*/
|
*/
|
||||||
export default class OverlayFrame extends Component<Props, State> {
|
export default class OverlayFrame extends Component<Props> {
|
||||||
/**
|
|
||||||
* Initializes a new AbstractOverlay instance.
|
|
||||||
*
|
|
||||||
* @param {Object} props - The read-only properties with which the new
|
|
||||||
* instance is to be initialized.
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
constructor(props: Props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
/**
|
|
||||||
* Indicates whether the filmstrip only mode is enabled or not.
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
filmstripOnly:
|
|
||||||
typeof interfaceConfig !== 'undefined'
|
|
||||||
&& interfaceConfig.filmStripOnly
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements React's {@link Component#render()}.
|
* Implements React's {@link Component#render()}.
|
||||||
*
|
*
|
||||||
|
@ -66,20 +32,11 @@ export default class OverlayFrame extends Component<Props, State> {
|
||||||
* @returns {ReactElement|null}
|
* @returns {ReactElement|null}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
let containerClass = this.props.isLightOverlay
|
|
||||||
? 'overlay__container-light' : 'overlay__container';
|
|
||||||
let contentClass = 'overlay__content';
|
|
||||||
|
|
||||||
if (this.state.filmstripOnly) {
|
|
||||||
containerClass += ' filmstrip-only';
|
|
||||||
contentClass += ' filmstrip-only';
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className = { containerClass }
|
className = { this.props.isLightOverlay ? 'overlay__container-light' : 'overlay__container' }
|
||||||
id = 'overlay'>
|
id = 'overlay'>
|
||||||
<div className = { contentClass }>
|
<div className = { 'overlay__content' }>
|
||||||
{
|
{
|
||||||
this.props.children
|
this.props.children
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { translate } from '../../../base/i18n';
|
|
||||||
import { connect } from '../../../base/redux';
|
|
||||||
import AbstractPageReloadOverlay, { type Props, abstractMapStateToProps }
|
|
||||||
from '../AbstractPageReloadOverlay';
|
|
||||||
|
|
||||||
import FilmstripOnlyOverlayFrame from './FilmstripOnlyOverlayFrame';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements a React Component for page reload overlay for filmstrip only
|
|
||||||
* mode. Shown before the conference is reloaded. Shows a warning message and
|
|
||||||
* counts down towards the reload.
|
|
||||||
*/
|
|
||||||
class PageReloadFilmstripOnlyOverlay extends AbstractPageReloadOverlay<Props> {
|
|
||||||
/**
|
|
||||||
* Implements React's {@link Component#render()}.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {ReactElement}
|
|
||||||
*/
|
|
||||||
render() {
|
|
||||||
const { t } = this.props;
|
|
||||||
const { message, timeLeft, title } = this.state;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FilmstripOnlyOverlayFrame>
|
|
||||||
<div className = 'inlay-filmstrip-only__container'>
|
|
||||||
<div className = 'inlay-filmstrip-only__title'>
|
|
||||||
{ t(title) }
|
|
||||||
</div>
|
|
||||||
<div className = 'inlay-filmstrip-only__text'>
|
|
||||||
{ t(message, { seconds: timeLeft }) }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{ this._renderButton() }
|
|
||||||
{ this._renderProgressBar() }
|
|
||||||
</FilmstripOnlyOverlayFrame>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_renderButton: () => React$Element<*> | null
|
|
||||||
|
|
||||||
_renderProgressBar: () => React$Element<*> | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export default translate(
|
|
||||||
connect(abstractMapStateToProps)(PageReloadFilmstripOnlyOverlay));
|
|
|
@ -1,41 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { translate, translateToHTML } from '../../../base/i18n';
|
|
||||||
|
|
||||||
import AbstractSuspendedOverlay from './AbstractSuspendedOverlay';
|
|
||||||
import FilmstripOnlyOverlayFrame from './FilmstripOnlyOverlayFrame';
|
|
||||||
import ReloadButton from './ReloadButton';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements a React Component for suspended overlay for filmstrip only mode.
|
|
||||||
* Shown when suspended is detected.
|
|
||||||
*/
|
|
||||||
class SuspendedFilmstripOnlyOverlay extends AbstractSuspendedOverlay {
|
|
||||||
/**
|
|
||||||
* Implements React's {@link Component#render()}.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {ReactElement}
|
|
||||||
*/
|
|
||||||
render() {
|
|
||||||
const { t } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FilmstripOnlyOverlayFrame isLightOverlay = { true }>
|
|
||||||
<div className = 'inlay-filmstrip-only__container'>
|
|
||||||
<div className = 'inlay-filmstrip-only__title'>
|
|
||||||
{ t('suspendedoverlay.title') }
|
|
||||||
</div>
|
|
||||||
<div className = 'inlay-filmstrip-only__text'>
|
|
||||||
{ translateToHTML(t, 'suspendedoverlay.text') }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ReloadButton textKey = 'suspendedoverlay.rejoinKeyTitle' />
|
|
||||||
</FilmstripOnlyOverlayFrame>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default translate(SuspendedFilmstripOnlyOverlay);
|
|
|
@ -1,54 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { translate, translateToHTML } from '../../../base/i18n';
|
|
||||||
import { connect } from '../../../base/redux';
|
|
||||||
|
|
||||||
import AbstractUserMediaPermissionsOverlay, { abstractMapStateToProps }
|
|
||||||
from './AbstractUserMediaPermissionsOverlay';
|
|
||||||
import FilmstripOnlyOverlayFrame from './FilmstripOnlyOverlayFrame';
|
|
||||||
|
|
||||||
declare var interfaceConfig: Object;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements a React Component for overlay with guidance how to proceed with
|
|
||||||
* gUM prompt. This component will be displayed only for filmstrip only mode.
|
|
||||||
*/
|
|
||||||
class UserMediaPermissionsFilmstripOnlyOverlay
|
|
||||||
extends AbstractUserMediaPermissionsOverlay {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements React's {@link Component#render()}.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {ReactElement}
|
|
||||||
*/
|
|
||||||
render() {
|
|
||||||
const { t } = this.props;
|
|
||||||
const textKey = `userMedia.${this.props.browser}GrantPermissions`;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FilmstripOnlyOverlayFrame
|
|
||||||
icon = 'icon-mic-camera-combined'
|
|
||||||
isLightOverlay = { true }>
|
|
||||||
<div className = 'inlay-filmstrip-only__container'>
|
|
||||||
<div className = 'inlay-filmstrip-only__title'>
|
|
||||||
{
|
|
||||||
t('startupoverlay.title',
|
|
||||||
{ app: interfaceConfig.APP_NAME })
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div className = 'inlay-filmstrip-only__text'>
|
|
||||||
{
|
|
||||||
translateToHTML(t, textKey)
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</FilmstripOnlyOverlayFrame>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default translate(
|
|
||||||
connect(abstractMapStateToProps)(UserMediaPermissionsFilmstripOnlyOverlay));
|
|
|
@ -1,19 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
export { default as FilmstripOnlyOverlayFrame } from './FilmstripOnlyOverlayFrame';
|
|
||||||
export { default as OverlayFrame } from './OverlayFrame';
|
export { default as OverlayFrame } from './OverlayFrame';
|
||||||
|
|
||||||
export {
|
|
||||||
default as PageReloadFilmstripOnlyOverlay
|
|
||||||
} from './PageReloadFilmstripOnlyOverlay';
|
|
||||||
export { default as PageReloadOverlay } from './PageReloadOverlay';
|
export { default as PageReloadOverlay } from './PageReloadOverlay';
|
||||||
export {
|
|
||||||
default as SuspendedFilmstripOnlyOverlay
|
|
||||||
} from './SuspendedFilmstripOnlyOverlay';
|
|
||||||
export { default as SuspendedOverlay } from './SuspendedOverlay';
|
export { default as SuspendedOverlay } from './SuspendedOverlay';
|
||||||
export {
|
export { default as UserMediaPermissionsOverlay } from './UserMediaPermissionsOverlay';
|
||||||
default as UserMediaPermissionsFilmstripOnlyOverlay
|
|
||||||
} from './UserMediaPermissionsFilmstripOnlyOverlay';
|
|
||||||
export {
|
|
||||||
default as UserMediaPermissionsOverlay
|
|
||||||
} from './UserMediaPermissionsOverlay';
|
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PageReloadFilmstripOnlyOverlay,
|
|
||||||
PageReloadOverlay,
|
PageReloadOverlay,
|
||||||
SuspendedFilmstripOnlyOverlay,
|
|
||||||
SuspendedOverlay,
|
SuspendedOverlay,
|
||||||
UserMediaPermissionsFilmstripOnlyOverlay,
|
|
||||||
UserMediaPermissionsOverlay
|
UserMediaPermissionsOverlay
|
||||||
} from './components/web';
|
} from './components/web';
|
||||||
|
|
||||||
|
@ -17,22 +14,9 @@ declare var interfaceConfig: Object;
|
||||||
* @returns {Array<Object>}
|
* @returns {Array<Object>}
|
||||||
*/
|
*/
|
||||||
export function getOverlays(): Array<Object> {
|
export function getOverlays(): Array<Object> {
|
||||||
const overlays = [
|
return [
|
||||||
|
PageReloadOverlay,
|
||||||
SuspendedOverlay,
|
SuspendedOverlay,
|
||||||
UserMediaPermissionsOverlay
|
UserMediaPermissionsOverlay
|
||||||
];
|
];
|
||||||
|
|
||||||
const filmstripOnly
|
|
||||||
= typeof interfaceConfig === 'object' && interfaceConfig.filmStripOnly;
|
|
||||||
|
|
||||||
if (filmstripOnly) {
|
|
||||||
overlays.push(
|
|
||||||
PageReloadFilmstripOnlyOverlay,
|
|
||||||
SuspendedFilmstripOnlyOverlay,
|
|
||||||
UserMediaPermissionsFilmstripOnlyOverlay);
|
|
||||||
} else {
|
|
||||||
overlays.push(PageReloadOverlay);
|
|
||||||
}
|
|
||||||
|
|
||||||
return overlays;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,22 +5,14 @@ import { translate } from '../../../base/i18n';
|
||||||
import { IconSettings } from '../../../base/icons';
|
import { IconSettings } from '../../../base/icons';
|
||||||
import { connect } from '../../../base/redux';
|
import { connect } from '../../../base/redux';
|
||||||
import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
|
import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
|
||||||
import { openDeviceSelectionPopup } from '../../../device-selection';
|
|
||||||
import { openSettingsDialog } from '../../actions';
|
import { openSettingsDialog } from '../../actions';
|
||||||
import { SETTINGS_TABS } from '../../constants';
|
import { SETTINGS_TABS } from '../../constants';
|
||||||
|
|
||||||
declare var interfaceConfig: Object;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of {@link SettingsButton}.
|
* The type of the React {@code Component} props of {@link SettingsButton}.
|
||||||
*/
|
*/
|
||||||
type Props = AbstractButtonProps & {
|
type Props = AbstractButtonProps & {
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether we are in filmstrip only mode or not.
|
|
||||||
*/
|
|
||||||
_filmstripOnly: boolean,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default tab at which the settings dialog will be opened.
|
* The default tab at which the settings dialog will be opened.
|
||||||
*/
|
*/
|
||||||
|
@ -49,36 +41,12 @@ class SettingsButton extends AbstractButton<Props, *> {
|
||||||
*/
|
*/
|
||||||
_handleClick() {
|
_handleClick() {
|
||||||
const {
|
const {
|
||||||
_filmstripOnly,
|
|
||||||
defaultTab = SETTINGS_TABS.DEVICES,
|
defaultTab = SETTINGS_TABS.DEVICES,
|
||||||
dispatch } = this.props;
|
dispatch } = this.props;
|
||||||
|
|
||||||
sendAnalytics(createToolbarEvent('settings'));
|
sendAnalytics(createToolbarEvent('settings'));
|
||||||
if (_filmstripOnly) {
|
dispatch(openSettingsDialog(defaultTab));
|
||||||
dispatch(openDeviceSelectionPopup());
|
|
||||||
} else {
|
|
||||||
dispatch(openSettingsDialog(defaultTab));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export default translate(connect()(SettingsButton));
|
||||||
* Maps (parts of) the redux state to the associated props for the
|
|
||||||
* {@code SettingsButton} component.
|
|
||||||
*
|
|
||||||
* @param {Object} state - The Redux state.
|
|
||||||
* @private
|
|
||||||
* @returns {{
|
|
||||||
* _filmstripOnly: boolean
|
|
||||||
* }}
|
|
||||||
*/
|
|
||||||
function _mapStateToProps(state): Object { // eslint-disable-line no-unused-vars
|
|
||||||
// XXX: We are not currently using state here, but in the future, when
|
|
||||||
// interfaceConfig is part of redux we will.
|
|
||||||
|
|
||||||
return {
|
|
||||||
_filmstripOnly: Boolean(interfaceConfig.filmStripOnly)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default translate(connect(_mapStateToProps)(SettingsButton));
|
|
||||||
|
|
|
@ -25,10 +25,6 @@ export * from './actions.native';
|
||||||
*/
|
*/
|
||||||
export function dockToolbox(dock: boolean): Function {
|
export function dockToolbox(dock: boolean): Function {
|
||||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||||
if (interfaceConfig.filmStripOnly) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { timeoutMS, visible } = getState()['features/toolbox'];
|
const { timeoutMS, visible } = getState()['features/toolbox'];
|
||||||
|
|
||||||
if (dock) {
|
if (dock) {
|
||||||
|
|
|
@ -99,9 +99,6 @@ export function shouldDisplayTileView(state: Object = {}) {
|
||||||
// Editing etherpad
|
// Editing etherpad
|
||||||
state['features/etherpad']?.editing
|
state['features/etherpad']?.editing
|
||||||
|
|
||||||
// We're in filmstrip-only mode
|
|
||||||
|| (typeof interfaceConfig === 'object' && interfaceConfig?.filmStripOnly)
|
|
||||||
|
|
||||||
// We pinned a participant
|
// We pinned a participant
|
||||||
|| getPinnedParticipant(state)
|
|| getPinnedParticipant(state)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue