Put the right-click message context menu to the right (#8339)
* Improve `alwaysAboveRightOf()` typing Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com> * Improve typing of `alwaysAboveLeftOf()` Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com> * Add `aboveRightOf()` Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com> * Use `aboveRightOf()` Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com> * Fix typo Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
parent
741b13ab6f
commit
7c41b8612d
2 changed files with 38 additions and 6 deletions
|
@ -450,9 +450,37 @@ export const aboveLeftOf = (
|
||||||
return menuOptions;
|
return menuOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Placement method for <ContextMenu /> to position context menu right-aligned and flowing to the right of elementRect,
|
||||||
|
// and either above or below: wherever there is more space (maybe this should be aboveOrBelowRightOf?)
|
||||||
|
export const aboveRightOf = (
|
||||||
|
elementRect: Pick<DOMRect, "left" | "top" | "bottom">,
|
||||||
|
chevronFace = ChevronFace.None,
|
||||||
|
vPadding = 0,
|
||||||
|
): AboveLeftOf => {
|
||||||
|
const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace };
|
||||||
|
|
||||||
|
const buttonLeft = elementRect.left + window.pageXOffset;
|
||||||
|
const buttonBottom = elementRect.bottom + window.pageYOffset;
|
||||||
|
const buttonTop = elementRect.top + window.pageYOffset;
|
||||||
|
// Align the left edge of the menu to the left edge of the button
|
||||||
|
menuOptions.left = buttonLeft;
|
||||||
|
// Align the menu vertically on whichever side of the button has more space available.
|
||||||
|
if (buttonBottom < UIStore.instance.windowHeight / 2) {
|
||||||
|
menuOptions.top = buttonBottom + vPadding;
|
||||||
|
} else {
|
||||||
|
menuOptions.bottom = (UIStore.instance.windowHeight - buttonTop) + vPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
return menuOptions;
|
||||||
|
};
|
||||||
|
|
||||||
// Placement method for <ContextMenu /> to position context menu right-aligned and flowing to the left of elementRect
|
// Placement method for <ContextMenu /> to position context menu right-aligned and flowing to the left of elementRect
|
||||||
// and always above elementRect
|
// and always above elementRect
|
||||||
export const alwaysAboveLeftOf = (elementRect: DOMRect, chevronFace = ChevronFace.None, vPadding = 0) => {
|
export const alwaysAboveLeftOf = (
|
||||||
|
elementRect: Pick<DOMRect, "right" | "bottom" | "top">,
|
||||||
|
chevronFace = ChevronFace.None,
|
||||||
|
vPadding = 0,
|
||||||
|
) => {
|
||||||
const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace };
|
const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace };
|
||||||
|
|
||||||
const buttonRight = elementRect.right + window.pageXOffset;
|
const buttonRight = elementRect.right + window.pageXOffset;
|
||||||
|
@ -472,7 +500,11 @@ export const alwaysAboveLeftOf = (elementRect: DOMRect, chevronFace = ChevronFac
|
||||||
|
|
||||||
// Placement method for <ContextMenu /> to position context menu right-aligned and flowing to the right of elementRect
|
// Placement method for <ContextMenu /> to position context menu right-aligned and flowing to the right of elementRect
|
||||||
// and always above elementRect
|
// and always above elementRect
|
||||||
export const alwaysAboveRightOf = (elementRect: DOMRect, chevronFace = ChevronFace.None, vPadding = 0) => {
|
export const alwaysAboveRightOf = (
|
||||||
|
elementRect: Pick<DOMRect, "left" | "top">,
|
||||||
|
chevronFace = ChevronFace.None,
|
||||||
|
vPadding = 0,
|
||||||
|
) => {
|
||||||
const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace };
|
const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace };
|
||||||
|
|
||||||
const buttonLeft = elementRect.left + window.pageXOffset;
|
const buttonLeft = elementRect.left + window.pageXOffset;
|
||||||
|
|
|
@ -39,7 +39,7 @@ import { E2EState } from "./E2EIcon";
|
||||||
import { toRem } from "../../../utils/units";
|
import { toRem } from "../../../utils/units";
|
||||||
import RoomAvatar from "../avatars/RoomAvatar";
|
import RoomAvatar from "../avatars/RoomAvatar";
|
||||||
import MessageContextMenu, { IEventTileOps } from "../context_menus/MessageContextMenu";
|
import MessageContextMenu, { IEventTileOps } from "../context_menus/MessageContextMenu";
|
||||||
import { aboveLeftOf } from '../../structures/ContextMenu';
|
import { aboveRightOf } from '../../structures/ContextMenu';
|
||||||
import { objectHasDiff } from "../../../utils/objects";
|
import { objectHasDiff } from "../../../utils/objects";
|
||||||
import Tooltip from "../elements/Tooltip";
|
import Tooltip from "../elements/Tooltip";
|
||||||
import EditorStateTransfer from "../../../utils/EditorStateTransfer";
|
import EditorStateTransfer from "../../../utils/EditorStateTransfer";
|
||||||
|
@ -230,7 +230,7 @@ interface IState {
|
||||||
|
|
||||||
// Position of the context menu
|
// Position of the context menu
|
||||||
contextMenu?: {
|
contextMenu?: {
|
||||||
position: Pick<DOMRect, "right" | "top" | "bottom">;
|
position: Pick<DOMRect, "top" | "left" | "bottom">;
|
||||||
showPermalink?: boolean;
|
showPermalink?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -972,7 +972,7 @@ export class UnwrappedEventTile extends React.Component<IProps, IState> {
|
||||||
this.setState({
|
this.setState({
|
||||||
contextMenu: {
|
contextMenu: {
|
||||||
position: {
|
position: {
|
||||||
right: ev.clientX,
|
left: ev.clientX,
|
||||||
top: ev.clientY,
|
top: ev.clientY,
|
||||||
bottom: ev.clientY,
|
bottom: ev.clientY,
|
||||||
},
|
},
|
||||||
|
@ -1017,7 +1017,7 @@ export class UnwrappedEventTile extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MessageContextMenu
|
<MessageContextMenu
|
||||||
{...aboveLeftOf(this.state.contextMenu.position)}
|
{...aboveRightOf(this.state.contextMenu.position)}
|
||||||
mxEvent={this.props.mxEvent}
|
mxEvent={this.props.mxEvent}
|
||||||
permalinkCreator={this.props.permalinkCreator}
|
permalinkCreator={this.props.permalinkCreator}
|
||||||
eventTileOps={eventTileOps}
|
eventTileOps={eventTileOps}
|
||||||
|
|
Loading…
Reference in a new issue