mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2025-12-30 11:22:31 +00:00
feat(visitors) add info dialog (#14926)
This commit is contained in:
@@ -263,6 +263,7 @@
|
||||
"Remove": "Remove",
|
||||
"Share": "Share",
|
||||
"Submit": "Submit",
|
||||
"Understood": "Understood",
|
||||
"WaitForHostMsg": "The conference has not yet started because no moderators have yet arrived. If you'd like to become a moderator please log-in. Otherwise, please wait.",
|
||||
"WaitForHostNoAuthMsg": "The conference has not yet started because no moderators have yet arrived. Please wait.",
|
||||
"WaitingForHostButton": "Wait for moderator",
|
||||
@@ -1492,6 +1493,12 @@
|
||||
},
|
||||
"visitors": {
|
||||
"chatIndicator": "(visitor)",
|
||||
"joinMeeting": {
|
||||
"description": "You're currently an observer in this conference.",
|
||||
"raiseHand": "Raise your hand",
|
||||
"title": "Joining meeting",
|
||||
"wishToSpeak": "If you wish to speak, please raise your hand below and wait for the moderator's approval."
|
||||
},
|
||||
"labelTooltip": "Number of visitors: {{count}}",
|
||||
"notification": {
|
||||
"demoteDescription": "Sent here by {{actor}}, raise your hand to participate",
|
||||
|
||||
@@ -111,12 +111,9 @@ const Dialog = ({
|
||||
}, [ onCancel ]);
|
||||
|
||||
const submit = useCallback(() => {
|
||||
if (onSubmit && (
|
||||
(document.activeElement && !operatesWithEnterKey(document.activeElement))
|
||||
|| !document.activeElement
|
||||
)) {
|
||||
if ((document.activeElement && !operatesWithEnterKey(document.activeElement)) || !document.activeElement) {
|
||||
!disableAutoHideOnSubmit && dispatch(hideDialog());
|
||||
onSubmit();
|
||||
onSubmit?.();
|
||||
}
|
||||
}, [ onSubmit ]);
|
||||
|
||||
|
||||
@@ -40,6 +40,11 @@ interface IProps extends AbstractButtonProps {
|
||||
*/
|
||||
_raisedHand: boolean;
|
||||
|
||||
/**
|
||||
* Whether or not the click is disabled.
|
||||
*/
|
||||
disableClick?: boolean;
|
||||
|
||||
/**
|
||||
* Used to close the overflow menu after raise hand is clicked.
|
||||
*/
|
||||
@@ -75,8 +80,14 @@ class RaiseHandButton extends Component<IProps> {
|
||||
* @returns {void}
|
||||
*/
|
||||
_onClick() {
|
||||
const { disableClick, onCancel } = this.props;
|
||||
|
||||
if (disableClick) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._toggleRaisedHand();
|
||||
this.props.onCancel();
|
||||
onCancel();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,4 +170,23 @@ function _mapStateToProps(state: IReduxState) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @private
|
||||
* @returns {IProps}
|
||||
*/
|
||||
function _standaloneMapStateToProps(state: IReduxState) {
|
||||
const _enabled = getFeatureFlag(state, RAISE_HAND_ENABLED, true);
|
||||
|
||||
return {
|
||||
_enabled
|
||||
};
|
||||
}
|
||||
|
||||
const StandaloneRaiseHandButton = translate(connect(_standaloneMapStateToProps)(RaiseHandButton));
|
||||
|
||||
export { StandaloneRaiseHandButton };
|
||||
|
||||
export default translate(connect(_mapStateToProps)(RaiseHandButton));
|
||||
|
||||
@@ -2,7 +2,7 @@ import { connect } from 'react-redux';
|
||||
|
||||
import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
|
||||
import { sendAnalytics } from '../../../analytics/functions';
|
||||
import { IReduxState } from '../../../app/types';
|
||||
import { IReduxState, IStore } from '../../../app/types';
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import { IconRaiseHand } from '../../../base/icons/svg';
|
||||
import { raiseHand } from '../../../base/participants/actions';
|
||||
@@ -15,6 +15,16 @@ import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/too
|
||||
*/
|
||||
interface IProps extends AbstractButtonProps {
|
||||
|
||||
/**
|
||||
* Whether or not the click is disabled.
|
||||
*/
|
||||
disableClick?: boolean;
|
||||
|
||||
/**
|
||||
* Redux dispatch function.
|
||||
*/
|
||||
dispatch: IStore['dispatch'];
|
||||
|
||||
/**
|
||||
* Whether or not the hand is raised.
|
||||
*/
|
||||
@@ -51,7 +61,11 @@ class RaiseHandButton extends AbstractButton<IProps> {
|
||||
* @returns {void}
|
||||
*/
|
||||
_handleClick() {
|
||||
const { dispatch, raisedHand } = this.props;
|
||||
const { disableClick, dispatch, raisedHand } = this.props;
|
||||
|
||||
if (disableClick) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendAnalytics(createToolbarEvent(
|
||||
'raise.hand',
|
||||
@@ -76,4 +90,6 @@ const mapStateToProps = (state: IReduxState) => {
|
||||
};
|
||||
};
|
||||
|
||||
export { RaiseHandButton };
|
||||
|
||||
export default translate(connect(mapStateToProps)(RaiseHandButton));
|
||||
|
||||
1
react/features/visitors/components/index.native.ts
Normal file
1
react/features/visitors/components/index.native.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as JoinMeetingDialog } from './native/JoinMeetingDialog';
|
||||
1
react/features/visitors/components/index.web.ts
Normal file
1
react/features/visitors/components/index.web.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as JoinMeetingDialog } from './web/JoinMeetingDialog';
|
||||
@@ -0,0 +1,40 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { View, ViewStyle } from 'react-native';
|
||||
import Dialog from 'react-native-dialog';
|
||||
|
||||
import { StandaloneRaiseHandButton as RaiseHandButton } from '../../../reactions/components/native/RaiseHandButton';
|
||||
import styles from '../../components/native/styles';
|
||||
|
||||
/**
|
||||
* Component that renders the join meeting dialog for visitors.
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export default function JoinMeetingDialog() {
|
||||
const { t } = useTranslation();
|
||||
const [ visible, setVisible ] = useState(true);
|
||||
|
||||
const closeDialog = useCallback(() => {
|
||||
setVisible(false);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Dialog.Container
|
||||
coverScreen = { false }
|
||||
visible = { visible }>
|
||||
<Dialog.Title>{ t('visitors.joinMeeting.title') }</Dialog.Title>
|
||||
<Dialog.Description>
|
||||
{ t('visitors.joinMeeting.description') }
|
||||
<View style = { styles.raiseHandButton as ViewStyle }>
|
||||
{/* @ts-ignore */}
|
||||
<RaiseHandButton disableClick = { true } />
|
||||
</View>
|
||||
</Dialog.Description>
|
||||
<Dialog.Description>{t('visitors.joinMeeting.wishToSpeak')}</Dialog.Description>
|
||||
<Dialog.Button
|
||||
label = { t('dialog.Understood') }
|
||||
onPress = { closeDialog } />
|
||||
</Dialog.Container>
|
||||
);
|
||||
}
|
||||
12
react/features/visitors/components/native/styles.ts
Normal file
12
react/features/visitors/components/native/styles.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* The styles of the feature visitors.
|
||||
*/
|
||||
export default {
|
||||
|
||||
raiseHandButton: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '100%'
|
||||
}
|
||||
};
|
||||
75
react/features/visitors/components/web/JoinMeetingDialog.tsx
Normal file
75
react/features/visitors/components/web/JoinMeetingDialog.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import { noop } from 'lodash';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
import { IconArrowUp } from '../../../base/icons/svg';
|
||||
import ToolboxButtonWithPopup from '../../../base/toolbox/components/web/ToolboxButtonWithPopup';
|
||||
import Dialog from '../../../base/ui/components/web/Dialog';
|
||||
import { RaiseHandButton } from '../../../reactions/components/web/RaiseHandButton';
|
||||
|
||||
const useStyles = makeStyles()(theme => {
|
||||
return {
|
||||
raiseHand: {
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
marginTop: theme.spacing(3),
|
||||
marginBottom: theme.spacing(3),
|
||||
pointerEvents: 'none'
|
||||
},
|
||||
raiseHandTooltip: {
|
||||
border: '1px solid #444',
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
paddingBottom: theme.spacing(1),
|
||||
paddingTop: theme.spacing(1),
|
||||
paddingLeft: theme.spacing(2),
|
||||
paddingRight: theme.spacing(2)
|
||||
},
|
||||
raiseHandButton: {
|
||||
display: 'inline-block',
|
||||
marginTop: theme.spacing(2),
|
||||
marginBottom: theme.spacing(2),
|
||||
position: 'relative'
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Component that renders the join meeting dialog for visitors.
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export default function JoinMeetingDialog() {
|
||||
const { t } = useTranslation();
|
||||
const { classes } = useStyles();
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
cancel = {{ hidden: true }}
|
||||
ok = {{ translationKey: 'dialog.Understood' }}
|
||||
titleKey = 'visitors.joinMeeting.title'>
|
||||
<div className = 'join-meeting-dialog'>
|
||||
<p>{t('visitors.joinMeeting.description')}</p>
|
||||
<div className = { classes.raiseHand }>
|
||||
<p className = { classes.raiseHandTooltip }>{t('visitors.joinMeeting.raiseHand')}</p>
|
||||
<div className = { classes.raiseHandButton }>
|
||||
<ToolboxButtonWithPopup
|
||||
icon = { IconArrowUp }
|
||||
iconDisabled = { false }
|
||||
onPopoverClose = { noop }
|
||||
onPopoverOpen = { noop }
|
||||
popoverContent = { null }
|
||||
visible = { false }>
|
||||
{/* @ts-ignore */}
|
||||
<RaiseHandButton
|
||||
disableClick = { true }
|
||||
raisedHand = { true } />
|
||||
</ToolboxButtonWithPopup>
|
||||
</div>
|
||||
</div>
|
||||
<p>{t('visitors.joinMeeting.wishToSpeak')}</p>
|
||||
</div>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import { SET_CONFIG } from '../base/config/actionTypes';
|
||||
import { CONNECTION_FAILED } from '../base/connection/actionTypes';
|
||||
import { connect, setPreferVisitor } from '../base/connection/actions';
|
||||
import { disconnect } from '../base/connection/actions.any';
|
||||
import { openDialog } from '../base/dialog/actions';
|
||||
import { JitsiConferenceEvents, JitsiConnectionErrors } from '../base/lib-jitsi-meet';
|
||||
import { PARTICIPANT_UPDATED } from '../base/participants/actionTypes';
|
||||
import { raiseHand } from '../base/participants/actions';
|
||||
@@ -48,6 +49,7 @@ import {
|
||||
updateVisitorsCount,
|
||||
updateVisitorsInQueueCount
|
||||
} from './actions';
|
||||
import { JoinMeetingDialog } from './components';
|
||||
import { getPromotionRequests, getVisitorsCount, getVisitorsInQueueCount } from './functions';
|
||||
import logger from './logger';
|
||||
import { WebsocketClient } from './websocket-client';
|
||||
@@ -70,6 +72,8 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
||||
const { conference } = action;
|
||||
|
||||
if (getState()['features/visitors'].iAmVisitor) {
|
||||
dispatch(openDialog(JoinMeetingDialog));
|
||||
|
||||
const { demoteActorDisplayName } = getState()['features/visitors'];
|
||||
|
||||
dispatch(setVisitorDemoteActor(undefined));
|
||||
|
||||
Reference in New Issue
Block a user