You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

OverflowMenuButton.tsx 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import React, { ReactNode, useCallback } from 'react';
  2. import { useSelector } from 'react-redux';
  3. import { makeStyles } from 'tss-react/mui';
  4. import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
  5. import { sendAnalytics } from '../../../analytics/functions';
  6. import Popover from '../../../base/popover/components/Popover.web';
  7. import ReactionEmoji from '../../../reactions/components/web/ReactionEmoji';
  8. import ReactionsMenu from '../../../reactions/components/web/ReactionsMenu';
  9. import { REACTIONS_MENU_HEIGHT } from '../../../reactions/constants';
  10. import { getReactionsQueue } from '../../../reactions/functions.any';
  11. import { DRAWER_MAX_HEIGHT } from '../../constants';
  12. import { showOverflowDrawer } from '../../functions.web';
  13. import Drawer from './Drawer';
  14. import JitsiPortal from './JitsiPortal';
  15. import OverflowToggleButton from './OverflowToggleButton';
  16. /**
  17. * The type of the React {@code Component} props of {@link OverflowMenuButton}.
  18. */
  19. interface IProps {
  20. /**
  21. * ID of the menu that is controlled by this button.
  22. */
  23. ariaControls: string;
  24. /**
  25. * A child React Element to display within {@code Popover}.
  26. */
  27. children: ReactNode;
  28. /**
  29. * Whether or not the OverflowMenu popover should display.
  30. */
  31. isOpen: boolean;
  32. /**
  33. * Callback to change the visibility of the overflow menu.
  34. */
  35. onVisibilityChange: Function;
  36. /**
  37. * Whether or not to display the reactions in the mobile menu.
  38. */
  39. showMobileReactions: boolean;
  40. }
  41. const useStyles = makeStyles()(() => {
  42. return {
  43. overflowMenuDrawer: {
  44. overflowY: 'auto' as const,
  45. height: `calc(${DRAWER_MAX_HEIGHT} - ${REACTIONS_MENU_HEIGHT}px - 16px)`
  46. }
  47. };
  48. });
  49. const OverflowMenuButton = ({
  50. children,
  51. isOpen,
  52. onVisibilityChange,
  53. showMobileReactions
  54. }: IProps) => {
  55. const { classes } = useStyles();
  56. const overflowDrawer = useSelector(showOverflowDrawer);
  57. const reactionsQueue = useSelector(getReactionsQueue);
  58. const onCloseDialog = useCallback(() => {
  59. onVisibilityChange(false);
  60. }, [ onVisibilityChange ]);
  61. const onOpenDialog = useCallback(() => {
  62. onVisibilityChange(true);
  63. }, [ onVisibilityChange ]);
  64. const onEscClick = useCallback((event: React.KeyboardEvent) => {
  65. if (event.key === 'Escape' && isOpen) {
  66. event.preventDefault();
  67. event.stopPropagation();
  68. onCloseDialog();
  69. }
  70. }, [ onCloseDialog ]);
  71. const toggleDialogVisibility = useCallback(() => {
  72. sendAnalytics(createToolbarEvent('overflow'));
  73. onVisibilityChange(!isOpen);
  74. }, [ isOpen, onVisibilityChange ]);
  75. return (
  76. <div className = 'toolbox-button-wth-dialog context-menu'>
  77. {
  78. overflowDrawer ? (
  79. <>
  80. <OverflowToggleButton
  81. handleClick = { toggleDialogVisibility }
  82. isOpen = { isOpen }
  83. onKeyDown = { onEscClick } />
  84. <JitsiPortal>
  85. <Drawer
  86. isOpen = { isOpen }
  87. onClose = { onCloseDialog }>
  88. <>
  89. <div className = { classes.overflowMenuDrawer }>
  90. {children}
  91. </div>
  92. {showMobileReactions && <ReactionsMenu overflowMenu = { true } />}
  93. </>
  94. </Drawer>
  95. {showMobileReactions && <div className = 'reactions-animations-container'>
  96. {reactionsQueue.map(({ reaction, uid }, index) => (<ReactionEmoji
  97. index = { index }
  98. key = { uid }
  99. reaction = { reaction }
  100. uid = { uid } />))}
  101. </div>}
  102. </JitsiPortal>
  103. </>
  104. ) : (
  105. <Popover
  106. content = { children }
  107. headingId = 'overflow-context-menu'
  108. onPopoverClose = { onCloseDialog }
  109. onPopoverOpen = { onOpenDialog }
  110. position = 'top'
  111. trigger = 'click'
  112. visible = { isOpen }>
  113. <OverflowToggleButton
  114. isOpen = { isOpen }
  115. onKeyDown = { onEscClick } />
  116. </Popover>
  117. )
  118. }
  119. </div>
  120. );
  121. };
  122. export default OverflowMenuButton;