ref: Convert files to TS (#12007)
Convert files that use material-ui to TS (needed for material-ui upgrade)
This commit is contained in:
parent
fc60ab8383
commit
3bd3be4df0
|
@ -143,6 +143,7 @@
|
|||
"@types/react": "17.0.14",
|
||||
"@types/react-native": "0.68.1",
|
||||
"@types/react-redux": "7.1.24",
|
||||
"@types/react-window": "1.8.5",
|
||||
"@types/unorm": "1.3.28",
|
||||
"@types/uuid": "8.3.4",
|
||||
"@types/zxcvbn": "4.4.1",
|
||||
|
@ -5534,6 +5535,15 @@
|
|||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-window": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz",
|
||||
"integrity": "sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/retry": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz",
|
||||
|
@ -23993,6 +24003,15 @@
|
|||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-window": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz",
|
||||
"integrity": "sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/retry": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz",
|
||||
|
|
|
@ -148,6 +148,7 @@
|
|||
"@types/react": "17.0.14",
|
||||
"@types/react-native": "0.68.1",
|
||||
"@types/react-redux": "7.1.24",
|
||||
"@types/react-window": "1.8.5",
|
||||
"@types/unorm": "1.3.28",
|
||||
"@types/uuid": "8.3.4",
|
||||
"@types/zxcvbn": "4.4.1",
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @flow
|
||||
|
||||
import { PureComponent } from 'react';
|
||||
|
||||
export type Props = {
|
||||
|
@ -32,21 +30,21 @@ export type Props = {
|
|||
/**
|
||||
* The URL of the avatar to render.
|
||||
*/
|
||||
url?: ?string | Object
|
||||
url?: string|Function
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements an abstract stateless avatar component that renders an avatar purely from what gets passed through
|
||||
* props.
|
||||
*/
|
||||
export default class AbstractStatelessAvatar<P: Props> extends PureComponent<P> {
|
||||
export default class AbstractStatelessAvatar<P extends Props> extends PureComponent<P> {
|
||||
/**
|
||||
* Checks if the passed prop is a loaded icon or not.
|
||||
*
|
||||
* @param {string? | Object?} iconProp - The prop to check.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_isIcon(iconProp: ?string | ?Object): boolean {
|
||||
_isIcon(iconProp?: string | Function): iconProp is Function {
|
||||
return Boolean(iconProp) && (typeof iconProp === 'object' || typeof iconProp === 'function');
|
||||
}
|
||||
}
|
|
@ -1,25 +1,23 @@
|
|||
// @flow
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
import { Icon } from '../../../icons';
|
||||
import Icon from '../../../icons/components/Icon';
|
||||
import AbstractStatelessAvatar, { type Props as AbstractProps } from '../AbstractStatelessAvatar';
|
||||
import { PRESENCE_AVAILABLE_COLOR, PRESENCE_AWAY_COLOR, PRESENCE_BUSY_COLOR, PRESENCE_IDLE_COLOR } from '../styles';
|
||||
|
||||
type Props = AbstractProps & {
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: Object,
|
||||
|
||||
/**
|
||||
* External class name passed through props.
|
||||
*/
|
||||
className?: string,
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: any,
|
||||
|
||||
/**
|
||||
* The default avatar URL if we want to override the app bundled one (e.g. AlwaysOnTop).
|
||||
*/
|
||||
|
@ -33,7 +31,7 @@ type Props = AbstractProps & {
|
|||
/**
|
||||
* One of the expected status strings (e.g. 'available') to render a badge on the avatar, if necessary.
|
||||
*/
|
||||
status?: ?string,
|
||||
status?: string,
|
||||
|
||||
/**
|
||||
* TestId of the element, if any.
|
||||
|
@ -43,7 +41,7 @@ type Props = AbstractProps & {
|
|||
/**
|
||||
* Indicates whether to load the avatar using CORS or not.
|
||||
*/
|
||||
useCORS?: ?boolean
|
||||
useCORS?: boolean
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -211,10 +209,10 @@ class StatelessAvatar extends AbstractStatelessAvatar<Props> {
|
|||
/**
|
||||
* Constructs a style object to be used on the avatars.
|
||||
*
|
||||
* @param {string?} color - The desired background color.
|
||||
* @param {string} color - The desired background color.
|
||||
* @returns {Object}
|
||||
*/
|
||||
_getAvatarStyle(color) {
|
||||
_getAvatarStyle(color?: string) {
|
||||
const { size } = this.props;
|
||||
|
||||
return {
|
||||
|
@ -231,7 +229,7 @@ class StatelessAvatar extends AbstractStatelessAvatar<Props> {
|
|||
* @param {string} additional - Any additional class to add.
|
||||
* @returns {string}
|
||||
*/
|
||||
_getAvatarClassName(additional) {
|
||||
_getAvatarClassName(additional?: string) {
|
||||
return clsx('avatar', additional, this.props.className, this.props.classes.avatar);
|
||||
}
|
||||
|
||||
|
@ -250,10 +248,6 @@ class StatelessAvatar extends AbstractStatelessAvatar<Props> {
|
|||
return '';
|
||||
}
|
||||
|
||||
_isIcon: (?string | ?Object) => boolean;
|
||||
|
||||
_onAvatarLoadError: () => void;
|
||||
|
||||
/**
|
||||
* Handles avatar load errors.
|
||||
*
|
||||
|
@ -268,4 +262,5 @@ class StatelessAvatar extends AbstractStatelessAvatar<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
export default withStyles(styles)(StatelessAvatar);
|
|
@ -1,17 +1,15 @@
|
|||
// @flow
|
||||
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
|
||||
import { withStyles } from '@material-ui/styles';
|
||||
import clsx from 'clsx';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { Icon, IconCheck, IconCopy } from '../../base/icons';
|
||||
import Icon from '../icons/components/Icon';
|
||||
import { IconCheck, IconCopy } from '../icons/svg/index';
|
||||
import { withPixelLineHeight } from '../styles/functions.web';
|
||||
import { copyText } from '../util';
|
||||
import { Theme } from '../ui/types';
|
||||
import { copyText } from '../util/helpers';
|
||||
|
||||
|
||||
const styles = theme => {
|
||||
const styles = (theme: Theme) => {
|
||||
return {
|
||||
copyButton: {
|
||||
...withPixelLineHeight(theme.typography.bodyLongRegular),
|
||||
|
@ -54,34 +52,29 @@ const styles = theme => {
|
|||
};
|
||||
};
|
||||
|
||||
let mounted;
|
||||
let mounted: boolean;
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: Object,
|
||||
|
||||
/**
|
||||
* Css class to apply on container.
|
||||
*/
|
||||
className: string,
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: any,
|
||||
|
||||
/**
|
||||
* The displayed text.
|
||||
*/
|
||||
displayedText: string,
|
||||
|
||||
/**
|
||||
* The text that needs to be copied (might differ from the displayedText).
|
||||
* The id of the button.
|
||||
*/
|
||||
textToCopy: string,
|
||||
|
||||
/**
|
||||
* The text displayed on mouse hover.
|
||||
*/
|
||||
textOnHover: string,
|
||||
id?: string,
|
||||
|
||||
/**
|
||||
* The text displayed on copy success.
|
||||
|
@ -89,9 +82,14 @@ type Props = {
|
|||
textOnCopySuccess: string,
|
||||
|
||||
/**
|
||||
* The id of the button.
|
||||
* The text displayed on mouse hover.
|
||||
*/
|
||||
id?: string,
|
||||
textOnHover: string,
|
||||
|
||||
/**
|
||||
* The text that needs to be copied (might differ from the displayedText).
|
||||
*/
|
||||
textToCopy: string
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -160,7 +158,7 @@ function CopyButton({ classes, className, displayedText, textToCopy, textOnHover
|
|||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function onKeyPress(e) {
|
||||
function onKeyPress(e: React.KeyboardEvent) {
|
||||
if (onClick && (e.key === ' ' || e.key === 'Enter')) {
|
||||
e.preventDefault();
|
||||
onClick();
|
||||
|
@ -216,4 +214,5 @@ CopyButton.defaultProps = {
|
|||
className: ''
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
export default withStyles(styles)(CopyButton);
|
|
@ -1,11 +1,14 @@
|
|||
// @flow
|
||||
/* eslint-disable lines-around-comment */
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import clsx from 'clsx';
|
||||
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import React, { ReactNode, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
// @ts-ignore
|
||||
import { getComputedOuterHeight } from '../../../participants-pane/functions';
|
||||
// @ts-ignore
|
||||
import { Drawer, JitsiPortal } from '../../../toolbox/components/web';
|
||||
// @ts-ignore
|
||||
import { showOverflowDrawer } from '../../../toolbox/functions.web';
|
||||
import participantsPaneTheme from '../themes/participantsPaneTheme.json';
|
||||
|
||||
|
@ -19,12 +22,12 @@ type Props = {
|
|||
/**
|
||||
* Children of the context menu.
|
||||
*/
|
||||
children: React$Node,
|
||||
children: ReactNode,
|
||||
|
||||
/**
|
||||
* Class name for context menu. Used to overwrite default styles.
|
||||
*/
|
||||
className?: ?string,
|
||||
className?: string,
|
||||
|
||||
/**
|
||||
* The entity for which the context menu is displayed.
|
||||
|
@ -39,7 +42,7 @@ type Props = {
|
|||
/**
|
||||
* Whether or not the menu is already in a drawer.
|
||||
*/
|
||||
inDrawer?: ?boolean,
|
||||
inDrawer?: boolean,
|
||||
|
||||
/**
|
||||
* Whether or not drawer should be open.
|
||||
|
@ -54,32 +57,32 @@ type Props = {
|
|||
/**
|
||||
* Callback for click on an item in the menu.
|
||||
*/
|
||||
onClick?: Function,
|
||||
|
||||
/**
|
||||
* Keydown handler.
|
||||
*/
|
||||
onKeyDown?: Function,
|
||||
onClick?: (e?: React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* Callback for drawer close.
|
||||
*/
|
||||
onDrawerClose?: Function,
|
||||
onDrawerClose?: (e?: React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* Keydown handler.
|
||||
*/
|
||||
onKeyDown?: (e?: React.KeyboardEvent) => void,
|
||||
|
||||
/**
|
||||
* Callback for the mouse entering the component.
|
||||
*/
|
||||
onMouseEnter?: Function,
|
||||
onMouseEnter?: (e?: React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* Callback for the mouse leaving the component.
|
||||
*/
|
||||
onMouseLeave?: Function
|
||||
onMouseLeave?: (e?: React.MouseEvent) => void
|
||||
};
|
||||
|
||||
const MAX_HEIGHT = 400;
|
||||
|
||||
const useStyles = makeStyles(theme => {
|
||||
const useStyles = makeStyles((theme: any) => {
|
||||
return {
|
||||
contextMenu: {
|
||||
backgroundColor: theme.palette.ui02,
|
|
@ -1,12 +1,11 @@
|
|||
// @flow
|
||||
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import React, { ReactNode } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
// @ts-ignore
|
||||
import { showOverflowDrawer } from '../../../toolbox/functions.web';
|
||||
import { Icon } from '../../icons';
|
||||
import Icon from '../../icons/components/Icon';
|
||||
|
||||
export type Props = {
|
||||
|
||||
|
@ -24,37 +23,37 @@ export type Props = {
|
|||
* Custom icon. If used, the icon prop is ignored.
|
||||
* Used to allow custom children instead of just the default icons.
|
||||
*/
|
||||
customIcon?: React$Node,
|
||||
customIcon?: ReactNode,
|
||||
|
||||
/**
|
||||
* Whether or not the action is disabled.
|
||||
*/
|
||||
disabled?: boolean,
|
||||
|
||||
/**
|
||||
* Id of the action container.
|
||||
*/
|
||||
id?: string,
|
||||
|
||||
/**
|
||||
* Default icon for action.
|
||||
*/
|
||||
icon?: Function,
|
||||
|
||||
/**
|
||||
* Id of the action container.
|
||||
*/
|
||||
id?: string,
|
||||
|
||||
/**
|
||||
* Click handler.
|
||||
*/
|
||||
onClick?: Function,
|
||||
onClick?: (e?: React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* Keydown handler.
|
||||
*/
|
||||
onKeyDown?: Function,
|
||||
onKeyDown?: (e?: React.KeyboardEvent) => void,
|
||||
|
||||
/**
|
||||
* Keypress handler.
|
||||
*/
|
||||
onKeyPress?: Function,
|
||||
onKeyPress?: (e?: React.KeyboardEvent) => void,
|
||||
|
||||
/**
|
||||
* TestId of the element, if any.
|
||||
|
@ -72,7 +71,7 @@ export type Props = {
|
|||
textClassName?: string
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(theme => {
|
||||
const useStyles = makeStyles((theme: any) => {
|
||||
return {
|
||||
contextMenuItem: {
|
||||
alignItems: 'center',
|
||||
|
@ -121,7 +120,7 @@ const ContextMenuItem = ({
|
|||
text,
|
||||
textClassName }: Props) => {
|
||||
const styles = useStyles();
|
||||
const _overflowDrawer = useSelector(showOverflowDrawer);
|
||||
const _overflowDrawer: boolean = useSelector(showOverflowDrawer);
|
||||
|
||||
return (
|
||||
<div
|
|
@ -1,8 +1,7 @@
|
|||
// @flow
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import React, { ReactNode } from 'react';
|
||||
|
||||
import ContextMenuItem from './ContextMenuItem';
|
||||
import ContextMenuItem, { Props as ItemProps } from './ContextMenuItem';
|
||||
|
||||
|
||||
type Props = {
|
||||
|
@ -10,15 +9,15 @@ type Props = {
|
|||
/**
|
||||
* List of actions in this group.
|
||||
*/
|
||||
actions?: Array<Object>,
|
||||
actions?: Array<ItemProps>,
|
||||
|
||||
/**
|
||||
* The children of the component.
|
||||
*/
|
||||
children?: React$Node,
|
||||
children?: ReactNode,
|
||||
};
|
||||
|
||||
const useStyles = makeStyles(theme => {
|
||||
const useStyles = makeStyles((theme: any) => {
|
||||
return {
|
||||
contextMenuItemGroup: {
|
||||
'&:not(:empty)': {
|
|
@ -1,9 +1,8 @@
|
|||
// @flow
|
||||
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import React, { ReactNode } from 'react';
|
||||
|
||||
// @ts-ignore
|
||||
import { ACTION_TRIGGER } from '../../../participants-pane/constants';
|
||||
import { isMobileBrowser } from '../../environment/utils';
|
||||
import participantsPaneTheme from '../themes/participantsPaneTheme.json';
|
||||
|
@ -13,32 +12,32 @@ type Props = {
|
|||
/**
|
||||
* List item actions.
|
||||
*/
|
||||
actions: React$Node,
|
||||
actions: ReactNode,
|
||||
|
||||
/**
|
||||
* List item container class name.
|
||||
*/
|
||||
className: string,
|
||||
|
||||
/**
|
||||
* Whether or not the actions should be hidden.
|
||||
*/
|
||||
hideActions?: boolean,
|
||||
|
||||
/**
|
||||
* Icon to be displayed on the list item. (Avatar for participants).
|
||||
*/
|
||||
icon: React$Node,
|
||||
icon: ReactNode,
|
||||
|
||||
/**
|
||||
* Id of the container.
|
||||
*/
|
||||
id: string,
|
||||
|
||||
/**
|
||||
* Whether or not the actions should be hidden.
|
||||
*/
|
||||
hideActions?: Boolean,
|
||||
|
||||
/**
|
||||
* Indicators to be displayed on the list item.
|
||||
*/
|
||||
indicators?: React$Node,
|
||||
indicators?: ReactNode,
|
||||
|
||||
/**
|
||||
* Whether or not the item is highlighted.
|
||||
|
@ -48,17 +47,17 @@ type Props = {
|
|||
/**
|
||||
* Click handler.
|
||||
*/
|
||||
onClick: Function,
|
||||
onClick: (e?: React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* Long press handler.
|
||||
*/
|
||||
onLongPress: Function,
|
||||
onLongPress: (e?: EventTarget) => void,
|
||||
|
||||
/**
|
||||
* Mouse leave handler.
|
||||
*/
|
||||
onMouseLeave: Function,
|
||||
onMouseLeave: (e?: React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* Data test id.
|
||||
|
@ -68,7 +67,7 @@ type Props = {
|
|||
/**
|
||||
* Text children to be displayed on the list item.
|
||||
*/
|
||||
textChildren: React$Node | string,
|
||||
textChildren: ReactNode | string,
|
||||
|
||||
/**
|
||||
* The actions trigger. Can be Hover or Permanent.
|
||||
|
@ -77,7 +76,7 @@ type Props = {
|
|||
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(theme => {
|
||||
const useStyles = makeStyles((theme: any) => {
|
||||
return {
|
||||
container: {
|
||||
alignItems: 'center',
|
||||
|
@ -194,7 +193,7 @@ const ListItem = ({
|
|||
}: Props) => {
|
||||
const styles = useStyles();
|
||||
const _isMobile = isMobileBrowser();
|
||||
let timeoutHandler;
|
||||
let timeoutHandler: number;
|
||||
|
||||
/**
|
||||
* Set calling long press handler after x milliseconds.
|
||||
|
@ -202,10 +201,10 @@ const ListItem = ({
|
|||
* @param {TouchEvent} e - Touch start event.
|
||||
* @returns {void}
|
||||
*/
|
||||
function _onTouchStart(e) {
|
||||
function _onTouchStart(e: React.TouchEvent) {
|
||||
const target = e.touches[0].target;
|
||||
|
||||
timeoutHandler = setTimeout(() => onLongPress(target), 600);
|
||||
timeoutHandler = window.setTimeout(() => onLongPress(target), 600);
|
||||
}
|
||||
|
||||
/**
|
|
@ -1,4 +1,4 @@
|
|||
// @flow
|
||||
/* eslint-disable lines-around-comment */
|
||||
/* eslint-disable react/no-multi-comp */
|
||||
import ErrorIcon from '@atlaskit/icon/glyph/error';
|
||||
import WarningIcon from '@atlaskit/icon/glyph/warning';
|
||||
|
@ -7,12 +7,15 @@ import {
|
|||
Title,
|
||||
titleIconWrapperStyles,
|
||||
TitleText
|
||||
// @ts-ignore
|
||||
} from '@atlaskit/modal-dialog/dist/es2019/styled/Content';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import React from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
|
||||
import { translate } from '../../../i18n';
|
||||
import { translate } from '../../../i18n/functions';
|
||||
import { IconClose } from '../../../icons/svg/index';
|
||||
// @ts-ignore
|
||||
import { withPixelLineHeight } from '../../../styles/functions';
|
||||
import Button from '../../../ui/components/web/Button';
|
||||
import { BUTTON_TYPES } from '../../../ui/constants';
|
||||
|
@ -31,17 +34,16 @@ const TitleIcon = ({ appearance }: { appearance?: 'danger' | 'warning' }) => {
|
|||
);
|
||||
};
|
||||
|
||||
type Props = {
|
||||
id: string,
|
||||
interface Props extends WithTranslation {
|
||||
appearance?: 'danger' | 'warning',
|
||||
classes: Object,
|
||||
classes: any,
|
||||
heading: string,
|
||||
hideCloseIconButton: boolean,
|
||||
onClose: Function,
|
||||
showKeyline: boolean,
|
||||
id?: string,
|
||||
isHeadingMultiline: boolean,
|
||||
testId: string,
|
||||
t: Function
|
||||
onClose: (e?: any) => void,
|
||||
showKeyline: boolean,
|
||||
testId?: string
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,7 +53,7 @@ type Props = {
|
|||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
const styles = theme => {
|
||||
const styles = (theme: any) => {
|
||||
return {
|
||||
closeButton: {
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
|
@ -95,15 +97,13 @@ class ModalHeader extends React.Component<Props> {
|
|||
* @param {*} props - The read-only properties with which the new instance
|
||||
* is to be initialized.
|
||||
*/
|
||||
constructor(props) {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handler so it is only bound once for every instance.
|
||||
this._onKeyPress = this._onKeyPress.bind(this);
|
||||
}
|
||||
|
||||
_onKeyPress: (Object) => void;
|
||||
|
||||
/**
|
||||
* KeyPress handler for accessibility.
|
||||
*
|
||||
|
@ -111,7 +111,7 @@ class ModalHeader extends React.Component<Props> {
|
|||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_onKeyPress(e) {
|
||||
_onKeyPress(e: React.KeyboardEvent) {
|
||||
if (this.props.onClose && (e.key === ' ' || e.key === 'Enter')) {
|
||||
e.preventDefault();
|
||||
this.props.onClose();
|
|
@ -1,9 +1,8 @@
|
|||
// @flow
|
||||
|
||||
/* eslint-disable lines-around-comment */
|
||||
import Modal, { ModalFooter } from '@atlaskit/modal-dialog';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import _ from 'lodash';
|
||||
import React, { Component } from 'react';
|
||||
import React, { Component, ReactElement } from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
|
||||
import { translate } from '../../../i18n/functions';
|
||||
import Button from '../../../ui/components/web/Button';
|
||||
|
@ -31,17 +30,23 @@ const OK_BUTTON_ID = 'modal-dialog-ok-button';
|
|||
*
|
||||
* @static
|
||||
*/
|
||||
type Props = DialogProps & {
|
||||
interface Props extends DialogProps, WithTranslation {
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: Object,
|
||||
classes: any,
|
||||
|
||||
/**
|
||||
* Custom dialog header that replaces the standard heading.
|
||||
*/
|
||||
customHeader?: React$Element<any> | Function,
|
||||
customHeader?: ReactElement<any> | Function,
|
||||
|
||||
/**
|
||||
* Disables dismissing the dialog when the blanket is clicked. Enabled
|
||||
* by default.
|
||||
*/
|
||||
disableBlanketClickDismiss: boolean,
|
||||
|
||||
/*
|
||||
* True if listening for the Enter key should be disabled.
|
||||
|
@ -49,10 +54,9 @@ type Props = DialogProps & {
|
|||
disableEnter: boolean,
|
||||
|
||||
/**
|
||||
* Disables dismissing the dialog when the blanket is clicked. Enabled
|
||||
* by default.
|
||||
* If true, no footer will be displayed.
|
||||
*/
|
||||
disableBlanketClickDismiss: boolean,
|
||||
disableFooter?: boolean,
|
||||
|
||||
/**
|
||||
* If true, the cancel button will not display but cancel actions, like
|
||||
|
@ -65,13 +69,6 @@ type Props = DialogProps & {
|
|||
*/
|
||||
hideCloseIconButton: boolean,
|
||||
|
||||
/**
|
||||
* If true, no footer will be displayed.
|
||||
*/
|
||||
disableFooter?: boolean,
|
||||
|
||||
i18n: Object,
|
||||
|
||||
/**
|
||||
* Whether the dialog is modal. This means clicking on the blanket will
|
||||
* leave the dialog open. No cancel button.
|
||||
|
@ -82,7 +79,7 @@ type Props = DialogProps & {
|
|||
* The handler for the event when clicking the 'confirmNo' button.
|
||||
* Defaults to onCancel if absent.
|
||||
*/
|
||||
onDecline?: Function,
|
||||
onDecline?: () => void,
|
||||
|
||||
/**
|
||||
* Callback invoked when setting the ref of the Dialog.
|
||||
|
@ -94,11 +91,6 @@ type Props = DialogProps & {
|
|||
*/
|
||||
submitDisabled: boolean,
|
||||
|
||||
/**
|
||||
* Function to be used to retrieve translated i18n labels.
|
||||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* Width of the dialog, can be:
|
||||
* - 'small' (400px), 'medium' (600px), 'large' (800px),
|
||||
|
@ -107,7 +99,7 @@ type Props = DialogProps & {
|
|||
* - string value for percentage.
|
||||
*/
|
||||
width: string
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the styles for the component.
|
||||
|
@ -115,7 +107,7 @@ type Props = DialogProps & {
|
|||
* @param {Object} theme - The theme.
|
||||
* @returns {Object}
|
||||
*/
|
||||
const styles = theme => {
|
||||
const styles = (theme: any) => {
|
||||
return {
|
||||
footer: {
|
||||
boxShadow: 'none'
|
||||
|
@ -139,20 +131,13 @@ class StatelessDialog extends Component<Props> {
|
|||
hideCloseIconButton: false
|
||||
};
|
||||
|
||||
/**
|
||||
* The functional component to be used for rendering the modal footer.
|
||||
*/
|
||||
_Footer: ?Function;
|
||||
|
||||
_dialogElement: ?HTMLElement;
|
||||
|
||||
/**
|
||||
* Initializes a new {@code StatelessDialog} instance.
|
||||
*
|
||||
* @param {Object} props - The read-only properties with which the new
|
||||
* instance is to be initialized.
|
||||
*/
|
||||
constructor(props) {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once for every instance.
|
||||
|
@ -175,7 +160,7 @@ class StatelessDialog extends Component<Props> {
|
|||
customHeader,
|
||||
children,
|
||||
hideCloseIconButton,
|
||||
t /* The following fixes a flow error: */ = _.identity,
|
||||
t,
|
||||
titleString,
|
||||
titleKey,
|
||||
width
|
||||
|
@ -185,10 +170,12 @@ class StatelessDialog extends Component<Props> {
|
|||
<Modal
|
||||
autoFocus = { true }
|
||||
components = {{
|
||||
// @ts-ignore
|
||||
Header: customHeader ? customHeader : props => (
|
||||
// @ts-ignore
|
||||
<ModalHeader
|
||||
{ ...props }
|
||||
heading = { titleString || t(titleKey) }
|
||||
heading = { titleString || t(titleKey ?? '') }
|
||||
hideCloseIconButton = { hideCloseIconButton } />
|
||||
)
|
||||
}}
|
||||
|
@ -212,8 +199,6 @@ class StatelessDialog extends Component<Props> {
|
|||
);
|
||||
}
|
||||
|
||||
_renderFooter: () => React$Node;
|
||||
|
||||
/**
|
||||
* Returns a ReactElement to display buttons for closing the modal.
|
||||
*
|
||||
|
@ -222,7 +207,7 @@ class StatelessDialog extends Component<Props> {
|
|||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderFooter(propsFromModalFooter) {
|
||||
_renderFooter(propsFromModalFooter: any) {
|
||||
// Filter out falsy (null) values because {@code ButtonGroup} will error
|
||||
// if passed in anything but buttons with valid type props.
|
||||
const buttons = [
|
||||
|
@ -252,8 +237,6 @@ class StatelessDialog extends Component<Props> {
|
|||
);
|
||||
}
|
||||
|
||||
_onCancel: () => void;
|
||||
|
||||
/**
|
||||
* Dispatches action to hide the dialog.
|
||||
*
|
||||
|
@ -267,8 +250,6 @@ class StatelessDialog extends Component<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
_onDialogDismissed: () => void;
|
||||
|
||||
/**
|
||||
* Handles click on the blanket area.
|
||||
*
|
||||
|
@ -280,8 +261,6 @@ class StatelessDialog extends Component<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
_onSubmit: (?string) => void;
|
||||
|
||||
/**
|
||||
* Dispatches the action when submitting the dialog.
|
||||
*
|
||||
|
@ -289,7 +268,7 @@ class StatelessDialog extends Component<Props> {
|
|||
* @param {string} value - The submitted value if any.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onSubmit(value) {
|
||||
_onSubmit(value?: any) {
|
||||
const { onSubmit } = this.props;
|
||||
|
||||
onSubmit && onSubmit(value);
|
||||
|
@ -310,12 +289,13 @@ class StatelessDialog extends Component<Props> {
|
|||
}
|
||||
|
||||
const {
|
||||
t /* The following fixes a flow error: */ = _.identity,
|
||||
t,
|
||||
onDecline
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Button
|
||||
accessibilityLabel = { t(this.props.cancelKey || 'dialog.Cancel') }
|
||||
id = { CANCEL_BUTTON_ID }
|
||||
key = { CANCEL_BUTTON_ID }
|
||||
label = { t(this.props.cancelKey || 'dialog.Cancel') }
|
||||
|
@ -332,16 +312,18 @@ class StatelessDialog extends Component<Props> {
|
|||
* @returns {ReactElement|null} The OK button if enabled.
|
||||
*/
|
||||
_renderOKButton() {
|
||||
if (this.props.submitDisabled) {
|
||||
const {
|
||||
submitDisabled,
|
||||
t
|
||||
} = this.props;
|
||||
|
||||
if (submitDisabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
t /* The following fixes a flow error: */ = _.identity
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Button
|
||||
accessibilityLabel = { t(this.props.okKey || 'dialog.Ok') }
|
||||
disabled = { this.props.okDisabled }
|
||||
id = { OK_BUTTON_ID }
|
||||
key = { OK_BUTTON_ID }
|
||||
|
@ -351,8 +333,6 @@ class StatelessDialog extends Component<Props> {
|
|||
);
|
||||
}
|
||||
|
||||
_onDialogRef: (?Element) => void;
|
||||
|
||||
/**
|
||||
* Callback invoked when setting the ref of the dialog's child passing the Modal ref.
|
||||
* It is done this way because we cannot directly access the ref of the Modal component.
|
||||
|
@ -361,12 +341,10 @@ class StatelessDialog extends Component<Props> {
|
|||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onDialogRef(element: ?Element) {
|
||||
_onDialogRef(element?: any) {
|
||||
this.props.onDialogRef && this.props.onDialogRef(element && element.parentNode);
|
||||
}
|
||||
|
||||
_onKeyPress: (Object) => void;
|
||||
|
||||
/**
|
||||
* Handles 'Enter' key in the dialog to submit/hide dialog depending on
|
||||
* the available buttons and their disabled state.
|
||||
|
@ -375,7 +353,7 @@ class StatelessDialog extends Component<Props> {
|
|||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onKeyPress(event) {
|
||||
_onKeyPress(event: React.KeyboardEvent) {
|
||||
// If the event coming to the dialog has been subject to preventDefault
|
||||
// we don't handle it here.
|
||||
if (event.defaultPrevented) {
|
|
@ -1,31 +1,31 @@
|
|||
// @flow
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
export type DialogProps = {
|
||||
|
||||
/**
|
||||
* Whether cancel button is disabled. Enabled by default.
|
||||
*/
|
||||
cancelDisabled: ?boolean,
|
||||
cancelDisabled?: boolean,
|
||||
|
||||
/**
|
||||
* Optional i18n key to change the cancel button title.
|
||||
*/
|
||||
cancelKey: ?string,
|
||||
cancelKey?: string,
|
||||
|
||||
/**
|
||||
* The React {@code Component} children which represents the dialog's body.
|
||||
*/
|
||||
children: ?React$Node,
|
||||
children?: ReactNode,
|
||||
|
||||
/**
|
||||
* Is ok button enabled/disabled. Enabled by default.
|
||||
*/
|
||||
okDisabled: ?boolean,
|
||||
okDisabled?: boolean,
|
||||
|
||||
/**
|
||||
* Optional i18n key to change the ok button title.
|
||||
*/
|
||||
okKey: ?string,
|
||||
okKey?: string,
|
||||
|
||||
/**
|
||||
* The handler for onCancel event.
|
||||
|
@ -47,14 +47,14 @@ export type DialogProps = {
|
|||
/**
|
||||
* Key to use for showing a title.
|
||||
*/
|
||||
titleKey: ?string,
|
||||
titleKey?: string,
|
||||
|
||||
/**
|
||||
* The string to use as a title instead of {@code titleKey}. If a truthy
|
||||
* value is specified, it takes precedence over {@code titleKey} i.e.
|
||||
* The latter is unused.
|
||||
*/
|
||||
titleString: ?string
|
||||
titleString?: string
|
||||
};
|
||||
|
||||
/**
|
|
@ -159,7 +159,7 @@ export function getFirstLoadableAvatarUrl(participant: Participant, store: IStor
|
|||
* features/base/participants.
|
||||
* @returns {(Participant|undefined)}
|
||||
*/
|
||||
export function getLocalParticipant(stateful: IStore | Function) {
|
||||
export function getLocalParticipant(stateful: IStore | Function | IState) {
|
||||
const state = toState(stateful)['features/base/participants'];
|
||||
|
||||
return state.local;
|
||||
|
@ -342,7 +342,7 @@ export function getParticipantCountWithFake(stateful: IStore | Function) {
|
|||
* @param {string} id - The ID of the participant's display name to retrieve.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getParticipantDisplayName(stateful: IStore | Function, id: string): string {
|
||||
export function getParticipantDisplayName(stateful: IStore | Function | IState, id: string): string {
|
||||
const participant = getParticipantById(stateful, id);
|
||||
const {
|
||||
defaultLocalDisplayName,
|
||||
|
@ -374,7 +374,7 @@ export function getParticipantDisplayName(stateful: IStore | Function, id: strin
|
|||
* @param {string} id - The ID of the screenshare participant's display name to retrieve.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getScreenshareParticipantDisplayName(stateful: IStore | Function, id: string) {
|
||||
export function getScreenshareParticipantDisplayName(stateful: IStore | Function| IState, id: string) {
|
||||
const ownerDisplayName = getParticipantDisplayName(stateful, getVirtualScreenshareParticipantOwnerId(id));
|
||||
|
||||
return i18next.t('screenshareDisplayName', { name: ownerDisplayName });
|
||||
|
@ -648,6 +648,6 @@ export function getRaiseHandsQueue(stateful: IStore | Function): Array<Object> {
|
|||
* @param {Object} participant - The participant.
|
||||
* @returns {boolean} - Whether participant has raise hand or not.
|
||||
*/
|
||||
export function hasRaisedHand(participant: Participant): boolean {
|
||||
return Boolean(participant && participant.raisedHandTimestamp);
|
||||
export function hasRaisedHand(participant?: Participant): boolean {
|
||||
return Boolean(participant?.raisedHandTimestamp);
|
||||
}
|
||||
|
|
|
@ -1,29 +1,48 @@
|
|||
// @flow
|
||||
|
||||
import { withStyles } from '@material-ui/styles';
|
||||
import clsx from 'clsx';
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { ReactNode, useCallback } from 'react';
|
||||
|
||||
import { Icon, IconArrowDown } from '../../../icons';
|
||||
import Icon from '../../../icons/components/Icon';
|
||||
import { IconArrowDown } from '../../../icons/svg/index';
|
||||
import { withPixelLineHeight } from '../../../styles/functions.web';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Text of the button.
|
||||
* Icon to display in the options section.
|
||||
*/
|
||||
children: React$Node,
|
||||
OptionsIcon?: Function,
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
* The Label of the child element.
|
||||
*/
|
||||
classes: Object,
|
||||
ariaDropDownLabel?: string,
|
||||
|
||||
/**
|
||||
* The Label of the current element.
|
||||
*/
|
||||
ariaLabel?: string,
|
||||
|
||||
/**
|
||||
* To give a aria-pressed to the icon.
|
||||
*/
|
||||
ariaPressed?: boolean,
|
||||
|
||||
/**
|
||||
* Text of the button.
|
||||
*/
|
||||
children: ReactNode,
|
||||
|
||||
/**
|
||||
* Text css class of the button.
|
||||
*/
|
||||
className?: string,
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: any,
|
||||
|
||||
/**
|
||||
* If the button is disabled or not.
|
||||
*/
|
||||
|
@ -34,10 +53,26 @@ type Props = {
|
|||
*/
|
||||
hasOptions?: boolean,
|
||||
|
||||
|
||||
/**
|
||||
* Icon to display in the options section.
|
||||
* OnClick button handler.
|
||||
*/
|
||||
OptionsIcon?: React$Node,
|
||||
onClick?: (e?: React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* Click handler for options.
|
||||
*/
|
||||
onOptionsClick?: (e?: React.KeyboardEvent | React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* To give a role to the icon.
|
||||
*/
|
||||
role?: string,
|
||||
|
||||
/**
|
||||
* To navigate with the keyboard.
|
||||
*/
|
||||
tabIndex?: number,
|
||||
|
||||
/**
|
||||
* TestId of the button. Can be used to locate element when testing UI.
|
||||
|
@ -47,43 +82,7 @@ type Props = {
|
|||
/**
|
||||
* The type of th button: primary, secondary, text.
|
||||
*/
|
||||
type: string,
|
||||
|
||||
/**
|
||||
* OnClick button handler.
|
||||
*/
|
||||
onClick: Function,
|
||||
|
||||
|
||||
/**
|
||||
* Click handler for options.
|
||||
*/
|
||||
onOptionsClick?: Function,
|
||||
|
||||
/**
|
||||
* To navigate with the keyboard.
|
||||
*/
|
||||
tabIndex?: number,
|
||||
|
||||
/**
|
||||
* To give a role to the icon.
|
||||
*/
|
||||
role?: string,
|
||||
|
||||
/**
|
||||
* To give a aria-pressed to the icon.
|
||||
*/
|
||||
ariaPressed?: boolean,
|
||||
|
||||
/**
|
||||
* The Label of the current element.
|
||||
*/
|
||||
ariaLabel?: string,
|
||||
|
||||
/**
|
||||
* The Label of the child element.
|
||||
*/
|
||||
ariaDropDownLabel?: string
|
||||
type: string
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -93,7 +92,7 @@ type Props = {
|
|||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
const styles = theme => {
|
||||
const styles = (theme: any) => {
|
||||
return {
|
||||
actionButton: {
|
||||
...withPixelLineHeight(theme.typography.bodyLongBold),
|
||||
|
@ -254,4 +253,5 @@ function ActionButton({
|
|||
);
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
export default withStyles(styles)(ActionButton);
|
|
@ -1,16 +1,21 @@
|
|||
// @flow
|
||||
|
||||
/* eslint-disable lines-around-comment */
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
|
||||
import { translate } from '../../../i18n';
|
||||
import { Icon, IconArrowDownSmall, IconWifi1Bar, IconWifi2Bars, IconWifi3Bars } from '../../../icons';
|
||||
import { connect } from '../../../redux';
|
||||
import { IState } from '../../../../app/types';
|
||||
import { translate } from '../../../i18n/functions';
|
||||
import Icon from '../../../icons/components/Icon';
|
||||
import { IconArrowDownSmall, IconWifi1Bar, IconWifi2Bars, IconWifi3Bars } from '../../../icons/svg/index';
|
||||
import { connect } from '../../../redux/functions';
|
||||
// @ts-ignore
|
||||
import { PREJOIN_DEFAULT_CONTENT_WIDTH } from '../../../ui/components/variables';
|
||||
// @ts-ignore
|
||||
import { CONNECTION_TYPE } from '../../constants';
|
||||
// @ts-ignore
|
||||
import { getConnectionData } from '../../functions';
|
||||
|
||||
type Props = {
|
||||
interface Props extends WithTranslation {
|
||||
|
||||
/**
|
||||
* List of strings with details about the connection.
|
||||
|
@ -20,15 +25,10 @@ type Props = {
|
|||
/**
|
||||
* The type of the connection. Can be: 'none', 'poor', 'nonOptimal' or 'good'.
|
||||
*/
|
||||
connectionType: string,
|
||||
|
||||
/**
|
||||
* Used for translation.
|
||||
*/
|
||||
t: Function
|
||||
connectionType: string
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(theme => {
|
||||
const useStyles = makeStyles((theme: any) => {
|
||||
return {
|
||||
connectionStatus: {
|
||||
borderRadius: '6px',
|
||||
|
@ -121,7 +121,7 @@ const useStyles = makeStyles(theme => {
|
|||
};
|
||||
});
|
||||
|
||||
const CONNECTION_TYPE_MAP = {
|
||||
const CONNECTION_TYPE_MAP: any = {
|
||||
[CONNECTION_TYPE.POOR]: {
|
||||
connectionClass: 'con-status--poor',
|
||||
icon: IconWifi1Bar,
|
||||
|
@ -152,7 +152,7 @@ function ConnectionStatus({ connectionDetails, t, connectionType }: Props) {
|
|||
const arrowClassName = showDetails
|
||||
? 'con-status-arrow con-status-arrow--up'
|
||||
: 'con-status-arrow';
|
||||
const detailsText = connectionDetails.map(t).join(' ');
|
||||
const detailsText = connectionDetails.map(d => t(d)).join(' ');
|
||||
const detailsClassName = showDetails
|
||||
? 'con-status-details-visible'
|
||||
: 'con-status-details-hidden';
|
||||
|
@ -202,7 +202,7 @@ function ConnectionStatus({ connectionDetails, t, connectionType }: Props) {
|
|||
tabIndex = { 0 } />
|
||||
</div>
|
||||
<div
|
||||
aria-level = '2'
|
||||
aria-level = { 2 }
|
||||
className = { `con-status-details ${detailsClassName}` }
|
||||
role = 'heading'>
|
||||
{detailsText}</div>
|
||||
|
@ -216,7 +216,7 @@ function ConnectionStatus({ connectionDetails, t, connectionType }: Props) {
|
|||
* @param {Object} state - The redux state.
|
||||
* @returns {Object}
|
||||
*/
|
||||
function mapStateToProps(state): Object {
|
||||
function mapStateToProps(state: IState): Object {
|
||||
const { connectionDetails, connectionType } = getConnectionData(state);
|
||||
|
||||
return {
|
|
@ -1,36 +1,37 @@
|
|||
/* @flow */
|
||||
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
|
||||
import { translate } from '../../../i18n';
|
||||
import { Icon } from '../../../icons';
|
||||
import { translate } from '../../../i18n/functions';
|
||||
import Icon from '../../../icons/components/Icon';
|
||||
// eslint-disable-next-line lines-around-comment
|
||||
// @ts-ignore
|
||||
import { Tooltip } from '../../../tooltip';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link BaseIndicator}.
|
||||
*/
|
||||
type Props = {
|
||||
interface Props extends WithTranslation {
|
||||
|
||||
/**
|
||||
* Additional CSS class name.
|
||||
*/
|
||||
className: string,
|
||||
className?: string,
|
||||
|
||||
/**
|
||||
* The icon component to use.
|
||||
*/
|
||||
icon: Object,
|
||||
icon: Function,
|
||||
|
||||
/**
|
||||
* The CSS classnames to set on the icon element of the component.
|
||||
*/
|
||||
iconClassName: string,
|
||||
iconClassName?: string,
|
||||
|
||||
/**
|
||||
* The color of the icon.
|
||||
*/
|
||||
iconColor: ?string,
|
||||
iconColor?: string,
|
||||
|
||||
/**
|
||||
* Id of the icon to be rendered.
|
||||
|
@ -45,12 +46,7 @@ type Props = {
|
|||
/**
|
||||
* The ID attribute to set on the root element of the component.
|
||||
*/
|
||||
id: string,
|
||||
|
||||
/**
|
||||
* Invoked to obtain translated strings.
|
||||
*/
|
||||
t: Function,
|
||||
id?: string,
|
||||
|
||||
/**
|
||||
* The translation key to use for displaying a tooltip when hovering over
|
||||
|
@ -63,7 +59,7 @@ type Props = {
|
|||
* defaulting to "top".
|
||||
*/
|
||||
tooltipPosition: string
|
||||
};
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(() => {
|
||||
return {
|
||||
|
@ -95,7 +91,7 @@ const BaseIndicator = ({
|
|||
tooltipPosition = 'top'
|
||||
}: Props) => {
|
||||
const styles = useStyles();
|
||||
const style = {};
|
||||
const style: any = {};
|
||||
|
||||
if (iconSize) {
|
||||
style.fontSize = iconSize;
|
|
@ -1,8 +1,8 @@
|
|||
// @flow
|
||||
|
||||
import { createStyles, makeStyles } from '@material-ui/core';
|
||||
|
||||
import { commonStyles, getGlobalStyles } from '../constants';
|
||||
// eslint-disable-next-line lines-around-comment
|
||||
// @ts-ignore
|
||||
import { formatCommonClasses } from '../functions';
|
||||
|
||||
/**
|
||||
|
@ -12,7 +12,7 @@ import { formatCommonClasses } from '../functions';
|
|||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
const useStyles = makeStyles(theme =>
|
||||
const useStyles = makeStyles((theme: any) =>
|
||||
createStyles({
|
||||
'@global': {
|
||||
...formatCommonClasses(commonStyles(theme)),
|
|
@ -1,5 +1,3 @@
|
|||
// @flow
|
||||
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import React from 'react';
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import clsx from 'clsx';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import React, { ReactElement, useEffect, useRef } from 'react';
|
||||
|
||||
import { isMobileBrowser } from '../../../base/environment/utils';
|
||||
|
||||
|
@ -11,7 +9,7 @@ type Props = {
|
|||
/**
|
||||
* The component(s) that need to be scrollable on mobile.
|
||||
*/
|
||||
children: React$Node,
|
||||
children: ReactElement,
|
||||
|
||||
/**
|
||||
* Whether the component should be flex container or not.
|
||||
|
@ -48,7 +46,7 @@ function TouchmoveHack({ children, isModal, flex }: Props) {
|
|||
return children;
|
||||
}
|
||||
|
||||
const touchMoveElementRef = useRef(null);
|
||||
const touchMoveElementRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
/**
|
||||
* Atlaskit's {@code Modal} uses a third party library to disable touchmove events
|
|
@ -1,15 +1,20 @@
|
|||
/* eslint-disable lines-around-comment */
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { IconRaisedHand } from '../../../base/icons';
|
||||
import { IState } from '../../../app/types';
|
||||
import { IconRaisedHand } from '../../../base/icons/svg/index';
|
||||
// @ts-ignore
|
||||
import { Label } from '../../../base/label';
|
||||
// @ts-ignore
|
||||
import { Tooltip } from '../../../base/tooltip';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme.web';
|
||||
// @ts-ignore
|
||||
import { open as openParticipantsPane } from '../../../participants-pane/actions';
|
||||
|
||||
const useStyles = makeStyles(theme => {
|
||||
const useStyles = makeStyles((theme: any) => {
|
||||
return {
|
||||
label: {
|
||||
backgroundColor: theme.palette.warning02,
|
||||
|
@ -22,7 +27,7 @@ const useStyles = makeStyles(theme => {
|
|||
const RaisedHandsCountLabel = () => {
|
||||
const styles = useStyles();
|
||||
const dispatch = useDispatch();
|
||||
const raisedHandsCount = useSelector(state =>
|
||||
const raisedHandsCount = useSelector((state: IState) =>
|
||||
(state['features/base/participants'].raisedHandsQueue || []).length);
|
||||
const { t } = useTranslation();
|
||||
const onClick = useCallback(() => {
|
||||
|
@ -38,7 +43,7 @@ const RaisedHandsCountLabel = () => {
|
|||
iconColor = { BaseTheme.palette.uiBackground }
|
||||
id = 'raisedHandsCountLabel'
|
||||
onClick = { onClick }
|
||||
text = { raisedHandsCount } />
|
||||
text = { `${raisedHandsCount}` } />
|
||||
</Tooltip>);
|
||||
};
|
||||
|
|
@ -1,33 +1,40 @@
|
|||
// @flow
|
||||
|
||||
/* eslint-disable lines-around-comment */
|
||||
import { withStyles } from '@material-ui/styles';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
import { connect } from 'react-redux';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { IState } from '../../../app/types';
|
||||
// @ts-ignore
|
||||
import { getSourceNameSignalingFeatureFlag } from '../../../base/config';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { MEDIA_TYPE } from '../../../base/media';
|
||||
import { getLocalParticipant, getParticipantById } from '../../../base/participants';
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import { MEDIA_TYPE } from '../../../base/media/constants';
|
||||
import { getLocalParticipant, getParticipantById } from '../../../base/participants/functions';
|
||||
// @ts-ignore
|
||||
import { Popover } from '../../../base/popover';
|
||||
import { connect } from '../../../base/redux';
|
||||
import {
|
||||
getVirtualScreenshareParticipantTrack,
|
||||
getSourceNameByParticipantId,
|
||||
getSourceNameByParticipantId, // @ts-ignore
|
||||
getTrackByMediaTypeAndParticipant } from '../../../base/tracks';
|
||||
import {
|
||||
isParticipantConnectionStatusInactive,
|
||||
isParticipantConnectionStatusInterrupted,
|
||||
isTrackStreamingStatusInactive,
|
||||
isTrackStreamingStatusInterrupted
|
||||
// @ts-ignore
|
||||
} from '../../functions';
|
||||
import AbstractConnectionIndicator, {
|
||||
INDICATOR_DISPLAY_THRESHOLD,
|
||||
type Props as AbstractProps,
|
||||
type State as AbstractState
|
||||
// @ts-ignore
|
||||
} from '../AbstractConnectionIndicator';
|
||||
|
||||
// @ts-ignore
|
||||
import ConnectionIndicatorContent from './ConnectionIndicatorContent';
|
||||
// @ts-ignore
|
||||
import { ConnectionIndicatorIcon } from './ConnectionIndicatorIcon';
|
||||
|
||||
/**
|
||||
|
@ -37,7 +44,11 @@ import { ConnectionIndicatorIcon } from './ConnectionIndicatorIcon';
|
|||
*
|
||||
* @type {Object[]}
|
||||
*/
|
||||
const QUALITY_TO_WIDTH: Array<Object> = [
|
||||
const QUALITY_TO_WIDTH: Array<{
|
||||
colorClass: string;
|
||||
percent: number;
|
||||
tip: string;
|
||||
}> = [
|
||||
|
||||
// Full (3 bars)
|
||||
{
|
||||
|
@ -66,7 +77,12 @@ const QUALITY_TO_WIDTH: Array<Object> = [
|
|||
/**
|
||||
* The type of the React {@code Component} props of {@link ConnectionIndicator}.
|
||||
*/
|
||||
type Props = AbstractProps & {
|
||||
type Props = AbstractProps & WithTranslation & {
|
||||
|
||||
/**
|
||||
* Disable/enable inactive indicator.
|
||||
*/
|
||||
_connectionIndicatorInactiveDisabled: boolean,
|
||||
|
||||
/**
|
||||
* The current condition of the user's connection, matching one of the
|
||||
|
@ -74,16 +90,21 @@ type Props = AbstractProps & {
|
|||
*/
|
||||
_connectionStatus: string,
|
||||
|
||||
/**
|
||||
* Disable/enable inactive indicator.
|
||||
*/
|
||||
_connectionIndicatorInactiveDisabled: boolean,
|
||||
|
||||
/**
|
||||
* Whether the indicator popover is disabled.
|
||||
*/
|
||||
_popoverDisabled: boolean,
|
||||
|
||||
/**
|
||||
* The source name of the track.
|
||||
*/
|
||||
_sourceName: string,
|
||||
|
||||
/**
|
||||
* Whether source name signaling is enabled.
|
||||
*/
|
||||
_sourceNameSignalingEnabled: boolean,
|
||||
|
||||
/**
|
||||
* Whether or not the component should ignore setting a visibility class for
|
||||
* hiding the component when the connection quality is not strong.
|
||||
|
@ -95,6 +116,7 @@ type Props = AbstractProps & {
|
|||
*/
|
||||
audioSsrc: number,
|
||||
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
|
@ -105,7 +127,6 @@ type Props = AbstractProps & {
|
|||
*/
|
||||
dispatch: Dispatch<any>,
|
||||
|
||||
|
||||
/**
|
||||
* Whether or not clicking the indicator should display a popover for more
|
||||
* details.
|
||||
|
@ -121,22 +142,7 @@ type Props = AbstractProps & {
|
|||
* Relative to the icon from where the popover for more connection details
|
||||
* should display.
|
||||
*/
|
||||
statsPopoverPosition: string,
|
||||
|
||||
/**
|
||||
* Invoked to obtain translated strings.
|
||||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* The source name of the track.
|
||||
*/
|
||||
_sourceName: string,
|
||||
|
||||
/**
|
||||
* Whether source name signaling is enabled.
|
||||
*/
|
||||
_sourceNameSignalingEnabled: boolean
|
||||
statsPopoverPosition: string
|
||||
};
|
||||
|
||||
type State = AbstractState & {
|
||||
|
@ -147,7 +153,7 @@ type State = AbstractState & {
|
|||
popoverVisible: boolean
|
||||
}
|
||||
|
||||
const styles = theme => {
|
||||
const styles = (theme: any) => {
|
||||
return {
|
||||
container: {
|
||||
display: 'inline-block'
|
||||
|
@ -209,6 +215,7 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
|
|||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
// @ts-ignore
|
||||
this.state = {
|
||||
showIndicator: false,
|
||||
stats: {},
|
||||
|
@ -225,9 +232,11 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
// @ts-ignore
|
||||
const { enableStatsDisplay, participantId, statsPopoverPosition, classes } = this.props;
|
||||
const visibilityClass = this._getVisibilityClass();
|
||||
|
||||
// @ts-ignore
|
||||
if (this.props._popoverDisabled) {
|
||||
return this._renderIndicator();
|
||||
}
|
||||
|
@ -236,6 +245,7 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
|
|||
<Popover
|
||||
className = { clsx(classes.container, visibilityClass) }
|
||||
content = { <ConnectionIndicatorContent
|
||||
// @ts-ignore
|
||||
inheritedStats = { this.state.stats }
|
||||
participantId = { participantId } /> }
|
||||
disablePopover = { !enableStatsDisplay }
|
||||
|
@ -244,6 +254,7 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
|
|||
onPopoverClose = { this._onHidePopover }
|
||||
onPopoverOpen = { this._onShowPopover }
|
||||
position = { statsPopoverPosition }
|
||||
// @ts-ignore
|
||||
visible = { this.state.popoverVisible }>
|
||||
{ this._renderIndicator() }
|
||||
</Popover>
|
||||
|
@ -259,12 +270,14 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
|
|||
*/
|
||||
_getConnectionColorClass() {
|
||||
// TODO We currently do not have logic to emit and handle stats changes for tracks.
|
||||
// @ts-ignore
|
||||
const { percent } = this.state.stats;
|
||||
|
||||
const {
|
||||
_isConnectionStatusInactive,
|
||||
_isConnectionStatusInterrupted,
|
||||
_connectionIndicatorInactiveDisabled
|
||||
// @ts-ignore
|
||||
} = this.props;
|
||||
|
||||
if (_isConnectionStatusInactive) {
|
||||
|
@ -293,7 +306,7 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
|
|||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
_getDisplayConfiguration(percent: number): Object {
|
||||
_getDisplayConfiguration(percent: number): any {
|
||||
return QUALITY_TO_WIDTH.find(x => percent >= x.percent) || {};
|
||||
}
|
||||
|
||||
|
@ -305,17 +318,18 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
|
|||
* @returns {string}
|
||||
*/
|
||||
_getVisibilityClass() {
|
||||
// @ts-ignore
|
||||
const { _isConnectionStatusInactive, _isConnectionStatusInterrupted, classes } = this.props;
|
||||
|
||||
// @ts-ignore
|
||||
return this.state.showIndicator
|
||||
// @ts-ignore
|
||||
|| this.props.alwaysVisible
|
||||
|| _isConnectionStatusInterrupted
|
||||
|| _isConnectionStatusInactive
|
||||
? '' : classes.hidden;
|
||||
}
|
||||
|
||||
_onHidePopover: () => void;
|
||||
|
||||
/**
|
||||
* Hides popover.
|
||||
*
|
||||
|
@ -323,12 +337,10 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onHidePopover() {
|
||||
// @ts-ignore
|
||||
this.setState({ popoverVisible: false });
|
||||
}
|
||||
|
||||
|
||||
_onShowPopover: () => void;
|
||||
|
||||
/**
|
||||
* Shows popover.
|
||||
*
|
||||
|
@ -336,6 +348,7 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onShowPopover() {
|
||||
// @ts-ignore
|
||||
this.setState({ popoverVisible: true });
|
||||
}
|
||||
|
||||
|
@ -353,6 +366,7 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
|
|||
_videoTrack,
|
||||
classes,
|
||||
iconSize
|
||||
// @ts-ignore
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
|
@ -377,7 +391,7 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
|
|||
* @param {Props} ownProps - The own props of the component.
|
||||
* @returns {Props}
|
||||
*/
|
||||
export function _mapStateToProps(state: Object, ownProps: Props) {
|
||||
export function _mapStateToProps(state: IState, ownProps: Props) {
|
||||
const { participantId } = ownProps;
|
||||
const tracks = state['features/base/tracks'];
|
||||
const sourceNameSignalingEnabled = getSourceNameSignalingFeatureFlag(state);
|
||||
|
@ -411,4 +425,5 @@ export function _mapStateToProps(state: Object, ownProps: Props) {
|
|||
};
|
||||
}
|
||||
export default translate(connect(_mapStateToProps)(
|
||||
// @ts-ignore
|
||||
withStyles(styles)(ConnectionIndicator)));
|
|
@ -1,18 +1,22 @@
|
|||
/* @flow */
|
||||
|
||||
import { withStyles } from '@material-ui/styles';
|
||||
import clsx from 'clsx';
|
||||
import React, { Component } from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
|
||||
import { isMobileBrowser } from '../../../features/base/environment/utils';
|
||||
import ContextMenu from '../../base/components/context-menu/ContextMenu';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { isMobileBrowser } from '../../base/environment/utils';
|
||||
import { translate } from '../../base/i18n/functions';
|
||||
|
||||
type DownloadUpload = {
|
||||
download: number;
|
||||
upload: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of
|
||||
* {@link ConnectionStatsTable}.
|
||||
*/
|
||||
type Props = {
|
||||
interface Props extends WithTranslation {
|
||||
|
||||
/**
|
||||
* The audio SSRC of this client.
|
||||
|
@ -26,7 +30,7 @@ type Props = {
|
|||
* upload: Number
|
||||
* }}.
|
||||
*/
|
||||
bandwidth: Object,
|
||||
bandwidth: DownloadUpload,
|
||||
|
||||
/**
|
||||
* Statistics related to bitrate.
|
||||
|
@ -35,7 +39,7 @@ type Props = {
|
|||
* upload: Number
|
||||
* }}.
|
||||
*/
|
||||
bitrate: Object,
|
||||
bitrate: DownloadUpload,
|
||||
|
||||
/**
|
||||
* The number of bridges (aka media servers) currently used in the
|
||||
|
@ -46,18 +50,28 @@ type Props = {
|
|||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: Object,
|
||||
classes: any,
|
||||
|
||||
/**
|
||||
* Audio/video codecs in use for the connection.
|
||||
*/
|
||||
codec: Object,
|
||||
codec: {
|
||||
[key: string]: {
|
||||
audio: string;
|
||||
video: string;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* A message describing the connection quality.
|
||||
*/
|
||||
connectionSummary: string,
|
||||
|
||||
/**
|
||||
* Whether or not should display the "Show More" link.
|
||||
*/
|
||||
disableShowMoreStats: boolean,
|
||||
|
||||
/**
|
||||
* The end-to-end round-trip-time.
|
||||
*/
|
||||
|
@ -68,16 +82,6 @@ type Props = {
|
|||
*/
|
||||
enableSaveLogs: boolean,
|
||||
|
||||
/**
|
||||
* Whether or not should display the "Show More" link.
|
||||
*/
|
||||
disableShowMoreStats: boolean,
|
||||
|
||||
/**
|
||||
* The endpoint id of this client.
|
||||
*/
|
||||
participantId: string,
|
||||
|
||||
/**
|
||||
* Statistics related to frame rates for each ssrc.
|
||||
* {{
|
||||
|
@ -105,12 +109,12 @@ type Props = {
|
|||
/**
|
||||
* Callback to invoke when the user clicks on the download logs link.
|
||||
*/
|
||||
onSaveLogs: Function,
|
||||
onSaveLogs: () => void,
|
||||
|
||||
/**
|
||||
* Callback to invoke when the show additional stats link is clicked.
|
||||
*/
|
||||
onShowMore: Function,
|
||||
onShowMore: (e?: React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* Statistics related to packet loss.
|
||||
|
@ -119,7 +123,12 @@ type Props = {
|
|||
* upload: Number
|
||||
* }}.
|
||||
*/
|
||||
packetLoss: Object,
|
||||
packetLoss: DownloadUpload,
|
||||
|
||||
/**
|
||||
* The endpoint id of this client.
|
||||
*/
|
||||
participantId: string,
|
||||
|
||||
/**
|
||||
* The region that we think the client is in.
|
||||
|
@ -135,7 +144,12 @@ type Props = {
|
|||
* }
|
||||
* }}.
|
||||
*/
|
||||
resolution: Object,
|
||||
resolution: {
|
||||
[ssrc: string]: {
|
||||
height: number;
|
||||
width: number;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The region of the media server that we are connected to.
|
||||
|
@ -149,25 +163,28 @@ type Props = {
|
|||
shouldShowMore: boolean,
|
||||
|
||||
/**
|
||||
* Invoked to obtain translated strings.
|
||||
* Whether source name signaling is enabled.
|
||||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* The video SSRC of this client.
|
||||
*/
|
||||
videoSsrc: number,
|
||||
sourceNameSignalingEnabled: boolean,
|
||||
|
||||
/**
|
||||
* Statistics related to transports.
|
||||
*/
|
||||
transport: Array<Object>,
|
||||
transport: Array<{
|
||||
ip: string;
|
||||
localCandidateType: string;
|
||||
localip: string;
|
||||
p2p: boolean;
|
||||
remoteCandidateType: string;
|
||||
transportType: string;
|
||||
type: string;
|
||||
}>,
|
||||
|
||||
/**
|
||||
* Whether source name signaling is enabled.
|
||||
* The video SSRC of this client.
|
||||
*/
|
||||
sourceNameSignalingEnabled: boolean
|
||||
};
|
||||
videoSsrc: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Click handler.
|
||||
|
@ -175,13 +192,13 @@ type Props = {
|
|||
* @param {SyntheticEvent} event - The click event.
|
||||
* @returns {void}
|
||||
*/
|
||||
function onClick(event) {
|
||||
function onClick(event: React.MouseEvent) {
|
||||
// If the event is propagated to the thumbnail container the participant will be pinned. That's why the propagation
|
||||
// needs to be stopped.
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
const styles = theme => {
|
||||
const styles = (theme: any) => {
|
||||
return {
|
||||
actions: {
|
||||
margin: '10px auto',
|
||||
|
@ -599,7 +616,7 @@ class ConnectionStatsTable extends Component<Props> {
|
|||
frameRateString = framerate || 'N/A';
|
||||
} else {
|
||||
frameRateString = Object.keys(framerate || {})
|
||||
.map(ssrc => framerate[ssrc])
|
||||
.map(ssrc => framerate[ssrc as keyof typeof framerate])
|
||||
.join(', ') || 'N/A';
|
||||
}
|
||||
|
||||
|
@ -791,7 +808,13 @@ class ConnectionStatsTable extends Component<Props> {
|
|||
return [ NA ];
|
||||
}
|
||||
|
||||
const data = {
|
||||
const data: {
|
||||
localIP: string[],
|
||||
localPort: string[],
|
||||
remoteIP: string[],
|
||||
remotePort: string[],
|
||||
transportType: string[]
|
||||
} = {
|
||||
localIP: [],
|
||||
localPort: [],
|
||||
remoteIP: [],
|
||||
|
@ -897,7 +920,7 @@ class ConnectionStatsTable extends Component<Props> {
|
|||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderTransportTableRow(config: Object) {
|
||||
_renderTransportTableRow(config: any) {
|
||||
const { additionalData, data, key, label } = config;
|
||||
|
||||
return (
|
||||
|
@ -924,7 +947,7 @@ class ConnectionStatsTable extends Component<Props> {
|
|||
* @private
|
||||
* @returns {string}
|
||||
*/
|
||||
function getIP(value) {
|
||||
function getIP(value: string) {
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
|
@ -940,7 +963,7 @@ function getIP(value) {
|
|||
* @private
|
||||
* @returns {string}
|
||||
*/
|
||||
function getPort(value) {
|
||||
function getPort(value: string) {
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
|
@ -955,7 +978,7 @@ function getPort(value) {
|
|||
* @private
|
||||
* @returns {string}
|
||||
*/
|
||||
function getStringFromArray(array) {
|
||||
function getStringFromArray(array: string[]) {
|
||||
let res = '';
|
||||
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
|
@ -965,4 +988,5 @@ function getStringFromArray(array) {
|
|||
return res;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
export default translate(withStyles(styles)(ConnectionStatsTable));
|
|
@ -1,24 +1,28 @@
|
|||
/* @flow */
|
||||
|
||||
/* eslint-disable lines-around-comment */
|
||||
import { withStyles } from '@material-ui/styles';
|
||||
import React, { Component } from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
import { connect } from 'react-redux';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { IState } from '../../../app/types';
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import {
|
||||
getParticipantDisplayName,
|
||||
getParticipantById
|
||||
} from '../../../base/participants';
|
||||
import { connect } from '../../../base/redux';
|
||||
} from '../../../base/participants/functions';
|
||||
// @ts-ignore
|
||||
import { updateSettings } from '../../../base/settings';
|
||||
// @ts-ignore
|
||||
import { Tooltip } from '../../../base/tooltip';
|
||||
// @ts-ignore
|
||||
import { getIndicatorsTooltipPosition } from '../../../filmstrip/functions.web';
|
||||
import { appendSuffix } from '../../functions';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link DisplayName}.
|
||||
*/
|
||||
type Props = {
|
||||
interface Props extends WithTranslation {
|
||||
|
||||
/**
|
||||
* The participant's current display name which should be shown when in
|
||||
|
@ -36,6 +40,11 @@ type Props = {
|
|||
*/
|
||||
allowEditing: boolean,
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: any,
|
||||
|
||||
/**
|
||||
* Invoked to update the participant's display name.
|
||||
*/
|
||||
|
@ -46,11 +55,6 @@ type Props = {
|
|||
*/
|
||||
displayNameSuffix: string,
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: Object,
|
||||
|
||||
/**
|
||||
* The ID attribute to add to the component. Useful for global querying for
|
||||
* the component by legacy components and torture tests.
|
||||
|
@ -62,16 +66,11 @@ type Props = {
|
|||
*/
|
||||
participantID: string,
|
||||
|
||||
/**
|
||||
* Invoked to obtain translated strings.
|
||||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* The type of thumbnail.
|
||||
*/
|
||||
thumbnailType: string
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} state of {@link DisplayName}.
|
||||
|
@ -89,7 +88,7 @@ type State = {
|
|||
isEditing: boolean
|
||||
};
|
||||
|
||||
const styles = theme => {
|
||||
const styles = (theme: any) => {
|
||||
return {
|
||||
displayName: {
|
||||
...theme.typography.labelBold,
|
||||
|
@ -119,7 +118,7 @@ const styles = theme => {
|
|||
* @augments Component
|
||||
*/
|
||||
class DisplayName extends Component<Props, State> {
|
||||
_nameInput: ?HTMLInputElement;
|
||||
_nameInput?: HTMLInputElement;
|
||||
|
||||
static defaultProps = {
|
||||
_configuredDisplayName: ''
|
||||
|
@ -148,7 +147,7 @@ class DisplayName extends Component<Props, State> {
|
|||
* @private
|
||||
* @type {HTMLInputElement}
|
||||
*/
|
||||
this._nameInput = null;
|
||||
this._nameInput = undefined;
|
||||
|
||||
// Bind event handlers so they are only bound once for every instance.
|
||||
this._onChange = this._onChange.bind(this);
|
||||
|
@ -165,7 +164,7 @@ class DisplayName extends Component<Props, State> {
|
|||
* @inheritdoc
|
||||
* @returns {void}
|
||||
*/
|
||||
componentDidUpdate(previousProps, previousState) {
|
||||
componentDidUpdate(previousProps: Props, previousState: State) {
|
||||
if (!previousState.isEditing
|
||||
&& this.state.isEditing
|
||||
&& this._nameInput) {
|
||||
|
@ -229,12 +228,10 @@ class DisplayName extends Component<Props, State> {
|
|||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onClick(e) {
|
||||
_onClick(e: React.MouseEvent) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
_onChange: () => void;
|
||||
|
||||
/**
|
||||
* Updates the internal state of the display name entered into the edit
|
||||
* field.
|
||||
|
@ -243,14 +240,12 @@ class DisplayName extends Component<Props, State> {
|
|||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onChange(event) {
|
||||
_onChange(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
this.setState({
|
||||
editDisplayNameValue: event.target.value
|
||||
});
|
||||
}
|
||||
|
||||
_onKeyDown: () => void;
|
||||
|
||||
/**
|
||||
* Submits the edited display name update if the enter key is pressed.
|
||||
*
|
||||
|
@ -258,14 +253,12 @@ class DisplayName extends Component<Props, State> {
|
|||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onKeyDown(event) {
|
||||
_onKeyDown(event: React.KeyboardEvent) {
|
||||
if (event.key === 'Enter') {
|
||||
this._onSubmit();
|
||||
}
|
||||
}
|
||||
|
||||
_onStartEditing: () => void;
|
||||
|
||||
/**
|
||||
* Updates the component to display an editable input field and sets the
|
||||
* initial value to the current display name.
|
||||
|
@ -274,7 +267,7 @@ class DisplayName extends Component<Props, State> {
|
|||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onStartEditing(e) {
|
||||
_onStartEditing(e: React.MouseEvent) {
|
||||
if (this.props.allowEditing) {
|
||||
e.stopPropagation();
|
||||
this.setState({
|
||||
|
@ -284,8 +277,6 @@ class DisplayName extends Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
_onSubmit: () => void;
|
||||
|
||||
/**
|
||||
* Dispatches an action to update the display name if any change has
|
||||
* occurred after editing. Clears any temporary state used to keep track
|
||||
|
@ -309,11 +300,9 @@ class DisplayName extends Component<Props, State> {
|
|||
editDisplayNameValue: ''
|
||||
});
|
||||
|
||||
this._nameInput = null;
|
||||
this._nameInput = undefined;
|
||||
}
|
||||
|
||||
_setNameInputRef: (HTMLInputElement | null) => void;
|
||||
|
||||
/**
|
||||
* Sets the internal reference to the HTML element backing the React
|
||||
* {@code Component} input with id {@code editDisplayName}.
|
||||
|
@ -323,7 +312,7 @@ class DisplayName extends Component<Props, State> {
|
|||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_setNameInputRef(element) {
|
||||
_setNameInputRef(element: HTMLInputElement) {
|
||||
this._nameInput = element;
|
||||
}
|
||||
}
|
||||
|
@ -339,13 +328,13 @@ class DisplayName extends Component<Props, State> {
|
|||
* _nameToDisplay: string
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state, ownProps) {
|
||||
function _mapStateToProps(state: IState, ownProps: Partial<Props>) {
|
||||
const { participantID } = ownProps;
|
||||
const participant = getParticipantById(state, participantID);
|
||||
const participant = getParticipantById(state, participantID ?? '');
|
||||
|
||||
return {
|
||||
_configuredDisplayName: participant && participant.name,
|
||||
_nameToDisplay: getParticipantDisplayName(state, participantID)
|
||||
_nameToDisplay: getParticipantDisplayName(state, participantID ?? '')
|
||||
};
|
||||
}
|
||||
|
|
@ -1,20 +1,25 @@
|
|||
// @flow
|
||||
|
||||
/* eslint-disable lines-around-comment */
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { IState } from '../../../app/types';
|
||||
// @ts-ignore
|
||||
import { isDisplayNameVisible } from '../../../base/config/functions.any';
|
||||
import { getLocalParticipant, getParticipantDisplayName } from '../../../base/participants';
|
||||
import { getLocalParticipant, getParticipantDisplayName } from '../../../base/participants/functions';
|
||||
import { Participant } from '../../../base/participants/reducer';
|
||||
import { withPixelLineHeight } from '../../../base/styles/functions.web';
|
||||
// @ts-ignore
|
||||
import { getLargeVideoParticipant } from '../../../large-video/functions';
|
||||
// @ts-ignore
|
||||
import { isToolboxVisible } from '../../../toolbox/functions.web';
|
||||
// @ts-ignore
|
||||
import { isLayoutTileView } from '../../../video-layout';
|
||||
|
||||
import DisplayNameBadge from './DisplayNameBadge';
|
||||
|
||||
const useStyles = makeStyles(theme => {
|
||||
const useStyles = makeStyles((theme: any) => {
|
||||
return {
|
||||
badgeContainer: {
|
||||
...withPixelLineHeight(theme.typography.bodyShortRegularLarge),
|
||||
|
@ -43,15 +48,15 @@ const useStyles = makeStyles(theme => {
|
|||
*/
|
||||
const StageParticipantNameLabel = () => {
|
||||
const classes = useStyles();
|
||||
const largeVideoParticipant = useSelector(getLargeVideoParticipant);
|
||||
const largeVideoParticipant: Participant = useSelector(getLargeVideoParticipant);
|
||||
const selectedId = largeVideoParticipant?.id;
|
||||
const nameToDisplay = useSelector(state => getParticipantDisplayName(state, selectedId));
|
||||
const nameToDisplay = useSelector((state: IState) => getParticipantDisplayName(state, selectedId));
|
||||
|
||||
const localParticipant = useSelector(getLocalParticipant);
|
||||
const localId = localParticipant?.id;
|
||||
|
||||
const isTileView = useSelector(isLayoutTileView);
|
||||
const toolboxVisible = useSelector(isToolboxVisible);
|
||||
const toolboxVisible: boolean = useSelector(isToolboxVisible);
|
||||
const showDisplayName = useSelector(isDisplayNameVisible);
|
||||
|
||||
if (showDisplayName && nameToDisplay && selectedId !== localId && !isTileView) {
|
|
@ -1,5 +1,3 @@
|
|||
// @flow
|
||||
|
||||
import { createMuiTheme } from '@material-ui/core/styles';
|
||||
|
||||
import { font, colors, colorMap, spacing, shape, typography, breakpoints } from '../base/ui/Tokens';
|
||||
|
@ -11,7 +9,7 @@ import { createColorTokens } from '../base/ui/utils';
|
|||
* @param {Object} customTheme - The branded custom theme.
|
||||
* @returns {Object} - The MUI theme.
|
||||
*/
|
||||
export function createMuiBrandingTheme(customTheme: Object) {
|
||||
export function createMuiBrandingTheme(customTheme: any) {
|
||||
const {
|
||||
palette: customPalette,
|
||||
shape: customShape,
|
||||
|
@ -82,9 +80,10 @@ export function createMuiBrandingTheme(customTheme: Object) {
|
|||
function overwriteRecurrsive(obj1: Object, obj2: Object) {
|
||||
Object.keys(obj2).forEach(key => {
|
||||
if (obj1.hasOwnProperty(key)) {
|
||||
if (typeof obj1[key] === 'object') {
|
||||
overwriteRecurrsive(obj1[key], obj2[key]);
|
||||
if (typeof obj1[key as keyof typeof obj1] === 'object') {
|
||||
overwriteRecurrsive(obj1[key as keyof typeof obj1], obj2[key as keyof typeof obj2]);
|
||||
} else {
|
||||
// @ts-ignore
|
||||
obj1[key] = obj2[key];
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
/* @flow */
|
||||
|
||||
/* eslint-disable lines-around-comment */
|
||||
import { withStyles } from '@material-ui/styles';
|
||||
import clsx from 'clsx';
|
||||
import _ from 'lodash';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
import { FixedSizeList, FixedSizeGrid } from 'react-window';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
|
@ -11,15 +11,23 @@ import {
|
|||
createShortcutEvent,
|
||||
createToolbarEvent,
|
||||
sendAnalytics
|
||||
// @ts-ignore
|
||||
} from '../../../analytics';
|
||||
// @ts-ignore
|
||||
import { getSourceNameSignalingFeatureFlag, getToolbarButtons } from '../../../base/config';
|
||||
import { isMobileBrowser } from '../../../base/environment/utils';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { Icon, IconMenuDown, IconMenuUp } from '../../../base/icons';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import Icon from '../../../base/icons/components/Icon';
|
||||
import { IconMenuDown, IconMenuUp } from '../../../base/icons/svg/index';
|
||||
import { Participant } from '../../../base/participants/reducer';
|
||||
import { connect } from '../../../base/redux/functions';
|
||||
// @ts-ignore
|
||||
import { shouldHideSelfView } from '../../../base/settings/functions.any';
|
||||
// @ts-ignore
|
||||
import { showToolbox } from '../../../toolbox/actions.web';
|
||||
// @ts-ignore
|
||||
import { isButtonEnabled, isToolboxVisible } from '../../../toolbox/functions.web';
|
||||
// @ts-ignore
|
||||
import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
|
||||
import {
|
||||
setFilmstripVisible,
|
||||
|
@ -28,6 +36,7 @@ import {
|
|||
setUserIsResizing,
|
||||
setTopPanelVisible,
|
||||
setVisibleRemoteParticipants
|
||||
// @ts-ignore
|
||||
} from '../../actions';
|
||||
import {
|
||||
ASPECT_RATIO_BREAKPOINT,
|
||||
|
@ -43,51 +52,55 @@ import {
|
|||
getVerticalViewMaxWidth,
|
||||
shouldRemoteVideosBeVisible,
|
||||
isStageFilmstripTopPanel
|
||||
// @ts-ignore
|
||||
} from '../../functions';
|
||||
|
||||
// @ts-ignore
|
||||
import AudioTracksContainer from './AudioTracksContainer';
|
||||
// @ts-ignore
|
||||
import Thumbnail from './Thumbnail';
|
||||
// @ts-ignore
|
||||
import ThumbnailWrapper from './ThumbnailWrapper';
|
||||
// @ts-ignore
|
||||
import { styles } from './styles';
|
||||
|
||||
declare var APP: Object;
|
||||
declare var interfaceConfig: Object;
|
||||
declare let APP: any;
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link Filmstrip}.
|
||||
*/
|
||||
type Props = {
|
||||
interface Props extends WithTranslation {
|
||||
|
||||
/**
|
||||
* Additional CSS class names top add to the root.
|
||||
*/
|
||||
_className: string,
|
||||
|
||||
/**
|
||||
* The current layout of the filmstrip.
|
||||
*/
|
||||
_currentLayout: string,
|
||||
|
||||
/**
|
||||
* The number of columns in tile view.
|
||||
*/
|
||||
_columns: number,
|
||||
|
||||
/**
|
||||
* The current layout of the filmstrip.
|
||||
*/
|
||||
_currentLayout: string,
|
||||
|
||||
/**
|
||||
* Whether or not to hide the self view.
|
||||
*/
|
||||
_disableSelfView: boolean,
|
||||
|
||||
/**
|
||||
* The width of the filmstrip.
|
||||
*/
|
||||
_filmstripWidth: number,
|
||||
|
||||
/**
|
||||
* The height of the filmstrip.
|
||||
*/
|
||||
_filmstripHeight: number,
|
||||
|
||||
/**
|
||||
* The width of the filmstrip.
|
||||
*/
|
||||
_filmstripWidth: number,
|
||||
|
||||
/**
|
||||
* Whether or not we have scroll on the filmstrip.
|
||||
*/
|
||||
|
@ -116,7 +129,7 @@ type Props = {
|
|||
/**
|
||||
* The local screen share participant. This prop is behind the sourceNameSignaling feature flag.
|
||||
*/
|
||||
_localScreenShare: Object,
|
||||
_localScreenShare: Participant,
|
||||
|
||||
/**
|
||||
* Whether or not the filmstrip videos should currently be displayed.
|
||||
|
@ -173,16 +186,16 @@ type Props = {
|
|||
*/
|
||||
_topPanelFilmstrip: boolean,
|
||||
|
||||
/**
|
||||
* The height of the top panel (user resized).
|
||||
*/
|
||||
_topPanelHeight?: number,
|
||||
|
||||
/**
|
||||
* The max height of the top panel.
|
||||
*/
|
||||
_topPanelMaxHeight: number,
|
||||
|
||||
/**
|
||||
* The height of the top panel (user resized).
|
||||
*/
|
||||
_topPanelHeight: ?number,
|
||||
|
||||
/**
|
||||
* Whether or not the top panel is visible.
|
||||
*/
|
||||
|
@ -191,7 +204,7 @@ type Props = {
|
|||
/**
|
||||
* The width of the vertical filmstrip (user resized).
|
||||
*/
|
||||
_verticalFilmstripWidth: ?number,
|
||||
_verticalFilmstripWidth?: number,
|
||||
|
||||
/**
|
||||
* Whether or not the vertical filmstrip should have a background color.
|
||||
|
@ -216,7 +229,7 @@ type Props = {
|
|||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: Object,
|
||||
classes: any,
|
||||
|
||||
/**
|
||||
* The redux {@code dispatch} function.
|
||||
|
@ -226,16 +239,21 @@ type Props = {
|
|||
/**
|
||||
* The type of filmstrip to be displayed.
|
||||
*/
|
||||
filmstripType: string,
|
||||
|
||||
/**
|
||||
* Invoked to obtain translated strings.
|
||||
*/
|
||||
t: Function
|
||||
};
|
||||
filmstripType: string
|
||||
}
|
||||
|
||||
type State = {
|
||||
|
||||
/**
|
||||
* Initial top panel height on drag handle mouse down.
|
||||
*/
|
||||
dragFilmstripHeight?: number,
|
||||
|
||||
/**
|
||||
* Initial filmstrip width on drag handle mouse down.
|
||||
*/
|
||||
dragFilmstripWidth?: number|null,
|
||||
|
||||
/**
|
||||
* Whether or not the mouse is pressed.
|
||||
*/
|
||||
|
@ -244,17 +262,7 @@ type State = {
|
|||
/**
|
||||
* Initial mouse position on drag handle mouse down.
|
||||
*/
|
||||
mousePosition: ?number,
|
||||
|
||||
/**
|
||||
* Initial filmstrip width on drag handle mouse down.
|
||||
*/
|
||||
dragFilmstripWidth: ?number,
|
||||
|
||||
/**
|
||||
* Initial top panel height on drag handle mouse down.
|
||||
*/
|
||||
dragFilmstripHeight: ?number
|
||||
mousePosition?: number|null
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -317,6 +325,7 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
'keyboardShortcuts.toggleFilmstrip'
|
||||
);
|
||||
document.addEventListener('mouseup', this._onDragMouseUp);
|
||||
// @ts-ignore
|
||||
document.addEventListener('mousemove', this._throttledResize);
|
||||
}
|
||||
|
||||
|
@ -328,6 +337,7 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
componentWillUnmount() {
|
||||
APP.keyboardshortcut.unregisterShortcut('F');
|
||||
document.removeEventListener('mouseup', this._onDragMouseUp);
|
||||
// @ts-ignore
|
||||
document.removeEventListener('mousemove', this._throttledResize);
|
||||
}
|
||||
|
||||
|
@ -338,7 +348,7 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const filmstripStyle = { };
|
||||
const filmstripStyle: any = { };
|
||||
const {
|
||||
_currentLayout,
|
||||
_disableSelfView,
|
||||
|
@ -466,15 +476,13 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
);
|
||||
}
|
||||
|
||||
_onDragHandleMouseDown: (MouseEvent) => void;
|
||||
|
||||
/**
|
||||
* Handles mouse down on the drag handle.
|
||||
*
|
||||
* @param {MouseEvent} e - The mouse down event.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onDragHandleMouseDown(e) {
|
||||
_onDragHandleMouseDown(e: React.MouseEvent) {
|
||||
const { _topPanelFilmstrip, _topPanelHeight, _verticalFilmstripWidth } = this.props;
|
||||
|
||||
this.setState({
|
||||
|
@ -486,8 +494,6 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
this.props.dispatch(setUserIsResizing(true));
|
||||
}
|
||||
|
||||
_onDragMouseUp: () => void;
|
||||
|
||||
/**
|
||||
* Drag handle mouse up handler.
|
||||
*
|
||||
|
@ -502,15 +508,13 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
_onFilmstripResize: (MouseEvent) => void;
|
||||
|
||||
/**
|
||||
* Handles drag handle mouse move.
|
||||
*
|
||||
* @param {MouseEvent} e - The mousemove event.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onFilmstripResize(e) {
|
||||
_onFilmstripResize(e: React.MouseEvent) {
|
||||
if (this.state.isMouseDown) {
|
||||
const {
|
||||
dispatch,
|
||||
|
@ -523,9 +527,9 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
const { dragFilmstripWidth, dragFilmstripHeight, mousePosition } = this.state;
|
||||
|
||||
if (_topPanelFilmstrip) {
|
||||
const diff = e.clientY - mousePosition;
|
||||
const diff = e.clientY - (mousePosition ?? 0);
|
||||
const height = Math.max(
|
||||
Math.min(dragFilmstripHeight + diff, _maxTopPanelHeight),
|
||||
Math.min((dragFilmstripHeight ?? 0) + diff, _maxTopPanelHeight),
|
||||
TOP_FILMSTRIP_HEIGHT
|
||||
);
|
||||
|
||||
|
@ -533,9 +537,9 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
dispatch(setUserFilmstripHeight(height));
|
||||
}
|
||||
} else {
|
||||
const diff = mousePosition - e.clientX;
|
||||
const diff = (mousePosition ?? 0) - e.clientX;
|
||||
const width = Math.max(
|
||||
Math.min(dragFilmstripWidth + diff, _maxFilmstripWidth),
|
||||
Math.min((dragFilmstripWidth ?? 0) + diff, _maxFilmstripWidth),
|
||||
DEFAULT_FILMSTRIP_WIDTH
|
||||
);
|
||||
|
||||
|
@ -553,7 +557,7 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
* @param {number} stopIndex - The stop index.
|
||||
* @returns {Object}
|
||||
*/
|
||||
_calculateIndices(startIndex, stopIndex) {
|
||||
_calculateIndices(startIndex: number, stopIndex: number) {
|
||||
const { _currentLayout, _iAmRecorder, _thumbnailsReordered, _disableSelfView } = this.props;
|
||||
let start = startIndex;
|
||||
let stop = stopIndex;
|
||||
|
@ -573,8 +577,6 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
};
|
||||
}
|
||||
|
||||
_onTabIn: () => void;
|
||||
|
||||
/**
|
||||
* Toggle the toolbar visibility when tabbing into it.
|
||||
*
|
||||
|
@ -586,15 +588,13 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
_listItemKey: number => string;
|
||||
|
||||
/**
|
||||
* The key to be used for every ThumbnailWrapper element in stage view.
|
||||
*
|
||||
* @param {number} index - The index of the ThumbnailWrapper instance.
|
||||
* @returns {string} - The key.
|
||||
*/
|
||||
_listItemKey(index) {
|
||||
_listItemKey(index: number) {
|
||||
const { _remoteParticipants, _remoteParticipantsLength } = this.props;
|
||||
|
||||
if (typeof index !== 'number' || _remoteParticipantsLength <= index) {
|
||||
|
@ -604,15 +604,13 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
return _remoteParticipants[index];
|
||||
}
|
||||
|
||||
_gridItemKey: Object => string;
|
||||
|
||||
/**
|
||||
* The key to be used for every ThumbnailWrapper element in tile views.
|
||||
*
|
||||
* @param {Object} data - An object with the indexes identifying the ThumbnailWrapper instance.
|
||||
* @returns {string} - The key.
|
||||
*/
|
||||
_gridItemKey({ columnIndex, rowIndex }) {
|
||||
_gridItemKey({ columnIndex, rowIndex }: {columnIndex: number, rowIndex: number}) {
|
||||
const {
|
||||
_disableSelfView,
|
||||
_columns,
|
||||
|
@ -638,23 +636,20 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
return _remoteParticipants[remoteIndex];
|
||||
}
|
||||
|
||||
_onListItemsRendered: Object => void;
|
||||
|
||||
/**
|
||||
* Handles items rendered changes in stage view.
|
||||
*
|
||||
* @param {Object} data - Information about the rendered items.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onListItemsRendered({ visibleStartIndex, visibleStopIndex }) {
|
||||
_onListItemsRendered({ visibleStartIndex, visibleStopIndex }
|
||||
: { visibleStartIndex: number, visibleStopIndex: number }) {
|
||||
const { dispatch } = this.props;
|
||||
const { startIndex, stopIndex } = this._calculateIndices(visibleStartIndex, visibleStopIndex);
|
||||
|
||||
dispatch(setVisibleRemoteParticipants(startIndex, stopIndex));
|
||||
}
|
||||
|
||||
_onGridItemsRendered: Object => void;
|
||||
|
||||
/**
|
||||
* Handles items rendered changes in tile view.
|
||||
*
|
||||
|
@ -666,6 +661,11 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
visibleColumnStopIndex,
|
||||
visibleRowStartIndex,
|
||||
visibleRowStopIndex
|
||||
}: {
|
||||
visibleColumnStartIndex: number,
|
||||
visibleColumnStopIndex: number,
|
||||
visibleRowStartIndex: number,
|
||||
visibleRowStopIndex: number
|
||||
}) {
|
||||
const { _columns, dispatch } = this.props;
|
||||
const start = (visibleRowStartIndex * _columns) + visibleColumnStartIndex;
|
||||
|
@ -713,6 +713,7 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
initialScrollLeft = { 0 }
|
||||
initialScrollTop = { 0 }
|
||||
itemData = {{ filmstripType }}
|
||||
// @ts-ignore
|
||||
itemKey = { this._gridItemKey }
|
||||
onItemsRendered = { this._onGridItemsRendered }
|
||||
overscanRowCount = { 1 }
|
||||
|
@ -727,7 +728,7 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
}
|
||||
|
||||
|
||||
const props = {
|
||||
const props: any = {
|
||||
itemCount: _remoteParticipantsLength,
|
||||
className: `filmstrip__videos remote-videos ${_resizableFilmstrip ? '' : 'height-transition'}`,
|
||||
height: _filmstripHeight,
|
||||
|
@ -746,8 +747,6 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
const isNotOverflowing = !_hasScroll;
|
||||
|
||||
props.itemSize = itemSize;
|
||||
|
||||
// $FlowFixMe
|
||||
props.layout = 'horizontal';
|
||||
if (isNotOverflowing) {
|
||||
props.className += ' is-not-overflowing';
|
||||
|
@ -787,8 +786,6 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
: dispatch(setFilmstripVisible(!_mainFilmstripVisible));
|
||||
}
|
||||
|
||||
_onShortcutToggleFilmstrip: () => void;
|
||||
|
||||
/**
|
||||
* Creates an analytics keyboard shortcut event and dispatches an action for
|
||||
* toggling filmstrip visibility.
|
||||
|
@ -806,8 +803,6 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
this._doToggleFilmstrip();
|
||||
}
|
||||
|
||||
_onToolbarToggleFilmstrip: () => void;
|
||||
|
||||
/**
|
||||
* Creates an analytics toolbar event and dispatches an action for opening
|
||||
* the speaker stats modal.
|
||||
|
@ -825,8 +820,6 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
this._doToggleFilmstrip();
|
||||
}
|
||||
|
||||
_onToggleButtonTouch: (SyntheticEvent<HTMLButtonElement>) => void;
|
||||
|
||||
/**
|
||||
* Handler for touch start event of the 'toggle button'.
|
||||
*
|
||||
|
@ -834,7 +827,7 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
* @param {Object} e - The synthetic event.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onToggleButtonTouch(e: SyntheticEvent<HTMLButtonElement>) {
|
||||
_onToggleButtonTouch(e: React.TouchEvent) {
|
||||
// Don't propagate the touchStart event so the toolbar doesn't get toggled.
|
||||
e.stopPropagation();
|
||||
this._onToolbarToggleFilmstrip();
|
||||
|
@ -893,7 +886,7 @@ class Filmstrip extends PureComponent <Props, State> {
|
|||
* @private
|
||||
* @returns {Props}
|
||||
*/
|
||||
function _mapStateToProps(state, ownProps) {
|
||||
function _mapStateToProps(state: any, ownProps: any) {
|
||||
const { _hasScroll = false, filmstripType, _topPanelFilmstrip, _remoteParticipants } = ownProps;
|
||||
const toolbarButtons = getToolbarButtons(state);
|
||||
const { testing = {}, iAmRecorder } = state['features/base/config'];
|
|
@ -1,12 +1,13 @@
|
|||
/* @flow */
|
||||
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { IconPinParticipant } from '../../../base/icons';
|
||||
import { getParticipantById } from '../../../base/participants';
|
||||
import { BaseIndicator } from '../../../base/react';
|
||||
import { IState } from '../../../app/types';
|
||||
import { IconPinParticipant } from '../../../base/icons/svg/index';
|
||||
import { getParticipantById } from '../../../base/participants/functions';
|
||||
import BaseIndicator from '../../../base/react/components/web/BaseIndicator';
|
||||
// eslint-disable-next-line lines-around-comment
|
||||
// @ts-ignore
|
||||
import { getPinnedActiveParticipants, isStageFilmstripAvailable } from '../../functions.web';
|
||||
|
||||
/**
|
||||
|
@ -55,8 +56,10 @@ const PinnedIndicator = ({
|
|||
tooltipPosition
|
||||
}: Props) => {
|
||||
const stageFilmstrip = useSelector(isStageFilmstripAvailable);
|
||||
const pinned = useSelector(state => getParticipantById(state, participantId))?.pinned;
|
||||
const isPinned = useSelector(getPinnedActiveParticipants).find(p => p.participantId === participantId);
|
||||
const pinned = useSelector((state: IState) => getParticipantById(state, participantId))?.pinned;
|
||||
const activePinnedParticipants: Array<{participantId: string; pinned: boolean}>
|
||||
= useSelector(getPinnedActiveParticipants);
|
||||
const isPinned = activePinnedParticipants.find(p => p.participantId === participantId);
|
||||
const styles = useStyles();
|
||||
|
||||
if ((stageFilmstrip && !isPinned) || (!stageFilmstrip && !pinned)) {
|
|
@ -1,13 +1,13 @@
|
|||
/* @flow */
|
||||
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { IconRaisedHand } from '../../../base/icons';
|
||||
import { getParticipantById, hasRaisedHand } from '../../../base/participants';
|
||||
import { BaseIndicator } from '../../../base/react';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme';
|
||||
import { IState } from '../../../app/types';
|
||||
import { IconRaisedHand } from '../../../base/icons/svg/index';
|
||||
import { getParticipantById, hasRaisedHand } from '../../../base/participants/functions';
|
||||
import { Participant } from '../../../base/participants/reducer';
|
||||
import BaseIndicator from '../../../base/react/components/web/BaseIndicator';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme.web';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link RaisedHandIndicator}.
|
||||
|
@ -31,7 +31,7 @@ type Props = {
|
|||
tooltipPosition: string
|
||||
};
|
||||
|
||||
const useStyles = makeStyles(theme => {
|
||||
const useStyles = makeStyles((theme: any) => {
|
||||
return {
|
||||
raisedHandIndicator: {
|
||||
backgroundColor: theme.palette.warning02,
|
||||
|
@ -54,8 +54,9 @@ const RaisedHandIndicator = ({
|
|||
participantId,
|
||||
tooltipPosition
|
||||
}: Props) => {
|
||||
const _raisedHand = hasRaisedHand(useSelector(state =>
|
||||
getParticipantById(state, participantId)));
|
||||
const participant: Participant|undefined = useSelector((state: IState) =>
|
||||
getParticipantById(state, participantId));
|
||||
const _raisedHand = hasRaisedHand(participant);
|
||||
const styles = useStyles();
|
||||
|
||||
if (!_raisedHand) {
|
|
@ -67,7 +67,7 @@ type Props = {
|
|||
/**
|
||||
* Closes a drawer if open.
|
||||
*/
|
||||
closeDrawer?: Function,
|
||||
closeDrawer?: () => void,
|
||||
|
||||
/**
|
||||
* The participant for which the drawer is open.
|
||||
|
@ -91,17 +91,17 @@ type Props = {
|
|||
/**
|
||||
* Callback for the mouse entering the component.
|
||||
*/
|
||||
onEnter?: Function,
|
||||
onEnter?: (e?: React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* Callback for the mouse leaving the component.
|
||||
*/
|
||||
onLeave?: Function,
|
||||
onLeave?: (e?: React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* Callback for making a selection in the menu.
|
||||
*/
|
||||
onSelect: Function,
|
||||
onSelect: (value?: boolean | React.MouseEvent) => void,
|
||||
|
||||
/**
|
||||
* Participant reference.
|
||||
|
@ -157,7 +157,7 @@ const ParticipantContextMenu = ({
|
|||
const _isVideoForceMuted = useSelector(state =>
|
||||
isForceMuted(participant, MEDIA_TYPE.VIDEO, state));
|
||||
const _isAudioMuted = useSelector(state => isParticipantAudioMuted(participant, state));
|
||||
const _overflowDrawer = useSelector(showOverflowDrawer);
|
||||
const _overflowDrawer: boolean = useSelector(showOverflowDrawer);
|
||||
const { remoteVideoMenu = {}, disableRemoteMute, startSilent }
|
||||
= useSelector((state: IState) => state['features/base/config']);
|
||||
const { disableKick, disableGrantModerator, disablePrivateChat } = remoteVideoMenu;
|
||||
|
@ -315,7 +315,7 @@ const ParticipantContextMenu = ({
|
|||
entity = { participant }
|
||||
hidden = { thumbnailMenu ? false : undefined }
|
||||
inDrawer = { thumbnailMenu && _overflowDrawer }
|
||||
isDrawerOpen = { drawerParticipant }
|
||||
isDrawerOpen = { Boolean(drawerParticipant) }
|
||||
offsetTarget = { offsetTarget }
|
||||
onClick = { onSelect }
|
||||
onDrawerClose = { thumbnailMenu ? onSelect : closeDrawer }
|
||||
|
|
Loading…
Reference in New Issue