Merge pull request #15008 from JoVictorNunes/fix-popover-menu

[2.5] fix: popover menus in RTL mode
This commit is contained in:
Ramón Souza 2022-05-16 14:50:47 +01:00 committed by GitHub
commit 226abc4bd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 92 additions and 28 deletions

View File

@ -251,6 +251,7 @@ class ActionsDropdown extends PureComponent {
isMeteorConnected,
isDropdownOpen,
isMobile,
isRTL,
} = this.props;
const availableActions = this.getAvailableActions();
@ -263,7 +264,7 @@ class ActionsDropdown extends PureComponent {
|| !isMeteorConnected) {
return null;
}
const customStyles = { top: '-3rem' };
const customStyles = { top: '-1rem' };
return (
<BBBMenu
@ -291,8 +292,8 @@ class ActionsDropdown extends PureComponent {
elevation: 3,
getContentAnchorEl: null,
fullwidth: "true",
anchorOrigin: { vertical: 'top', horizontal: 'left' },
transformorigin: { vertical: 'top', horizontal: 'left' },
anchorOrigin: { vertical: 'top', horizontal: isRTL ? 'right' : 'left' },
transformOrigin: { vertical: 'bottom', horizontal: isRTL ? 'right' : 'left' },
}}
/>
);

View File

@ -4,7 +4,7 @@ import Presentations from '/imports/api/presentations';
import PresentationUploaderService from '/imports/ui/components/presentation/presentation-uploader/service';
import PresentationPodService from '/imports/ui/components/presentation-pod/service';
import ActionsDropdown from './component';
import { layoutSelectInput, layoutDispatch } from '../../layout/context';
import { layoutSelectInput, layoutDispatch, layoutSelect } from '../../layout/context';
import getFromUserSettings from '/imports/ui/services/users-settings';
import { SMALL_VIEWPORT_BREAKPOINT } from '../../layout/enums';
@ -14,6 +14,7 @@ const ActionsDropdownContainer = (props) => {
const { width: browserWidth } = layoutSelectInput((i) => i.browser);
const isMobile = browserWidth <= SMALL_VIEWPORT_BREAKPOINT;
const layoutContextDispatch = layoutDispatch();
const isRTL = layoutSelect((i) => i.isRTL);
return (
<ActionsDropdown {...{
@ -21,6 +22,7 @@ const ActionsDropdownContainer = (props) => {
sidebarContent,
sidebarNavigation,
isMobile,
isRTL,
...props,
}}
/>

View File

@ -79,9 +79,9 @@ class AudioControls extends PureComponent {
}
static renderLeaveButtonWithLiveStreamSelector(props) {
const { handleLeaveAudio } = props;
const { handleLeaveAudio, isRTL } = props;
return (
<InputStreamLiveSelectorContainer {...{ handleLeaveAudio }} />
<InputStreamLiveSelectorContainer {...{ handleLeaveAudio, isRTL }} />
);
}

View File

@ -14,6 +14,7 @@ import {
setUserSelectedMicrophone,
setUserSelectedListenOnly,
} from '../audio-modal/service';
import { layoutSelect } from '/imports/ui/components/layout/context';
import Service from '../service';
import AppService from '/imports/ui/components/app/service';
@ -25,7 +26,8 @@ const AudioControlsContainer = (props) => {
const {
users, lockSettings, userLocks, children, ...newProps
} = props;
return <AudioControls {...newProps} />;
const isRTL = layoutSelect((i) => i.isRTL);
return <AudioControls {...{ ...newProps, isRTL }} />;
};
const handleLeaveAudio = () => {

View File

@ -263,6 +263,7 @@ class InputStreamLiveSelector extends Component {
currentInputDeviceId,
currentOutputDeviceId,
isListenOnly,
isRTL,
} = this.props;
const inputDeviceList = !isListenOnly
@ -313,6 +314,16 @@ class InputStreamLiveSelector extends Component {
</>
)}
actions={dropdownListComplete}
opts={{
id: 'default-dropdown-menu',
keepMounted: true,
transitionDuration: 0,
elevation: 3,
getContentAnchorEl: null,
fullwidth: 'true',
anchorOrigin: { vertical: 'top', horizontal: isRTL ? 'left' : 'right' },
transformOrigin: { vertical: 'bottom', horizontal: isRTL ? 'right' : 'left' },
}}
/>
);
}

View File

@ -65,6 +65,7 @@ class BreakoutDropdown extends PureComponent {
render() {
const {
intl,
isRTL,
} = this.props;
return (
@ -91,8 +92,8 @@ class BreakoutDropdown extends PureComponent {
elevation: 3,
getContentAnchorEl: null,
fullwidth: "true",
anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
transformorigin: { vertical: 'bottom', horizontal: 'left' },
anchorOrigin: { vertical: 'bottom', horizontal: isRTL ? 'right' : 'left' },
transformOrigin: { vertical: 'top', horizontal: isRTL ? 'right' : 'left' },
}}
actions={this.getAvailableActions()}
/>

View File

@ -547,6 +547,7 @@ class BreakoutRoom extends PureComponent {
intl,
endAllBreakouts,
amIModerator,
isRTL,
} = this.props;
return (
<Styled.Panel ref={(n) => this.panel = n}>
@ -568,6 +569,7 @@ class BreakoutRoom extends PureComponent {
}}
isMeteorConnected={isMeteorConnected}
amIModerator={amIModerator}
isRTL={isRTL}
/>
) }
</Styled.Header>

View File

@ -4,7 +4,7 @@ import AudioService from '/imports/ui/components/audio/service';
import AudioManager from '/imports/ui/services/audio-manager';
import BreakoutComponent from './component';
import Service from './service';
import { layoutDispatch } from '../layout/context';
import { layoutDispatch, layoutSelect } from '../layout/context';
import Auth from '/imports/ui/services/auth';
import { UsersContext } from '/imports/ui/components/components-data/users-context/context';
import {
@ -18,10 +18,11 @@ const BreakoutContainer = (props) => {
const usingUsersContext = useContext(UsersContext);
const { users } = usingUsersContext;
const amIPresenter = users[Auth.meetingID][Auth.userID].presenter;
const isRTL = layoutSelect((i) => i.isRTL);
return <BreakoutComponent
amIPresenter={amIPresenter}
{...{ layoutContextDispatch, ...props }}
{...{ layoutContextDispatch, isRTL, ...props }}
/>;
};

View File

@ -131,6 +131,7 @@ class ChatDropdown extends PureComponent {
const {
intl,
amIModerator,
isRTL,
} = this.props;
if (!amIModerator && !ENABLE_SAVE_AND_COPY_PUBLIC_CHAT) return null;
@ -158,8 +159,8 @@ class ChatDropdown extends PureComponent {
elevation: 3,
getContentAnchorEl: null,
fullwidth: "true",
anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
transformorigin: { vertical: 'bottom', horizontal: 'left' },
anchorOrigin: { vertical: 'bottom', horizontal: isRTL ? 'right' : 'left' },
transformOrigin: { vertical: 'top', horizontal: isRTL ? 'right' : 'left' },
}}
actions={this.getAvailableActions()}
/>

View File

@ -4,12 +4,14 @@ import Auth from '/imports/ui/services/auth';
import Meetings from '/imports/api/meetings';
import { UsersContext } from '/imports/ui/components/components-data/users-context/context';
import ChatDropdown from './component';
import { layoutSelect } from '../../layout/context';
const ChatDropdownContainer = ({ ...props }) => {
const usingUsersContext = useContext(UsersContext);
const { users } = usingUsersContext;
const isRTL = layoutSelect((i) => i.isRTL);
return <ChatDropdown {...props} users={users[Auth.meetingID]} />;
return <ChatDropdown {...{ isRTL, ...props }} users={users[Auth.meetingID]} />;
};
export default withTracker(() => {

View File

@ -45,6 +45,11 @@ const EmojiButton = styled.button`
z-index: 2;
border: none;
[dir="rtl"] & {
right: initial;
left: -.2em;
}
&:hover {
transform: scale(1.5);
transition-duration: 150ms;
@ -70,6 +75,11 @@ const EmojiButtonSpace = styled.div`
right: -.4em;
bottom: -.2em;
border-radius: 50%;
[dir="rtl"] & {
right: initial;
left: -.4em;
}
`;
export default {

View File

@ -26,7 +26,7 @@ class BBBMenu extends React.Component {
anchorEl: null,
};
this.opts = props.opts;
this.optsToMerge = {};
this.autoFocus = false;
this.handleClick = this.handleClick.bind(this);
@ -112,7 +112,7 @@ class BBBMenu extends React.Component {
render() {
const { anchorEl } = this.state;
const { trigger, intl, customStyles, dataTest } = this.props;
const { trigger, intl, customStyles, dataTest, opts } = this.props;
const actionsItems = this.makeMenuItems();
let menuStyles = { zIndex: 9999 };
@ -129,7 +129,7 @@ class BBBMenu extends React.Component {
const firefoxInputSource = !([1, 5].includes(e.nativeEvent.mozInputSource)); // 1 = mouse, 5 = touch (firefox only)
const chromeInputSource = !(['mouse', 'touch'].includes(e.nativeEvent.pointerType));
this.opts.autoFocus = firefoxInputSource && chromeInputSource;
this.optsToMerge.autoFocus = firefoxInputSource && chromeInputSource;
this.handleClick(e);
}}
onKeyPress={(e) => {
@ -144,7 +144,8 @@ class BBBMenu extends React.Component {
</div>
<Menu
{...this.opts}
{...opts}
{...this.optsToMerge}
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={this.handleClose}

View File

@ -6,8 +6,8 @@ export const INITIAL_INPUT_STATE = {
},
browser: {
width: 0,
height: 0,
width: window.document.documentElement.clientWidth,
height: window.document.documentElement.clientHeight,
},
bannerBar: {
hasBanner: false,

View File

@ -279,9 +279,10 @@ class SettingsDropdown extends PureComponent {
shortcuts: OPEN_OPTIONS_AK,
isDropdownOpen,
isMobile,
isRTL,
} = this.props;
const customStyles = { top: '3rem' };
const customStyles = { top: '1rem' };
return (
<BBBMenu
@ -302,6 +303,16 @@ class SettingsDropdown extends PureComponent {
/>
)}
actions={this.renderMenuItems()}
opts={{
id: "default-dropdown-menu",
keepMounted: true,
transitionDuration: 0,
elevation: 3,
getContentAnchorEl: null,
fullwidth: "true",
anchorOrigin: { vertical: 'bottom', horizontal: isRTL ? 'left' : 'right' },
transformorigin: { vertical: 'top', horizontal: isRTL ? 'left' : 'right' },
}}
/>
);
}

View File

@ -5,7 +5,7 @@ import browserInfo from '/imports/utils/browserInfo';
import SettingsDropdown from './component';
import FullscreenService from '/imports/ui/components/common/fullscreen-button/service';
import { meetingIsBreakout } from '/imports/ui/components/app/service';
import { layoutSelectInput } from '../../layout/context';
import { layoutSelectInput, layoutSelect } from '../../layout/context';
import { SMALL_VIEWPORT_BREAKPOINT } from '../../layout/enums';
const { isIphone } = deviceInfo;
@ -16,9 +16,10 @@ const noIOSFullscreen = !!(((isSafari && !isValidSafariVersion) || isIphone));
const SettingsDropdownContainer = (props) => {
const { width: browserWidth } = layoutSelectInput((i) => i.browser);
const isMobile = browserWidth <= SMALL_VIEWPORT_BREAKPOINT;
const isRTL = layoutSelect((i) => i.isRTL);
return (
<SettingsDropdown {...{ isMobile, ...props }} />
<SettingsDropdown {...{ isMobile, isRTL, ...props }} />
);
};

View File

@ -343,7 +343,7 @@ class UserOptions extends PureComponent {
}
render() {
const { intl } = this.props;
const { intl, isRTL } = this.props;
return (
<BBBMenu
@ -360,6 +360,16 @@ class UserOptions extends PureComponent {
/>
)}
actions={this.renderMenuItems()}
opts={{
id: "default-dropdown-menu",
keepMounted: true,
transitionDuration: 0,
elevation: 3,
getContentAnchorEl: null,
fullwidth: "true",
anchorOrigin: { vertical: 'bottom', horizontal: isRTL ? 'right' : 'left' },
transformOrigin: { vertical: 'top', horizontal: isRTL ? 'right' : 'left' },
}}
/>
);
}

View File

@ -10,6 +10,7 @@ import logger from '/imports/startup/client/logger';
import { defineMessages, injectIntl } from 'react-intl';
import { notify } from '/imports/ui/services/notification';
import UserOptions from './component';
import { layoutSelect } from '/imports/ui/components/layout/context';
const propTypes = {
users: PropTypes.arrayOf(Object).isRequired,
@ -60,6 +61,8 @@ const UserOptionsContainer = withTracker((props) => {
return name;
};
const isRTL = layoutSelect((i) => i.isRTL);
return {
toggleMuteAllUsers: () => {
UserListService.muteAllUsers(Auth.userID);
@ -92,6 +95,7 @@ const UserOptionsContainer = withTracker((props) => {
meetingName: getMeetingName(),
openLearningDashboardUrl: LearningDashboardService.openLearningDashboardUrl,
dynamicGuestPolicy,
isRTL,
};
})(UserOptions);

View File

@ -17,7 +17,7 @@ import Styled from './styles';
const VideoListItem = (props) => {
const {
name, voiceUser, isFullscreenContext, layoutContextDispatch, user, onHandleVideoFocus,
cameraId, numOfStreams, focused, onVideoItemMount, onVideoItemUnmount,
cameraId, numOfStreams, focused, onVideoItemMount, onVideoItemUnmount, isRTL,
} = props;
const [videoIsReady, setVideoIsReady] = useState(false);
@ -124,6 +124,7 @@ const VideoListItem = (props) => {
onHandleVideoFocus={onHandleVideoFocus}
focused={focused}
onHandleMirror={() => setIsMirrored((value) => !value)}
isRTL={isRTL}
/>
<UserStatus
voiceUser={voiceUser}

View File

@ -13,6 +13,7 @@ const VideoListItemContainer = (props) => {
const { element } = fullscreen;
const isFullscreenContext = (element === cameraId);
const layoutContextDispatch = layoutDispatch();
const isRTL = layoutSelect((i) => i.isRTL);
return (
<VideoListItem
@ -20,6 +21,7 @@ const VideoListItemContainer = (props) => {
{...{
isFullscreenContext,
layoutContextDispatch,
isRTL,
}}
/>
);

View File

@ -41,7 +41,8 @@ const intlMessages = defineMessages({
const UserActions = (props) => {
const {
name, cameraId, numOfStreams, onHandleVideoFocus, user, focused, onHandleMirror,
name, cameraId, numOfStreams, onHandleVideoFocus,
user, focused, onHandleMirror, isRTL,
} = props;
const intl = useIntl();
@ -103,8 +104,8 @@ const UserActions = (props) => {
elevation: 3,
getContentAnchorEl: null,
fullwidth: 'true',
anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
transformorigin: { vertical: 'bottom', horizontal: 'left' },
anchorOrigin: { vertical: 'bottom', horizontal: isRTL ? 'right' : 'left' },
transformOrigin: { vertical: 'top', horizontal: isRTL ? 'right' : 'left' },
}}
/>
)