mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-05-13 02:22:30 +00:00
207 lines
7.4 KiB
TypeScript
207 lines
7.4 KiB
TypeScript
import i18n from 'i18next';
|
|
import { batch } from 'react-redux';
|
|
|
|
import { IStore } from '../app/types';
|
|
import {
|
|
CONFERENCE_JOINED,
|
|
CONFERENCE_JOIN_IN_PROGRESS,
|
|
ENDPOINT_MESSAGE_RECEIVED
|
|
} from '../base/conference/actionTypes';
|
|
import { connect, setPreferVisitor } from '../base/connection/actions';
|
|
import { disconnect } from '../base/connection/actions.any';
|
|
import { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
|
|
import { raiseHand } from '../base/participants/actions';
|
|
import { getLocalParticipant, getParticipantById } from '../base/participants/functions';
|
|
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
|
|
import { BUTTON_TYPES } from '../base/ui/constants.any';
|
|
import { hideNotification, showNotification } from '../notifications/actions';
|
|
import {
|
|
NOTIFICATION_ICON,
|
|
NOTIFICATION_TIMEOUT_TYPE,
|
|
VISITORS_PROMOTION_NOTIFICATION_ID
|
|
} from '../notifications/constants';
|
|
import { INotificationProps } from '../notifications/types';
|
|
import { open as openParticipantsPane } from '../participants-pane/actions';
|
|
|
|
import {
|
|
approveRequest,
|
|
clearPromotionRequest,
|
|
denyRequest,
|
|
promotionRequestReceived,
|
|
setVisitorDemoteActor,
|
|
setVisitorsSupported,
|
|
updateVisitorsCount
|
|
} from './actions';
|
|
import { getPromotionRequests } from './functions';
|
|
import logger from './logger';
|
|
|
|
MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
|
switch (action.type) {
|
|
case CONFERENCE_JOIN_IN_PROGRESS: {
|
|
const { conference } = action;
|
|
|
|
conference.on(JitsiConferenceEvents.PROPERTIES_CHANGED, (properties: { 'visitor-count': number; }) => {
|
|
const visitorCount = Number(properties?.['visitor-count']);
|
|
|
|
if (!isNaN(visitorCount) && getState()['features/visitors'].count !== visitorCount) {
|
|
dispatch(updateVisitorsCount(visitorCount));
|
|
}
|
|
});
|
|
break;
|
|
}
|
|
case CONFERENCE_JOINED: {
|
|
const { conference } = action;
|
|
|
|
if (getState()['features/visitors'].iAmVisitor) {
|
|
const { demoteActorDisplayName } = getState()['features/visitors'];
|
|
|
|
dispatch(setVisitorDemoteActor(undefined));
|
|
|
|
const notificationParams: INotificationProps = {
|
|
titleKey: 'visitors.notification.title',
|
|
descriptionKey: 'visitors.notification.description'
|
|
};
|
|
|
|
if (demoteActorDisplayName) {
|
|
notificationParams.descriptionKey = 'visitors.notification.demoteDescription';
|
|
notificationParams.descriptionArguments = {
|
|
actor: demoteActorDisplayName
|
|
};
|
|
}
|
|
|
|
// check for demote actor and update notification
|
|
dispatch(showNotification(notificationParams, NOTIFICATION_TIMEOUT_TYPE.STICKY));
|
|
} else {
|
|
dispatch(setVisitorsSupported(conference.isVisitorsSupported()));
|
|
conference.on(JitsiConferenceEvents.VISITORS_SUPPORTED_CHANGED, (value: boolean) => {
|
|
dispatch(setVisitorsSupported(value));
|
|
});
|
|
}
|
|
|
|
conference.on(JitsiConferenceEvents.VISITORS_MESSAGE, (
|
|
msg: { action: string; actor: string; from: string; id: string; nick: string; on: boolean; }) => {
|
|
|
|
if (msg.action === 'demote-request') {
|
|
// we need it before the disconnect
|
|
const participantById = getParticipantById(getState, msg.actor);
|
|
const localParticipant = getLocalParticipant(getState);
|
|
|
|
if (localParticipant && localParticipant.id === msg.id) {
|
|
// handle demote
|
|
dispatch(disconnect(true))
|
|
.then(() => dispatch(setPreferVisitor(true)))
|
|
.then(() => {
|
|
// we need to set the name, so we can use it later in the notification
|
|
if (participantById) {
|
|
dispatch(setVisitorDemoteActor(participantById.name));
|
|
}
|
|
|
|
return dispatch(connect());
|
|
});
|
|
}
|
|
} else if (msg.action === 'promotion-request') {
|
|
const request = {
|
|
from: msg.from,
|
|
nick: msg.nick
|
|
};
|
|
|
|
if (msg.on) {
|
|
dispatch(promotionRequestReceived(request));
|
|
} else {
|
|
dispatch(clearPromotionRequest(request));
|
|
}
|
|
_handlePromotionNotification({
|
|
dispatch,
|
|
getState
|
|
});
|
|
} else {
|
|
logger.error('Unknown action:', msg.action);
|
|
}
|
|
});
|
|
|
|
conference.on(JitsiConferenceEvents.VISITORS_REJECTION, () => {
|
|
dispatch(raiseHand(false));
|
|
});
|
|
|
|
break;
|
|
}
|
|
case ENDPOINT_MESSAGE_RECEIVED: {
|
|
const { data } = action;
|
|
|
|
if (data?.action === 'promotion-response' && data.approved) {
|
|
const request = getPromotionRequests(getState())
|
|
.find(r => r.from === data.id);
|
|
|
|
request && dispatch(clearPromotionRequest(request));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return next(action);
|
|
});
|
|
|
|
/**
|
|
* Function to handle the promotion notification.
|
|
*
|
|
* @param {Object} store - The Redux store.
|
|
* @returns {void}
|
|
*/
|
|
function _handlePromotionNotification(
|
|
{ dispatch, getState }: { dispatch: IStore['dispatch']; getState: IStore['getState']; }) {
|
|
const requests = getPromotionRequests(getState());
|
|
|
|
if (requests.length === 0) {
|
|
dispatch(hideNotification(VISITORS_PROMOTION_NOTIFICATION_ID));
|
|
|
|
return;
|
|
}
|
|
|
|
let notificationTitle;
|
|
let customActionNameKey;
|
|
let customActionHandler;
|
|
let customActionType;
|
|
let descriptionKey;
|
|
let icon;
|
|
|
|
if (requests.length === 1) {
|
|
const firstRequest = requests[0];
|
|
|
|
descriptionKey = 'notify.participantWantsToJoin';
|
|
notificationTitle = firstRequest.nick;
|
|
icon = NOTIFICATION_ICON.PARTICIPANT;
|
|
customActionNameKey = [ 'participantsPane.actions.admit', 'participantsPane.actions.reject' ];
|
|
customActionType = [ BUTTON_TYPES.PRIMARY, BUTTON_TYPES.DESTRUCTIVE ];
|
|
customActionHandler = [ () => batch(() => {
|
|
dispatch(hideNotification(VISITORS_PROMOTION_NOTIFICATION_ID));
|
|
dispatch(approveRequest(firstRequest));
|
|
}),
|
|
() => batch(() => {
|
|
dispatch(hideNotification(VISITORS_PROMOTION_NOTIFICATION_ID));
|
|
dispatch(denyRequest(firstRequest));
|
|
}) ];
|
|
} else {
|
|
descriptionKey = 'notify.participantsWantToJoin';
|
|
notificationTitle = i18n.t('notify.waitingParticipants', {
|
|
waitingParticipants: requests.length
|
|
});
|
|
icon = NOTIFICATION_ICON.PARTICIPANTS;
|
|
customActionNameKey = [ 'notify.viewVisitors' ];
|
|
customActionType = [ BUTTON_TYPES.PRIMARY ];
|
|
customActionHandler = [ () => batch(() => {
|
|
dispatch(hideNotification(VISITORS_PROMOTION_NOTIFICATION_ID));
|
|
dispatch(openParticipantsPane());
|
|
}) ];
|
|
}
|
|
|
|
dispatch(showNotification({
|
|
title: notificationTitle,
|
|
descriptionKey,
|
|
uid: VISITORS_PROMOTION_NOTIFICATION_ID,
|
|
customActionNameKey,
|
|
customActionType,
|
|
customActionHandler,
|
|
icon
|
|
}, NOTIFICATION_TIMEOUT_TYPE.STICKY));
|
|
}
|