"Fossies" - the Fresh Open Source Software Archive

Member "jitsi-meet-7319/react/features/base/media/reducer.ts" (6 Jun 2023, 8862 Bytes) of package /linux/misc/jitsi-meet-7319.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 last Fossies "Diffs" side-by-side code changes report for "reducer.ts": 7309_vs_7312.

    1 import { AnyAction, combineReducers } from 'redux';
    2 
    3 import { CONFERENCE_FAILED, CONFERENCE_LEFT } from '../conference/actionTypes';
    4 import ReducerRegistry from '../redux/ReducerRegistry';
    5 import { TRACK_REMOVED } from '../tracks/actionTypes';
    6 
    7 import {
    8     GUM_PENDING,
    9     SET_AUDIO_AVAILABLE,
   10     SET_AUDIO_MUTED,
   11     SET_AUDIO_UNMUTE_PERMISSIONS,
   12     SET_CAMERA_FACING_MODE,
   13     SET_SCREENSHARE_MUTED,
   14     SET_VIDEO_AVAILABLE,
   15     SET_VIDEO_MUTED,
   16     SET_VIDEO_UNMUTE_PERMISSIONS,
   17     STORE_VIDEO_TRANSFORM,
   18     TOGGLE_CAMERA_FACING_MODE
   19 } from './actionTypes';
   20 import { CAMERA_FACING_MODE, MEDIA_TYPE, SCREENSHARE_MUTISM_AUTHORITY } from './constants';
   21 import { IGUMPendingState } from './types';
   22 
   23 /**
   24  * Media state object for local audio.
   25  *
   26  * @typedef {Object} AudioMediaState
   27  * @property {boolean} muted=false - Audio muted state.
   28  */
   29 
   30 // FIXME Technically, _AUDIO_INITIAL_MEDIA_STATE is a constant internal to the
   31 // feature base/media and used in multiple files so it should be in
   32 // constants.js. Practically though, AudioMediaState would then be used in
   33 // multiple files as well so I don't know where and how to move it.
   34 /**
   35  * Initial state for local audio.
   36  *
   37  * @type {AudioMediaState}
   38  */
   39 export const _AUDIO_INITIAL_MEDIA_STATE = {
   40     available: true,
   41     gumPending: IGUMPendingState.NONE,
   42     unmuteBlocked: false,
   43     muted: false
   44 };
   45 
   46 /**
   47  * Reducer for audio media state.
   48  *
   49  * @param {AudioMediaState} state - Media state of local audio.
   50  * @param {Object} action - Action object.
   51  * @param {string} action.type - Type of action.
   52  * @private
   53  * @returns {AudioMediaState}
   54  */
   55 function _audio(state: IAudioState = _AUDIO_INITIAL_MEDIA_STATE, action: AnyAction) {
   56     switch (action.type) {
   57     case SET_AUDIO_AVAILABLE:
   58         return {
   59             ...state,
   60             available: action.available
   61         };
   62 
   63     case GUM_PENDING:
   64         if (action.mediaTypes.includes(MEDIA_TYPE.AUDIO)) {
   65             return {
   66                 ...state,
   67                 gumPending: action.status
   68             };
   69         }
   70 
   71         return state;
   72 
   73     case SET_AUDIO_MUTED:
   74         return {
   75             ...state,
   76             muted: action.muted
   77         };
   78 
   79     case SET_AUDIO_UNMUTE_PERMISSIONS:
   80         return {
   81             ...state,
   82             unmuteBlocked: action.blocked
   83         };
   84 
   85     default:
   86         return state;
   87     }
   88 }
   89 
   90 /**
   91  * Media state object for local screenshare.
   92  *
   93  * @typedef {Object} ScreenshareMediaState
   94  * @property {boolean} available=true - Screenshare available state.
   95  * @property {boolean} muted=true - Screenshare muted state.
   96  * @property {boolean} unmuteBlocked=false - Screenshare unmute blocked state.
   97  */
   98 
   99 /**
  100  * Initial state for video.
  101  *
  102  * @type {ScreenshareMediaState}
  103  */
  104 export const _SCREENSHARE_INITIAL_MEDIA_STATE = {
  105     available: true,
  106     muted: SCREENSHARE_MUTISM_AUTHORITY.USER,
  107     unmuteBlocked: false
  108 };
  109 
  110 /**
  111  * Reducer for screenshare media state.
  112  *
  113  * @param {VideoMediaState} state - Media state of local screenshare.
  114  * @param {Object} action - Action object.
  115  * @param {string} action.type - Type of action.
  116  * @private
  117  * @returns {ScreenshareMediaState}
  118  */
  119 function _screenshare(state: IScreenshareState = _SCREENSHARE_INITIAL_MEDIA_STATE, action: AnyAction) {
  120     switch (action.type) {
  121     case SET_SCREENSHARE_MUTED:
  122         return {
  123             ...state,
  124             muted: action.muted
  125         };
  126 
  127     case SET_VIDEO_UNMUTE_PERMISSIONS:
  128         return {
  129             ...state,
  130             unmuteBlocked: action.blocked
  131         };
  132 
  133     default:
  134         return state;
  135     }
  136 }
  137 
  138 /**
  139  * Media state object for local video.
  140  *
  141  * @typedef {Object} VideoMediaState
  142  * @property {CAMERA_FACING_MODE} facingMode='user' - Camera facing mode.
  143  * @property {boolean} muted=false - Video muted state.
  144  */
  145 
  146 // FIXME Technically, _VIDEO_INITIAL_MEDIA_STATE is a constant internal to the
  147 // feature base/media and used in multiple files so it should be in
  148 // constants.js. Practically though, VideoMediaState would then be used in
  149 // multiple files as well so I don't know where and how to move it.
  150 /**
  151  * Initial state for video.
  152  *
  153  * @type {VideoMediaState}
  154  */
  155 export const _VIDEO_INITIAL_MEDIA_STATE = {
  156     available: true,
  157     gumPending: IGUMPendingState.NONE,
  158     unmuteBlocked: false,
  159     facingMode: CAMERA_FACING_MODE.USER,
  160     muted: 0,
  161 
  162     /**
  163      * The video {@link Transform}s applied to {@code MediaStream}s by
  164      * {@code id} i.e. "pinch to zoom".
  165      */
  166     transforms: {}
  167 };
  168 
  169 /**
  170  * Reducer for camera media state.
  171  *
  172  * @param {VideoMediaState} state - Media state of local video.
  173  * @param {Object} action - Action object.
  174  * @param {string} action.type - Type of action.
  175  * @private
  176  * @returns {VideoMediaState}
  177  */
  178 function _video(state: IVideoState = _VIDEO_INITIAL_MEDIA_STATE, action: any) {
  179     switch (action.type) {
  180     case CONFERENCE_FAILED:
  181     case CONFERENCE_LEFT:
  182         return _clearAllVideoTransforms(state);
  183 
  184     case GUM_PENDING:
  185         if (action.mediaTypes.includes(MEDIA_TYPE.VIDEO)) {
  186             return {
  187                 ...state,
  188                 gumPending: action.status
  189             };
  190         }
  191 
  192         return state;
  193 
  194     case SET_CAMERA_FACING_MODE:
  195         return {
  196             ...state,
  197             facingMode: action.cameraFacingMode
  198         };
  199 
  200     case SET_VIDEO_AVAILABLE:
  201         return {
  202             ...state,
  203             available: action.available
  204         };
  205 
  206     case SET_VIDEO_MUTED:
  207         return {
  208             ...state,
  209             muted: action.muted
  210         };
  211 
  212     case SET_VIDEO_UNMUTE_PERMISSIONS:
  213         return {
  214             ...state,
  215             unmuteBlocked: action.blocked
  216         };
  217 
  218     case STORE_VIDEO_TRANSFORM:
  219         return _storeVideoTransform(state, action);
  220 
  221     case TOGGLE_CAMERA_FACING_MODE: {
  222         let cameraFacingMode = state.facingMode;
  223 
  224         cameraFacingMode
  225             = cameraFacingMode === CAMERA_FACING_MODE.USER
  226                 ? CAMERA_FACING_MODE.ENVIRONMENT
  227                 : CAMERA_FACING_MODE.USER;
  228 
  229         return {
  230             ...state,
  231             facingMode: cameraFacingMode
  232         };
  233     }
  234 
  235     case TRACK_REMOVED:
  236         return _trackRemoved(state, action);
  237 
  238     default:
  239         return state;
  240     }
  241 }
  242 
  243 interface IAudioState {
  244     available: boolean;
  245     gumPending: IGUMPendingState;
  246     muted: boolean;
  247     unmuteBlocked: boolean;
  248 }
  249 
  250 interface IScreenshareState {
  251     available: boolean;
  252     muted: number;
  253     unmuteBlocked: boolean;
  254 }
  255 
  256 interface IVideoState {
  257     available: boolean;
  258     facingMode: string;
  259     gumPending: IGUMPendingState;
  260     muted: number;
  261     transforms: Object;
  262     unmuteBlocked: boolean;
  263 }
  264 
  265 export interface IMediaState {
  266     audio: IAudioState;
  267     screenshare: IScreenshareState;
  268     video: IVideoState;
  269 }
  270 
  271 /**
  272  * Listen for various actions related to media devices.
  273  *
  274  * @param {Object} state - State of media devices.
  275  * @param {Object} action - Action object.
  276  * @param {string} action.type - Type of action.
  277  * @param {Object} action.media - Information about media devices to be
  278  * modified.
  279  * @returns {Object}
  280  */
  281 ReducerRegistry.register<IMediaState>('features/base/media', combineReducers({
  282     audio: _audio,
  283     screenshare: _screenshare,
  284     video: _video
  285 }));
  286 
  287 /**
  288  * Removes all stored video {@link Transform}s.
  289  *
  290  * @param {Object} state - The {@code video} state of the feature base/media.
  291  * @private
  292  * @returns {Object}
  293  */
  294 function _clearAllVideoTransforms(state: IVideoState) {
  295     return {
  296         ...state,
  297         transforms: _VIDEO_INITIAL_MEDIA_STATE.transforms
  298     };
  299 }
  300 
  301 /**
  302  * Stores the last applied transform to a stream.
  303  *
  304  * @param {Object} state - The {@code video} state of the feature base/media.
  305  * @param {Object} action - The redux action {@link STORE_VIDEO_TRANSFORM}.
  306  * @private
  307  * @returns {Object}
  308  */
  309 function _storeVideoTransform(state: IVideoState, { streamId, transform }: { streamId: string; transform: string; }) {
  310     return {
  311         ...state,
  312         transforms: {
  313             ...state.transforms,
  314             [streamId]: transform
  315         }
  316     };
  317 }
  318 
  319 /**
  320  * Removes the stored video {@link Transform} associated with a
  321  * {@code MediaStream} when its respective track is removed.
  322  *
  323  * @param {Object} state - The {@code video} state of the feature base/media.
  324  * @param {Object} action - The redux action {@link TRACK_REMOVED}.
  325  * @private
  326  * @returns {Object}
  327  */
  328 function _trackRemoved(state: IVideoState, { track: { jitsiTrack } }: { track: { jitsiTrack: any; }; }) {
  329     if (jitsiTrack) {
  330         const streamId = jitsiTrack.getStreamId();
  331 
  332         if (streamId && streamId in state.transforms) {
  333             const nextTransforms: any = {
  334                 ...state.transforms
  335             };
  336 
  337             delete nextTransforms[streamId];
  338 
  339             return {
  340                 ...state,
  341                 transforms: nextTransforms
  342             };
  343         }
  344     }
  345 
  346     return state;
  347 }