fix(transcribing): Handle transcriber status changed.

* fix(subtitles): Handle errors to revert to default state.

* fix(transcribing): Handle transcriber status changed.

Drops potential transcribers and hidden participant actions and handling. Expect ljm to detect transcriptions on and off.

* feat(transcriptions): Adds a notification if transcriber leaves abruptly.

* squash: Renames action.

* chore(deps) lib-jitsi-meet@latest

https://github.com/jitsi/lib-jitsi-meet/compare/v1869.0.0+5671c5d6...v1872.0.0+8940b5c9
pull/15171/head jitsi-meet_9760
Дамян Минков 8 months ago committed by GitHub
parent 5da69192e3
commit d5269e881a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 11
      conference.js
  2. 2
      config.js
  3. 2
      lang/main.json
  4. 10
      package-lock.json
  5. 2
      package.json
  6. 13
      react/features/base/conference/actions.any.ts
  7. 10
      react/features/base/conference/functions.ts
  8. 22
      react/features/base/participants/actionTypes.ts
  9. 38
      react/features/base/participants/actions.ts
  10. 2
      react/features/subtitles/middleware.ts
  11. 6
      react/features/subtitles/reducer.ts
  12. 16
      react/features/transcribing/actionTypes.ts
  13. 39
      react/features/transcribing/actions.ts
  14. 50
      react/features/transcribing/middleware.ts
  15. 30
      react/features/transcribing/reducer.ts

@ -164,6 +164,7 @@ import { toggleScreenshotCaptureSummary } from './react/features/screenshot-capt
import { AudioMixerEffect } from './react/features/stream-effects/audio-mixer/AudioMixerEffect';
import { createRnnoiseProcessor } from './react/features/stream-effects/rnnoise';
import { handleToggleVideoMuted } from './react/features/toolbox/actions.any';
import { transcriberJoined, transcriberLeft } from './react/features/transcribing/actions';
import { muteLocal } from './react/features/video-menu/actions.any';
const logger = Logger.getLogger(__filename);
@ -1684,6 +1685,16 @@ export default {
}
);
room.on(
JitsiConferenceEvents.TRANSCRIPTION_STATUS_CHANGED,
(status, id, abruptly) => {
if (status === JitsiMeetJS.constants.transcriptionStatus.ON) {
APP.store.dispatch(transcriberJoined(id));
} else if (status === JitsiMeetJS.constants.transcriptionStatus.OFF) {
APP.store.dispatch(transcriberLeft(id, abruptly));
}
});
room.on(
JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
(participant, data) => {

@ -1721,7 +1721,7 @@ var config = {
// 'toolbar.noAudioSignalTitle', // shown when a broken mic is detected
// 'toolbar.noisyAudioInputTitle', // shown when noise is detected for the current microphone
// 'toolbar.talkWhileMutedPopup', // shown when user tries to speak while muted
// 'transcribing.failedToStart', // shown when transcribing fails to start
// 'transcribing.failed', // shown when transcribing fails
// ],
// List of notifications to be disabled. Works in tandem with the above setting.

@ -1390,7 +1390,7 @@
"transcribing": {
"ccButtonTooltip": "Start / Stop subtitles",
"expandedLabel": "Transcribing is currently on",
"failedToStart": "Transcribing failed to start",
"failed": "Transcribing failed",
"labelToolTip": "The meeting is being transcribed",
"sourceLanguageDesc": "Currently the meeting language is set to <b>{{sourceLanguage}}</b>. <br/> You can change it from ",
"sourceLanguageHere": "here",

10
package-lock.json generated

@ -61,7 +61,7 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1869.0.0+5671c5d6/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1872.0.0+8940b5c9/lib-jitsi-meet.tgz",
"lodash-es": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
@ -12498,8 +12498,8 @@
},
"node_modules/lib-jitsi-meet": {
"version": "0.0.0",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1869.0.0+5671c5d6/lib-jitsi-meet.tgz",
"integrity": "sha512-s2bAk8lq1SU/oQQxI9NTP2xOWI0yHFaFB7WjzL1E0gn6ntoaTH0FN1KQmJctfGGzm71I3lXy6SwgNHwi8hEtHA==",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1872.0.0+8940b5c9/lib-jitsi-meet.tgz",
"integrity": "sha512-/pcCiU7XguZ9ooOQ/HSQhU52kG3mvGtD15TWMsH/fbJwHG8Vt6TOA0DECyK/8xkPnRy1VCI7qt2e6zhk7VBgUA==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
@ -28005,8 +28005,8 @@
}
},
"lib-jitsi-meet": {
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1869.0.0+5671c5d6/lib-jitsi-meet.tgz",
"integrity": "sha512-s2bAk8lq1SU/oQQxI9NTP2xOWI0yHFaFB7WjzL1E0gn6ntoaTH0FN1KQmJctfGGzm71I3lXy6SwgNHwi8hEtHA==",
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1872.0.0+8940b5c9/lib-jitsi-meet.tgz",
"integrity": "sha512-/pcCiU7XguZ9ooOQ/HSQhU52kG3mvGtD15TWMsH/fbJwHG8Vt6TOA0DECyK/8xkPnRy1VCI7qt2e6zhk7VBgUA==",
"requires": {
"@jitsi/js-utils": "2.2.1",
"@jitsi/logger": "2.0.2",

@ -67,7 +67,7 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1869.0.0+5671c5d6/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1872.0.0+8940b5c9/lib-jitsi-meet.tgz",
"lodash-es": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",

@ -1,6 +1,7 @@
import { createStartMutedConfigurationEvent } from '../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../analytics/functions';
import { IReduxState, IStore } from '../../app/types';
import { transcriberJoined, transcriberLeft } from '../../transcribing/actions';
import { setIAmVisitor } from '../../visitors/actions';
import { iAmVisitor } from '../../visitors/functions';
import { overwriteConfig } from '../config/actions';
@ -8,7 +9,7 @@ import { getReplaceParticipant } from '../config/functions';
import { connect, disconnect, hangup } from '../connection/actions';
import { JITSI_CONNECTION_CONFERENCE_KEY } from '../connection/constants';
import { hasAvailableDevices } from '../devices/functions.any';
import { JitsiConferenceEvents, JitsiE2ePingEvents } from '../lib-jitsi-meet';
import JitsiMeetJS, { JitsiConferenceEvents, JitsiE2ePingEvents } from '../lib-jitsi-meet';
import {
setAudioMuted,
setAudioUnmutePermissions,
@ -276,6 +277,16 @@ function _addConferenceListeners(conference: IJitsiConference, dispatch: IStore[
botType
})));
conference.on(
JitsiConferenceEvents.TRANSCRIPTION_STATUS_CHANGED,
(status: string, id: string, abruptly: boolean) => {
if (status === JitsiMeetJS.constants.transcriptionStatus.ON) {
dispatch(transcriberJoined(id));
} else if (status === JitsiMeetJS.constants.transcriptionStatus.OFF) {
dispatch(transcriberLeft(id, abruptly));
}
});
conference.addCommandListener(
AVATAR_URL_COMMAND,
(data: { value: string; }, id: string) => {

@ -7,8 +7,6 @@ import { determineTranscriptionLanguage } from '../../transcribing/functions';
import { IStateful } from '../app/types';
import { JitsiTrackErrors } from '../lib-jitsi-meet';
import {
hiddenParticipantJoined,
hiddenParticipantLeft,
participantJoined,
participantLeft
} from '../participants/actions';
@ -85,9 +83,7 @@ export function commonUserJoinedHandling(
const id = user.getId();
const displayName = user.getDisplayName();
if (user.isHidden()) {
dispatch(hiddenParticipantJoined(id, displayName));
} else {
if (!user.isHidden()) {
const isReplacing = user?.isReplacing();
// the identity and avatar come from jwt and never change in the presence
@ -122,9 +118,7 @@ export function commonUserLeftHandling(
user: any) {
const id = user.getId();
if (user.isHidden()) {
dispatch(hiddenParticipantLeft(id));
} else {
if (!user.isHidden()) {
const isReplaced = user.isReplaced?.();
dispatch(participantLeft(id, conference, { isReplaced }));

@ -146,28 +146,6 @@ export const PARTICIPANT_UPDATED = 'PARTICIPANT_UPDATED';
*/
export const PIN_PARTICIPANT = 'PIN_PARTICIPANT';
/**
* Action to signal that a hidden participant has joined.
*
* {
* type: HIDDEN_PARTICIPANT_JOINED,
* participant: Participant
* }
*/
export const HIDDEN_PARTICIPANT_JOINED = 'HIDDEN_PARTICIPANT_JOINED';
/**
* Action to handle case when hidden participant leaves.
*
* {
* type: PARTICIPANT_LEFT,
* participant: {
* id: string
* }
* }
*/
export const HIDDEN_PARTICIPANT_LEFT = 'HIDDEN_PARTICIPANT_LEFT';
/**
* The type of Redux action which notifies the app that the loadable avatar URL has changed.
*

@ -7,8 +7,6 @@ import { set } from '../redux/functions';
import {
DOMINANT_SPEAKER_CHANGED,
GRANT_MODERATOR,
HIDDEN_PARTICIPANT_JOINED,
HIDDEN_PARTICIPANT_LEFT,
KICK_PARTICIPANT,
LOCAL_PARTICIPANT_AUDIO_LEVEL_CHANGED,
LOCAL_PARTICIPANT_RAISE_HAND,
@ -331,42 +329,6 @@ export function updateRemoteParticipantFeatures(jitsiParticipant: any) {
};
}
/**
* Action to signal that a hidden participant has joined the conference.
*
* @param {string} id - The id of the participant.
* @param {string} displayName - The display name, or undefined when
* unknown.
* @returns {{
* type: HIDDEN_PARTICIPANT_JOINED,
* displayName: string,
* id: string
* }}
*/
export function hiddenParticipantJoined(id: string, displayName: string) {
return {
type: HIDDEN_PARTICIPANT_JOINED,
id,
displayName
};
}
/**
* Action to signal that a hidden participant has left the conference.
*
* @param {string} id - The id of the participant.
* @returns {{
* type: HIDDEN_PARTICIPANT_LEFT,
* id: string
* }}
*/
export function hiddenParticipantLeft(id: string) {
return {
type: HIDDEN_PARTICIPANT_LEFT,
id
};
}
/**
* Action to signal that a participant has left.
*

@ -259,7 +259,7 @@ function _requestingSubtitlesChange(
logger.error('Error dialing', e);
// let's back to the correct state
dispatch(setRequestingSubtitles(false, false));
dispatch(setRequestingSubtitles(false, false, null));
});
}
}

@ -1,4 +1,5 @@
import ReducerRegistry from '../base/redux/ReducerRegistry';
import { TRANSCRIBER_LEFT } from '../transcribing/actionTypes';
import {
REMOVE_TRANSCRIPT_MESSAGE,
@ -48,6 +49,11 @@ ReducerRegistry.register<ISubtitlesState>('features/subtitles', (
...state,
_requestingSubtitles: !state._requestingSubtitles
};
case TRANSCRIBER_LEFT:
return {
...state,
...defaultState
};
}
return state;

@ -8,7 +8,7 @@
* }
* @private
*/
export const _TRANSCRIBER_JOINED = 'TRANSCRIBER_JOINED';
export const TRANSCRIBER_JOINED = 'TRANSCRIBER_JOINED';
/**
* The type of Redux action signalling that the transcriber has left
@ -19,16 +19,4 @@ export const _TRANSCRIBER_JOINED = 'TRANSCRIBER_JOINED';
* }
* @private
*/
export const _TRANSCRIBER_LEFT = 'TRANSCRIBER_LEFT';
/**
* The type of a Redux action signalling that a hidden participant has joined,
* which can be candidate for being a transcriber.
*
* {
* type: _POTENTIAL_TRANSCRIBER_JOINED,
* }
* @private
*/
export const _POTENTIAL_TRANSCRIBER_JOINED
= 'POTENTIAL_TRANSCRIBER_JOINED';
export const TRANSCRIBER_LEFT = 'TRANSCRIBER_LEFT';

@ -1,7 +1,6 @@
import {
_POTENTIAL_TRANSCRIBER_JOINED,
_TRANSCRIBER_JOINED,
_TRANSCRIBER_LEFT
TRANSCRIBER_JOINED,
TRANSCRIBER_LEFT
} from './actionTypes';
/**
@ -9,13 +8,13 @@ import {
*
* @param {string} participantId - The participant id of the transcriber.
* @returns {{
* type: _TRANSCRIBER_JOINED,
* type: TRANSCRIBER_JOINED,
* participantId: string
* }}
*/
export function transcriberJoined(participantId: string) {
return {
type: _TRANSCRIBER_JOINED,
type: TRANSCRIBER_JOINED,
transcriberJID: participantId
};
}
@ -24,30 +23,18 @@ export function transcriberJoined(participantId: string) {
* Notify that the transcriber, with a unique ID, has left.
*
* @param {string} participantId - The participant id of the transcriber.
* @param {boolean} abruptly - The transcriber did not exit the conference gracefully with switching off first.
* It maybe there was some backend problem, like network.
* @returns {{
* type: _TRANSCRIBER_LEFT,
* participantId: string
* }}
*/
export function transcriberLeft(participantId: string) {
return {
type: _TRANSCRIBER_LEFT,
transcriberJID: participantId
};
}
/**
* Notify that a potential transcriber, with a unique ID, has joined.
*
* @param {string} participantId - The participant id of the transcriber.
* @returns {{
* type: _POTENTIAL_TRANSCRIBER_JOINED,
* participantId: string
* type: TRANSCRIBER_LEFT,
* participantId: string,
* abruptly: boolean
* }}
*/
export function potentialTranscriberJoined(participantId: string) {
export function transcriberLeft(participantId: string, abruptly: boolean) {
return {
type: _POTENTIAL_TRANSCRIBER_JOINED,
transcriberJID: participantId
type: TRANSCRIBER_LEFT,
transcriberJID: participantId,
abruptly
};
}

@ -1,18 +1,8 @@
import {
HIDDEN_PARTICIPANT_JOINED,
HIDDEN_PARTICIPANT_LEFT,
PARTICIPANT_UPDATED
} from '../base/participants/actionTypes';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { showErrorNotification } from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants';
import {
potentialTranscriberJoined,
transcriberJoined,
transcriberLeft
} from './actions';
import './subscriber';
const TRANSCRIBER_DISPLAY_NAME = 'Transcriber';
import { TRANSCRIBER_LEFT } from './actionTypes';
/**
* Implements the middleware of the feature transcribing.
@ -20,37 +10,15 @@ const TRANSCRIBER_DISPLAY_NAME = 'Transcriber';
* @param {Store} store - The redux store.
* @returns {Function}
*/
// eslint-disable-next-line no-unused-vars
MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
const {
transcriberJID,
potentialTranscriberJIDs
} = getState()['features/transcribing'];
MiddlewareRegistry.register(({ dispatch }) => next => action => {
switch (action.type) {
case HIDDEN_PARTICIPANT_JOINED:
if (action.displayName === TRANSCRIBER_DISPLAY_NAME) {
dispatch(transcriberJoined(action.id));
} else {
dispatch(potentialTranscriberJoined(action.id));
}
break;
case HIDDEN_PARTICIPANT_LEFT:
if (action.id === transcriberJID) {
dispatch(transcriberLeft(action.id));
case TRANSCRIBER_LEFT:
if (action.abruptly) {
dispatch(showErrorNotification({
titleKey: 'transcribing.failed'
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
}
break;
case PARTICIPANT_UPDATED: {
const { participant } = action;
if (potentialTranscriberJIDs.includes(participant.id) && participant.name === TRANSCRIBER_DISPLAY_NAME) {
dispatch(transcriberJoined(participant.id));
}
break;
}
}
return next(action);

@ -1,9 +1,8 @@
import ReducerRegistry from '../base/redux/ReducerRegistry';
import {
_POTENTIAL_TRANSCRIBER_JOINED,
_TRANSCRIBER_JOINED,
_TRANSCRIBER_LEFT
TRANSCRIBER_JOINED,
TRANSCRIBER_LEFT
} from './actionTypes';
/**
@ -11,8 +10,7 @@ import {
*
* @returns {{
* isTranscribing: boolean,
* transcriberJID: null,
* potentialTranscriberJIDs: Array
* transcriberJID: null
* }}
* @private
*/
@ -31,20 +29,12 @@ function _getInitialState() {
*
* @type { string }
*/
transcriberJID: null,
/**
* A list containing potential JID's of transcriber participants.
*
* @type { Array }
*/
potentialTranscriberJIDs: []
transcriberJID: null
};
}
export interface ITranscribingState {
isTranscribing: boolean;
potentialTranscriberJIDs: string[];
transcriberJID?: string | null;
}
@ -54,23 +44,17 @@ export interface ITranscribingState {
ReducerRegistry.register<ITranscribingState>('features/transcribing',
(state = _getInitialState(), action): ITranscribingState => {
switch (action.type) {
case _TRANSCRIBER_JOINED:
case TRANSCRIBER_JOINED:
return {
...state,
isTranscribing: true,
transcriberJID: action.transcriberJID
};
case _TRANSCRIBER_LEFT:
case TRANSCRIBER_LEFT:
return {
...state,
isTranscribing: false,
transcriberJID: undefined,
potentialTranscriberJIDs: []
};
case _POTENTIAL_TRANSCRIBER_JOINED:
return {
...state,
potentialTranscriberJIDs: [ action.transcriberJID, ...state.potentialTranscriberJIDs ]
transcriberJID: undefined
};
default:
return state;

Loading…
Cancel
Save