ref(ui-components) Use new Dialog (#12363)

Convert some files to TS
Improve Dialog component
This commit is contained in:
Robert Pintilii 2022-10-17 14:27:48 +03:00 committed by GitHub
parent 6274299d49
commit dd6478b3cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 148 additions and 163 deletions

View File

@ -7,11 +7,10 @@ import { connect } from '../../../../../connection';
import { IState, IStore } from '../../../app/types'; import { IState, IStore } from '../../../app/types';
import { IConfig } from '../../../base/config/configType'; import { IConfig } from '../../../base/config/configType';
import { toJid } from '../../../base/connection/functions'; import { toJid } from '../../../base/connection/functions';
// @ts-ignore
import { Dialog } from '../../../base/dialog';
import { translate, translateToHTML } from '../../../base/i18n/functions'; import { translate, translateToHTML } from '../../../base/i18n/functions';
import { JitsiConnectionErrors } from '../../../base/lib-jitsi-meet'; import { JitsiConnectionErrors } from '../../../base/lib-jitsi-meet';
import { connect as reduxConnect } from '../../../base/redux/functions'; import { connect as reduxConnect } from '../../../base/redux/functions';
import Dialog from '../../../base/ui/components/web/Dialog';
import Input from '../../../base/ui/components/web/Input'; import Input from '../../../base/ui/components/web/Input';
import { import {
authenticateAndUpgradeRole, authenticateAndUpgradeRole,
@ -255,19 +254,18 @@ class LoginDialog extends Component<Props, State> {
return ( return (
<Dialog <Dialog
disableBlanketClickDismiss = { true } disableBackdropClose = { true }
hideCloseIconButton = { true } hideCloseButton = { true }
okDisabled = { ok = {{
connecting disabled: connecting
|| loginStarted || loginStarted
|| !password || !password
|| !username || !username,
} translationKey: 'dialog.login'
okKey = { t('dialog.login') } }}
onCancel = { this._onCancelLogin } onCancel = { this._onCancelLogin }
onSubmit = { this._onLogin } onSubmit = { this._onLogin }
titleKey = { t('dialog.authenticationRequired') } titleKey = { t('dialog.authenticationRequired') }>
width = { 'small' }>
<Input <Input
autoFocus = { true } autoFocus = { true }
label = { t('dialog.user') } label = { t('dialog.user') }
@ -278,6 +276,7 @@ class LoginDialog extends Component<Props, State> {
value = { username } /> value = { username } />
<br /> <br />
<Input <Input
className = 'dialog-bottom-margin'
label = { t('dialog.userPassword') } label = { t('dialog.userPassword') }
name = 'password' name = 'password'
onChange = { this._onPasswordChange } onChange = { this._onPasswordChange }

View File

@ -1,32 +1,28 @@
// @flow
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import type { Dispatch } from 'redux'; import { WithTranslation } from 'react-i18next';
import { Dialog } from '../../../base/dialog'; import { IStore } from '../../../app/types';
import { translate } from '../../../base/i18n'; import { translate } from '../../../base/i18n/functions';
import { connect } from '../../../base/redux'; import { connect } from '../../../base/redux/functions';
import Dialog from '../../../base/ui/components/web/Dialog';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import { cancelWaitForOwner } from '../../actions.web'; import { cancelWaitForOwner } from '../../actions.web';
/** /**
* The type of the React {@code Component} props of {@link WaitForOwnerDialog}. * The type of the React {@code Component} props of {@link WaitForOwnerDialog}.
*/ */
type Props = { interface Props extends WithTranslation {
/** /**
* Redux store dispatch method. * Redux store dispatch method.
*/ */
dispatch: Dispatch<any>, dispatch: IStore['dispatch'];
/** /**
* Function to be invoked after click. * Function to be invoked after click.
*/ */
onAuthNow: ?Function, onAuthNow?: Function;
/**
* Invoked to obtain translated strings.
*/
t: Function
} }
/** /**
@ -48,8 +44,6 @@ class WaitForOwnerDialog extends PureComponent<Props> {
this._onIAmHost = this._onIAmHost.bind(this); this._onIAmHost = this._onIAmHost.bind(this);
} }
_onCancelWaitForOwner: () => void;
/** /**
* Called when the cancel button is clicked. * Called when the cancel button is clicked.
* *
@ -62,8 +56,6 @@ class WaitForOwnerDialog extends PureComponent<Props> {
dispatch(cancelWaitForOwner()); dispatch(cancelWaitForOwner());
} }
_onIAmHost: () => void;
/** /**
* Called when the OK button is clicked. * Called when the OK button is clicked.
* *
@ -73,7 +65,7 @@ class WaitForOwnerDialog extends PureComponent<Props> {
_onIAmHost() { _onIAmHost() {
const { onAuthNow } = this.props; const { onAuthNow } = this.props;
onAuthNow && onAuthNow(); onAuthNow?.();
} }
/** /**
@ -88,13 +80,12 @@ class WaitForOwnerDialog extends PureComponent<Props> {
return ( return (
<Dialog <Dialog
disableBlanketClickDismiss = { true } disableBackdropClose = { true }
hideCloseIconButton = { true } hideCloseButton = { true }
okKey = { t('dialog.IamHost') } ok = {{ translationKey: 'dialog.IamHost' }}
onCancel = { this._onCancelWaitForOwner } onCancel = { this._onCancelWaitForOwner }
onSubmit = { this._onIAmHost } onSubmit = { this._onIAmHost }
titleKey = { t('dialog.WaitingForHostTitle') } titleKey = { t('dialog.WaitingForHostTitle') }>
width = { 'small' }>
<span> <span>
{ t('dialog.WaitForHostMsg') } { t('dialog.WaitForHostMsg') }
</span> </span>

View File

@ -1,5 +1,8 @@
/* eslint-disable lines-around-comment */ /* eslint-disable lines-around-comment */
import LoginDialog from '../../authentication/components/web/LoginDialog';
import WaitForOwnerDialog from '../../authentication/components/web/WaitForOwnerDialog';
import ChatPrivacyDialog from '../../chat/components/web/ChatPrivacyDialog'; import ChatPrivacyDialog from '../../chat/components/web/ChatPrivacyDialog';
import DesktopPicker from '../../desktop-picker/components/DesktopPicker';
import DisplayNamePrompt from '../../display-name/components/web/DisplayNamePrompt'; import DisplayNamePrompt from '../../display-name/components/web/DisplayNamePrompt';
import EmbedMeetingDialog from '../../embed-meeting/components/EmbedMeetingDialog'; import EmbedMeetingDialog from '../../embed-meeting/components/EmbedMeetingDialog';
// @ts-ignore // @ts-ignore
@ -15,9 +18,12 @@ import StopLiveStreamDialog from '../../recording/components/LiveStream/web/Stop
import StartRecordingDialog from '../../recording/components/Recording/web/StartRecordingDialog'; import StartRecordingDialog from '../../recording/components/Recording/web/StartRecordingDialog';
// @ts-ignore // @ts-ignore
import StopRecordingDialog from '../../recording/components/Recording/web/StopRecordingDialog'; import StopRecordingDialog from '../../recording/components/Recording/web/StopRecordingDialog';
// @ts-ignore
import RemoteControlAuthorizationDialog from '../../remote-control/components/RemoteControlAuthorizationDialog';
import ShareAudioDialog from '../../screen-share/components/ShareAudioDialog'; import ShareAudioDialog from '../../screen-share/components/ShareAudioDialog';
import ShareScreenWarningDialog from '../../screen-share/components/ShareScreenWarningDialog'; import ShareScreenWarningDialog from '../../screen-share/components/ShareScreenWarningDialog';
import SecurityDialog from '../../security/components/security-dialog/web/SecurityDialog'; import SecurityDialog from '../../security/components/security-dialog/web/SecurityDialog';
import LogoutDialog from '../../settings/components/web/LogoutDialog';
import SharedVideoDialog from '../../shared-video/components/web/SharedVideoDialog'; import SharedVideoDialog from '../../shared-video/components/web/SharedVideoDialog';
import SpeakerStats from '../../speaker-stats/components/web/SpeakerStats'; import SpeakerStats from '../../speaker-stats/components/web/SpeakerStats';
import LanguageSelectorDialog from '../../subtitles/components/LanguageSelectorDialog.web'; import LanguageSelectorDialog from '../../subtitles/components/LanguageSelectorDialog.web';
@ -41,7 +47,8 @@ const NEW_DIALOG_LIST = [ KeyboardShortcutsDialog, ChatPrivacyDialog, DisplayNam
StartRecordingDialog, StopRecordingDialog, ShareAudioDialog, ShareScreenWarningDialog, SecurityDialog, StartRecordingDialog, StopRecordingDialog, ShareAudioDialog, ShareScreenWarningDialog, SecurityDialog,
SharedVideoDialog, SpeakerStats, LanguageSelectorDialog, MuteEveryoneDialog, MuteEveryonesVideoDialog, SharedVideoDialog, SpeakerStats, LanguageSelectorDialog, MuteEveryoneDialog, MuteEveryonesVideoDialog,
GrantModeratorDialog, KickRemoteParticipantDialog, MuteRemoteParticipantsVideoDialog, VideoQualityDialog, GrantModeratorDialog, KickRemoteParticipantDialog, MuteRemoteParticipantsVideoDialog, VideoQualityDialog,
VirtualBackgroundDialog ]; VirtualBackgroundDialog, LoginDialog, WaitForOwnerDialog, DesktopPicker, RemoteControlAuthorizationDialog,
LogoutDialog ];
// This function is necessary while the transition from @atlaskit dialog to our component is ongoing. // This function is necessary while the transition from @atlaskit dialog to our component is ongoing.
const isNewDialog = (component: any) => NEW_DIALOG_LIST.some(comp => comp === component); const isNewDialog = (component: any) => NEW_DIALOG_LIST.some(comp => comp === component);

View File

@ -1,5 +1,5 @@
import { Theme } from '@mui/material'; import { Theme } from '@mui/material';
import React, { ReactElement, useCallback, useContext, useEffect } from 'react'; import React, { useCallback, useContext, useEffect } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { keyframes } from 'tss-react'; import { keyframes } from 'tss-react';
@ -177,9 +177,11 @@ interface DialogProps {
hidden?: boolean; hidden?: boolean;
translationKey?: string; translationKey?: string;
}; };
children?: ReactElement | ReactElement[]; children?: React.ReactNode;
className?: string; className?: string;
description?: string; description?: string;
disableBackdropClose?: boolean;
hideCloseButton?: boolean;
ok?: { ok?: {
disabled?: boolean; disabled?: boolean;
hidden?: boolean; hidden?: boolean;
@ -197,6 +199,8 @@ const Dialog = ({
children, children,
className, className,
description, description,
disableBackdropClose,
hideCloseButton,
ok = { translationKey: 'dialog.Ok' }, ok = { translationKey: 'dialog.Ok' },
onCancel, onCancel,
onSubmit, onSubmit,
@ -214,17 +218,24 @@ const Dialog = ({
dispatch(hideDialog()); dispatch(hideDialog());
}, [ onCancel ]); }, [ onCancel ]);
const handleKeyDown = useCallback((e: KeyboardEvent) => {
if (e.key === 'Escape') {
onClose();
}
}, []);
const submit = useCallback(() => { const submit = useCallback(() => {
onSubmit?.(); onSubmit?.();
dispatch(hideDialog()); dispatch(hideDialog());
}, [ onSubmit ]); }, [ onSubmit ]);
const handleKeyDown = useCallback((e: KeyboardEvent) => {
if (e.key === 'Escape') {
onClose();
}
if (e.key === 'Enter') {
submit();
}
}, []);
const onBackdropClick = useCallback(() => {
!disableBackdropClose && onClose();
}, [ disableBackdropClose, onClose ]);
useEffect(() => { useEffect(() => {
window.addEventListener('keydown', handleKeyDown); window.addEventListener('keydown', handleKeyDown);
@ -235,7 +246,7 @@ const Dialog = ({
<div className = { cx(classes.container, isUnmounting && 'unmount') }> <div className = { cx(classes.container, isUnmounting && 'unmount') }>
<div <div
className = { classes.backdrop } className = { classes.backdrop }
onClick = { onClose } /> onClick = { onBackdropClick } />
<div <div
aria-describedby = { description } aria-describedby = { description }
aria-labelledby = { title ?? t(titleKey ?? '') } aria-labelledby = { title ?? t(titleKey ?? '') }
@ -248,11 +259,13 @@ const Dialog = ({
id = 'dialog-title'> id = 'dialog-title'>
{title ?? t(titleKey ?? '')} {title ?? t(titleKey ?? '')}
</p> </p>
<ClickableIcon {!hideCloseButton && (
accessibilityLabel = { t('dialog.close') } <ClickableIcon
icon = { IconClose } accessibilityLabel = { t('dialog.close') }
id = 'modal-header-close-button' icon = { IconClose }
onClick = { onClose } /> id = 'modal-header-close-button'
onClick = { onClose } />
)}
</div> </div>
<div className = { classes.content }>{children}</div> <div className = { classes.content }>{children}</div>
<div className = { classes.footer }> <div className = { classes.footer }>

View File

@ -1,14 +1,17 @@
// @flow /* eslint-disable lines-around-comment */
import Tabs from '@atlaskit/tabs'; import Tabs from '@atlaskit/tabs';
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import type { Dispatch } from 'redux'; import { WithTranslation } from 'react-i18next';
import { Dialog, hideDialog } from '../../base/dialog'; import { IStore } from '../../app/types';
import { translate } from '../../base/i18n'; import { hideDialog } from '../../base/dialog/actions';
import { connect } from '../../base/redux'; import { translate } from '../../base/i18n/functions';
import { connect } from '../../base/redux/functions';
import Dialog from '../../base/ui/components/web/Dialog';
// @ts-ignore
import { obtainDesktopSources } from '../functions'; import { obtainDesktopSources } from '../functions';
// @ts-ignore
import DesktopPickerPane from './DesktopPickerPane'; import DesktopPickerPane from './DesktopPickerPane';
/** /**
@ -45,29 +48,24 @@ const VALID_TYPES = Object.keys(TAB_LABELS);
/** /**
* The type of the React {@code Component} props of {@link DesktopPicker}. * The type of the React {@code Component} props of {@link DesktopPicker}.
*/ */
type Props = { interface Props extends WithTranslation {
/** /**
* An array with desktop sharing sources to be displayed. * An array with desktop sharing sources to be displayed.
*/ */
desktopSharingSources: Array<string>, desktopSharingSources: Array<string>;
/** /**
* Used to request DesktopCapturerSources. * Used to request DesktopCapturerSources.
*/ */
dispatch: Dispatch<any>, dispatch: IStore['dispatch'];
/** /**
* The callback to be invoked when the component is closed or when a * The callback to be invoked when the component is closed or when a
* DesktopCapturerSource has been chosen. * DesktopCapturerSource has been chosen.
*/ */
onSourceChoose: Function, onSourceChoose: Function;
}
/**
* Used to obtain translations.
*/
t: Function
};
/** /**
* The type of the React {@code Component} state of {@link DesktopPicker}. * The type of the React {@code Component} state of {@link DesktopPicker}.
@ -77,27 +75,27 @@ type State = {
/** /**
* The state of the audio screen share checkbox. * The state of the audio screen share checkbox.
*/ */
screenShareAudio: boolean, screenShareAudio: boolean;
/** /**
* The currently highlighted DesktopCapturerSource. * The currently highlighted DesktopCapturerSource.
*/ */
selectedSource: Object, selectedSource: any;
/** /**
* The desktop source type currently being displayed. * The desktop source type currently being displayed.
*/ */
selectedTab: number, selectedTab: number;
/** /**
* An object containing all the DesktopCapturerSources. * An object containing all the DesktopCapturerSources.
*/ */
sources: Object, sources: Object;
/** /**
* The desktop source types to fetch previews for. * The desktop source types to fetch previews for.
*/ */
types: Array<string> types: Array<string>;
}; };
@ -112,7 +110,7 @@ class DesktopPicker extends PureComponent<Props, State> {
* *
* @inheritdoc * @inheritdoc
*/ */
static getDerivedStateFromProps(props) { static getDerivedStateFromProps(props: Props) {
return { return {
types: DesktopPicker._getValidTypes(props.desktopSharingSources) types: DesktopPicker._getValidTypes(props.desktopSharingSources)
}; };
@ -125,14 +123,14 @@ class DesktopPicker extends PureComponent<Props, State> {
* @private * @private
* @returns {Array<string>} The filtered types. * @returns {Array<string>} The filtered types.
*/ */
static _getValidTypes(types = []) { static _getValidTypes(types: string[] = []) {
return types.filter( return types.filter(
type => VALID_TYPES.includes(type)); type => VALID_TYPES.includes(type));
} }
_poller = null; _poller: any = null;
state = { state: State = {
screenShareAudio: false, screenShareAudio: false,
selectedSource: {}, selectedSource: {},
selectedTab: 0, selectedTab: 0,
@ -195,33 +193,34 @@ class DesktopPicker extends PureComponent<Props, State> {
render() { render() {
return ( return (
<Dialog <Dialog
isModal = { false } ok = {{
okDisabled = { Boolean(!this.state.selectedSource.id) } disabled: Boolean(!this.state.selectedSource.id),
okKey = 'dialog.Share' translationKey: 'dialog.Share'
}}
onCancel = { this._onCloseModal } onCancel = { this._onCloseModal }
onSubmit = { this._onSubmit } onSubmit = { this._onSubmit }
titleKey = 'dialog.shareYourScreen' size = 'large'
width = 'medium' > titleKey = 'dialog.shareYourScreen'>
{ this._renderTabs() } { this._renderTabs() }
</Dialog> </Dialog>
); );
} }
/** /**
* Computates the selected source. * Computes the selected source.
* *
* @param {Object} sources - The available sources. * @param {Object} sources - The available sources.
* @returns {Object} The selectedSource value. * @returns {Object} The selectedSource value.
*/ */
_getSelectedSource(sources = {}) { _getSelectedSource(sources: any = {}) {
const { selectedSource } = this.state; const { selectedSource } = this.state;
/** /**
* If there are no sources for this type (or no sources for any type) * If there are no sources for this type (or no sources for any type)
* we can't select anything. * we can't select anything.
*/ */
if (!Array.isArray(sources[this._selectedTabType]) if (!Array.isArray(sources[this._selectedTabType as keyof typeof sources])
|| sources[this._selectedTabType].length <= 0) { || sources[this._selectedTabType as keyof typeof sources].length <= 0) {
return {}; return {};
} }
@ -235,7 +234,7 @@ class DesktopPicker extends PureComponent<Props, State> {
if (!selectedSource // scenario 1) if (!selectedSource // scenario 1)
|| selectedSource.type !== this._selectedTabType // scenario 2) || selectedSource.type !== this._selectedTabType // scenario 2)
|| !sources[this._selectedTabType].some( // scenario 3) || !sources[this._selectedTabType].some( // scenario 3)
source => source.id === selectedSource.id)) { (source: any) => source.id === selectedSource.id)) {
return { return {
id: sources[this._selectedTabType][0].id, id: sources[this._selectedTabType][0].id,
type: this._selectedTabType type: this._selectedTabType
@ -248,8 +247,6 @@ class DesktopPicker extends PureComponent<Props, State> {
return selectedSource; return selectedSource;
} }
_onCloseModal: (?string, string, ?boolean) => void;
/** /**
* Dispatches an action to hide the DesktopPicker and invokes the passed in * Dispatches an action to hide the DesktopPicker and invokes the passed in
* callback with a selectedSource, if any. * callback with a selectedSource, if any.
@ -262,13 +259,11 @@ class DesktopPicker extends PureComponent<Props, State> {
* screen sharing session. * screen sharing session.
* @returns {void} * @returns {void}
*/ */
_onCloseModal(id = '', type, screenShareAudio = false) { _onCloseModal(id = '', type?: string, screenShareAudio = false) {
this.props.onSourceChoose(id, type, screenShareAudio); this.props.onSourceChoose(id, type, screenShareAudio);
this.props.dispatch(hideDialog()); this.props.dispatch(hideDialog());
} }
_onPreviewClick: (string, string) => void;
/** /**
* Sets the currently selected DesktopCapturerSource. * Sets the currently selected DesktopCapturerSource.
* *
@ -276,7 +271,7 @@ class DesktopPicker extends PureComponent<Props, State> {
* @param {string} type - The type of DesktopCapturerSource. * @param {string} type - The type of DesktopCapturerSource.
* @returns {void} * @returns {void}
*/ */
_onPreviewClick(id, type) { _onPreviewClick(id: string, type: string) {
this.setState({ this.setState({
selectedSource: { selectedSource: {
id, id,
@ -285,8 +280,6 @@ class DesktopPicker extends PureComponent<Props, State> {
}); });
} }
_onSubmit: () => void;
/** /**
* Request to close the modal and execute callbacks with the selected source * Request to close the modal and execute callbacks with the selected source
* id. * id.
@ -299,19 +292,17 @@ class DesktopPicker extends PureComponent<Props, State> {
this._onCloseModal(id, type, screenShareAudio); this._onCloseModal(id, type, screenShareAudio);
} }
_onTabSelected: () => void;
/** /**
* Stores the selected tab and updates the selected source via * Stores the selected tab and updates the selected source via
* {@code _getSelectedSource}. * {@code _getSelectedSource}.
* *
* @param {Object} tab - The configuration passed into atlaskit tabs to * @param {Object} _tab - The configuration passed into atlaskit tabs to
* describe how to display the selected tab. * describe how to display the selected tab.
* @param {number} tabIndex - The index of the tab within the array of * @param {number} tabIndex - The index of the tab within the array of
* displayed tabs. * displayed tabs.
* @returns {void} * @returns {void}
*/ */
_onTabSelected(tab, tabIndex) { // eslint-disable-line no-unused-vars _onTabSelected(_tab: Object, tabIndex: number) {
const { types, sources } = this.state; const { types, sources } = this.state;
this._selectedTabType = types[tabIndex]; this._selectedTabType = types[tabIndex];
@ -325,8 +316,6 @@ class DesktopPicker extends PureComponent<Props, State> {
}); });
} }
_onShareAudioChecked: (boolean) => void;
/** /**
* Set the screenSharingAudio state indicating whether or not to also share * Set the screenSharingAudio state indicating whether or not to also share
* system audio. * system audio.
@ -334,7 +323,7 @@ class DesktopPicker extends PureComponent<Props, State> {
* @param {boolean} checked - Share audio or not. * @param {boolean} checked - Share audio or not.
* @returns {void} * @returns {void}
*/ */
_onShareAudioChecked(checked) { _onShareAudioChecked(checked: boolean) {
this.setState({ screenShareAudio: checked }); this.setState({ screenShareAudio: checked });
} }
@ -357,9 +346,9 @@ class DesktopPicker extends PureComponent<Props, State> {
onDoubleClick = { this._onSubmit } onDoubleClick = { this._onSubmit }
onShareAudioChecked = { this._onShareAudioChecked } onShareAudioChecked = { this._onShareAudioChecked }
selectedSourceId = { selectedSource.id } selectedSourceId = { selectedSource.id }
sources = { sources[type] } sources = { sources[type as keyof typeof sources] }
type = { type } />, type = { type } />,
label: t(TAB_LABELS[type]) label: t(TAB_LABELS[type as keyof typeof TAB_LABELS])
}; };
}); });
@ -393,8 +382,6 @@ class DesktopPicker extends PureComponent<Props, State> {
this._poller = null; this._poller = null;
} }
_updateSources: () => void;
/** /**
* Obtains the desktop sources and updates state with them. * Obtains the desktop sources and updates state with them.
* *
@ -409,7 +396,7 @@ class DesktopPicker extends PureComponent<Props, State> {
this.state.types, this.state.types,
{ thumbnailSize: THUMBNAIL_SIZE } { thumbnailSize: THUMBNAIL_SIZE }
) )
.then(sources => { .then((sources: any) => {
const selectedSource = this._getSelectedSource(sources); const selectedSource = this._getSelectedSource(sources);
// TODO: Maybe check if we have stopped the timer and unmounted // TODO: Maybe check if we have stopped the timer and unmounted

View File

@ -2,11 +2,12 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Dialog, hideDialog } from '../../base/dialog'; import { hideDialog } from '../../base/dialog/actions';
import { translate } from '../../base/i18n'; import { translate } from '../../base/i18n';
import { getParticipantById } from '../../base/participants'; import { getParticipantById } from '../../base/participants';
import { connect } from '../../base/redux'; import { connect } from '../../base/redux';
import { getLocalVideoTrack } from '../../base/tracks'; import { getLocalVideoTrack } from '../../base/tracks';
import Dialog from '../../base/ui/components/web/Dialog';
import { deny, grant } from '../actions'; import { deny, grant } from '../actions';
declare var APP: Object; declare var APP: Object;
@ -68,11 +69,10 @@ class RemoteControlAuthorizationDialog extends Component<Props> {
render() { render() {
return ( return (
<Dialog <Dialog
okKey = { 'dialog.allow' } ok = {{ translationKey: 'dialog.allow' }}
onCancel = { this._onCancel } onCancel = { this._onCancel }
onSubmit = { this._onSubmit } onSubmit = { this._onSubmit }
titleKey = 'dialog.remoteControlTitle' titleKey = 'dialog.remoteControlTitle'>
width = 'small'>
{ {
this.props.t( this.props.t(
'dialog.remoteControlRequestMessage', 'dialog.remoteControlRequestMessage',

View File

@ -11,8 +11,7 @@ import { Dialog } from '../../../base/dialog';
import { hideDialog } from '../../../base/dialog/actions'; import { hideDialog } from '../../../base/dialog/actions';
import Icon from '../../../base/icons/components/Icon'; import Icon from '../../../base/icons/components/Icon';
import { IconSearch } from '../../../base/icons/svg'; import { IconSearch } from '../../../base/icons/svg';
// @ts-ignore import { getFieldValue } from '../../../base/react/functions';
import { getFieldValue } from '../../../base/react';
import { withPixelLineHeight } from '../../../base/styles/functions.web'; import { withPixelLineHeight } from '../../../base/styles/functions.web';
import { NOTES_MAX_LENGTH } from '../../constants'; import { NOTES_MAX_LENGTH } from '../../constants';
// @ts-ignore // @ts-ignore
@ -20,7 +19,6 @@ import { useSalesforceLinkDialog } from '../../useSalesforceLinkDialog';
import { RecordItem } from './RecordItem'; import { RecordItem } from './RecordItem';
// @ts-ignore
const useStyles = makeStyles()((theme: Theme) => { const useStyles = makeStyles()((theme: Theme) => {
return { return {
container: { container: {
@ -102,7 +100,7 @@ const useStyles = makeStyles()((theme: Theme) => {
minHeight: '130px', minHeight: '130px',
resize: 'vertical', resize: 'vertical',
width: '100%', width: '100%',
boxSizing: 'borderBox', boxSizing: 'border-box',
overflow: 'hidden', overflow: 'hidden',
border: '1px solid', border: '1px solid',
borderColor: theme.palette.ui05, borderColor: theme.palette.ui05,

View File

@ -1,48 +0,0 @@
// @flow
import React from 'react';
import { Dialog } from '../../../base/dialog';
import { translate } from '../../../base/i18n';
import { connect } from '../../../base/redux';
/**
* The type of {@link LogoutDialog}'s React {@code Component} props.
*/
type Props = {
/**
* Logout handler.
*/
onLogout: Function,
/**
* Function to be used to translate i18n labels.
*/
t: Function
};
/**
* Implements the Logout dialog.
*
* @param {Object} props - The props of the component.
* @returns {React$Element}.
*/
function LogoutDialog(props: Props) {
const { onLogout, t } = props;
return (
<Dialog
hideCancelButton = { false }
okKey = { t('dialog.Yes') }
onSubmit = { onLogout }
titleKey = { t('dialog.logoutTitle') }
width = { 'small' }>
<div>
{ t('dialog.logoutQuestion') }
</div>
</Dialog>
);
}
export default translate(connect()(LogoutDialog));

View File

@ -0,0 +1,38 @@
import React from 'react';
import { WithTranslation } from 'react-i18next';
import { translate } from '../../../base/i18n/functions';
import { connect } from '../../../base/redux/functions';
import Dialog from '../../../base/ui/components/web/Dialog';
/**
* The type of {@link LogoutDialog}'s React {@code Component} props.
*/
interface Props extends WithTranslation {
/**
* Logout handler.
*/
onLogout: () => void;
}
/**
* Implements the Logout dialog.
*
* @param {Object} props - The props of the component.
* @returns {React$Element}.
*/
function LogoutDialog({ onLogout, t }: Props) {
return (
<Dialog
ok = {{ translationKey: 'dialog.Yes' }}
onSubmit = { onLogout }
titleKey = { t('dialog.logoutTitle') }>
<div>
{ t('dialog.logoutQuestion') }
</div>
</Dialog>
);
}
export default translate(connect()(LogoutDialog));