Fix positioning of the thread context menu (#7918)
This commit is contained in:
parent
b02d5ecb97
commit
115e17b097
2 changed files with 15 additions and 38 deletions
|
@ -260,10 +260,11 @@ export default class ContextMenu extends React.PureComponent<IProps, IState> {
|
||||||
const { windowWidth, windowHeight } = UIStore.instance;
|
const { windowWidth, windowHeight } = UIStore.instance;
|
||||||
if (contextMenuRect) {
|
if (contextMenuRect) {
|
||||||
if (position.top !== undefined) {
|
if (position.top !== undefined) {
|
||||||
position.top = Math.min(
|
let maxTop = windowHeight - WINDOW_PADDING;
|
||||||
position.top,
|
if (!this.props.bottomAligned) {
|
||||||
windowHeight - contextMenuRect.height - WINDOW_PADDING,
|
maxTop -= contextMenuRect.height;
|
||||||
);
|
}
|
||||||
|
position.top = Math.min(position.top, maxTop);
|
||||||
// Adjust the chevron if necessary
|
// Adjust the chevron if necessary
|
||||||
if (chevronOffset.top !== undefined) {
|
if (chevronOffset.top !== undefined) {
|
||||||
chevronOffset.top = props.chevronOffset + props.top - position.top;
|
chevronOffset.top = props.chevronOffset + props.top - position.top;
|
||||||
|
@ -278,10 +279,11 @@ export default class ContextMenu extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (position.left !== undefined) {
|
if (position.left !== undefined) {
|
||||||
position.left = Math.min(
|
let maxLeft = windowWidth - WINDOW_PADDING;
|
||||||
position.left,
|
if (!this.props.rightAligned) {
|
||||||
windowWidth - contextMenuRect.width - WINDOW_PADDING,
|
maxLeft -= contextMenuRect.width;
|
||||||
);
|
}
|
||||||
|
position.left = Math.min(position.left, maxLeft);
|
||||||
if (chevronOffset.left !== undefined) {
|
if (chevronOffset.left !== undefined) {
|
||||||
chevronOffset.left = props.chevronOffset + props.left - position.left;
|
chevronOffset.left = props.chevronOffset + props.left - position.left;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { RefObject, useCallback, useEffect } from "react";
|
import React, { useCallback, useEffect } from "react";
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src";
|
import { MatrixEvent } from "matrix-js-sdk/src";
|
||||||
|
|
||||||
import { ButtonEvent } from "../elements/AccessibleButton";
|
import { ButtonEvent } from "../elements/AccessibleButton";
|
||||||
|
@ -27,7 +27,6 @@ import { _t } from "../../../languageHandler";
|
||||||
import IconizedContextMenu, { IconizedContextMenuOption, IconizedContextMenuOptionList } from "./IconizedContextMenu";
|
import IconizedContextMenu, { IconizedContextMenuOption, IconizedContextMenuOptionList } from "./IconizedContextMenu";
|
||||||
import { WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
|
import { WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
|
||||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
import { useRovingTabIndex } from "../../../accessibility/RovingTabIndex";
|
|
||||||
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
@ -36,13 +35,6 @@ interface IProps {
|
||||||
onMenuToggle?: (open: boolean) => void;
|
onMenuToggle?: (open: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IExtendedProps extends IProps {
|
|
||||||
// Props for making the button into a roving one
|
|
||||||
tabIndex?: number;
|
|
||||||
inputRef?: RefObject<HTMLElement>;
|
|
||||||
onFocus?(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const contextMenuBelow = (elementRect: DOMRect) => {
|
const contextMenuBelow = (elementRect: DOMRect) => {
|
||||||
// align the context menu's icons with the icon which opened the context menu
|
// align the context menu's icons with the icon which opened the context menu
|
||||||
const left = elementRect.left + window.pageXOffset + elementRect.width;
|
const left = elementRect.left + window.pageXOffset + elementRect.width;
|
||||||
|
@ -51,27 +43,13 @@ const contextMenuBelow = (elementRect: DOMRect) => {
|
||||||
return { left, top, chevronFace };
|
return { left, top, chevronFace };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RovingThreadListContextMenu: React.FC<IProps> = (props) => {
|
const ThreadListContextMenu: React.FC<IProps> = ({
|
||||||
const [onFocus, isActive, ref] = useRovingTabIndex();
|
|
||||||
|
|
||||||
return <ThreadListContextMenu
|
|
||||||
{...props}
|
|
||||||
onFocus={onFocus}
|
|
||||||
tabIndex={isActive ? 0 : -1}
|
|
||||||
inputRef={ref}
|
|
||||||
/>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ThreadListContextMenu: React.FC<IExtendedProps> = ({
|
|
||||||
mxEvent,
|
mxEvent,
|
||||||
permalinkCreator,
|
permalinkCreator,
|
||||||
onMenuToggle,
|
onMenuToggle,
|
||||||
onFocus,
|
|
||||||
inputRef,
|
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const [menuDisplayed, _ref, openMenu, closeThreadOptions] = useContextMenu();
|
const [menuDisplayed, button, openMenu, closeThreadOptions] = useContextMenu();
|
||||||
const button = inputRef ?? _ref; // prefer the ref we receive via props in case we are being controlled
|
|
||||||
|
|
||||||
const viewInRoom = useCallback((evt: ButtonEvent): void => {
|
const viewInRoom = useCallback((evt: ButtonEvent): void => {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
@ -95,11 +73,8 @@ const ThreadListContextMenu: React.FC<IExtendedProps> = ({
|
||||||
}, [mxEvent, closeThreadOptions, permalinkCreator]);
|
}, [mxEvent, closeThreadOptions, permalinkCreator]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (onMenuToggle) {
|
onMenuToggle?.(menuDisplayed);
|
||||||
onMenuToggle(menuDisplayed);
|
}, [menuDisplayed, onMenuToggle]);
|
||||||
}
|
|
||||||
onFocus?.();
|
|
||||||
}, [menuDisplayed, onMenuToggle, onFocus]);
|
|
||||||
|
|
||||||
const isMainSplitTimelineShown = !WidgetLayoutStore.instance.hasMaximisedWidget(
|
const isMainSplitTimelineShown = !WidgetLayoutStore.instance.hasMaximisedWidget(
|
||||||
MatrixClientPeg.get().getRoom(mxEvent.getRoomId()),
|
MatrixClientPeg.get().getRoom(mxEvent.getRoomId()),
|
||||||
|
|
Loading…
Reference in a new issue