Merge pull request #15008 from JoVictorNunes/fix-popover-menu
[2.5] fix: popover menus in RTL mode
This commit is contained in:
commit
226abc4bd1
@ -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' },
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -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,
|
||||
}}
|
||||
/>
|
||||
|
@ -79,9 +79,9 @@ class AudioControls extends PureComponent {
|
||||
}
|
||||
|
||||
static renderLeaveButtonWithLiveStreamSelector(props) {
|
||||
const { handleLeaveAudio } = props;
|
||||
const { handleLeaveAudio, isRTL } = props;
|
||||
return (
|
||||
<InputStreamLiveSelectorContainer {...{ handleLeaveAudio }} />
|
||||
<InputStreamLiveSelectorContainer {...{ handleLeaveAudio, isRTL }} />
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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 = () => {
|
||||
|
@ -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' },
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -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()}
|
||||
/>
|
||||
|
@ -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>
|
||||
|
@ -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 }}
|
||||
/>;
|
||||
};
|
||||
|
||||
|
@ -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()}
|
||||
/>
|
||||
|
@ -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(() => {
|
||||
|
@ -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 {
|
||||
|
@ -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}
|
||||
|
@ -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,
|
||||
|
@ -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' },
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -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 }} />
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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' },
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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}
|
||||
|
@ -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,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -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' },
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user