diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx
index c84452a264..a3c214eb45 100644
--- a/src/components/structures/ContextMenu.tsx
+++ b/src/components/structures/ContextMenu.tsx
@@ -450,9 +450,37 @@ export const aboveLeftOf = (
return menuOptions;
};
+// Placement method for 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,
+ 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 to position context menu right-aligned and flowing to the left of elementRect
// and always above elementRect
-export const alwaysAboveLeftOf = (elementRect: DOMRect, chevronFace = ChevronFace.None, vPadding = 0) => {
+export const alwaysAboveLeftOf = (
+ elementRect: Pick,
+ chevronFace = ChevronFace.None,
+ vPadding = 0,
+) => {
const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace };
const buttonRight = elementRect.right + window.pageXOffset;
@@ -472,7 +500,11 @@ export const alwaysAboveLeftOf = (elementRect: DOMRect, chevronFace = ChevronFac
// Placement method for to position context menu right-aligned and flowing to the right of elementRect
// and always above elementRect
-export const alwaysAboveRightOf = (elementRect: DOMRect, chevronFace = ChevronFace.None, vPadding = 0) => {
+export const alwaysAboveRightOf = (
+ elementRect: Pick,
+ chevronFace = ChevronFace.None,
+ vPadding = 0,
+) => {
const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace };
const buttonLeft = elementRect.left + window.pageXOffset;
diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx
index a4eec106d8..9d5dc2cefe 100644
--- a/src/components/views/rooms/EventTile.tsx
+++ b/src/components/views/rooms/EventTile.tsx
@@ -39,7 +39,7 @@ import { E2EState } from "./E2EIcon";
import { toRem } from "../../../utils/units";
import RoomAvatar from "../avatars/RoomAvatar";
import MessageContextMenu, { IEventTileOps } from "../context_menus/MessageContextMenu";
-import { aboveLeftOf } from '../../structures/ContextMenu';
+import { aboveRightOf } from '../../structures/ContextMenu';
import { objectHasDiff } from "../../../utils/objects";
import Tooltip from "../elements/Tooltip";
import EditorStateTransfer from "../../../utils/EditorStateTransfer";
@@ -230,7 +230,7 @@ interface IState {
// Position of the context menu
contextMenu?: {
- position: Pick;
+ position: Pick;
showPermalink?: boolean;
};
@@ -972,7 +972,7 @@ export class UnwrappedEventTile extends React.Component {
this.setState({
contextMenu: {
position: {
- right: ev.clientX,
+ left: ev.clientX,
top: ev.clientY,
bottom: ev.clientY,
},
@@ -1017,7 +1017,7 @@ export class UnwrappedEventTile extends React.Component {
return (