From 2eddb6ca01dc17d41ee0601d3803461471cb78d4 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Tue, 12 Nov 2019 11:24:14 +0000
Subject: [PATCH] DRY context menu placement algorithms
---
src/components/structures/ContextualMenu.js | 8 +++
src/components/views/elements/TagTile.js | 11 +---
.../views/groups/GroupInviteTile.js | 10 +---
.../views/messages/MessageActionBar.js | 60 +++++++------------
src/components/views/rooms/RoomTile.js | 10 +---
5 files changed, 36 insertions(+), 63 deletions(-)
diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js
index 6d046c08d4..c172daf991 100644
--- a/src/components/structures/ContextualMenu.js
+++ b/src/components/structures/ContextualMenu.js
@@ -559,6 +559,14 @@ MenuItemRadio.propTypes = {
onClick: PropTypes.func.isRequired,
};
+// Placement method for to position context menu to right of elementRect with chevronOffset
+export const toRightOf = (elementRect, chevronOffset=12) => {
+ const left = elementRect.right + window.pageXOffset + 3;
+ let top = (elementRect.top + (elementRect.height / 2) + window.pageYOffset);
+ top = top - (chevronOffset + 8); // where 8 is half the height of the chevron
+ return {left, top};
+};
+
export function createMenu(ElementClass, props, hasBackground=true) {
const closeMenu = function(...args) {
ReactDOM.unmountComponentAtNode(getOrCreateContainer());
diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js
index 03d7f61204..c9afd487cb 100644
--- a/src/components/views/elements/TagTile.js
+++ b/src/components/views/elements/TagTile.js
@@ -29,7 +29,7 @@ import * as FormattingUtils from '../../../utils/FormattingUtils';
import FlairStore from '../../../stores/FlairStore';
import GroupStore from '../../../stores/GroupStore';
import TagOrderStore from '../../../stores/TagOrderStore';
-import {ContextMenu} from "../../structures/ContextualMenu";
+import {ContextMenu, toRightOf} from "../../structures/ContextualMenu";
// A class for a child of TagPanel (possibly wrapped in a DNDTagTile) that represents
// a thing to click on for the user to filter the visible rooms in the RoomList to:
@@ -176,16 +176,9 @@ export default createReactClass({
let contextMenu;
if (this.state.menuDisplayed) {
const elementRect = this._contextMenuButton.current.getBoundingClientRect();
-
- // The window X and Y offsets are to adjust position when zoomed in to page
- const left = elementRect.right + window.pageXOffset + 3;
- const chevronOffset = 12;
- let top = (elementRect.top + (elementRect.height / 2) + window.pageYOffset);
- top = top - (chevronOffset + 8); // where 8 is half the height of the chevron
-
const TagTileContextMenu = sdk.getComponent('context_menus.TagTileContextMenu');
contextMenu = (
-
+
);
diff --git a/src/components/views/groups/GroupInviteTile.js b/src/components/views/groups/GroupInviteTile.js
index 99427acb03..cfc50cc008 100644
--- a/src/components/views/groups/GroupInviteTile.js
+++ b/src/components/views/groups/GroupInviteTile.js
@@ -24,7 +24,7 @@ import sdk from '../../../index';
import dis from '../../../dispatcher';
import classNames from 'classnames';
import MatrixClientPeg from "../../../MatrixClientPeg";
-import {ContextMenu} from "../../structures/ContextualMenu";
+import {ContextMenu, toRightOf} from "../../structures/ContextualMenu";
export default createReactClass({
displayName: 'GroupInviteTile',
@@ -144,15 +144,9 @@ export default createReactClass({
let contextMenu;
if (this.state.menuDisplayed) {
const elementRect = this._contextMenuButton.current.getBoundingClientRect();
- // The window X and Y offsets are to adjust position when zoomed in to page
- const left = elementRect.right + window.pageXOffset + 3;
- const chevronOffset = 12;
- let top = (elementRect.top + (elementRect.height / 2) + window.pageYOffset);
- top = top - (chevronOffset + 8); // where 8 is half the height of the chevron
-
const GroupInviteTileContextMenu = sdk.getComponent('context_menus.GroupInviteTileContextMenu');
contextMenu = (
-
+
);
diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js
index b67107eebf..d59e74623a 100644
--- a/src/components/views/messages/MessageActionBar.js
+++ b/src/components/views/messages/MessageActionBar.js
@@ -27,6 +27,26 @@ import {ContextMenu} from '../../structures/ContextualMenu';
import { isContentActionable, canEditContent } from '../../../utils/EventUtils';
import {RoomContext} from "../../structures/RoomView";
+const contextMenuProps = (elementRect) => {
+ const menuOptions = {
+ chevronFace: "none",
+ };
+
+ const buttonRight = elementRect.right + window.pageXOffset;
+ const buttonBottom = elementRect.bottom + window.pageYOffset;
+ const buttonTop = elementRect.top + window.pageYOffset;
+ // Align the right edge of the menu to the right edge of the button
+ menuOptions.right = window.innerWidth - buttonRight;
+ // Align the menu vertically on whichever side of the button has more space available.
+ if (buttonBottom < window.innerHeight / 2) {
+ menuOptions.top = buttonBottom;
+ } else {
+ menuOptions.bottom = window.innerHeight - buttonTop;
+ }
+
+ return menuOptions;
+};
+
const useContextMenu = () => {
const _button = useRef(null);
const [isOpen, setIsOpen] = useState(false);
@@ -65,26 +85,8 @@ const OptionsButton = ({mxEvent, getTile, getReplyThread, permalinkCreator, onFo
e2eInfoCallback = onCryptoClick;
}
- const menuOptions = {
- chevronFace: "none",
- };
-
const buttonRect = _button.current.getBoundingClientRect();
- // The window X and Y offsets are to adjust position when zoomed in to page
- const buttonRight = buttonRect.right + window.pageXOffset;
- const buttonBottom = buttonRect.bottom + window.pageYOffset;
- const buttonTop = buttonRect.top + window.pageYOffset;
- // Align the right edge of the menu to the right edge of the button
- menuOptions.right = window.innerWidth - buttonRight;
- // Align the menu vertically on whichever side of the button has more
- // space available.
- if (buttonBottom < window.innerHeight / 2) {
- menuOptions.top = buttonBottom;
- } else {
- menuOptions.bottom = window.innerHeight - buttonTop;
- }
-
- contextMenu =
+ contextMenu =
{
let contextMenu;
if (menuDisplayed) {
- const menuOptions = {
- chevronFace: "none",
- };
-
const buttonRect = _button.current.getBoundingClientRect();
- // The window X and Y offsets are to adjust position when zoomed in to page
- const buttonRight = buttonRect.right + window.pageXOffset;
- const buttonBottom = buttonRect.bottom + window.pageYOffset;
- const buttonTop = buttonRect.top + window.pageYOffset;
- // Align the right edge of the menu to the right edge of the button
- menuOptions.right = window.innerWidth - buttonRight;
- // Align the menu vertically on whichever side of the button has more
- // space available.
- if (buttonBottom < window.innerHeight / 2) {
- menuOptions.top = buttonBottom;
- } else {
- menuOptions.bottom = window.innerHeight - buttonTop;
- }
-
const ReactionPicker = sdk.getComponent('emojipicker.ReactionPicker');
- contextMenu =
+ contextMenu =
;
}
diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js
index 9702b24eff..edd50d0330 100644
--- a/src/components/views/rooms/RoomTile.js
+++ b/src/components/views/rooms/RoomTile.js
@@ -25,7 +25,7 @@ import dis from '../../../dispatcher';
import MatrixClientPeg from '../../../MatrixClientPeg';
import DMRoomMap from '../../../utils/DMRoomMap';
import sdk from '../../../index';
-import {ContextMenu} from '../../structures/ContextualMenu';
+import {ContextMenu, toRightOf} from '../../structures/ContextualMenu';
import * as RoomNotifs from '../../../RoomNotifs';
import * as FormattingUtils from '../../../utils/FormattingUtils';
import ActiveRoomObserver from '../../../ActiveRoomObserver';
@@ -379,15 +379,9 @@ module.exports = createReactClass({
let contextMenu;
if (this.state.menuDisplayed) {
const elementRect = this._contextMenuButton.current.getBoundingClientRect();
- // The window X and Y offsets are to adjust position when zoomed in to page
- const left = elementRect.right + window.pageXOffset + 3;
- const chevronOffset = 12;
- let top = (elementRect.top + (elementRect.height / 2) + window.pageYOffset);
- top = top - (chevronOffset + 8); // where 8 is half the height of the chevron
-
const RoomTileContextMenu = sdk.getComponent('context_menus.RoomTileContextMenu');
contextMenu = (
-
+
);