"Fossies" - the Fresh Open Source Software Archive

Member "jitsi-meet-7328/react/features/base/conference/reducer.ts" (8 Jun 2023, 18256 Bytes) of package /linux/misc/jitsi-meet-7328.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) TypeScript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "reducer.ts": 7323_vs_7328.

    1 import { AnyAction } from 'redux';
    2 
    3 import { FaceLandmarks } from '../../face-landmarks/types';
    4 import { LOCKED_LOCALLY, LOCKED_REMOTELY } from '../../room-lock/constants';
    5 import { ISpeakerStats } from '../../speaker-stats/reducer';
    6 import { CONNECTION_WILL_CONNECT, SET_LOCATION_URL } from '../connection/actionTypes';
    7 import { JitsiConferenceErrors } from '../lib-jitsi-meet';
    8 import ReducerRegistry from '../redux/ReducerRegistry';
    9 import { assign, set } from '../redux/functions';
   10 
   11 import {
   12     AUTH_STATUS_CHANGED,
   13     CONFERENCE_FAILED,
   14     CONFERENCE_JOINED,
   15     CONFERENCE_LEFT,
   16     CONFERENCE_LOCAL_SUBJECT_CHANGED,
   17     CONFERENCE_SUBJECT_CHANGED,
   18     CONFERENCE_TIMESTAMP_CHANGED,
   19     CONFERENCE_WILL_JOIN,
   20     CONFERENCE_WILL_LEAVE,
   21     LOCK_STATE_CHANGED,
   22     P2P_STATUS_CHANGED,
   23     SET_ASSUMED_BANDWIDTH_BPS,
   24     SET_FOLLOW_ME,
   25     SET_OBFUSCATED_ROOM,
   26     SET_PASSWORD,
   27     SET_PENDING_SUBJECT_CHANGE,
   28     SET_ROOM,
   29     SET_START_MUTED_POLICY,
   30     SET_START_REACTIONS_MUTED
   31 } from './actionTypes';
   32 import { isRoomValid } from './functions';
   33 
   34 const DEFAULT_STATE = {
   35     assumedBandwidthBps: undefined,
   36     conference: undefined,
   37     e2eeSupported: undefined,
   38     joining: undefined,
   39     leaving: undefined,
   40     locked: undefined,
   41     membersOnly: undefined,
   42     password: undefined,
   43     passwordRequired: undefined
   44 };
   45 
   46 export interface IJitsiConference {
   47     addCommandListener: Function;
   48     addLobbyMessageListener: Function;
   49     addTrack: Function;
   50     authenticateAndUpgradeRole: Function;
   51     avModerationApprove: Function;
   52     avModerationReject: Function;
   53     callUUID?: string;
   54     createVideoSIPGWSession: Function;
   55     dial: Function;
   56     disableAVModeration: Function;
   57     disableLobby: Function;
   58     enableAVModeration: Function;
   59     enableLobby: Function;
   60     end: Function;
   61     getBreakoutRooms: Function;
   62     getLocalParticipantProperty: Function;
   63     getLocalTracks: Function;
   64     getMeetingUniqueId: Function;
   65     getMetadataHandler: Function;
   66     getName: Function;
   67     getParticipantById: Function;
   68     getParticipantCount: Function;
   69     getParticipants: Function;
   70     getRole: Function;
   71     getSpeakerStats: () => ISpeakerStats;
   72     getSsrcByTrack: Function;
   73     grantOwner: Function;
   74     isAVModerationSupported: Function;
   75     isCallstatsEnabled: Function;
   76     isE2EEEnabled: Function;
   77     isE2EESupported: Function;
   78     isEndConferenceSupported: Function;
   79     isLobbySupported: Function;
   80     isP2PActive: Function;
   81     isSIPCallingSupported: Function;
   82     isStartAudioMuted: Function;
   83     isStartVideoMuted: Function;
   84     join: Function;
   85     joinLobby: Function;
   86     kickParticipant: Function;
   87     leave: Function;
   88     lobbyApproveAccess: Function;
   89     lobbyDenyAccess: Function;
   90     lock: Function;
   91     markParticipantVerified: Function;
   92     muteParticipant: Function;
   93     myLobbyUserId: Function;
   94     myUserId: Function;
   95     off: Function;
   96     on: Function;
   97     options: any;
   98     removeTrack: Function;
   99     replaceTrack: Function;
  100     room: IJitsiConferenceRoom;
  101     sendApplicationLog: Function;
  102     sendCommand: Function;
  103     sendCommandOnce: Function;
  104     sendEndpointMessage: Function;
  105     sendFaceLandmarks: (faceLandmarks: FaceLandmarks) => void;
  106     sendFeedback: Function;
  107     sendLobbyMessage: Function;
  108     sendMessage: Function;
  109     sendPrivateTextMessage: Function;
  110     sendTextMessage: Function;
  111     sendTones: Function;
  112     sessionId: string;
  113     setAssumedBandwidthBps: (value: number) => void;
  114     setDesktopSharingFrameRate: Function;
  115     setDisplayName: Function;
  116     setLocalParticipantProperty: Function;
  117     setMediaEncryptionKey: Function;
  118     setReceiverConstraints: Function;
  119     setSenderVideoConstraint: Function;
  120     setStartMutedPolicy: Function;
  121     setSubject: Function;
  122     startRecording: Function;
  123     startVerification: Function;
  124     stopRecording: Function;
  125     toggleE2EE: Function;
  126 }
  127 
  128 export interface IConferenceState {
  129     assumedBandwidthBps?: number;
  130     authEnabled?: boolean;
  131     authLogin?: string;
  132     authRequired?: IJitsiConference;
  133     conference?: IJitsiConference;
  134     conferenceTimestamp?: number;
  135     e2eeSupported?: boolean;
  136     error?: Error;
  137     followMeEnabled?: boolean;
  138     joining?: IJitsiConference;
  139     leaving?: IJitsiConference;
  140     localSubject?: string;
  141     locked?: string;
  142     membersOnly?: IJitsiConference;
  143     obfuscatedRoom?: string;
  144     obfuscatedRoomSource?: string;
  145     p2p?: Object;
  146     password?: string;
  147     passwordRequired?: IJitsiConference;
  148     pendingSubjectChange?: string;
  149     room?: string;
  150     startAudioMutedPolicy?: boolean;
  151     startReactionsMuted?: boolean;
  152     startVideoMutedPolicy?: boolean;
  153     subject?: string;
  154 }
  155 
  156 export interface IJitsiConferenceRoom {
  157     locked: boolean;
  158     myroomjid: string;
  159     roomjid: string;
  160 }
  161 
  162 /**
  163  * Listen for actions that contain the conference object, so that it can be
  164  * stored for use by other action creators.
  165  */
  166 ReducerRegistry.register<IConferenceState>('features/base/conference',
  167     (state = DEFAULT_STATE, action): IConferenceState => {
  168         switch (action.type) {
  169         case AUTH_STATUS_CHANGED:
  170             return _authStatusChanged(state, action);
  171 
  172         case CONFERENCE_FAILED:
  173             return _conferenceFailed(state, action);
  174 
  175         case CONFERENCE_JOINED:
  176             return _conferenceJoined(state, action);
  177 
  178         case CONFERENCE_SUBJECT_CHANGED:
  179             return set(state, 'subject', action.subject);
  180 
  181         case CONFERENCE_LOCAL_SUBJECT_CHANGED:
  182             return set(state, 'localSubject', action.localSubject);
  183 
  184         case CONFERENCE_TIMESTAMP_CHANGED:
  185             return set(state, 'conferenceTimestamp', action.conferenceTimestamp);
  186 
  187         case CONFERENCE_LEFT:
  188         case CONFERENCE_WILL_LEAVE:
  189             return _conferenceLeftOrWillLeave(state, action);
  190 
  191         case CONFERENCE_WILL_JOIN:
  192             return _conferenceWillJoin(state, action);
  193 
  194         case CONNECTION_WILL_CONNECT:
  195             return set(state, 'authRequired', undefined);
  196 
  197         case LOCK_STATE_CHANGED:
  198             return _lockStateChanged(state, action);
  199 
  200         case P2P_STATUS_CHANGED:
  201             return _p2pStatusChanged(state, action);
  202 
  203         case SET_ASSUMED_BANDWIDTH_BPS: {
  204             const assumedBandwidthBps = action.assumedBandwidthBps >= 0
  205                 ? Number(action.assumedBandwidthBps)
  206                 : undefined;
  207 
  208             return set(state, 'assumedBandwidthBps', assumedBandwidthBps);
  209         }
  210         case SET_FOLLOW_ME:
  211             return set(state, 'followMeEnabled', action.enabled);
  212 
  213         case SET_START_REACTIONS_MUTED:
  214             return set(state, 'startReactionsMuted', action.muted);
  215 
  216         case SET_LOCATION_URL:
  217             return set(state, 'room', undefined);
  218 
  219         case SET_OBFUSCATED_ROOM:
  220             return { ...state,
  221                 obfuscatedRoom: action.obfuscatedRoom,
  222                 obfuscatedRoomSource: action.obfuscatedRoomSource
  223             };
  224 
  225         case SET_PASSWORD:
  226             return _setPassword(state, action);
  227 
  228         case SET_PENDING_SUBJECT_CHANGE:
  229             return set(state, 'pendingSubjectChange', action.subject);
  230 
  231         case SET_ROOM:
  232             return _setRoom(state, action);
  233 
  234         case SET_START_MUTED_POLICY:
  235             return {
  236                 ...state,
  237                 startAudioMutedPolicy: action.startAudioMutedPolicy,
  238                 startVideoMutedPolicy: action.startVideoMutedPolicy
  239             };
  240         }
  241 
  242         return state;
  243     });
  244 
  245 /**
  246  * Reduces a specific Redux action AUTH_STATUS_CHANGED of the feature
  247  * base/conference.
  248  *
  249  * @param {Object} state - The Redux state of the feature base/conference.
  250  * @param {Action} action - The Redux action AUTH_STATUS_CHANGED to reduce.
  251  * @private
  252  * @returns {Object} The new state of the feature base/conference after the
  253  * reduction of the specified action.
  254  */
  255 function _authStatusChanged(state: IConferenceState,
  256         { authEnabled, authLogin }: { authEnabled: boolean; authLogin: string; }) {
  257     return assign(state, {
  258         authEnabled,
  259         authLogin
  260     });
  261 }
  262 
  263 /**
  264  * Reduces a specific Redux action CONFERENCE_FAILED of the feature
  265  * base/conference.
  266  *
  267  * @param {Object} state - The Redux state of the feature base/conference.
  268  * @param {Action} action - The Redux action CONFERENCE_FAILED to reduce.
  269  * @private
  270  * @returns {Object} The new state of the feature base/conference after the
  271  * reduction of the specified action.
  272  */
  273 function _conferenceFailed(state: IConferenceState, { conference, error }: {
  274     conference: IJitsiConference; error: Error; }) {
  275     // The current (similar to getCurrentConference in
  276     // base/conference/functions.any.js) conference which is joining or joined:
  277     const conference_ = state.conference || state.joining;
  278 
  279     if (conference_ && conference_ !== conference) {
  280         return state;
  281     }
  282 
  283     let authRequired;
  284     let membersOnly;
  285     let passwordRequired;
  286 
  287     switch (error.name) {
  288     case JitsiConferenceErrors.AUTHENTICATION_REQUIRED:
  289         authRequired = conference;
  290         break;
  291 
  292     case JitsiConferenceErrors.CONFERENCE_ACCESS_DENIED:
  293     case JitsiConferenceErrors.MEMBERS_ONLY_ERROR:
  294         membersOnly = conference;
  295         break;
  296 
  297     case JitsiConferenceErrors.PASSWORD_REQUIRED:
  298         passwordRequired = conference;
  299         break;
  300     }
  301 
  302     return assign(state, {
  303         authRequired,
  304         conference: undefined,
  305         e2eeSupported: undefined,
  306         error,
  307         joining: undefined,
  308         leaving: undefined,
  309 
  310         /**
  311          * The indicator of how the conference/room is locked. If falsy, the
  312          * conference/room is unlocked; otherwise, it's either
  313          * {@code LOCKED_LOCALLY} or {@code LOCKED_REMOTELY}.
  314          *
  315          * @type {string}
  316          */
  317         locked: passwordRequired ? LOCKED_REMOTELY : undefined,
  318         membersOnly,
  319         password: undefined,
  320 
  321         /**
  322          * The JitsiConference instance which requires a password to join.
  323          *
  324          * @type {JitsiConference}
  325          */
  326         passwordRequired
  327     });
  328 }
  329 
  330 /**
  331  * Reduces a specific Redux action CONFERENCE_JOINED of the feature
  332  * base/conference.
  333  *
  334  * @param {Object} state - The Redux state of the feature base/conference.
  335  * @param {Action} action - The Redux action CONFERENCE_JOINED to reduce.
  336  * @private
  337  * @returns {Object} The new state of the feature base/conference after the
  338  * reduction of the specified action.
  339  */
  340 function _conferenceJoined(state: IConferenceState, { conference }: { conference: IJitsiConference; }) {
  341     // FIXME The indicator which determines whether a JitsiConference is locked
  342     // i.e. password-protected is private to lib-jitsi-meet. However, the
  343     // library does not fire LOCK_STATE_CHANGED upon joining a JitsiConference
  344     // with a password.
  345     // FIXME Technically JitsiConference.room is a private field.
  346     const locked = conference.room?.locked ? LOCKED_REMOTELY : undefined;
  347 
  348     return assign(state, {
  349         authRequired: undefined,
  350 
  351         /**
  352          * The JitsiConference instance represented by the Redux state of the
  353          * feature base/conference.
  354          *
  355          * @type {JitsiConference}
  356          */
  357         conference,
  358 
  359         e2eeSupported: conference.isE2EESupported(),
  360 
  361         joining: undefined,
  362         membersOnly: undefined,
  363         leaving: undefined,
  364 
  365         /**
  366          * The indicator which determines whether the conference is locked.
  367          *
  368          * @type {boolean}
  369          */
  370         locked,
  371         passwordRequired: undefined
  372     });
  373 }
  374 
  375 /**
  376  * Reduces a specific redux action {@link CONFERENCE_LEFT} or
  377  * {@link CONFERENCE_WILL_LEAVE} for the feature base/conference.
  378  *
  379  * @param {Object} state - The redux state of the feature base/conference.
  380  * @param {Action} action - The redux action {@code CONFERENCE_LEFT} or
  381  * {@code CONFERENCE_WILL_LEAVE} to reduce.
  382  * @private
  383  * @returns {Object} The next/new state of the feature base/conference after the
  384  * reduction of the specified action.
  385  */
  386 function _conferenceLeftOrWillLeave(state: IConferenceState, { conference, type }:
  387     { conference: IJitsiConference; type: string; }) {
  388     const nextState = { ...state };
  389 
  390     // The redux action CONFERENCE_LEFT is the last time that we should be
  391     // hearing from a JitsiConference instance.
  392     //
  393     // The redux action CONFERENCE_WILL_LEAVE represents the order of the user
  394     // to leave a JitsiConference instance. From the user's perspective, there's
  395     // no going back (with respect to the instance itself). The app will perform
  396     // due clean-up like leaving the associated room, but the instance is no
  397     // longer the focus of the attention of the user and, consequently, the app.
  398     for (const p in state) {
  399         if (state[p as keyof IConferenceState] === conference) {
  400             nextState[p as keyof IConferenceState] = undefined;
  401 
  402             switch (p) {
  403             case 'conference':
  404             case 'passwordRequired':
  405                 // XXX Clear/unset locked & password for a conference which has
  406                 // been LOCKED_LOCALLY or LOCKED_REMOTELY.
  407                 delete nextState.locked;
  408                 delete nextState.password;
  409                 break;
  410             }
  411         }
  412     }
  413 
  414     if (type === CONFERENCE_WILL_LEAVE) {
  415         // A CONFERENCE_WILL_LEAVE is of further consequence only if it is
  416         // expected i.e. if the specified conference is joining or joined.
  417         if (conference === state.joining || conference === state.conference) {
  418             /**
  419              * The JitsiConference instance which is currently in the process of
  420              * being left.
  421              *
  422              * @type {JitsiConference}
  423              */
  424             nextState.leaving = conference;
  425         }
  426     }
  427 
  428     return nextState;
  429 }
  430 
  431 /**
  432  * Reduces a specific Redux action CONFERENCE_WILL_JOIN of the feature
  433  * base/conference.
  434  *
  435  * @param {Object} state - The Redux state of the feature base/conference.
  436  * @param {Action} action - The Redux action CONFERENCE_WILL_JOIN to reduce.
  437  * @private
  438  * @returns {Object} The new state of the feature base/conference after the
  439  * reduction of the specified action.
  440  */
  441 function _conferenceWillJoin(state: IConferenceState, { conference }: { conference: IJitsiConference; }) {
  442     return assign(state, {
  443         error: undefined,
  444         joining: conference
  445     });
  446 }
  447 
  448 /**
  449  * Reduces a specific Redux action LOCK_STATE_CHANGED of the feature
  450  * base/conference.
  451  *
  452  * @param {Object} state - The Redux state of the feature base/conference.
  453  * @param {Action} action - The Redux action LOCK_STATE_CHANGED to reduce.
  454  * @private
  455  * @returns {Object} The new state of the feature base/conference after the
  456  * reduction of the specified action.
  457  */
  458 function _lockStateChanged(state: IConferenceState, { conference, locked }: { conference: Object; locked: boolean; }) {
  459     if (state.conference !== conference) {
  460         return state;
  461     }
  462 
  463     return assign(state, {
  464         locked: locked ? state.locked || LOCKED_REMOTELY : undefined,
  465         password: locked ? state.password : undefined
  466     });
  467 }
  468 
  469 /**
  470  * Reduces a specific Redux action P2P_STATUS_CHANGED of the feature
  471  * base/conference.
  472  *
  473  * @param {Object} state - The Redux state of the feature base/conference.
  474  * @param {Action} action - The Redux action P2P_STATUS_CHANGED to reduce.
  475  * @private
  476  * @returns {Object} The new state of the feature base/conference after the
  477  * reduction of the specified action.
  478  */
  479 function _p2pStatusChanged(state: IConferenceState, action: AnyAction) {
  480     return set(state, 'p2p', action.p2p);
  481 }
  482 
  483 /**
  484  * Reduces a specific Redux action SET_PASSWORD of the feature base/conference.
  485  *
  486  * @param {Object} state - The Redux state of the feature base/conference.
  487  * @param {Action} action - The Redux action SET_PASSWORD to reduce.
  488  * @private
  489  * @returns {Object} The new state of the feature base/conference after the
  490  * reduction of the specified action.
  491  */
  492 function _setPassword(state: IConferenceState, { conference, method, password }: {
  493     conference: IJitsiConference; method: Object; password: string; }) {
  494     switch (method) {
  495     case conference.join:
  496         return assign(state, {
  497             // 1. The JitsiConference which transitions away from
  498             // passwordRequired MUST remain in the redux state
  499             // features/base/conference until it transitions into
  500             // conference; otherwise, there is a span of time during which
  501             // the redux state does not even know that there is a
  502             // JitsiConference whatsoever.
  503             //
  504             // 2. The redux action setPassword will attempt to join the
  505             // JitsiConference so joining is an appropriate transitional
  506             // redux state.
  507             //
  508             // 3. The redux action setPassword will perform the same check
  509             // before it proceeds with the re-join.
  510             joining: state.conference ? state.joining : conference,
  511             locked: LOCKED_REMOTELY,
  512 
  513             /**
  514              * The password with which the conference is to be joined.
  515              *
  516              * @type {string}
  517              */
  518             password
  519         });
  520 
  521     case conference.lock:
  522         return assign(state, {
  523             locked: password ? LOCKED_LOCALLY : undefined,
  524             password
  525         });
  526     }
  527 
  528     return state;
  529 }
  530 
  531 /**
  532  * Reduces a specific Redux action SET_ROOM of the feature base/conference.
  533  *
  534  * @param {Object} state - The Redux state of the feature base/conference.
  535  * @param {Action} action - The Redux action SET_ROOM to reduce.
  536  * @private
  537  * @returns {Object} The new state of the feature base/conference after the
  538  * reduction of the specified action.
  539  */
  540 function _setRoom(state: IConferenceState, action: AnyAction) {
  541     let { room } = action;
  542 
  543     if (!isRoomValid(room)) {
  544         // Technically, there are multiple values which don't represent valid
  545         // room names. Practically, each of them is as bad as the rest of them
  546         // because we can't use any of them to join a conference.
  547         room = undefined;
  548     }
  549 
  550     /**
  551      * The name of the room of the conference (to be) joined.
  552      *
  553      * @type {string}
  554      */
  555     return assign(state, {
  556         error: undefined,
  557         room
  558     });
  559 }
  560