Skip to content

Commit

Permalink
chore: improve useJumpToMessage (RocketChat#31907)
Browse files Browse the repository at this point in the history
  • Loading branch information
ggazzo committed Mar 6, 2024
1 parent 939a6fa commit 85fe51a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useToggle } from '@rocket.chat/fuselage-hooks';
import { MessageAvatar } from '@rocket.chat/ui-avatar';
import { useUserId } from '@rocket.chat/ui-contexts';
import type { ComponentProps, ReactElement } from 'react';
import React, { useRef, memo } from 'react';
import React, { memo } from 'react';

import type { MessageActionContext } from '../../../../app/ui-utils/client/lib/MessageAction';
import { useIsMessageHighlight } from '../../../views/room/MessageList/contexts/MessageHighlightContext';
Expand Down Expand Up @@ -51,15 +51,15 @@ const RoomMessage = ({
const editing = useIsMessageHighlight(message._id);
const [displayIgnoredMessage, toggleDisplayIgnoredMessage] = useToggle(false);
const ignored = (ignoredUser || message.ignored) && !displayIgnoredMessage;
const messageRef = useRef(null);
const { openUserCard, triggerProps } = useUserCard();

const selecting = useIsSelecting();
const toggleSelected = useToggleSelect(message._id);
const selected = useIsSelectedMessage(message._id);

useCountSelected();
useJumpToMessage(message._id, messageRef);

const messageRef = useJumpToMessage(message._id);

return (
<Message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useToggle } from '@rocket.chat/fuselage-hooks';
import { MessageAvatar } from '@rocket.chat/ui-avatar';
import { useUserId } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
import React, { memo, useRef } from 'react';
import React, { memo } from 'react';

import type { MessageActionContext } from '../../../../app/ui-utils/client/lib/MessageAction';
import { useIsMessageHighlight } from '../../../views/room/MessageList/contexts/MessageHighlightContext';
Expand All @@ -30,12 +30,10 @@ const ThreadMessage = ({ message, sequential, unread, showUserAvatar }: ThreadMe
const [ignored, toggleIgnoring] = useToggle((message as { ignored?: boolean }).ignored);
const { openUserCard, triggerProps } = useUserCard();

const messageRef = useRef(null);

// Checks if is videoconf message to limit toolbox actions
const messageContext: MessageActionContext = isVideoConfMessage(message) ? 'videoconf-threads' : 'threads';

useJumpToMessage(message._id, messageRef);
const messageRef = useJumpToMessage(message._id);

return (
<Message
Expand Down
81 changes: 44 additions & 37 deletions apps/meteor/client/views/room/MessageList/hooks/useJumpToMessage.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,58 @@
import type { IMessage } from '@rocket.chat/core-typings';
import { useRouter } from '@rocket.chat/ui-contexts';
import type { RefObject } from 'react';
import { useLayoutEffect } from 'react';
import { useCallback } from 'react';

import { useMessageListJumpToMessageParam, useMessageListScroll } from '../../../../components/message/list/MessageListContext';
import { setHighlightMessage, clearHighlightMessage } from '../providers/messageHighlightSubscription';

// this is an arbitrary value so that there's a gap between the header and the message;
const SCROLL_EXTRA_OFFSET = 60;

export const useJumpToMessage = (messageId: IMessage['_id'], messageRef: RefObject<HTMLDivElement>): void => {
export const useJumpToMessage = (messageId: IMessage['_id']) => {
const jumpToMessageParam = useMessageListJumpToMessageParam();
const scroll = useMessageListScroll();
const router = useRouter();

useLayoutEffect(() => {
if (jumpToMessageParam !== messageId || !messageRef.current || !scroll) {
return;
}

setTimeout(() => {
scroll((wrapper) => {
if (!wrapper || !messageRef.current) {
return;
}
const containerRect = wrapper.getBoundingClientRect();
const messageRect = messageRef.current.getBoundingClientRect();

const offset = messageRect.top - containerRect.top;
const scrollPosition = wrapper.scrollTop;
const newScrollPosition = scrollPosition + offset - SCROLL_EXTRA_OFFSET;

return { top: newScrollPosition, behavior: 'smooth' };
});

const search = router.getSearchParameters();
delete search.msg;
router.navigate(
{
pathname: router.getLocationPathname(),
search,
},
{ replace: true },
);

setHighlightMessage(messageId);
setTimeout(clearHighlightMessage, 2000);
}, 500);
}, [messageId, jumpToMessageParam, messageRef, scroll, router]);
const ref = useCallback(
(node: HTMLElement | null) => {
if (!node || !scroll) {
return;
}
setTimeout(() => {
scroll((wrapper) => {
if (!wrapper || !node) {
return;
}
const containerRect = wrapper.getBoundingClientRect();
const messageRect = node.getBoundingClientRect();

const offset = messageRect.top - containerRect.top;
const scrollPosition = wrapper.scrollTop;
const newScrollPosition = scrollPosition + offset - SCROLL_EXTRA_OFFSET;

return { top: newScrollPosition, behavior: 'smooth' };
});

const { msg: _, ...search } = router.getSearchParameters();

router.navigate(
{
pathname: router.getLocationPathname(),
search,
},
{ replace: true },
);

setHighlightMessage(messageId);
setTimeout(clearHighlightMessage, 2000);
}, 500);
},
[messageId, router, scroll],
);

if (jumpToMessageParam !== messageId) {
return undefined;
}

return ref;
};

0 comments on commit 85fe51a

Please sign in to comment.