diff --git a/conference.js b/conference.js index 876713f065ca..e627d2ba21bf 100644 --- a/conference.js +++ b/conference.js @@ -2133,7 +2133,7 @@ export default { * @param {boolean} [notifyOnConferenceTermination] whether to notify * the user on conference termination */ - hangup(requestFeedback = false, hangupReason, notifyOnConferenceTermination) { + hangup(requestFeedback = false, hangupReason, notifyOnConferenceTermination, hangupMessage) { APP.store.dispatch(disableReceiver()); this._stopProxyConnection(); @@ -2154,7 +2154,7 @@ export default { const feedbackDialogClosed = (feedbackResult = {}) => { if (!feedbackResult.wasDialogShown && hangupReason && notifyOnConferenceTermination) { return APP.store.dispatch( - openLeaveReasonDialog(hangupReason)).then(() => feedbackResult); + openLeaveReasonDialog(hangupReason, hangupMessage)).then(() => feedbackResult); } return Promise.resolve(feedbackResult); diff --git a/lang/main-es.json b/lang/main-es.json index 0d232107973d..68df08c3644a 100644 --- a/lang/main-es.json +++ b/lang/main-es.json @@ -330,6 +330,8 @@ "incorrectRoomLockPassword": "Contraseña incorrecta", "internalError": "¡Ups! Algo salió mal. El siguiente error ocurrió: {{error}}", "internalErrorTitle": "Error interno", + "kickDuplicateTitle": "Oops! Ya estas en la reunión ", + "kickDuplicateMessage": "Parece que ya estabas en la reunión. Prueba a mirar en otra ventana, quiza ya tengas la reunion iniciada.", "kickMessage": "Puede ponerse en contacto con {{participantDisplayName}} para obtener más detalles.", "kickParticipantButton": "Expulsar", "kickParticipantDialog": "¿Seguro que quiere expulsar a este participante?", diff --git a/lang/main.json b/lang/main.json index b9ce97430f15..67637be06208 100644 --- a/lang/main.json +++ b/lang/main.json @@ -376,6 +376,8 @@ "incorrectRoomLockPassword": "Incorrect password", "internalError": "Oops! Something went wrong. The following error occurred: {{error}}", "internalErrorTitle": "Internal error", + "kickDuplicateTitle": "Oops! You are already in the meeting", + "kickDuplicateMessage": "It looks like you already joined this meeting. Try looking into other open windows where you might have the meeting running", "kickMessage": "You can contact {{participantDisplayName}} for more details.", "kickParticipantButton": "Kick", "kickParticipantDialog": "Are you sure you want to kick this participant?", diff --git a/react/features/base/connection/actions.web.ts b/react/features/base/connection/actions.web.ts index b16145a1876a..aa87312ecf58 100644 --- a/react/features/base/connection/actions.web.ts +++ b/react/features/base/connection/actions.web.ts @@ -103,7 +103,7 @@ export function connect(id?: string, password?: string) { * the user on conference termination. * @returns {Function} */ -export function hangup(requestFeedback = false, roomId?: string, feedbackTitle?: string, notifyOnConferenceTermination?: boolean) { +export function hangup(requestFeedback = false, roomId?: string, feedbackTitle?: string, notifyOnConferenceTermination?: boolean, feedbackMessage?: string) { // XXX For web based version we use conference hanging up logic from the old app. return async (dispatch: IStore["dispatch"]) => { if (LocalRecordingManager.isRecordingLocally()) { @@ -130,7 +130,7 @@ export function hangup(requestFeedback = false, roomId?: string, feedbackTitle?: await leaveCallWithUserIdentification(roomId); - return APP.conference.hangup(requestFeedback, feedbackTitle, notifyOnConferenceTermination); + return APP.conference.hangup(requestFeedback, feedbackTitle, notifyOnConferenceTermination, feedbackMessage); }; } diff --git a/react/features/base/meet/views/Conference/components/LeaveWithMessageDialog.tsx b/react/features/base/meet/views/Conference/components/LeaveWithMessageDialog.tsx new file mode 100644 index 000000000000..6d03f47a8d78 --- /dev/null +++ b/react/features/base/meet/views/Conference/components/LeaveWithMessageDialog.tsx @@ -0,0 +1,71 @@ +import React, { useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; +import { makeStyles } from 'tss-react/mui'; + +import Dialog from '../../../../ui/components/web/Dialog'; + +const useStyles = makeStyles()(theme => { + return { + dialog: { + marginBottom: theme.spacing(1) + }, + + title: { + fontSize: '1.25rem', + fontWeight: 'bold', + textAlign: 'left' + }, + + text: { + fontSize: '1.25rem' + } + }; +}); + +/** + * The type of the React {@code Component} props of {@link LeaveReasonDialog}. + */ +interface IProps { + + /** + * Callback invoked when {@code LeaveReasonDialog} is unmounted. + */ + onClose: () => void; + + /** + * The title to display in the dialog. + */ + title?: string; + + message?: string; +} + +/** + * A React {@code Component} for displaying a dialog with a reason that ended the conference. + * + * @param {IProps} props - Component's props. + * @returns {JSX} + */ +const LeaveWithMessageDialog = ({ onClose, title, message }: IProps) => { + const { classes } = useStyles(); + const { t } = useTranslation(); + + useEffect(() => () => { + onClose?.(); + }, []); + + return ( + +
+ {title ?
{t(title)}
: null} + {message ?
{t(message)}
: null} +
+
+ ); +}; + +export default LeaveWithMessageDialog; \ No newline at end of file diff --git a/react/features/conference/actions.web.ts b/react/features/conference/actions.web.ts index 7697f665ac65..ab79ebfb22c6 100644 --- a/react/features/conference/actions.web.ts +++ b/react/features/conference/actions.web.ts @@ -5,7 +5,7 @@ import { getJitsiMeetGlobalNSConnectionTimes } from '../base/util/helpers'; import { getBackendSafeRoomName } from '../base/util/uri'; import { DISMISS_CALENDAR_NOTIFICATION } from './actionTypes'; -import LeaveReasonDialog from './components/web/LeaveReasonDialog.web'; +import LeaveWithMessageDialog from '../base/meet/views/Conference/components/LeaveWithMessageDialog'; import logger from './logger'; /** @@ -15,11 +15,12 @@ import logger from './logger'; * * @returns {Promise} Resolved when the dialog is closed. */ -export function openLeaveReasonDialog(title?: string) { +export function openLeaveReasonDialog(title?: string, message?: string) { return (dispatch: IStore['dispatch']): Promise => new Promise(resolve => { - dispatch(openDialog('LeaveReasonDialog', LeaveReasonDialog, { + dispatch(openDialog('LeaveWithMessageDialog', LeaveWithMessageDialog, { onClose: resolve, - title + title, + message })); }); } diff --git a/react/features/conference/middleware.web.ts b/react/features/conference/middleware.web.ts index abfe1f15787a..44db75122dfc 100644 --- a/react/features/conference/middleware.web.ts +++ b/react/features/conference/middleware.web.ts @@ -2,7 +2,6 @@ import i18next from 'i18next'; import { ENDPOINT_MESSAGE_RECEIVED, KICKED_OUT } from '../base/conference/actionTypes'; import { hangup } from '../base/connection/actions.web'; -import { getParticipantDisplayName } from '../base/participants/functions'; import MiddlewareRegistry from '../base/redux/MiddlewareRegistry'; import { openAllowToggleCameraDialog, setCameraFacingMode } from '../base/tracks/actions.web'; import { CAMERA_FACING_MODE_MESSAGE } from '../base/tracks/constants'; @@ -25,24 +24,20 @@ MiddlewareRegistry.register(store => next => action => { case KICKED_OUT: { const { dispatch, getState } = store; - const { participant } = action; const { room } = getState()["features/base/conference"]; // we need to first finish dispatching or the notification can be cleared out const result = next(action); - const participantDisplayName - = getParticipantDisplayName(store.getState, participant.getId()); - const roomId = room ?? ""; + const roomId = room ?? ""; - dispatch( + dispatch( hangup( true, roomId, - participantDisplayName - ? i18next.t("dialog.kickTitle", { participantDisplayName }) - : i18next.t("dialog.kickSystemTitle"), - true + i18next.t("dialog.kickDuplicateTitle"), + true, + i18next.t("dialog.kickDuplicateMessage"), ) );