jiti-meet/react/features/whiteboard/middleware.ts

118 lines
4.1 KiB
TypeScript
Raw Normal View History

import { generateCollaborationLinkData } from '@jitsi/excalidraw';
import { IStore } from '../app/types';
import { getCurrentConference } from '../base/conference/functions';
import { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
import { participantJoined, participantLeft, pinParticipant } from '../base/participants/actions';
import { FakeParticipant } from '../base/participants/types';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import StateListenerRegistry from '../base/redux/StateListenerRegistry';
import { getCurrentRoomId } from '../breakout-rooms/functions';
import { addStageParticipant } from '../filmstrip/actions.web';
import { isStageFilmstripAvailable } from '../filmstrip/functions';
import { RESET_WHITEBOARD, SET_WHITEBOARD_OPEN } from './actionTypes';
import { resetWhiteboard, setWhiteboardOpen, setupWhiteboard } from './actions';
import { WHITEBOARD_ID, WHITEBOARD_PARTICIPANT_NAME } from './constants';
import { getCollabDetails, getCollabServerUrl, isWhiteboardPresent } from './functions';
const focusWhiteboard = (store: IStore) => {
const { dispatch, getState } = store;
const state = getState();
const conference = getCurrentConference(state);
const stageFilmstrip = isStageFilmstripAvailable(state);
const isPresent = isWhiteboardPresent(state);
if (!isPresent) {
dispatch(participantJoined({
conference,
fakeParticipant: FakeParticipant.Whiteboard,
id: WHITEBOARD_ID,
name: WHITEBOARD_PARTICIPANT_NAME
}));
}
if (stageFilmstrip) {
dispatch(addStageParticipant(WHITEBOARD_ID, true));
} else {
dispatch(pinParticipant(WHITEBOARD_ID));
}
};
/**
* Middleware which intercepts whiteboard actions to handle changes to the related state.
*
* @param {Store} store - The redux store.
* @returns {Function}
*/
MiddlewareRegistry.register((store: IStore) => (next: Function) => async (action: any) => {
const { dispatch, getState } = store;
const state = getState();
const conference = getCurrentConference(state);
switch (action.type) {
case SET_WHITEBOARD_OPEN: {
const existingCollabDetails = getCollabDetails(state);
if (!existingCollabDetails) {
const collabLinkData = await generateCollaborationLinkData();
const collabServerUrl = getCollabServerUrl(state);
const roomId = getCurrentRoomId(state);
const collabDetails = {
roomId,
roomKey: collabLinkData.roomKey
};
focusWhiteboard(store);
dispatch(setupWhiteboard({ collabDetails }));
conference.getMetadataHandler().setMetadata(WHITEBOARD_ID, {
collabServerUrl,
collabDetails
});
return;
}
if (action.isOpen) {
focusWhiteboard(store);
return;
}
dispatch(participantLeft(WHITEBOARD_ID, conference, { fakeParticipant: FakeParticipant.Whiteboard }));
break;
}
case RESET_WHITEBOARD: {
dispatch(participantLeft(WHITEBOARD_ID, conference, { fakeParticipant: FakeParticipant.Whiteboard }));
break;
}
}
return next(action);
});
/**
* Set up state change listener to perform maintenance tasks when the conference
* is left or failed, e.g. Disable the whiteboard if it's left open.
*/
StateListenerRegistry.register(
// @ts-ignore
state => getCurrentConference(state),
// @ts-ignore
(conference, { dispatch }, previousConference): void => {
if (conference !== previousConference) {
dispatch(resetWhiteboard());
}
if (conference && !previousConference) {
conference.on(JitsiConferenceEvents.METADATA_UPDATED, (metadata: any) => {
if (metadata[WHITEBOARD_ID]) {
dispatch(setupWhiteboard({
collabDetails: metadata[WHITEBOARD_ID].collabDetails
}));
dispatch(setWhiteboardOpen(true));
}
});
}
});