From 11e0a3a8fa3f77f7babc92330a44633ba3b4c8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 15 Apr 2022 20:12:40 +0200 Subject: [PATCH] Enable the message right-click context menu in the browser (#8336) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Enable the message right-click context menu in the browser Signed-off-by: Šimon Brandner * Move `getSelectedText()` to `strings.ts` Signed-off-by: Šimon Brandner * Move `canCancel()` to `EventUtils.ts` Signed-off-by: Šimon Brandner --- .../views/context_menus/MessageContextMenu.tsx | 14 +++----------- .../views/messages/MessageActionBar.tsx | 4 ++-- src/components/views/rooms/EventTile.tsx | 17 +++++++++++++++-- src/utils/EventUtils.ts | 4 ++++ src/utils/strings.ts | 8 ++++++++ 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/components/views/context_menus/MessageContextMenu.tsx b/src/components/views/context_menus/MessageContextMenu.tsx index 1f7f6ac62c..f77a0dd41e 100644 --- a/src/components/views/context_menus/MessageContextMenu.tsx +++ b/src/components/views/context_menus/MessageContextMenu.tsx @@ -37,7 +37,7 @@ import { ReadPinsEventId } from "../right_panel/types"; import { Action } from "../../../dispatcher/actions"; import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks'; import { ButtonEvent } from '../elements/AccessibleButton'; -import { copyPlaintext } from '../../../utils/strings'; +import { copyPlaintext, getSelectedText } from '../../../utils/strings'; import ContextMenu, { toRightOf } from '../../structures/ContextMenu'; import ReactionPicker from '../emojipicker/ReactionPicker'; import ViewSource from '../../structures/ViewSource'; @@ -54,10 +54,6 @@ import { OpenForwardDialogPayload } from "../../../dispatcher/payloads/OpenForwa import { OpenReportEventDialogPayload } from "../../../dispatcher/payloads/OpenReportEventDialogPayload"; import { createMapSiteLink } from '../../../utils/location'; -export function canCancel(status: EventStatus): boolean { - return status === EventStatus.QUEUED || status === EventStatus.NOT_SENT || status === EventStatus.ENCRYPTING; -} - export interface IEventTileOps { isWidgetHidden(): boolean; unhideWidget(): void; @@ -263,7 +259,7 @@ export default class MessageContextMenu extends React.Component }; private onCopyClick = (): void => { - copyPlaintext(this.getSelectedText()); + copyPlaintext(getSelectedText()); this.closeMenu(); }; @@ -310,10 +306,6 @@ export default class MessageContextMenu extends React.Component }); } - private getSelectedText(): string { - return window.getSelection().toString(); - } - private getPermalink(): string { if (!this.props.permalinkCreator) return; return this.props.permalinkCreator.forEvent(this.props.mxEvent.getId()); @@ -539,7 +531,7 @@ export default class MessageContextMenu extends React.Component ); } - if (rightClick && this.getSelectedText()) { + if (rightClick && getSelectedText()) { copyButton = ( { }; private showContextMenu(ev: React.MouseEvent, showPermalink?: boolean): void { + // Return if message right-click context menu isn't enabled if (!SettingsStore.getValue("feature_message_right_click_context_menu")) return; + + // Return if we're in a browser and click either an a tag or we have + // selected text, as in those cases we want to use the native browser + // menu + const clickTarget = ev.target as HTMLElement; + if ( + !PlatformPeg.get().allowOverridingNativeContextMenus() && + (clickTarget.tagName === "a" || clickTarget.closest("a") || getSelectedText()) + ) return; + // There is no way to copy non-PNG images into clipboard, so we can't // have our own handling for copying images, so we leave it to the // Electron layer (webcontents-handler.ts) if (ev.target instanceof HTMLImageElement) return; - if (!PlatformPeg.get().allowOverridingNativeContextMenus()) return; + + // We don't want to show the menu when editing a message if (this.props.editState) return; + ev.preventDefault(); ev.stopPropagation(); this.setState({ diff --git a/src/utils/EventUtils.ts b/src/utils/EventUtils.ts index 4b626397f9..3aef3eb369 100644 --- a/src/utils/EventUtils.ts +++ b/src/utils/EventUtils.ts @@ -258,3 +258,7 @@ export function editEvent( }); } } + +export function canCancel(status: EventStatus): boolean { + return status === EventStatus.QUEUED || status === EventStatus.NOT_SENT || status === EventStatus.ENCRYPTING; +} diff --git a/src/utils/strings.ts b/src/utils/strings.ts index 1ca7aee630..41f80ed1c5 100644 --- a/src/utils/strings.ts +++ b/src/utils/strings.ts @@ -84,3 +84,11 @@ const collator = new Intl.Collator(); export function compare(a: string, b: string): number { return collator.compare(a, b); } + +/** + * Returns text which has been selected by the user + * @returns the selected text + */ +export function getSelectedText(): string { + return window.getSelection().toString(); +}