Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions apps/meteor/client/hooks/useMergedRefsV2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { MutableRefObject, Ref, RefCallback } from 'react';
import { useCallback } from 'react';

const isRefCallback = <T>(x: unknown): x is RefCallback<T> => typeof x === 'function';
const isMutableRefObject = <T>(x: unknown): x is MutableRefObject<T> => typeof x === 'object';

export const setRef = <T>(ref: Ref<T> | undefined, refValue: T) => {
if (isRefCallback<T>(ref)) {
ref(refValue);
return;
}

if (isMutableRefObject<T>(ref)) {
ref.current = refValue;
}
};

// TODO: backport to fuselage-hooks
/**
* Merges multiple refs into a single ref callback
*
* @param refs The refs to merge.
* @returns The merged ref callback.
*/
export const useMergedRefsV2 = <T>(...refs: (Ref<T> | undefined)[]): RefCallback<T> => {
return useCallback((refValue: T) => {
refs.forEach((ref) => setRef(ref, refValue));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, refs);
};
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ export const useJumpToMessageImperative = () => {
if (!jumpToRef.current || !containerRef.current) {
return;
}
jumpToRef.current.scrollIntoView({
block: 'center',
});

// calculate the scroll position to center the message
// avoiding scrollIntoView because it will can scroll parent elements
containerRef.current.scrollTop =
jumpToRef.current.offsetTop - containerRef.current.clientHeight / 2 + jumpToRef.current.offsetHeight / 2;
}, []);

return {
Expand Down
8 changes: 4 additions & 4 deletions apps/meteor/client/views/room/body/RoomBody.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Box } from '@rocket.chat/fuselage';
import { useMergedRefs } from '@rocket.chat/fuselage-hooks';
import { usePermission, useRole, useSetting, useTranslation, useUser, useUserPreference } from '@rocket.chat/ui-contexts';
import type { MouseEvent, ReactElement } from 'react';
import { memo, useCallback, useMemo } from 'react';
Expand All @@ -16,6 +15,7 @@ import { useReadMessageWindowEvents } from './hooks/useReadMessageWindowEvents';
import { isTruthy } from '../../../../lib/isTruthy';
import { CustomScrollbars } from '../../../components/CustomScrollbars';
import { useEmbeddedLayout } from '../../../hooks/useEmbeddedLayout';
import { useMergedRefsV2 } from '../../../hooks/useMergedRefsV2';
import { BubbleDate } from '../BubbleDate';
import MessageListErrorBoundary from '../MessageList/MessageListErrorBoundary';
import RoomAnnouncement from '../RoomAnnouncement';
Expand Down Expand Up @@ -110,7 +110,7 @@ const RoomBody = (): ReactElement => {

const { innerRef: restoreScrollPositionInnerRef, jumpToRef: jumpToRefRestoreScrollPosition } = useRestoreScrollPosition(room._id);

const jumpToRef = useMergedRefs(
const jumpToRef = useMergedRefsV2(
jumpToRefGetMore,
jumpToRefIsAtBottom,
jumpToRefRestoreScrollPosition,
Expand All @@ -135,7 +135,7 @@ const RoomBody = (): ReactElement => {
isAtBottom,
});

const innerRef = useMergedRefs(
const innerRef = useMergedRefsV2(
dateScrollInnerRef,
restoreScrollPositionInnerRef,
isAtBottomInnerRef,
Expand All @@ -147,7 +147,7 @@ const RoomBody = (): ReactElement => {
jumpToRefGetMoreImperativeInnerRef,
);

const wrapperBoxRefs = useMergedRefs(unreadBarWrapperRef);
const wrapperBoxRefs = useMergedRefsV2(unreadBarWrapperRef);

const handleNavigateToPreviousMessage = useCallback((): void => {
chat.messageEditing.toPreviousMessage();
Expand Down
6 changes: 3 additions & 3 deletions apps/meteor/client/views/room/body/RoomBodyV2.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Box } from '@rocket.chat/fuselage';
import { useMergedRefs } from '@rocket.chat/fuselage-hooks';
import { usePermission, useRole, useSetting, useTranslation, useUser, useUserPreference } from '@rocket.chat/ui-contexts';
import type { MouseEvent, ReactElement } from 'react';
import { memo, useCallback, useMemo } from 'react';

import { isTruthy } from '../../../../lib/isTruthy';
import { CustomScrollbars } from '../../../components/CustomScrollbars';
import { useEmbeddedLayout } from '../../../hooks/useEmbeddedLayout';
import { useMergedRefsV2 } from '../../../hooks/useMergedRefsV2';
import { BubbleDate } from '../BubbleDate';
import { MessageList } from '../MessageList';
import DropTargetOverlay from './DropTargetOverlay';
Expand Down Expand Up @@ -110,7 +110,7 @@ const RoomBody = (): ReactElement => {

const { innerRef: restoreScrollPositionInnerRef, jumpToRef: jumpToRefRestoreScrollPosition } = useRestoreScrollPosition(room._id);

const jumpToRef = useMergedRefs(
const jumpToRef = useMergedRefsV2(
jumpToRefIsAtBottom,
jumpToRefGetMore,
jumpToRefRestoreScrollPosition,
Expand All @@ -135,7 +135,7 @@ const RoomBody = (): ReactElement => {
isAtBottom,
});

const innerRef = useMergedRefs(
const innerRef = useMergedRefsV2(
dateScrollInnerRef,
restoreScrollPositionInnerRef,
isAtBottomInnerRef,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ export function useRestoreScrollPosition(rid: string, wait = 100) {
node.scrollLeft = 30;
}
const handleWrapperScroll = withThrottling({ wait })((event) => {
const store = RoomManager.getStore(rid);
store?.update({ scroll: event.target.scrollTop, atBottom: isAtBottom(event.target, 50) });
});
node.addEventListener('scroll', handleWrapperScroll, { passive: true });
return () => {
handleWrapperScroll.cancel();
node.removeEventListener('scroll', handleWrapperScroll);
};
},
Expand Down
Loading