"Fossies" - the Fresh Open Source Software Archive

Member "jitsi-meet-7555/react/features/video-menu/components/web/LocalVideoMenuTriggerButton.tsx" (28 Sep 2023, 10089 Bytes) of package /linux/misc/jitsi-meet-7555.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) TSX (TypeScript with React) source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 import React, { useCallback } from 'react';
    2 import { useTranslation } from 'react-i18next';
    3 import { batch, connect, useSelector } from 'react-redux';
    4 import { makeStyles } from 'tss-react/mui';
    5 
    6 import { IReduxState, IStore } from '../../../app/types';
    7 import { getButtonNotifyMode, getParticipantMenuButtonsWithNotifyClick } from '../../../base/config/functions.web';
    8 import { isMobileBrowser } from '../../../base/environment/utils';
    9 import { IconDotsHorizontal } from '../../../base/icons/svg';
   10 import { getLocalParticipant } from '../../../base/participants/functions';
   11 import Popover from '../../../base/popover/components/Popover.web';
   12 import { setParticipantContextMenuOpen } from '../../../base/responsive-ui/actions';
   13 import { getHideSelfView } from '../../../base/settings/functions.web';
   14 import { getLocalVideoTrack } from '../../../base/tracks/functions';
   15 import Button from '../../../base/ui/components/web/Button';
   16 import ContextMenu from '../../../base/ui/components/web/ContextMenu';
   17 import ContextMenuItemGroup from '../../../base/ui/components/web/ContextMenuItemGroup';
   18 import ConnectionIndicatorContent from '../../../connection-indicator/components/web/ConnectionIndicatorContent';
   19 import { THUMBNAIL_TYPE } from '../../../filmstrip/constants';
   20 import { isStageFilmstripAvailable } from '../../../filmstrip/functions.web';
   21 import { NOTIFY_CLICK_MODE } from '../../../toolbox/constants';
   22 import { renderConnectionStatus } from '../../actions.web';
   23 import { PARTICIPANT_MENU_BUTTONS as BUTTONS } from '../../constants';
   24 
   25 import ConnectionStatusButton from './ConnectionStatusButton';
   26 import FlipLocalVideoButton from './FlipLocalVideoButton';
   27 import HideSelfViewVideoButton from './HideSelfViewVideoButton';
   28 import TogglePinToStageButton from './TogglePinToStageButton';
   29 
   30 /**
   31  * The type of the React {@code Component} props of
   32  * {@link LocalVideoMenuTriggerButton}.
   33  */
   34 interface IProps {
   35 
   36     /**
   37      * The id of the local participant.
   38      */
   39     _localParticipantId: string;
   40 
   41     /**
   42      * The position relative to the trigger the local video menu should display
   43      * from.
   44      */
   45     _menuPosition: string;
   46 
   47     /**
   48      * Whether to display the Popover as a drawer.
   49      */
   50     _overflowDrawer: boolean;
   51 
   52     /**
   53      * Whether to render the connection info pane.
   54      */
   55     _showConnectionInfo: boolean;
   56 
   57     /**
   58      * Whether to render the hide self view button.
   59      */
   60     _showHideSelfViewButton: boolean;
   61 
   62     /**
   63      * Shows/hides the local video flip button.
   64      */
   65     _showLocalVideoFlipButton: boolean;
   66 
   67     /**
   68      * Whether to render the pin to stage button.
   69      */
   70     _showPinToStage: boolean;
   71 
   72     /**
   73      * Whether or not the button should be visible.
   74      */
   75     buttonVisible: boolean;
   76 
   77     /**
   78      * The redux dispatch function.
   79      */
   80     dispatch: IStore['dispatch'];
   81 
   82     /**
   83      * Hides popover.
   84      */
   85     hidePopover?: Function;
   86 
   87     /**
   88      * Whether the popover is visible or not.
   89      */
   90     popoverVisible?: boolean;
   91 
   92     /**
   93      * Shows popover.
   94      */
   95     showPopover?: Function;
   96 
   97     /**
   98      * The type of the thumbnail.
   99      */
  100     thumbnailType: string;
  101 }
  102 
  103 const useStyles = makeStyles()(() => {
  104     return {
  105         triggerButton: {
  106             padding: '3px !important',
  107             borderRadius: '4px',
  108 
  109             '& svg': {
  110                 width: '18px',
  111                 height: '18px'
  112             }
  113         },
  114 
  115         contextMenu: {
  116             position: 'relative',
  117             marginTop: 0,
  118             right: 'auto',
  119             padding: '0',
  120             minWidth: '200px'
  121         },
  122 
  123         flipText: {
  124             marginLeft: '36px'
  125         }
  126     };
  127 });
  128 
  129 const LocalVideoMenuTriggerButton = ({
  130     _localParticipantId,
  131     _menuPosition,
  132     _overflowDrawer,
  133     _showConnectionInfo,
  134     _showHideSelfViewButton,
  135     _showLocalVideoFlipButton,
  136     _showPinToStage,
  137     buttonVisible,
  138     dispatch,
  139     hidePopover,
  140     showPopover,
  141     popoverVisible
  142 }: IProps) => {
  143     const { classes } = useStyles();
  144     const { t } = useTranslation();
  145     const buttonsWithNotifyClick = useSelector(getParticipantMenuButtonsWithNotifyClick);
  146 
  147     const notifyClick = useCallback(
  148         (buttonKey: string) => {
  149             const notifyMode = getButtonNotifyMode(buttonKey, buttonsWithNotifyClick);
  150 
  151             if (!notifyMode) {
  152                 return;
  153             }
  154 
  155             APP.API.notifyParticipantMenuButtonClicked(
  156                 buttonKey,
  157                 _localParticipantId,
  158                 notifyMode === NOTIFY_CLICK_MODE.PREVENT_AND_NOTIFY
  159             );
  160         }, [ buttonsWithNotifyClick, getButtonNotifyMode ]);
  161 
  162     const _onPopoverOpen = useCallback(() => {
  163         showPopover?.();
  164         dispatch(setParticipantContextMenuOpen(true));
  165     }, []);
  166 
  167     const _onPopoverClose = useCallback(() => {
  168         hidePopover?.();
  169         batch(() => {
  170             dispatch(setParticipantContextMenuOpen(false));
  171             dispatch(renderConnectionStatus(false));
  172         });
  173     }, []);
  174 
  175     const content = _showConnectionInfo
  176         ? <ConnectionIndicatorContent participantId = { _localParticipantId } />
  177         : (
  178             <ContextMenu
  179                 className = { classes.contextMenu }
  180                 hidden = { false }
  181                 inDrawer = { _overflowDrawer }>
  182                 <ContextMenuItemGroup>
  183                     {_showLocalVideoFlipButton
  184                         && <FlipLocalVideoButton
  185                             className = { _overflowDrawer ? classes.flipText : '' }
  186                             // eslint-disable-next-line react/jsx-no-bind
  187                             notifyClick = { () => notifyClick(BUTTONS.FLIP_LOCAL_VIDEO) }
  188                             notifyMode = { getButtonNotifyMode(BUTTONS.FLIP_LOCAL_VIDEO, buttonsWithNotifyClick) }
  189                             onClick = { hidePopover } />
  190                     }
  191                     {_showHideSelfViewButton
  192                         && <HideSelfViewVideoButton
  193                             className = { _overflowDrawer ? classes.flipText : '' }
  194                             // eslint-disable-next-line react/jsx-no-bind
  195                             notifyClick = { () => notifyClick(BUTTONS.HIDE_SELF_VIEW) }
  196                             notifyMode = { getButtonNotifyMode(BUTTONS.HIDE_SELF_VIEW, buttonsWithNotifyClick) }
  197                             onClick = { hidePopover } />
  198                     }
  199                     {
  200                         _showPinToStage && <TogglePinToStageButton
  201                             className = { _overflowDrawer ? classes.flipText : '' }
  202                             noIcon = { true }
  203                             // eslint-disable-next-line react/jsx-no-bind
  204                             notifyClick = { () => notifyClick(BUTTONS.PIN_TO_STAGE) }
  205                             notifyMode = { getButtonNotifyMode(BUTTONS.PIN_TO_STAGE, buttonsWithNotifyClick) }
  206                             onClick = { hidePopover }
  207                             participantID = { _localParticipantId } />
  208                     }
  209                     {
  210                         isMobileBrowser() && <ConnectionStatusButton
  211                             // eslint-disable-next-line react/jsx-no-bind
  212                             notifyClick = { () => notifyClick(BUTTONS.CONN_STATUS) }
  213                             notifyMode = { getButtonNotifyMode(BUTTONS.CONN_STATUS, buttonsWithNotifyClick) }
  214                             participantID = { _localParticipantId } />
  215                     }
  216                 </ContextMenuItemGroup>
  217             </ContextMenu>
  218         );
  219 
  220     return (
  221         isMobileBrowser() || _showLocalVideoFlipButton || _showHideSelfViewButton
  222             ? <Popover
  223                 content = { content }
  224                 headingLabel = { t('dialog.localUserControls') }
  225                 id = 'local-video-menu-trigger'
  226                 onPopoverClose = { _onPopoverClose }
  227                 onPopoverOpen = { _onPopoverOpen }
  228                 position = { _menuPosition }
  229                 visible = { Boolean(popoverVisible) }>
  230                 {buttonVisible && !isMobileBrowser() && (
  231                     <Button
  232                         accessibilityLabel = { t('dialog.localUserControls') }
  233                         className = { classes.triggerButton }
  234                         icon = { IconDotsHorizontal }
  235                         size = 'small' />
  236                 )}
  237             </Popover>
  238             : null
  239     );
  240 };
  241 
  242 /**
  243  * Maps (parts of) the Redux state to the associated {@code LocalVideoMenuTriggerButton}'s props.
  244  *
  245  * @param {Object} state - The Redux state.
  246  * @param {Object} ownProps - The own props of the component.
  247  * @private
  248  * @returns {IProps}
  249  */
  250 function _mapStateToProps(state: IReduxState, ownProps: Partial<IProps>) {
  251     const { thumbnailType } = ownProps;
  252     const localParticipant = getLocalParticipant(state);
  253     const { disableLocalVideoFlip, disableSelfViewSettings } = state['features/base/config'];
  254     const videoTrack = getLocalVideoTrack(state['features/base/tracks']);
  255     const { overflowDrawer } = state['features/toolbox'];
  256     const { showConnectionInfo } = state['features/base/connection'];
  257     const showHideSelfViewButton = !disableSelfViewSettings && !getHideSelfView(state);
  258 
  259     let _menuPosition;
  260 
  261     switch (thumbnailType) {
  262     case THUMBNAIL_TYPE.TILE:
  263         _menuPosition = 'left-start';
  264         break;
  265     case THUMBNAIL_TYPE.VERTICAL:
  266         _menuPosition = 'left-start';
  267         break;
  268     case THUMBNAIL_TYPE.HORIZONTAL:
  269         _menuPosition = 'top-start';
  270         break;
  271     default:
  272         _menuPosition = 'auto';
  273     }
  274 
  275     return {
  276         _menuPosition,
  277         _showLocalVideoFlipButton: !disableLocalVideoFlip && videoTrack?.videoType !== 'desktop',
  278         _showHideSelfViewButton: showHideSelfViewButton,
  279         _overflowDrawer: overflowDrawer,
  280         _localParticipantId: localParticipant?.id ?? '',
  281         _showConnectionInfo: Boolean(showConnectionInfo),
  282         _showPinToStage: isStageFilmstripAvailable(state)
  283     };
  284 }
  285 
  286 export default connect(_mapStateToProps)(LocalVideoMenuTriggerButton);