Avoid errant scroll on context menu hide
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
diff --git a/node_modules/react-contextmenu/modules/ContextMenu.js b/node_modules/react-contextmenu/modules/ContextMenu.js
|
diff --git a/node_modules/react-contextmenu/modules/ContextMenu.js b/node_modules/react-contextmenu/modules/ContextMenu.js
|
||||||
index 2f88213..4cf584a 100644
|
index 2f88213..41e47ea 100644
|
||||||
--- a/node_modules/react-contextmenu/modules/ContextMenu.js
|
--- a/node_modules/react-contextmenu/modules/ContextMenu.js
|
||||||
+++ b/node_modules/react-contextmenu/modules/ContextMenu.js
|
+++ b/node_modules/react-contextmenu/modules/ContextMenu.js
|
||||||
@@ -81,6 +81,11 @@ var ContextMenu = function (_AbstractMenu) {
|
@@ -81,6 +81,11 @@ var ContextMenu = function (_AbstractMenu) {
|
||||||
@@ -35,13 +35,15 @@ index 2f88213..4cf584a 100644
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -248,6 +259,14 @@ var ContextMenu = function (_AbstractMenu) {
|
@@ -248,6 +259,16 @@ var ContextMenu = function (_AbstractMenu) {
|
||||||
if (!_this2.menu) return;
|
if (!_this2.menu) return;
|
||||||
_this2.menu.style.opacity = 0;
|
_this2.menu.style.opacity = 0;
|
||||||
_this2.menu.style.pointerEvents = 'none';
|
_this2.menu.style.pointerEvents = 'none';
|
||||||
+
|
+
|
||||||
+ // Return to the previous focus state when dismissing the menu, unless the
|
+ // Return to the previous focus state when dismissing the menu, unless the
|
||||||
+ // menu option focused another element. This is important for keyboard mode.
|
+ // menu option focused another element. This is important for keyboard mode.
|
||||||
|
+ if (_this2.props.avoidFocusRestoreOnBlur) return;
|
||||||
|
+
|
||||||
+ var isFocusWithinMenu = _this2.menu.contains(document.activeElement);
|
+ var isFocusWithinMenu = _this2.menu.contains(document.activeElement);
|
||||||
+ if (isFocusWithinMenu && _this2.previousFocus && _this2.previousFocus.focus) {
|
+ if (isFocusWithinMenu && _this2.previousFocus && _this2.previousFocus.focus) {
|
||||||
+ _this2.previousFocus.focus();
|
+ _this2.previousFocus.focus();
|
||||||
@@ -139,3 +141,15 @@ index ad1dc70..c919be8 100644
|
|||||||
this.subMenu.classList.remove(_helpers.cssClasses.menuVisible);
|
this.subMenu.classList.remove(_helpers.cssClasses.menuVisible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
diff --git a/node_modules/react-contextmenu/src/index.d.ts b/node_modules/react-contextmenu/src/index.d.ts
|
||||||
|
index 753ce90..c5971a4 100644
|
||||||
|
--- a/node_modules/react-contextmenu/src/index.d.ts
|
||||||
|
+++ b/node_modules/react-contextmenu/src/index.d.ts
|
||||||
|
@@ -14,6 +14,7 @@ declare module "react-contextmenu" {
|
||||||
|
preventHideOnResize?: boolean,
|
||||||
|
preventHideOnScroll?: boolean,
|
||||||
|
style?: React.CSSProperties,
|
||||||
|
+ avoidFocusRestoreOnBlur?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContextMenuTriggerProps {
|
||||||
|
@@ -62,6 +62,7 @@ const getCommonProps = (options: {
|
|||||||
id: 'message-id',
|
id: 'message-id',
|
||||||
conversationId: conversation.id,
|
conversationId: conversation.id,
|
||||||
i18n,
|
i18n,
|
||||||
|
interactionMode: 'mouse',
|
||||||
isNextItemCallingNotification: false,
|
isNextItemCallingNotification: false,
|
||||||
onOutgoingAudioCallInConversation: action(
|
onOutgoingAudioCallInConversation: action(
|
||||||
'onOutgoingAudioCallInConversation'
|
'onOutgoingAudioCallInConversation'
|
||||||
|
@@ -38,6 +38,7 @@ import {
|
|||||||
import { MINUTE } from '../../util/durations';
|
import { MINUTE } from '../../util/durations';
|
||||||
import { isMoreRecentThan } from '../../util/timestamp';
|
import { isMoreRecentThan } from '../../util/timestamp';
|
||||||
import { InAnotherCallTooltip } from './InAnotherCallTooltip';
|
import { InAnotherCallTooltip } from './InAnotherCallTooltip';
|
||||||
|
import type { InteractionModeType } from '../../state/ducks/conversations';
|
||||||
|
|
||||||
export type PropsActionsType = {
|
export type PropsActionsType = {
|
||||||
onOutgoingAudioCallInConversation: (conversationId: string) => void;
|
onOutgoingAudioCallInConversation: (conversationId: string) => void;
|
||||||
@@ -50,6 +51,7 @@ type PropsHousekeeping = {
|
|||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
id: string;
|
id: string;
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
|
interactionMode: InteractionModeType;
|
||||||
isNextItemCallingNotification: boolean;
|
isNextItemCallingNotification: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -120,6 +122,7 @@ export const CallingNotification: React.FC<PropsType> = React.memo(
|
|||||||
<MessageContextMenu
|
<MessageContextMenu
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
triggerId={props.id}
|
triggerId={props.id}
|
||||||
|
interactionMode={props.interactionMode}
|
||||||
onDeleteMessage={() => {
|
onDeleteMessage={() => {
|
||||||
props.toggleDeleteMessagesModal({
|
props.toggleDeleteMessagesModal({
|
||||||
conversationId: props.conversationId,
|
conversationId: props.conversationId,
|
||||||
|
@@ -5,6 +5,7 @@ import React, { type RefObject } from 'react';
|
|||||||
import { ContextMenu, MenuItem } from 'react-contextmenu';
|
import { ContextMenu, MenuItem } from 'react-contextmenu';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import type { LocalizerType } from '../../types/I18N';
|
import type { LocalizerType } from '../../types/I18N';
|
||||||
|
import type { InteractionModeType } from '../../state/ducks/conversations';
|
||||||
|
|
||||||
export type ContextMenuTriggerType = {
|
export type ContextMenuTriggerType = {
|
||||||
handleContextClick: (
|
handleContextClick: (
|
||||||
@@ -16,7 +17,7 @@ type MessageContextProps = {
|
|||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
triggerId: string;
|
triggerId: string;
|
||||||
shouldShowAdditional: boolean;
|
shouldShowAdditional: boolean;
|
||||||
|
interactionMode: InteractionModeType;
|
||||||
onDownload: (() => void) | undefined;
|
onDownload: (() => void) | undefined;
|
||||||
onEdit: (() => void) | undefined;
|
onEdit: (() => void) | undefined;
|
||||||
onReplyToMessage: (() => void) | undefined;
|
onReplyToMessage: (() => void) | undefined;
|
||||||
@@ -33,6 +34,7 @@ export const MessageContextMenu = ({
|
|||||||
i18n,
|
i18n,
|
||||||
triggerId,
|
triggerId,
|
||||||
shouldShowAdditional,
|
shouldShowAdditional,
|
||||||
|
interactionMode,
|
||||||
onDownload,
|
onDownload,
|
||||||
onEdit,
|
onEdit,
|
||||||
onReplyToMessage,
|
onReplyToMessage,
|
||||||
@@ -46,7 +48,14 @@ export const MessageContextMenu = ({
|
|||||||
onDeleteMessage,
|
onDeleteMessage,
|
||||||
}: MessageContextProps): JSX.Element => {
|
}: MessageContextProps): JSX.Element => {
|
||||||
const menu = (
|
const menu = (
|
||||||
<ContextMenu id={triggerId}>
|
// We avoid restoring focus on this context menu because it is not intended for
|
||||||
|
// keyboard use and restoring focus to the message could cause an unwanted scroll
|
||||||
|
<ContextMenu
|
||||||
|
id={triggerId}
|
||||||
|
// In keyboard mode, we do want to restore focus to the message; the message is very
|
||||||
|
// likely already scrolled into view in this case.
|
||||||
|
avoidFocusRestoreOnBlur={interactionMode !== 'keyboard'}
|
||||||
|
>
|
||||||
{shouldShowAdditional && (
|
{shouldShowAdditional && (
|
||||||
<>
|
<>
|
||||||
{onDownload && (
|
{onDownload && (
|
||||||
|
@@ -286,6 +286,7 @@ export const TimelineItem = memo(function TimelineItem({
|
|||||||
<CallingNotification
|
<CallingNotification
|
||||||
id={id}
|
id={id}
|
||||||
conversationId={conversationId}
|
conversationId={conversationId}
|
||||||
|
interactionMode={reducedProps.interactionMode}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
isNextItemCallingNotification={isNextItemCallingNotification}
|
isNextItemCallingNotification={isNextItemCallingNotification}
|
||||||
onOutgoingAudioCallInConversation={onOutgoingAudioCallInConversation}
|
onOutgoingAudioCallInConversation={onOutgoingAudioCallInConversation}
|
||||||
|
@@ -365,6 +365,7 @@ export function TimelineMessage(props: Props): JSX.Element {
|
|||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
triggerId={triggerId}
|
triggerId={triggerId}
|
||||||
shouldShowAdditional={shouldShowAdditional}
|
shouldShowAdditional={shouldShowAdditional}
|
||||||
|
interactionMode={props.interactionMode}
|
||||||
onDownload={handleDownload}
|
onDownload={handleDownload}
|
||||||
onEdit={
|
onEdit={
|
||||||
canEditMessage
|
canEditMessage
|
||||||
|
Reference in New Issue
Block a user