Skip to content

Commit

Permalink
[CLNP-6022] fix scroll position issue when switching GroupChannel (#1282
Browse files Browse the repository at this point in the history
)

Fixes https://sendbird.atlassian.net/browse/CLNP-6022

This PR addresses an issue where the scroll position was not correctly
set to the bottom when switching from a channel with few messages to one
with many messages.

The problem was resolved by adding a delay to ensure the scroll
reference is updated before attempting to scroll to the bottom. This
change ensures that users always see the latest messages when switching
channels.
  • Loading branch information
AhyoungRyu authored Dec 10, 2024
1 parent 766d1d7 commit 68e0cb8
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 5 deletions.
7 changes: 4 additions & 3 deletions src/modules/GroupChannel/context/hooks/useGroupChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import useSendbird from '../../../../lib/Sendbird/context/hooks/useSendbird';
import { GroupChannelContext } from '../GroupChannelProvider';
import type { GroupChannelState, MessageActions } from '../types';
import { useMessageActions } from './useMessageActions';
import { delay } from '../../../../utils/utils';

export interface GroupChannelActions extends MessageActions {
// Channel actions
Expand Down Expand Up @@ -69,16 +70,16 @@ export const useGroupChannel = () => {

const scrollToBottom = async (animated?: boolean) => {
if (!state.scrollRef.current) return;
// wait a bit for scroll ref to be updated
await delay();

flagActions.setAnimatedMessageId(null);
flagActions.setIsScrollBottomReached(true);

if (config.isOnline && state.hasNext()) {
await state.resetWithStartingPoint(Number.MAX_SAFE_INTEGER);
state.scrollPubSub.publish('scrollToBottom', { animated });
} else {
state.scrollPubSub.publish('scrollToBottom', { animated });
}
state.scrollPubSub.publish('scrollToBottom', { animated });

if (state.currentChannel && !state.hasNext()) {
state.resetNewMessages();
Expand Down
1 change: 0 additions & 1 deletion src/modules/Thread/context/__test__/useThread.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,6 @@ describe('useThread', () => {
});

await waitFor(() => {
console.log(result.current.state.localThreadMessages[0]);
expect(result.current.state.localThreadMessages[0].messageParams.fileInfoList).toContain(newFileInfo);
});
});
Expand Down
39 changes: 38 additions & 1 deletion src/utils/__tests__/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
isMultipleFilesMessage,
} from '../index';
import { AdminMessage, FileMessage, MultipleFilesMessage, UserMessage } from '@sendbird/chat/message';
import { deleteNullish } from '../utils';
import { delay, deleteNullish } from '../utils';
import { isMobileIOS } from '../browser';

describe('Global-utils: verify message type util functions', () => {
Expand Down Expand Up @@ -234,3 +234,40 @@ describe('deleteNullish', () => {
expect(component({ a: null, b: '3', c: 4 })).toEqual({ a: 1, b: '3', c: 4 });
});
});

describe('delay', () => {
it('should resolve after the specified time', async () => {
const start = Date.now();
const delayTime = 100;

await delay(delayTime);

const end = Date.now();
const elapsed = end - start;

// Check if the elapsed time is at least the delay time
expect(elapsed).toBeGreaterThanOrEqual(delayTime);
});

it('should resolve immediately for 0 milliseconds', async () => {
const start = Date.now();

await delay(0);

const end = Date.now();
const elapsed = end - start;

// Check if the elapsed time is very small
expect(elapsed).toBeLessThan(10);
});
it('should resolve immediately when no parameter is provided', async () => {
const start = Date.now();

await delay();

const end = Date.now();
const elapsed = end - start;

expect(elapsed).toBeLessThan(10);
});
});
5 changes: 5 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { SendableMessageType } from './index';

/**
* @param ms - milliseconds to delay
* @returns Promise that resolves after the specified time
*/
export const delay = (ms?: number) => new Promise((resolve) => { setTimeout(resolve, ms); });
export const noop = () => {
/** noop * */
};
Expand Down

0 comments on commit 68e0cb8

Please sign in to comment.