feat: add toggleWhiteboard to Jitsi API (#13292)

* add toggleWhiteboard to Jitsi API

* eslint recommendations applied

* Prevent to send whiteboard status change notifications for mobile

* Fix code style errors (eslint)

* Requested changes (by mihhu) have been made.

---------

Co-authored-by: Fikret Huseynkhanov <fikret.huseynkhanov@simbrella.com>
pull/13321/head jitsi-meet_8633
FIKRAT HUSEYNKHANOV 2 years ago committed by GitHub
parent ed89f9af20
commit aaeb1a90e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      modules/API/API.js
  2. 6
      modules/API/external/external_api.js
  3. 31
      react/features/whiteboard/actions.any.ts
  4. 9
      react/features/whiteboard/functions.ts
  5. 21
      react/features/whiteboard/middleware.ts
  6. 13
      react/features/whiteboard/types.ts

@ -113,6 +113,8 @@ import { isAudioMuteButtonDisabled } from '../../react/features/toolbox/function
import { setTileView, toggleTileView } from '../../react/features/video-layout/actions.any';
import { muteAllParticipants } from '../../react/features/video-menu/actions';
import { setVideoQuality } from '../../react/features/video-quality/actions';
import { toggleWhiteboard } from '../../react/features/whiteboard/actions.any';
import { WhiteboardStatus } from '../../react/features/whiteboard/types';
import { getJitsiMeetTransport } from '../transport';
import {
@ -833,6 +835,9 @@ function initCommands() {
} else {
logger.error(' End Conference not supported');
}
},
'toggle-whiteboard': () => {
APP.store.dispatch(toggleWhiteboard());
}
};
transport.on('event', ({ data, name }) => {
@ -2014,6 +2019,20 @@ class API {
});
}
/**
* Notify external application (if API is enabled) if whiteboard state is
* changed.
*
* @param {WhiteboardStatus} status - The new whiteboard status.
* @returns {void}
*/
notifyWhiteboardStatusChanged(status: WhiteboardStatus) {
this._sendEvent({
name: 'whiteboard-status-changed',
status
});
}
/**
* Disposes the allocated resources.
*

@ -90,7 +90,8 @@ const commands = {
toggleSubtitles: 'toggle-subtitles',
toggleTileView: 'toggle-tile-view',
toggleVirtualBackgroundDialog: 'toggle-virtual-background',
toggleVideo: 'toggle-video'
toggleVideo: 'toggle-video',
toggleWhiteboard: 'toggle-whiteboard'
};
/**
@ -154,7 +155,8 @@ const events = {
'subject-change': 'subjectChange',
'suspend-detected': 'suspendDetected',
'tile-view-changed': 'tileViewChanged',
'toolbar-button-clicked': 'toolbarButtonClicked'
'toolbar-button-clicked': 'toolbarButtonClicked',
'whiteboard-status-changed': 'whiteboardStatusChanged'
};
/**

@ -0,0 +1,31 @@
import { IStore } from '../app/types';
import { setWhiteboardOpen } from './actions';
import { isWhiteboardAllowed, isWhiteboardOpen, isWhiteboardVisible } from './functions';
import { WhiteboardStatus } from './types';
/**
* API to toggle the whiteboard.
*
* @returns {Function}
*/
export function toggleWhiteboard() {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const isAllowed = isWhiteboardAllowed(state);
const isOpen = isWhiteboardOpen(state);
if (isAllowed) {
if (isOpen && !isWhiteboardVisible(state)) {
dispatch(setWhiteboardOpen(true));
} else if (isOpen && isWhiteboardVisible(state)) {
dispatch(setWhiteboardOpen(false));
} else if (!isOpen) {
dispatch(setWhiteboardOpen(true));
}
} else if (typeof APP !== 'undefined') {
APP.API.notifyWhiteboardStatusChanged(WhiteboardStatus.FORBIDDEN);
}
};
}

@ -89,3 +89,12 @@ export const getCollabServerUrl = (state: IReduxState): string | undefined => {
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);

@ -9,12 +9,13 @@ 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 { isStageFilmstripAvailable } from '../filmstrip/functions.web';
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';
import { WhiteboardStatus } from './types';
const focusWhiteboard = (store: IStore) => {
const { dispatch, getState } = store;
@ -68,21 +69,27 @@ MiddlewareRegistry.register((store: IStore) => (next: Function) => async (action
collabServerUrl,
collabDetails
});
raiseWhiteboardNotification(WhiteboardStatus.INSTANTIATED);
return;
}
if (action.isOpen) {
focusWhiteboard(store);
raiseWhiteboardNotification(WhiteboardStatus.SHOWN);
return;
}
dispatch(participantLeft(WHITEBOARD_ID, conference, { fakeParticipant: FakeParticipant.Whiteboard }));
raiseWhiteboardNotification(WhiteboardStatus.HIDDEN);
break;
}
case RESET_WHITEBOARD: {
dispatch(participantLeft(WHITEBOARD_ID, conference, { fakeParticipant: FakeParticipant.Whiteboard }));
raiseWhiteboardNotification(WhiteboardStatus.RESET);
break;
}
}
@ -90,6 +97,18 @@ MiddlewareRegistry.register((store: IStore) => (next: Function) => async (action
return next(action);
});
/**
* Raises the whiteboard status notifications changes (if API is enabled).
*
* @param {WhiteboardStatus} status - The whiteboard changed status.
* @returns {Function}
*/
function raiseWhiteboardNotification(status: WhiteboardStatus) {
if (typeof APP !== 'undefined') {
APP.API.notifyWhiteboardStatusChanged(status);
}
}
/**
* 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.

@ -0,0 +1,13 @@
/**
* Whiteboard statuses used to raise the notification when it's changed.
*
* @enum
*/
export enum WhiteboardStatus {
FORBIDDEN = 'FORBIDDEN',
HIDDEN = 'HIDDEN',
INSTANTIATED = 'INSTANTIATED',
RESET = 'RESET',
SHOWN = 'SHOWN'
}
Loading…
Cancel
Save