Skip to content

Commit

Permalink
Merge branch 'release-v11'
Browse files Browse the repository at this point in the history
# Conflicts:
#	CHANGELOG.md
#	package.json
#	yarn.lock
  • Loading branch information
MartinCupela committed Aug 22, 2024
2 parents afcd40f + 1802418 commit 44eab3c
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 51 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,20 @@ TypingIndicator is rendered as a child of MessageListMainPanel

* remove legacy style components ([#2394](https://github.com/GetStream/stream-chat-react/issues/2394)) ([9410153](https://github.com/GetStream/stream-chat-react/commit/94101535d1de9de23a1ab8913423af0e7009bab9))

## [11.23.7](https://github.com/GetStream/stream-chat-react/compare/v11.23.6...v11.23.7) (2024-08-22)


### Bug Fixes

* use the client pagination indicators for ChannelStateContext's hasMore and hasMoreNewer flags ([#2478](https://github.com/GetStream/stream-chat-react/issues/2478)) ([eb13bd5](https://github.com/GetStream/stream-chat-react/commit/eb13bd51ec296f36f9a09edd28704ea2d22f3ed1))

## [11.23.6](https://github.com/GetStream/stream-chat-react/compare/v11.23.5...v11.23.6) (2024-08-15)


### Bug Fixes

* **deps:** drop remark-gfm version ([#2471](https://github.com/GetStream/stream-chat-react/issues/2471)) ([1b359f7](https://github.com/GetStream/stream-chat-react/commit/1b359f7e4a5d4cca6edc3abbd97dee42b55c4a79))

## [11.23.5](https://github.com/GetStream/stream-chat-react/compare/v11.23.4...v11.23.5) (2024-08-08)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@
"react-dom": "^18.1.0",
"react-test-renderer": "^18.1.0",
"semantic-release": "^19.0.5",
"stream-chat": "^8.33.1",
"stream-chat": "8.39.0",
"ts-jest": "^29.1.4",
"typescript": "^5.4.5"
},
Expand Down
61 changes: 21 additions & 40 deletions src/components/Channel/Channel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,11 @@ const ChannelInner = <
channelReducer,
// channel.initialized === false if client.channel().query() was not called, e.g. ChannelList is not used
// => Channel will call channel.watch() in useLayoutEffect => state.loading is used to signal the watch() call state
{ ...initialState, loading: !channel.initialized },
{
...initialState,
hasMore: channel.state.messagePagination.hasPrev,
loading: !channel.initialized,
},
);

const isMounted = useIsMounted();
Expand Down Expand Up @@ -569,7 +573,6 @@ const ChannelInner = <
useLayoutEffect(() => {
let errored = false;
let done = false;
let channelInitializedExternally = true;

(async () => {
if (!channel.initialized && initializeOnMount) {
Expand All @@ -595,7 +598,6 @@ const ChannelInner = <
await getChannel({ channel, client, members, options: channelQueryOptions });
const config = channel.getConfig();
setChannelConfig(config);
channelInitializedExternally = false;
} catch (e) {
dispatch({ error: e as Error, type: 'setError' });
errored = true;
Expand All @@ -608,12 +610,7 @@ const ChannelInner = <
if (!errored) {
dispatch({
channel,
hasMore:
channelInitializedExternally ||
hasMoreMessagesProbably(
channel.state.messages.length,
channelQueryOptions.messages.limit,
),
hasMore: channel.state.messagePagination.hasPrev,
type: 'initStateFromChannel',
});

Expand Down Expand Up @@ -688,7 +685,8 @@ const ChannelInner = <
);

const loadMore = async (limit = DEFAULT_NEXT_CHANNEL_PAGE_SIZE) => {
if (!online.current || !window.navigator.onLine || !state.hasMore) return 0;
if (!online.current || !window.navigator.onLine || !channel.state.messagePagination.hasPrev)
return 0;

// prevent duplicate loading events...
const oldestMessage = state?.messages?.[0];
Expand All @@ -714,14 +712,14 @@ const ChannelInner = <
return 0;
}

const hasMoreMessages = queryResponse.messages.length === perPage;
loadMoreFinished(hasMoreMessages, channel.state.messages);
loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages);

return queryResponse.messages.length;
};

const loadMoreNewer = async (limit = DEFAULT_NEXT_CHANNEL_PAGE_SIZE) => {
if (!online.current || !window.navigator.onLine || !state.hasMoreNewer) return 0;
if (!online.current || !window.navigator.onLine || !channel.state.messagePagination.hasNext)
return 0;

const newestMessage = state?.messages?.[state?.messages?.length - 1];
if (state.loadingMore || state.loadingMoreNewer) return 0;
Expand All @@ -743,10 +741,8 @@ const ChannelInner = <
return 0;
}

const hasMoreNewerMessages = channel.state.messages !== channel.state.latestMessages;

dispatch({
hasMoreNewer: hasMoreNewerMessages,
hasMoreNewer: channel.state.messagePagination.hasNext,
messages: channel.state.messages,
type: 'loadMoreNewerFinished',
});
Expand All @@ -764,18 +760,9 @@ const ChannelInner = <
dispatch({ loadingMore: true, type: 'setLoadingMore' });
await channel.state.loadMessageIntoState(messageId, undefined, messageLimit);

/**
* if the message we are jumping to has less than half of the page size older messages,
* we have jumped to the beginning of the channel.
*/
const indexOfMessage = channel.state.messages.findIndex(
(message) => message.id === messageId,
);
const hasMoreMessages = indexOfMessage >= Math.floor(messageLimit / 2);

loadMoreFinished(hasMoreMessages, channel.state.messages);
loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages);
dispatch({
hasMoreNewer: channel.state.messages !== channel.state.latestMessages,
hasMoreNewer: channel.state.messagePagination.hasNext,
highlightedMessageId: messageId,
type: 'jumpToMessageFinished',
});
Expand All @@ -794,9 +781,7 @@ const ChannelInner = <

const jumpToLatestMessage: ChannelActionContextValue<StreamChatGenerics>['jumpToLatestMessage'] = useCallback(async () => {
await channel.state.loadMessageIntoState('latest');
// FIXME: we cannot rely on constant value 25 as the page size can be customized by integrators
const hasMoreOlder = channel.state.messages.length >= 25;
loadMoreFinished(hasMoreOlder, channel.state.messages);
loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages);
dispatch({
type: 'jumpToLatestMessage',
});
Expand All @@ -811,7 +796,6 @@ const ChannelInner = <
let lastReadMessageId = channelUnreadUiState?.last_read_message_id;
let firstUnreadMessageId = channelUnreadUiState?.first_unread_message_id;
let isInCurrentMessageSet = false;
let hasMoreMessages = true;

if (firstUnreadMessageId) {
const result = findInMsgSetById(firstUnreadMessageId, channel.state.messages);
Expand Down Expand Up @@ -850,14 +834,14 @@ const ChannelInner = <
).messages;
} catch (e) {
addNotification(t('Failed to jump to the first unread message'), 'error');
loadMoreFinished(hasMoreMessages, channel.state.messages);
loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages);
return;
}

const firstMessageWithCreationDate = messages.find((msg) => msg.created_at);
if (!firstMessageWithCreationDate) {
addNotification(t('Failed to jump to the first unread message'), 'error');
loadMoreFinished(hasMoreMessages, channel.state.messages);
loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages);
return;
}
const firstMessageTimestamp = new Date(
Expand All @@ -866,13 +850,11 @@ const ChannelInner = <
if (lastReadTimestamp < firstMessageTimestamp) {
// whole channel is unread
firstUnreadMessageId = firstMessageWithCreationDate.id;
hasMoreMessages = false;
} else {
const result = findInMsgSetByDate(channelUnreadUiState.last_read, messages);
lastReadMessageId = result.target?.id;
hasMoreMessages = result.index >= Math.floor(queryMessageLimit / 2);
}
loadMoreFinished(hasMoreMessages, channel.state.messages);
loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages);
}
}

Expand All @@ -893,13 +875,12 @@ const ChannelInner = <
const indexOfTarget = channel.state.messages.findIndex(
(message) => message.id === targetId,
) as number;
hasMoreMessages = indexOfTarget >= Math.floor(queryMessageLimit / 2);
loadMoreFinished(hasMoreMessages, channel.state.messages);
loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages);
firstUnreadMessageId =
firstUnreadMessageId ?? channel.state.messages[indexOfTarget + 1]?.id;
} catch (e) {
addNotification(t('Failed to jump to the first unread message'), 'error');
loadMoreFinished(hasMoreMessages, channel.state.messages);
loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages);
return;
}
}
Expand All @@ -916,7 +897,7 @@ const ChannelInner = <
});

dispatch({
hasMoreNewer: channel.state.messages !== channel.state.latestMessages,
hasMoreNewer: channel.state.messagePagination.hasNext,
highlightedMessageId: firstUnreadMessageId,
type: 'jumpToMessageFinished',
});
Expand Down
36 changes: 30 additions & 6 deletions src/components/Channel/__tests__/Channel.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ const ActiveChannelSetter = ({ activeChannel }) => {
const user = generateUser({ custom: 'custom-value', id: 'id', name: 'name' });

// create a full message state so that we can properly test `loadMore`
const messages = Array.from({ length: 25 }, () => generateMessage({ user }));
const messages = Array.from({ length: 25 }, (_, i) =>
generateMessage({ created_at: new Date((i + 1) * 1000000), user }),
);

const pinnedMessages = [generateMessage({ pinned: true, user })];

Expand Down Expand Up @@ -701,6 +703,20 @@ describe('Channel', () => {

describe('loading more messages', () => {
const limit = 10;
it("should initiate the hasMore flag with the current message set's pagination hasPrev value", async () => {
const { channel, chatClient } = await initClient();
let hasMore;
await renderComponent({ channel, chatClient }, ({ hasMore: hasMoreCtx }) => {
hasMore = hasMoreCtx;
});
expect(hasMore).toBe(true);

channel.state.messageSets[0].pagination.hasPrev = false;
await renderComponent({ channel, chatClient }, ({ hasMore: hasMoreCtx }) => {
hasMore = hasMoreCtx;
});
expect(hasMore).toBe(false);
});
it('should be able to load more messages', async () => {
const { channel, chatClient } = await initClient();
const channelQuerySpy = jest.spyOn(channel, 'query');
Expand Down Expand Up @@ -740,7 +756,7 @@ describe('Channel', () => {
it('should set hasMore to false if querying channel returns less messages than the limit', async () => {
const { channel, chatClient } = await initClient();
let channelHasMore = false;
const newMessages = [generateMessage()];
const newMessages = [generateMessage({ created_at: new Date(1000) })];
await renderComponent(
{ channel, chatClient },
({ hasMore, loadMore, messages: contextMessages }) => {
Expand Down Expand Up @@ -822,8 +838,12 @@ describe('Channel', () => {

it('should load the second page, if the previous query has returned message count equal default messages limit', async () => {
const { channel, chatClient } = await initClient();
const firstPageMessages = Array.from({ length: 25 }, generateMessage);
const secondPageMessages = Array.from({ length: 15 }, generateMessage);
const firstPageMessages = Array.from({ length: 25 }, (_, i) =>
generateMessage({ created_at: new Date((i + 16) * 100000) }),
);
const secondPageMessages = Array.from({ length: 15 }, (_, i) =>
generateMessage({ created_at: new Date((i + 1) * 100000) }),
);
useMockedApis(chatClient, [queryChannelWithNewMessages(firstPageMessages, channel)]);
let queryNextPageSpy;
let contextMessageCount;
Expand Down Expand Up @@ -896,8 +916,12 @@ describe('Channel', () => {
const channelQueryOptions = {
messages: { limit: equalCount },
};
const firstPageMessages = Array.from({ length: equalCount }, generateMessage);
const secondPageMessages = Array.from({ length: equalCount - 1 }, generateMessage);
const firstPageMessages = Array.from({ length: equalCount }, (_, i) =>
generateMessage({ created_at: new Date((i + 1 + equalCount) * 100000) }),
);
const secondPageMessages = Array.from({ length: equalCount - 1 }, (_, i) =>
generateMessage({ created_at: new Date((i + 1) * 100000) }),
);
useMockedApis(chatClient, [queryChannelWithNewMessages(firstPageMessages, channel)]);
let queryNextPageSpy;
let contextMessageCount;
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12194,10 +12194,10 @@ statuses@2.0.1:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==

stream-chat@^8.33.1:
version "8.36.0"
resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.36.0.tgz#a241829fc219a409a1e04d82034d726244b8d1f7"
integrity sha512-J0s5K6lOJdrncmnHQ1YmPHBfswkozuiJ49xKUwBqGL5T4wvKM/7C+6vhUdp5pILfbBivJtIkGzQHVVizjpzQPw==
stream-chat@8.39.0:
version "8.39.0"
resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-8.39.0.tgz#f4cb86bd5cac4c1272c24cd66ed4752bcda8d717"
integrity sha512-zQZR1tPrgGBbu+Gnv9F9KQx3OPUMvb0FN+39BEjkjgjRPm2JYhF78jfcYutQMiC538t3V+NgFGgj5N4sZvSsUA==
dependencies:
"@babel/runtime" "^7.16.3"
"@types/jsonwebtoken" "~9.0.0"
Expand Down

0 comments on commit 44eab3c

Please sign in to comment.