mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2025-12-20 02:08:57 +00:00
Fix react picker positioning in narrow window
This commit is contained in:
@@ -6,12 +6,6 @@ import type { LocalizerType } from '../../types/I18N.std.js';
|
||||
import { AxoMenuBuilder } from '../../axo/AxoMenuBuilder.dom.js';
|
||||
import { isPinnedMessagesEnabled } from '../../util/isPinnedMessagesEnabled.std.js';
|
||||
|
||||
export type ContextMenuTriggerType = {
|
||||
handleContextClick: (
|
||||
event: React.MouseEvent<HTMLDivElement> | MouseEvent
|
||||
) => void;
|
||||
};
|
||||
|
||||
type MessageContextMenuProps = Readonly<{
|
||||
i18n: LocalizerType;
|
||||
renderer: AxoMenuBuilder.Renderer;
|
||||
|
||||
@@ -3,14 +3,8 @@
|
||||
|
||||
import classNames from 'classnames';
|
||||
import lodash from 'lodash';
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import type { ReactNode, Ref } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Manager, Popper, Reference } from 'react-popper';
|
||||
import type { PreventOverflowModifier } from '@popperjs/core/lib/modifiers/preventOverflow.js';
|
||||
@@ -39,10 +33,7 @@ import type {
|
||||
ForwardMessagesPayload,
|
||||
} from '../../state/ducks/globalModals.preload.js';
|
||||
import { useScrollerLock } from '../../hooks/useScrollLock.dom.js';
|
||||
import {
|
||||
type ContextMenuTriggerType,
|
||||
MessageContextMenu,
|
||||
} from './MessageContextMenu.dom.js';
|
||||
import { MessageContextMenu } from './MessageContextMenu.dom.js';
|
||||
import { ForwardMessagesModalType } from '../ForwardMessagesModal.dom.js';
|
||||
import { useGroupedAndOrderedReactions } from '../../util/groupAndOrderReactions.dom.js';
|
||||
import { isNotNil } from '../../util/isNotNil.std.js';
|
||||
@@ -108,7 +99,6 @@ export type Props = PropsData &
|
||||
export function TimelineMessage(props: Props): JSX.Element {
|
||||
const {
|
||||
attachments,
|
||||
author,
|
||||
canDownload,
|
||||
canCopy,
|
||||
canEditMessage,
|
||||
@@ -149,7 +139,6 @@ export function TimelineMessage(props: Props): JSX.Element {
|
||||
const [reactionPickerRoot, setReactionPickerRoot] = useState<
|
||||
HTMLDivElement | undefined
|
||||
>(undefined);
|
||||
const menuTriggerRef = useRef<ContextMenuTriggerType | null>(null);
|
||||
const [pinMessageDialogOpen, setPinMessageDialogOpen] = useState(false);
|
||||
|
||||
const isWindowWidthNotNarrow =
|
||||
@@ -172,10 +161,6 @@ export function TimelineMessage(props: Props): JSX.Element {
|
||||
};
|
||||
}, [containerElementRef]);
|
||||
|
||||
// This id is what connects our triple-dot click with our associated pop-up menu.
|
||||
// It needs to be unique.
|
||||
const triggerId = String(id || `${author.id}-${timestamp}`);
|
||||
|
||||
const toggleReactionPicker = useCallback(
|
||||
(onlyRemove = false): void => {
|
||||
if (reactionPickerRoot) {
|
||||
@@ -392,10 +377,8 @@ export function TimelineMessage(props: Props): JSX.Element {
|
||||
<Manager>
|
||||
<MessageMenu
|
||||
i18n={i18n}
|
||||
triggerId={triggerId}
|
||||
isWindowWidthNotNarrow={isWindowWidthNotNarrow}
|
||||
direction={direction}
|
||||
menuTriggerRef={menuTriggerRef}
|
||||
onDownload={handleDownload}
|
||||
onReplyToMessage={canReply ? handleReplyToMessage : null}
|
||||
onReact={canReact ? handleReact : null}
|
||||
@@ -433,10 +416,8 @@ export function TimelineMessage(props: Props): JSX.Element {
|
||||
);
|
||||
}, [
|
||||
i18n,
|
||||
triggerId,
|
||||
isWindowWidthNotNarrow,
|
||||
direction,
|
||||
menuTriggerRef,
|
||||
canReply,
|
||||
canReact,
|
||||
handleDownload,
|
||||
@@ -484,9 +465,7 @@ export function TimelineMessage(props: Props): JSX.Element {
|
||||
|
||||
type MessageMenuProps = {
|
||||
i18n: LocalizerType;
|
||||
triggerId: string;
|
||||
isWindowWidthNotNarrow: boolean;
|
||||
menuTriggerRef: Ref<ContextMenuTriggerType>;
|
||||
onDownload: (() => void) | null;
|
||||
onReplyToMessage: (() => void) | null;
|
||||
onReact: (() => void) | null;
|
||||
@@ -595,9 +574,19 @@ function MessageMenu({
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{renderMessageContextMenu(
|
||||
<Reference>
|
||||
{({ ref: popperRef }) => {
|
||||
// Only attach the popper reference to the collapsed menu button if
|
||||
// the reaction button is not visible (it is hidden when the
|
||||
// timeline is narrow)
|
||||
const maybePopperRef = !isWindowWidthNotNarrow
|
||||
? popperRef
|
||||
: undefined;
|
||||
|
||||
return renderMessageContextMenu(
|
||||
'AxoDropdownMenu',
|
||||
<button
|
||||
ref={maybePopperRef}
|
||||
type="button"
|
||||
aria-label={i18n('icu:messageContextMenuButton')}
|
||||
className={classNames(
|
||||
@@ -609,7 +598,9 @@ function MessageMenu({
|
||||
ev.stopPropagation();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
);
|
||||
}}
|
||||
</Reference>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1843,13 +1843,6 @@
|
||||
"updated": "2021-01-20T21:30:08.430Z",
|
||||
"reasonDetail": "Doesn't touch the DOM."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/conversation/TimelineMessage.dom.tsx",
|
||||
"line": " const menuTriggerRef = useRef<ContextMenuTriggerType | null>(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-12-08T20:28:57.595Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/conversation/TypingBubble.dom.tsx",
|
||||
|
||||
Reference in New Issue
Block a user