snapshot of https://github.com/jitsi/jitsi-meet.git @ fd1749dd28f4138aa80234fc7f311b19aaffa0e7 (2026-09-15)
This commit is contained in:
242
react/features/whiteboard/functions.ts
Normal file
242
react/features/whiteboard/functions.ts
Normal file
@@ -0,0 +1,242 @@
|
||||
import md5 from 'js-md5';
|
||||
|
||||
import { getParticipantCount, getPinnedParticipant } from '../../features/base/participants/functions';
|
||||
import { IReduxState } from '../app/types';
|
||||
import { getCurrentConference } from '../base/conference/functions';
|
||||
import { IWhiteboardConfig } from '../base/config/configType';
|
||||
import { getRemoteParticipants, isLocalParticipantModerator } from '../base/participants/functions';
|
||||
import { encodeToBase64URL } from '../base/util/httpUtils';
|
||||
import { appendURLHashParam, appendURLParam, getBackendSafePath } from '../base/util/uri';
|
||||
import { getCurrentRoomId, isInBreakoutRoom } from '../breakout-rooms/functions';
|
||||
|
||||
import { MIN_USER_LIMIT, USER_LIMIT_THRESHOLD, WHITEBOARD_ID, WHITEBOARD_PATH_NAME } from './constants';
|
||||
import { IWhiteboardState } from './reducer';
|
||||
|
||||
const getWhiteboardState = (state: IReduxState): IWhiteboardState => state['features/whiteboard'];
|
||||
|
||||
export const getWhiteboardConfig = (state: IReduxState): IWhiteboardConfig =>
|
||||
state['features/base/config'].whiteboard || {};
|
||||
|
||||
const getWhiteboardUserLimit = (state: IReduxState): number => {
|
||||
const userLimit = getWhiteboardConfig(state).userLimit || Infinity;
|
||||
|
||||
return userLimit === Infinity
|
||||
? userLimit
|
||||
: Math.max(Number(getWhiteboardConfig(state).userLimit || 1), MIN_USER_LIMIT);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the whiteboard collaboration details.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {{ roomId: string, roomKey: string}|undefined}
|
||||
*/
|
||||
export const getCollabDetails = (state: IReduxState): {
|
||||
roomId: string; roomKey: string;
|
||||
} | undefined => getWhiteboardState(state).collabDetails;
|
||||
|
||||
/**
|
||||
* Indicates whether the whiteboard collaboration details are available.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const hasCollabDetails = (state: IReduxState): boolean => Boolean(
|
||||
getCollabDetails(state)?.roomId && getCollabDetails(state)?.roomKey
|
||||
);
|
||||
|
||||
/**
|
||||
* Indicates whether the whiteboard is enabled.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isWhiteboardEnabled = (state: IReduxState): boolean =>
|
||||
(getWhiteboardConfig(state).enabled ?? hasCollabDetails(state))
|
||||
&& getWhiteboardConfig(state).collabServerBaseUrl
|
||||
&& getCurrentConference(state)?.getMetadataHandler()
|
||||
?.isSupported();
|
||||
|
||||
/**
|
||||
* Indicates whether the whiteboard is open.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isWhiteboardOpen = (state: IReduxState): boolean => {
|
||||
const { iAmRecorder, iAmSipGateway } = state['features/base/config'];
|
||||
|
||||
if (iAmRecorder || iAmSipGateway) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getWhiteboardState(state).isOpen;
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates whether the whiteboard button is visible.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isWhiteboardButtonVisible = (state: IReduxState): boolean =>
|
||||
isWhiteboardEnabled(state)
|
||||
&& (isLocalParticipantModerator(state) || isWhiteboardOpen(state) || hasCollabDetails(state));
|
||||
|
||||
/**
|
||||
* Indicates whether the whiteboard is present as a meeting participant.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isWhiteboardPresent = (state: IReduxState): boolean => getRemoteParticipants(state).has(WHITEBOARD_ID);
|
||||
|
||||
/**
|
||||
* Builds the whiteboard collaboration server url.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {string}
|
||||
*/
|
||||
export const generateCollabServerUrl = (state: IReduxState): string | undefined => {
|
||||
const collabServerBaseUrl = getWhiteboardConfig(state).collabServerBaseUrl;
|
||||
|
||||
if (!collabServerBaseUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { locationURL } = state['features/base/connection'];
|
||||
const inBreakoutRoom = isInBreakoutRoom(state);
|
||||
const roomId = getCurrentRoomId(state);
|
||||
const room = md5.hex(
|
||||
`${getBackendSafePath(locationURL?.pathname)}${inBreakoutRoom ? `|${roomId}` : ''}`
|
||||
);
|
||||
|
||||
return appendURLParam(collabServerBaseUrl, 'room', room);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the whiteboard collaboration server url.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {string}
|
||||
*/
|
||||
export const getCollabServerUrl = (state: IReduxState): string | undefined =>
|
||||
getWhiteboardState(state).collabServerUrl;
|
||||
|
||||
/**
|
||||
* Returns the storage backend URL for saving whiteboard scenes and images.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {string}
|
||||
*/
|
||||
export const getStorageBackendUrl = (state: IReduxState): string | undefined =>
|
||||
getWhiteboardConfig(state).storageBackendUrl;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the whiteboard is visible on stage.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isWhiteboardVisible = (state: IReduxState): boolean =>
|
||||
getPinnedParticipant(state)?.id === WHITEBOARD_ID
|
||||
|| state['features/large-video'].participantId === WHITEBOARD_ID;
|
||||
|
||||
/**
|
||||
* Indicates whether the whiteboard is accessible to a participant that has a moderator role.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isWhiteboardAllowed = (state: IReduxState): boolean =>
|
||||
isWhiteboardEnabled(state) && isLocalParticipantModerator(state);
|
||||
|
||||
/**
|
||||
* Whether to enforce the whiteboard user limit.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const shouldEnforceUserLimit = (state: IReduxState): boolean => {
|
||||
const userLimit = getWhiteboardUserLimit(state);
|
||||
|
||||
if (userLimit === Infinity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const participantCount = getParticipantCount(state);
|
||||
|
||||
return participantCount > userLimit;
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether to show a warning about the whiteboard user limit.
|
||||
*
|
||||
* @param {IReduxState} state - The state from the Redux store.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const shouldNotifyUserLimit = (state: IReduxState): boolean => {
|
||||
const { iAmRecorder, iAmSipGateway } = state['features/base/config'];
|
||||
|
||||
if (iAmRecorder || iAmSipGateway) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const userLimit = getWhiteboardUserLimit(state);
|
||||
|
||||
if (userLimit === Infinity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const participantCount = getParticipantCount(state);
|
||||
|
||||
return participantCount + USER_LIMIT_THRESHOLD > userLimit;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates the URL for the static whiteboard page.
|
||||
*
|
||||
* @param {string} locationUrl - The window location href.
|
||||
* @param {string} collabServerUrl - The whiteboard collaboration server url.
|
||||
* @param {Object} collabDetails - The whiteboard collaboration details.
|
||||
* @param {string} localParticipantName - The local participant name.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getWhiteboardInfoForURIString(
|
||||
locationUrl: any,
|
||||
collabServerUrl: string,
|
||||
collabDetails: { roomId: string; roomKey: string; },
|
||||
localParticipantName: string
|
||||
): string | undefined {
|
||||
if (!collabServerUrl || !locationUrl) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let state = {};
|
||||
let url = `${locationUrl.substring(0, locationUrl.lastIndexOf('/'))}/${WHITEBOARD_PATH_NAME}`;
|
||||
|
||||
if (collabDetails?.roomId) {
|
||||
state = {
|
||||
...state,
|
||||
roomId: collabDetails.roomId
|
||||
};
|
||||
}
|
||||
|
||||
if (collabDetails?.roomKey) {
|
||||
state = {
|
||||
...state,
|
||||
roomKey: collabDetails.roomKey
|
||||
};
|
||||
}
|
||||
|
||||
state = {
|
||||
...state,
|
||||
collabServerUrl,
|
||||
localParticipantName
|
||||
};
|
||||
|
||||
url = appendURLHashParam(url, 'state', encodeToBase64URL(JSON.stringify(state)));
|
||||
|
||||
return url;
|
||||
}
|
||||
Reference in New Issue
Block a user