ref(ui-components) Update ContextMenu and move it to base/ui (#12318)

This commit is contained in:
Robert Pintilii 2022-10-06 13:09:40 +03:00 committed by GitHub
parent a2d39ca5b1
commit 6c9441fa7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 95 additions and 74 deletions

View File

@ -24,8 +24,6 @@
}
.drawer-menu {
background: #242528;
border-radius: 16px 16px 0 0;
overflow-y: auto;
margin-bottom: env(safe-area-inset-bottom, 0);
width: 100%;

View File

@ -1,3 +1 @@
export { default as ContextMenu } from './context-menu/ContextMenu';
export { default as ContextMenuItemGroup } from './context-menu/ContextMenuItemGroup';
export { default as ListItem } from './participants-pane-list/ListItem';

View File

@ -2,9 +2,9 @@
import React, { Fragment } from 'react';
import ContextMenuItem from '../../components/context-menu/ContextMenuItem';
import { Icon } from '../../icons';
import { Tooltip } from '../../tooltip';
import ContextMenuItem from '../../ui/components/web/ContextMenuItem';
import AbstractToolboxItem from './AbstractToolboxItem';
import type { Props as AbstractToolboxItemProps } from './AbstractToolboxItem';

View File

@ -5,13 +5,13 @@ import React, { ReactNode, useEffect, useLayoutEffect, useRef, useState } from '
import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
import { getComputedOuterHeight } from '../../../participants-pane/functions';
import { getComputedOuterHeight } from '../../../../participants-pane/functions';
// @ts-ignore
import { Drawer, JitsiPortal } from '../../../toolbox/components/web';
import { Drawer, JitsiPortal } from '../../../../toolbox/components/web';
// @ts-ignore
import { showOverflowDrawer } from '../../../toolbox/functions.web';
import { withPixelLineHeight } from '../../styles/functions.web';
import participantsPaneTheme from '../themes/participantsPaneTheme.json';
import { showOverflowDrawer } from '../../../../toolbox/functions.web';
import participantsPaneTheme from '../../../components/themes/participantsPaneTheme.json';
import { withPixelLineHeight } from '../../../styles/functions.web';
type Props = {
@ -86,9 +86,10 @@ const MAX_HEIGHT = 400;
const useStyles = makeStyles()((theme: Theme) => {
return {
contextMenu: {
backgroundColor: theme.palette.ui02,
borderRadius: `${Number(theme.shape.borderRadius) / 2}px`,
boxShadow: '0px 3px 16px rgba(0, 0, 0, 0.6), 0px 0px 4px 1px rgba(0, 0, 0, 0.25)',
backgroundColor: theme.palette.ui01,
border: `1px solid ${theme.palette.ui04}`,
borderRadius: `${Number(theme.shape.borderRadius)}px`,
boxShadow: '0px 4px 25px 4px rgba(20, 20, 20, 0.6)',
color: theme.palette.text01,
...withPixelLineHeight(theme.typography.bodyShortRegular),
marginTop: `${(participantsPaneTheme.panePadding * 2) + theme.typography.bodyShortRegular.fontSize}px`,
@ -97,7 +98,8 @@ const useStyles = makeStyles()((theme: Theme) => {
top: 0,
zIndex: 2,
maxHeight: `${MAX_HEIGHT}px`,
overflowY: 'auto'
overflowY: 'auto',
padding: `${theme.spacing(2)} 0`
},
contextMenuHidden: {
@ -106,6 +108,7 @@ const useStyles = makeStyles()((theme: Theme) => {
},
drawer: {
paddingTop: '16px',
'& > div': {
...withPixelLineHeight(theme.typography.bodyShortRegularLarge),
@ -113,10 +116,6 @@ const useStyles = makeStyles()((theme: Theme) => {
'& svg': {
fill: theme.palette.icon01
}
},
'& > *:first-child': {
paddingTop: '15px!important'
}
}
};

View File

@ -4,8 +4,9 @@ import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
// @ts-ignore
import { showOverflowDrawer } from '../../../toolbox/functions.web';
import Icon from '../../icons/components/Icon';
import { showOverflowDrawer } from '../../../../toolbox/functions.web';
import Icon from '../../../icons/components/Icon';
import { withPixelLineHeight } from '../../../styles/functions.web';
export type Props = {
@ -86,7 +87,11 @@ const useStyles = makeStyles()((theme: Theme) => {
},
'&:hover': {
backgroundColor: theme.palette.ui04
backgroundColor: theme.palette.ui02
},
'&:active': {
backgroundColor: theme.palette.ui03
}
},
@ -95,13 +100,22 @@ const useStyles = makeStyles()((theme: Theme) => {
},
contextMenuItemDrawer: {
padding: '12px 16px'
padding: '13px 16px'
},
contextMenuItemIcon: {
'& svg': {
fill: theme.palette.icon01
}
},
text: {
...withPixelLineHeight(theme.typography.bodyShortRegular),
color: theme.palette.text01
},
drawerText: {
...withPixelLineHeight(theme.typography.bodyShortRegularLarge)
}
};
});
@ -142,7 +156,7 @@ const ContextMenuItem = ({
className = { styles.contextMenuItemIcon }
size = { 20 }
src = { icon } />}
<span className = { textClassName ?? '' }>{text}</span>
<span className = { cx(textClassName) }>{text}</span>
</div>
);
};

View File

@ -27,6 +27,14 @@ const useStyles = makeStyles()((theme: Theme) => {
'& + &:not(:empty)': {
borderTop: `1px solid ${theme.palette.ui04}`
},
'&:first-of-type': {
paddingTop: 0
},
'&:last-of-type': {
paddingBottom: 0
}
}
};

View File

@ -1,25 +1,29 @@
// @flow
import { useCallback, useRef, useState } from 'react';
import { findAncestorByClass } from '../../../participants-pane/functions';
type RaiseContext = {|
/**
* Target elements against which positioning calculations are made.
*/
offsetTarget?: HTMLElement,
type RaiseContext = {
/**
* The entity for which the menu is context menu is raised.
*/
entity?: string | Object,
|};
entity?: string | Object;
/**
* Target elements against which positioning calculations are made.
*/
offsetTarget?: HTMLElement | null;
};
const initialState = Object.freeze({});
const useContextMenu = () => {
const useContextMenu = (): [(force?: boolean | Object) => void,
(entity: string | Object, target: HTMLElement | null) => void,
(entity: string | Object) => (e: MouseEvent) => void,
() => void,
() => void,
RaiseContext] => {
const [ raiseContext, setRaiseContext ] = useState < RaiseContext >(initialState);
const isMouseOverMenu = useRef(false);
@ -41,7 +45,7 @@ const useContextMenu = () => {
});
}, [ raiseContext ]);
const raiseMenu = useCallback((entity: string | Object, target: EventTarget) => {
const raiseMenu = useCallback((entity: string | Object, target: HTMLElement | null) => {
setRaiseContext({
entity,
offsetTarget: findAncestorByClass(target, 'list-item-container')
@ -55,7 +59,7 @@ const useContextMenu = () => {
if (raisedEntity && raisedEntity === entity) {
lowerMenu();
} else {
raiseMenu(entity, e.target);
raiseMenu(entity, e.target as HTMLElement);
}
}, [ raiseContext ]);

View File

@ -4,9 +4,9 @@ import clsx from 'clsx';
import React, { Component } from 'react';
import { WithTranslation } from 'react-i18next';
import ContextMenu from '../../base/components/context-menu/ContextMenu';
import { isMobileBrowser } from '../../base/environment/utils';
import { translate } from '../../base/i18n/functions';
import ContextMenu from '../../base/ui/components/web/ContextMenu';
type DownloadUpload = {
download: number;

View File

@ -5,12 +5,13 @@ import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../../../analytics';
import { ContextMenu, ContextMenuItemGroup } from '../../../../../base/components';
import {
IconClose,
IconRingGroup
} from '../../../../../base/icons';
import { isLocalParticipantModerator } from '../../../../../base/participants';
import ContextMenu from '../../../../../base/ui/components/web/ContextMenu';
import ContextMenuItemGroup from '../../../../../base/ui/components/web/ContextMenuItemGroup';
import { closeBreakoutRoom, moveToRoom, removeBreakoutRoom } from '../../../../../breakout-rooms/actions';
import { showOverflowDrawer } from '../../../../../toolbox/functions';

View File

@ -3,9 +3,9 @@
import React, { useCallback } from 'react';
import { useSelector } from 'react-redux';
import useContextMenu from '../../../../../base/components/context-menu/useContextMenu';
import { isLocalParticipantModerator } from '../../../../../base/participants';
import { equals } from '../../../../../base/redux';
import useContextMenu from '../../../../../base/ui/hooks/useContextMenu';
import {
getBreakoutRooms,
getBreakoutRoomsConfig,

View File

@ -7,9 +7,9 @@ import { makeStyles } from 'tss-react/mui';
// @ts-ignore
import { Avatar } from '../../../../../base/avatar';
// @ts-ignore
import { ContextMenu, ContextMenuItemGroup } from '../../../../../base/components';
import { isLocalParticipantModerator } from '../../../../../base/participants/functions';
import ContextMenu from '../../../../../base/ui/components/web/ContextMenu';
import ContextMenuItemGroup from '../../../../../base/ui/components/web/ContextMenuItemGroup';
// @ts-ignore
import { getBreakoutRooms } from '../../../../../breakout-rooms/functions';
// @ts-ignore
@ -38,17 +38,17 @@ type Props = {
/**
* Callback for the mouse entering the component.
*/
onEnter: Function;
onEnter: () => void;
/**
* Callback for the mouse leaving the component.
*/
onLeave: Function;
onLeave: () => void;
/**
* Callback for making a selection in the menu.
*/
onSelect: Function;
onSelect: (force?: any) => void;
};
const useStyles = makeStyles()((theme: Theme) => {

View File

@ -17,8 +17,6 @@ import {
isSupported as isAvModerationSupported
// @ts-ignore
} from '../../../av-moderation/functions';
import ContextMenu from '../../../base/components/context-menu/ContextMenu';
import ContextMenuItemGroup from '../../../base/components/context-menu/ContextMenuItemGroup';
// @ts-ignore
import { openDialog } from '../../../base/dialog';
import {
@ -31,6 +29,8 @@ import {
getParticipantCount,
isEveryoneModerator
} from '../../../base/participants/functions';
import ContextMenu from '../../../base/ui/components/web/ContextMenu';
import ContextMenuItemGroup from '../../../base/ui/components/web/ContextMenuItemGroup';
// @ts-ignore
import { isInBreakoutRoom } from '../../../breakout-rooms/functions';
import {

View File

@ -6,12 +6,12 @@ import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
import ContextMenu from '../../../base/components/context-menu/ContextMenu';
import ContextMenuItemGroup from '../../../base/components/context-menu/ContextMenuItemGroup';
import { IconChat, IconCloseCircle, IconHorizontalPoints } from '../../../base/icons/svg';
import { hasRaisedHand } from '../../../base/participants/functions';
import { Participant } from '../../../base/participants/types';
import Button from '../../../base/ui/components/web/Button';
import ContextMenu from '../../../base/ui/components/web/ContextMenu';
import ContextMenuItemGroup from '../../../base/ui/components/web/ContextMenuItemGroup';
import { BUTTON_TYPES } from '../../../base/ui/constants';
// @ts-ignore
import { showLobbyChatButton } from '../../../lobby/functions';

View File

@ -9,8 +9,6 @@ import { makeStyles } from 'tss-react/mui';
import { IState } from '../../../app/types';
// @ts-ignore
import { rejectParticipantAudio } from '../../../av-moderation/actions';
// @ts-ignore
import useContextMenu from '../../../base/components/context-menu/useContextMenu';
import participantsPaneTheme from '../../../base/components/themes/participantsPaneTheme.json';
// @ts-ignore
import { isToolbarButtonEnabled } from '../../../base/config/functions.web';
@ -19,6 +17,7 @@ import { getParticipantById } from '../../../base/participants/functions';
import { connect } from '../../../base/redux/functions';
import { withPixelLineHeight } from '../../../base/styles/functions.web';
import Input from '../../../base/ui/components/web/Input';
import useContextMenu from '../../../base/ui/hooks/useContextMenu';
import { normalizeAccents } from '../../../base/util/strings.web';
// @ts-ignore
import { getBreakoutRooms, getCurrentRoomId, isInBreakoutRoom } from '../../../breakout-rooms/functions';

View File

@ -31,8 +31,9 @@ type Props = {
const useStyles = makeStyles()((theme: Theme) => {
return {
drawer: {
backgroundColor: theme.palette.ui02,
maxHeight: `calc(${DRAWER_MAX_HEIGHT})`
backgroundColor: theme.palette.ui01,
maxHeight: `calc(${DRAWER_MAX_HEIGHT})`,
borderRadius: '24px 24px 0 0'
}
};
});

View File

@ -9,8 +9,6 @@ import keyboardShortcut from '../../../../../modules/keyboardshortcut/keyboardsh
import { ACTION_SHORTCUT_TRIGGERED, createShortcutEvent, createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IState } from '../../../app/types';
import ContextMenu from '../../../base/components/context-menu/ContextMenu';
import ContextMenuItemGroup from '../../../base/components/context-menu/ContextMenuItemGroup';
// @ts-ignore
import { getMultipleVideoSendingSupportFeatureFlag, getToolbarButtons } from '../../../base/config';
// @ts-ignore
@ -30,6 +28,8 @@ import {
import { connect } from '../../../base/redux/functions';
// @ts-ignore
import { getLocalVideoTrack } from '../../../base/tracks';
import ContextMenu from '../../../base/ui/components/web/ContextMenu';
import ContextMenuItemGroup from '../../../base/ui/components/web/ContextMenuItemGroup';
// @ts-ignore
import { toggleChat } from '../../../chat';
// @ts-ignore

View File

@ -5,8 +5,8 @@ import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import { approveParticipant } from '../../../av-moderation/actions';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { IconMicrophoneEmpty } from '../../../base/icons';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
type Props = {

View File

@ -1,10 +1,10 @@
// @flow
import React, { useCallback } from 'react';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { translate } from '../../../base/i18n';
import { IconInfo } from '../../../base/icons';
import { connect } from '../../../base/redux';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
import { renderConnectionStatus } from '../../actions.web';
type Props = {

View File

@ -8,10 +8,10 @@ import { useDispatch, useSelector } from 'react-redux';
import TogglePinToStageButton from '../../../../features/video-menu/components/web/TogglePinToStageButton';
// @ts-ignore
import { Avatar } from '../../../base/avatar';
import ContextMenu from '../../../base/components/context-menu/ContextMenu';
import ContextMenuItemGroup from '../../../base/components/context-menu/ContextMenuItemGroup';
import { IconShareVideo } from '../../../base/icons/svg';
import { Participant } from '../../../base/participants/types';
import ContextMenu from '../../../base/ui/components/web/ContextMenu';
import ContextMenuItemGroup from '../../../base/ui/components/web/ContextMenuItemGroup';
// @ts-ignore
import { stopSharedVideo } from '../../../shared-video/actions.any';
// @ts-ignore

View File

@ -2,10 +2,10 @@
import React, { PureComponent } from 'react';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { translate } from '../../../base/i18n';
import { connect } from '../../../base/redux';
import { updateSettings } from '../../../base/settings';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
/**
* The type of the React {@code Component} props of {@link FlipLocalVideoButton}.

View File

@ -2,10 +2,10 @@
import React from 'react';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { translate } from '../../../base/i18n';
import { IconCrown } from '../../../base/icons';
import { connect } from '../../../base/redux';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
import AbstractGrantModeratorButton, {
type Props,
_mapStateToProps

View File

@ -2,10 +2,10 @@
import React, { PureComponent } from 'react';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { translate } from '../../../base/i18n';
import { connect } from '../../../base/redux';
import { getHideSelfView, updateSettings } from '../../../base/settings';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
/**
* The type of the React {@code Component} props of {@link HideSelfViewVideoButton}.

View File

@ -2,10 +2,10 @@
import React from 'react';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { translate } from '../../../base/i18n';
import { IconCloseCircle } from '../../../base/icons';
import { connect } from '../../../base/redux';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
import AbstractKickButton, {
type Props
} from '../AbstractKickButton';

View File

@ -5,8 +5,6 @@ import { WithTranslation } from 'react-i18next';
import { batch } from 'react-redux';
import { IState } from '../../../app/types';
import ContextMenu from '../../../base/components/context-menu/ContextMenu';
import ContextMenuItemGroup from '../../../base/components/context-menu/ContextMenuItemGroup';
import { isMobileBrowser } from '../../../base/environment/utils';
// @ts-ignore
import { translate } from '../../../base/i18n';
@ -22,6 +20,8 @@ import { getHideSelfView } from '../../../base/settings';
// @ts-ignore
import { getLocalVideoTrack } from '../../../base/tracks';
import Button from '../../../base/ui/components/web/Button';
import ContextMenu from '../../../base/ui/components/web/ContextMenu';
import ContextMenuItemGroup from '../../../base/ui/components/web/ContextMenuItemGroup';
// @ts-ignore
import ConnectionIndicatorContent from '../../../connection-indicator/components/web/ConnectionIndicatorContent';
import { THUMBNAIL_TYPE } from '../../../filmstrip/constants';

View File

@ -2,10 +2,10 @@
import React from 'react';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { translate } from '../../../base/i18n';
import { IconMicrophoneEmptySlash } from '../../../base/icons';
import { connect } from '../../../base/redux';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
import AbstractMuteButton, {
type Props,
_mapStateToProps

View File

@ -2,10 +2,10 @@
import React from 'react';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { translate } from '../../../base/i18n';
import { IconMuteEveryoneElse } from '../../../base/icons';
import { connect } from '../../../base/redux';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
import AbstractMuteEveryoneElseButton, {
type Props
} from '../AbstractMuteEveryoneElseButton';

View File

@ -2,10 +2,10 @@
import React from 'react';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { translate } from '../../../base/i18n';
import { IconMuteVideoEveryoneElse } from '../../../base/icons';
import { connect } from '../../../base/redux';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
import AbstractMuteEveryoneElsesVideoButton, {
type Props
} from '../AbstractMuteEveryoneElsesVideoButton';

View File

@ -2,10 +2,10 @@
import React from 'react';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { translate } from '../../../base/i18n';
import { IconVideoOff } from '../../../base/icons';
import { connect } from '../../../base/redux';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
import AbstractMuteVideoButton, {
type Props,
_mapStateToProps

View File

@ -11,8 +11,6 @@ import { IState } from '../../../app/types';
import { isSupported as isAvModerationSupported } from '../../../av-moderation/functions';
// @ts-ignore
import { Avatar } from '../../../base/avatar';
import ContextMenu from '../../../base/components/context-menu/ContextMenu';
import ContextMenuItemGroup from '../../../base/components/context-menu/ContextMenuItemGroup';
import { isIosMobileBrowser, isMobileBrowser } from '../../../base/environment/utils';
import { MEDIA_TYPE } from '../../../base/media/constants';
import { PARTICIPANT_ROLE } from '../../../base/participants/constants';
@ -20,6 +18,8 @@ import { getLocalParticipant } from '../../../base/participants/functions';
import { Participant } from '../../../base/participants/types';
// @ts-ignore
import { isParticipantAudioMuted } from '../../../base/tracks';
import ContextMenu from '../../../base/ui/components/web/ContextMenu';
import ContextMenuItemGroup from '../../../base/ui/components/web/ContextMenuItemGroup';
// @ts-ignore
import { getBreakoutRooms, getCurrentRoomId, isInBreakoutRoom } from '../../../breakout-rooms/functions';
// @ts-ignore

View File

@ -2,10 +2,10 @@
import React, { Component } from 'react';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { translate } from '../../../base/i18n';
import { IconMessage } from '../../../base/icons';
import { connect } from '../../../base/redux';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
import { openChat } from '../../../chat/';
import {
type Props as AbstractProps,

View File

@ -6,9 +6,9 @@ import {
createRemoteVideoMenuButtonEvent,
sendAnalytics
} from '../../../analytics';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { translate } from '../../../base/i18n';
import { IconRemoteControlStart, IconRemoteControlStop } from '../../../base/icons';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
// TODO: Move these enums into the store after further reactification of the
// non-react RemoteVideo component.

View File

@ -129,7 +129,6 @@ const styles = () => {
position: 'relative' as const,
marginTop: 0,
right: 'auto',
padding: '0',
marginRight: '4px',
marginBottom: '4px'
}

View File

@ -5,8 +5,8 @@ import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../analytics';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { IconRingGroup } from '../../../base/icons';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
import { sendParticipantToRoom } from '../../../breakout-rooms/actions';
type Props = {

View File

@ -4,8 +4,8 @@ import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import ContextMenuItem from '../../../base/components/context-menu/ContextMenuItem';
import { IconPinParticipant, IconUnpin } from '../../../base/icons';
import ContextMenuItem from '../../../base/ui/components/web/ContextMenuItem';
import { togglePinStageParticipant } from '../../../filmstrip/actions.web';
import { getPinnedActiveParticipants } from '../../../filmstrip/functions.web';