"Fossies" - the Fresh Open Source Software Archive

Member "jitsi-meet-7316/react/features/reactions/components/web/ReactionsMenuButton.tsx" (5 Jun 2023, 6195 Bytes) of package /linux/misc/jitsi-meet-7316.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. See also the last Fossies "Diffs" side-by-side code changes report for "ReactionsMenuButton.tsx": jitsi-meet_8319_vs_jitsi-meet_8615.

    1 import React, { ReactElement, useCallback } from 'react';
    2 import { WithTranslation } from 'react-i18next';
    3 import { connect } from 'react-redux';
    4 
    5 import { IReduxState, IStore } from '../../../app/types';
    6 import { isMobileBrowser } from '../../../base/environment/utils';
    7 import { translate } from '../../../base/i18n/functions';
    8 import { IconArrowUp, IconFaceSmile } from '../../../base/icons/svg';
    9 import AbstractButton, { type IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
   10 import ToolboxButtonWithPopup from '../../../base/toolbox/components/web/ToolboxButtonWithPopup';
   11 import { toggleReactionsMenuVisibility } from '../../actions.web';
   12 import { IReactionEmojiProps } from '../../constants';
   13 import { getReactionsQueue, isReactionsEnabled } from '../../functions.any';
   14 import { getReactionsMenuVisibility, isReactionsButtonEnabled } from '../../functions.web';
   15 import { IReactionsMenuParent } from '../../types';
   16 
   17 import RaiseHandButton from './RaiseHandButton';
   18 import ReactionEmoji from './ReactionEmoji';
   19 import ReactionsMenu from './ReactionsMenu';
   20 
   21 interface IProps extends WithTranslation {
   22 
   23     /**
   24      * Whether a mobile browser is used or not.
   25      */
   26     _isMobile: boolean;
   27 
   28     /**
   29      * Whether the reactions should be displayed on separate button or not.
   30      */
   31     _reactionsButtonEnabled: boolean;
   32 
   33     /**
   34      * The button's key.
   35      */
   36     buttonKey?: string;
   37 
   38     /**
   39      * Redux dispatch function.
   40      */
   41     dispatch: IStore['dispatch'];
   42 
   43     /**
   44      * Click handler for raise hand functionality.
   45      */
   46     handleClick: Function;
   47 
   48     /**
   49      * Whether or not it's narrow mode or mobile browser.
   50      */
   51     isNarrow: boolean;
   52 
   53     /**
   54      * Whether or not the reactions menu is open.
   55      */
   56     isOpen: boolean;
   57 
   58     /**
   59      * Notify mode for `toolbarButtonClicked` event -
   60      * whether to only notify or to also prevent button click routine.
   61      */
   62     notifyMode?: string;
   63 
   64     /**
   65      * The array of reactions to be displayed.
   66      */
   67     reactionsQueue: Array<IReactionEmojiProps>;
   68 }
   69 
   70 
   71 /**
   72  * Implementation of a button for reactions.
   73  */
   74 class ReactionsButtonImpl extends AbstractButton<AbstractButtonProps> {
   75     accessibilityLabel = 'toolbar.accessibilityLabel.reactions';
   76     icon = IconFaceSmile;
   77     label = 'toolbar.reactions';
   78     toggledLabel = 'toolbar.reactions';
   79     tooltip = 'toolbar.reactions';
   80 }
   81 
   82 const ReactionsButton = translate(connect()(ReactionsButtonImpl));
   83 
   84 /**
   85  * Button used for the reactions menu.
   86  *
   87  * @returns {ReactElement}
   88  */
   89 function ReactionsMenuButton({
   90     _reactionsButtonEnabled,
   91     _isMobile,
   92     buttonKey,
   93     dispatch,
   94     handleClick,
   95     isOpen,
   96     isNarrow,
   97     notifyMode,
   98     reactionsQueue,
   99     t
  100 }: IProps) {
  101     const toggleReactionsMenu = useCallback(() => {
  102         dispatch(toggleReactionsMenuVisibility());
  103     }, [ dispatch ]);
  104 
  105     const openReactionsMenu = useCallback(() => {
  106         !isOpen && toggleReactionsMenu();
  107     }, [ isOpen, toggleReactionsMenu ]);
  108 
  109     const closeReactionsMenu = useCallback(() => {
  110         isOpen && toggleReactionsMenu();
  111     }, [ isOpen, toggleReactionsMenu ]);
  112 
  113     const reactionsMenu = (<div className = 'reactions-menu-container'>
  114         <ReactionsMenu parent = { IReactionsMenuParent.Button } />
  115     </div>);
  116 
  117     let content: ReactElement | null = null;
  118 
  119     if (_reactionsButtonEnabled) {
  120         content = (
  121             <ToolboxButtonWithPopup
  122                 ariaControls = 'reactions-menu-dialog'
  123                 ariaExpanded = { isOpen }
  124                 ariaHasPopup = { true }
  125                 ariaLabel = { t('toolbar.accessibilityLabel.reactionsMenu') }
  126                 onPopoverClose = { closeReactionsMenu }
  127                 onPopoverOpen = { openReactionsMenu }
  128                 popoverContent = { reactionsMenu }
  129                 trigger = { _isMobile ? 'click' : undefined }
  130                 visible = { isOpen }>
  131                 <ReactionsButton
  132                     buttonKey = { buttonKey }
  133                     notifyMode = { notifyMode } />
  134             </ToolboxButtonWithPopup>);
  135     } else {
  136         content = isNarrow
  137             ? (
  138                 <RaiseHandButton
  139                     buttonKey = { buttonKey }
  140                     handleClick = { handleClick }
  141                     notifyMode = { notifyMode } />)
  142             : (
  143                 <ToolboxButtonWithPopup
  144                     ariaControls = 'reactions-menu-dialog'
  145                     ariaExpanded = { isOpen }
  146                     ariaHasPopup = { true }
  147                     ariaLabel = { t('toolbar.accessibilityLabel.reactionsMenu') }
  148                     icon = { IconArrowUp }
  149                     iconDisabled = { false }
  150                     iconId = 'reactions-menu-button'
  151                     onPopoverClose = { toggleReactionsMenu }
  152                     onPopoverOpen = { openReactionsMenu }
  153                     popoverContent = { reactionsMenu }
  154                     visible = { isOpen }>
  155                     <RaiseHandButton
  156                         buttonKey = { buttonKey }
  157                         handleClick = { handleClick }
  158                         notifyMode = { notifyMode } />
  159                 </ToolboxButtonWithPopup>);
  160     }
  161 
  162     return (
  163         <div className = 'reactions-menu-popup-container'>
  164             { content }
  165             {reactionsQueue.map(({ reaction, uid }, index) => (<ReactionEmoji
  166                 index = { index }
  167                 key = { uid }
  168                 reaction = { reaction }
  169                 uid = { uid } />))}
  170         </div>
  171     );
  172 
  173 }
  174 
  175 /**
  176  * Function that maps parts of Redux state tree into component props.
  177  *
  178  * @param {Object} state - Redux state.
  179  * @returns {Object}
  180  */
  181 function mapStateToProps(state: IReduxState) {
  182     const { isNarrowLayout } = state['features/base/responsive-ui'];
  183 
  184     return {
  185         _reactionsButtonEnabled: isReactionsButtonEnabled(state),
  186         _reactionsEnabled: isReactionsEnabled(state),
  187         _isMobile: isMobileBrowser(),
  188         isOpen: getReactionsMenuVisibility(state),
  189         isNarrow: isNarrowLayout,
  190         reactionsQueue: getReactionsQueue(state)
  191     };
  192 }
  193 
  194 export default translate(connect(mapStateToProps)(ReactionsMenuButton));