diff --git a/.nvmrc b/.nvmrc index b009dfb9d9..a45fd52cc5 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -lts/* +24 diff --git a/examples/vite/src/App.tsx b/examples/vite/src/App.tsx index 531efa0370..5ffe46b61c 100644 --- a/examples/vite/src/App.tsx +++ b/examples/vite/src/App.tsx @@ -48,7 +48,13 @@ const filters: ChannelFilters = { type: 'messaging', archived: false, }; -const options: ChannelOptions = { limit: 5, presence: true, state: true }; +const options: ChannelOptions = { + // limit: 10, + // message_limit: 10, + // member_limit: 10, + presence: true, + state: true, +}; const sort: ChannelSort = { pinned_at: 1, last_message_at: -1, updated_at: -1 }; // @ts-ignore diff --git a/package.json b/package.json index 4bcc74c4d1..53b5077beb 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,6 @@ "i18next": "^25.2.1", "linkifyjs": "^4.3.2", "lodash.debounce": "^4.0.8", - "lodash.defaultsdeep": "^4.6.1", "lodash.mergewith": "^4.6.2", "lodash.throttle": "^4.1.1", "lodash.uniqby": "^4.7.0", diff --git a/src/components/Channel/Channel.tsx b/src/components/Channel/Channel.tsx index 32fc8fe0fb..19d2f65566 100644 --- a/src/components/Channel/Channel.tsx +++ b/src/components/Channel/Channel.tsx @@ -10,7 +10,6 @@ import React, { } from 'react'; import clsx from 'clsx'; import debounce from 'lodash.debounce'; -import defaultsDeep from 'lodash.defaultsdeep'; import throttle from 'lodash.throttle'; import type { APIErrorResponse, @@ -65,7 +64,6 @@ import { import { CHANNEL_CONTAINER_ID } from './constants'; import { DEFAULT_HIGHLIGHT_DURATION, - DEFAULT_INITIAL_CHANNEL_PAGE_SIZE, DEFAULT_JUMP_TO_PAGE_SIZE, DEFAULT_NEXT_CHANNEL_PAGE_SIZE, DEFAULT_THREAD_PAGE_SIZE, @@ -293,7 +291,7 @@ const ChannelInner = ( activeUnreadHandler, allowConcurrentAudioPlayback, channel, - channelQueryOptions: propChannelQueryOptions, + channelQueryOptions, children, doDeleteMessageRequest, doMarkReadRequest, @@ -308,16 +306,6 @@ const ChannelInner = ( skipMessageDataMemoization, } = props; - const channelQueryOptions: ChannelQueryOptions & { - messages: { limit: number }; - } = useMemo( - () => - defaultsDeep(propChannelQueryOptions, { - messages: { limit: DEFAULT_INITIAL_CHANNEL_PAGE_SIZE }, - }), - [propChannelQueryOptions], - ); - const { client, customClasses, latestMessageDatesByChannels, mutes, searchController } = useChatContext('Channel'); const { t } = useTranslationContext('Channel'); diff --git a/src/components/Channel/__tests__/Channel.test.js b/src/components/Channel/__tests__/Channel.test.js index db59877d03..d43c2229e2 100644 --- a/src/components/Channel/__tests__/Channel.test.js +++ b/src/components/Channel/__tests__/Channel.test.js @@ -334,7 +334,11 @@ describe('Channel', () => { it('should watch the current channel on mount', async () => { const watchSpy = jest.spyOn(channel, 'watch'); - await renderComponent({ channel, chatClient }); + await renderComponent({ + channel, + channelQueryOptions: { messages: { limit: 25 } }, + chatClient, + }); await waitFor(() => { expect(watchSpy).toHaveBeenCalledTimes(1); @@ -380,9 +384,12 @@ describe('Channel', () => { ]); let hasMore; await act(() => { - renderComponent({ channel, chatClient }, ({ hasMore: contextHasMore }) => { - hasMore = contextHasMore; - }); + renderComponent( + { channel, channelQueryOptions: { messages: { limit: 25 } }, chatClient }, + ({ hasMore: contextHasMore }) => { + hasMore = contextHasMore; + }, + ); }); await waitFor(() => { @@ -395,9 +402,12 @@ describe('Channel', () => { queryChannelWithNewMessages(Array.from({ length: 25 }, generateMessage), channel), ]); let hasMore; - await renderComponent({ channel, chatClient }, ({ hasMore: contextHasMore }) => { - hasMore = contextHasMore; - }); + await renderComponent( + { channel, channelQueryOptions: { messages: { limit: 25 } }, chatClient }, + ({ hasMore: contextHasMore }) => { + hasMore = contextHasMore; + }, + ); await waitFor(() => { expect(hasMore).toBe(true); @@ -761,15 +771,21 @@ describe('Channel', () => { const limit = 10; it("should initiate the hasMore flag with the current message set's pagination hasPrev value", async () => { let hasMore; - await renderComponent({ channel, chatClient }, ({ hasMore: hasMoreCtx }) => { - hasMore = hasMoreCtx; - }); + await renderComponent( + { channel, channelQueryOptions: { messages: { limit: 25 } }, chatClient }, + ({ hasMore: hasMoreCtx }) => { + hasMore = hasMoreCtx; + }, + ); expect(hasMore).toBe(true); channel.state.messageSets[0].pagination.hasPrev = false; - await renderComponent({ channel, chatClient }, ({ hasMore: hasMoreCtx }) => { - hasMore = hasMoreCtx; - }); + await renderComponent( + { channel, channelQueryOptions: { messages: { limit: 25 } }, chatClient }, + ({ hasMore: hasMoreCtx }) => { + hasMore = hasMoreCtx; + }, + ); expect(hasMore).toBe(false); }); it('should be able to load more messages', async () => { @@ -779,7 +795,7 @@ describe('Channel', () => { const newMessages = [generateMessage()]; await renderComponent( - { channel, chatClient }, + { channel, channelQueryOptions: { messages: { limit: 25 } }, chatClient }, ({ loadMore, messages: contextMessages }) => { if (!contextMessages.find((message) => message.id === newMessages[0].id)) { // Our new message is not yet passed as part of channel context. Call loadMore and mock API response to include it. @@ -837,7 +853,7 @@ describe('Channel', () => { .fill(null) .map(() => generateMessage()); await renderComponent( - { channel, chatClient }, + { channel, channelQueryOptions: { messages: { limit: 25 } }, chatClient }, ({ hasMore, loadMore, messages: contextMessages }) => { if (!contextMessages.some((message) => message.id === newMessages[0].id)) { // Our new messages are not yet passed as part of channel context. Call loadMore and mock API response to include it. @@ -859,12 +875,15 @@ describe('Channel', () => { const queryPromise = new Promise(() => {}); let isLoadingMore = false; - await renderComponent({ channel, chatClient }, ({ loadingMore, loadMore }) => { - // return a promise that hasn't resolved yet, so loadMore will be stuck in the 'await' part of the function - jest.spyOn(channel, 'query').mockImplementationOnce(() => queryPromise); - loadMore(); - isLoadingMore = loadingMore; - }); + await renderComponent( + { channel, channelQueryOptions: { messages: { limit: 25 } }, chatClient }, + ({ loadingMore, loadMore }) => { + // return a promise that hasn't resolved yet, so loadMore will be stuck in the 'await' part of the function + jest.spyOn(channel, 'query').mockImplementationOnce(() => queryPromise); + loadMore(); + isLoadingMore = loadingMore; + }, + ); await waitFor(() => expect(isLoadingMore).toBe(true)); }); @@ -912,7 +931,7 @@ describe('Channel', () => { let queryNextPageSpy; let contextMessageCount; await renderComponent( - { channel, chatClient }, + { channel, channelQueryOptions: { messages: { limit: 25 } }, chatClient }, ({ loadMore, messages: contextMessages }) => { queryNextPageSpy = jest.spyOn(channel, 'query'); contextMessageCount = contextMessages.length; @@ -935,9 +954,9 @@ describe('Channel', () => { expect(chatClient.axiosInstance.post.mock.calls[1][1]).toMatchObject( expect.objectContaining({ data: {}, - messages: { id_lt: firstPageMessages[0].id, limit: 100 }, + messages: { id_lt: firstPageMessages[0].id, limit: 25 }, state: true, - watchers: { limit: 100 }, + watchers: { limit: 25 }, }), ); expect(contextMessageCount).toBe( diff --git a/src/components/ChannelList/ChannelList.tsx b/src/components/ChannelList/ChannelList.tsx index 5b73f52aa6..fc7a43b6cd 100644 --- a/src/components/ChannelList/ChannelList.tsx +++ b/src/components/ChannelList/ChannelList.tsx @@ -31,7 +31,7 @@ import { useComponentContext, } from '../../context'; import { NullComponent } from '../UtilityComponents'; -import { MAX_QUERY_CHANNELS_LIMIT, moveChannelUpwards } from './utils'; +import { moveChannelUpwards } from './utils'; import type { CustomQueryChannelsFn } from './hooks/usePaginatedChannels'; import type { ChannelListMessengerProps } from './ChannelListMessenger'; import type { ChannelPreviewUIComponentProps } from '../ChannelPreview/ChannelPreview'; @@ -234,10 +234,7 @@ const UnMemoizedChannelList = (props: ChannelListProps) => { channels: Array, setChannels: React.Dispatch>>, ) => { - if ( - !channels.length || - channels.length > (options?.limit || MAX_QUERY_CHANNELS_LIMIT) - ) { + if (!channels.length) { return; } diff --git a/src/components/ChannelList/__tests__/ChannelList.test.js b/src/components/ChannelList/__tests__/ChannelList.test.js index 60e5f25ae9..9d53e3a549 100644 --- a/src/components/ChannelList/__tests__/ChannelList.test.js +++ b/src/components/ChannelList/__tests__/ChannelList.test.js @@ -186,6 +186,7 @@ describe('ChannelList', () => { const props = { filters: {}, List: ChannelListComponent, + options: { limit: 25, message_limit: 25 }, Preview: ChannelPreviewComponent, }; @@ -291,6 +292,7 @@ describe('ChannelList', () => { channelRenderFilterFn: customFilterFunction, filters: {}, List: ChannelListComponent, + options: { limit: 25, message_limit: 25 }, Preview: ChannelPreviewComponent, }; @@ -634,7 +636,13 @@ describe('ChannelList', () => { customActiveChannel={testChannel2.channel.id} filters={{}} List={ChannelListComponent} - options={{ presence: true, state: true, watch: true }} + options={{ + limit: 25, + message_limit: 25, + presence: true, + state: true, + watch: true, + }} Preview={ChannelPreviewComponent} setActiveChannel={setActiveChannel} setActiveChannelOnMount @@ -931,6 +939,7 @@ describe('ChannelList', () => { const channelListProps = { filters: {}, List: ChannelListComponent, + options: { limit: 25, message_limit: 25 }, Preview: ChannelPreviewComponent, renderChannels, }; @@ -957,6 +966,7 @@ describe('ChannelList', () => { const props = { filters: {}, List: ChannelListComponent, + options: { limit: 25, message_limit: 25 }, Preview: ChannelPreviewComponent, }; const sendNewMessageOnChannel3 = async () => { @@ -1065,7 +1075,13 @@ describe('ChannelList', () => { , @@ -1104,7 +1120,13 @@ describe('ChannelList', () => { filters={{}} List={ChannelListComponent} onMessageNew={onMessageNew} - options={{ presence: true, state: true, watch: true }} + options={{ + limit: 25, + message_limit: 25, + presence: true, + state: true, + watch: true, + }} Preview={ChannelPreviewComponent} /> , @@ -1131,7 +1153,13 @@ describe('ChannelList', () => { const channelListProps = { filters: {}, List: ChannelListComponent, - options: { presence: true, state: true, watch: true }, + options: { + limit: 25, + message_limit: 25, + presence: true, + state: true, + watch: true, + }, Preview: ChannelPreviewComponent, }; @@ -1200,6 +1228,7 @@ describe('ChannelList', () => { const channelListProps = { filters: {}, List: ChannelListComponent, + options: { limit: 25, message_limit: 25 }, Preview: ChannelPreviewComponent, }; @@ -1263,6 +1292,7 @@ describe('ChannelList', () => { const channelListProps = { filters: {}, List: ChannelListComponent, + options: { limit: 25, message_limit: 25 }, Preview: ChannelPreviewComponent, }; @@ -1331,6 +1361,7 @@ describe('ChannelList', () => { const channelListProps = { filters: {}, List: ChannelListComponent, + options: { limit: 25, message_limit: 25 }, Preview: ChannelPreviewComponent, }; @@ -1420,6 +1451,7 @@ describe('ChannelList', () => { const channelListProps = { filters: {}, List: ChannelListComponent, + options: { limit: 25, message_limit: 25 }, Preview: ChannelPreviewComponent, }; @@ -1487,7 +1519,13 @@ describe('ChannelList', () => { const channelListProps = { filters: {}, List: ChannelListComponent, - options: { presence: true, state: true, watch: true }, + options: { + limit: 25, + message_limit: 25, + presence: true, + state: true, + watch: true, + }, Preview: ChannelPreviewComponent, }; @@ -1555,6 +1593,7 @@ describe('ChannelList', () => { const channelListProps = { filters: {}, List: ChannelListComponent, + options: { limit: 25, message_limit: 25 }, Preview: ChannelPreviewComponent, }; @@ -1595,6 +1634,7 @@ describe('ChannelList', () => { const channelListProps = { filters: {}, List: ChannelListComponent, + options: { limit: 25, message_limit: 25 }, Preview: ChannelPreviewComponent, }; diff --git a/src/components/ChannelList/hooks/usePaginatedChannels.ts b/src/components/ChannelList/hooks/usePaginatedChannels.ts index 19999f0dba..3dfa592c56 100644 --- a/src/components/ChannelList/hooks/usePaginatedChannels.ts +++ b/src/components/ChannelList/hooks/usePaginatedChannels.ts @@ -1,8 +1,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import uniqBy from 'lodash.uniqby'; -import { MAX_QUERY_CHANNELS_LIMIT } from '../utils'; - import type { APIErrorResponse, Channel, @@ -16,7 +14,6 @@ import type { import { useChatContext } from '../../../context/ChatContext'; import type { ChannelsQueryState } from '../../Chat/hooks/useChannelsQueryState'; -import { DEFAULT_INITIAL_CHANNEL_PAGE_SIZE } from '../../../constants/limits'; const RECOVER_LOADED_CHANNELS_THROTTLE_INTERVAL_IN_MS = 5000; const MIN_RECOVER_LOADED_CHANNELS_THROTTLE_INTERVAL_IN_MS = 2000; @@ -83,8 +80,6 @@ export const usePaginatedChannels = ( const offset = queryType === 'reload' ? 0 : channels.length; const newOptions = { - limit: options?.limit ?? MAX_QUERY_CHANNELS_LIMIT, - message_limit: options?.message_limit ?? DEFAULT_INITIAL_CHANNEL_PAGE_SIZE, offset, ...options, }; @@ -101,7 +96,7 @@ export const usePaginatedChannels = ( : uniqBy([...channels, ...channelQueryResponse], 'cid'); setChannels(newChannels); - setHasNextPage(channelQueryResponse.length >= newOptions.limit); + setHasNextPage(channelQueryResponse.length >= (newOptions.limit ?? 1)); // Set active channel only on load of first page if (!offset && activeChannelHandler) { diff --git a/src/components/ChannelList/utils.ts b/src/components/ChannelList/utils.ts index 554bd17782..b1b5dbe51c 100644 --- a/src/components/ChannelList/utils.ts +++ b/src/components/ChannelList/utils.ts @@ -3,8 +3,6 @@ import type { Channel, ChannelSort, ChannelSortBase } from 'stream-chat'; import type { ChannelListProps } from './ChannelList'; -export const MAX_QUERY_CHANNELS_LIMIT = 30; - type MoveChannelUpParams = { channels: Array; cid: string; diff --git a/src/components/ChannelPreview/__tests__/ChannelPreview.test.js b/src/components/ChannelPreview/__tests__/ChannelPreview.test.js index eff538705c..087360b04e 100644 --- a/src/components/ChannelPreview/__tests__/ChannelPreview.test.js +++ b/src/components/ChannelPreview/__tests__/ChannelPreview.test.js @@ -759,6 +759,7 @@ describe('ChannelPreview', () => { describe('group channel', () => { const channelPreviewProps = { Avatar: ChannelAvatar, + watchers: { limit: 10 }, }; const channelName = 'channel-name'; const channelState = getChannelState(3, { channel: { name: channelName } }); diff --git a/src/components/Location/__tests__/ShareLocationDialog.test.js b/src/components/Location/__tests__/ShareLocationDialog.test.js index b59d62cdfd..7fe8a37dfa 100644 --- a/src/components/Location/__tests__/ShareLocationDialog.test.js +++ b/src/components/Location/__tests__/ShareLocationDialog.test.js @@ -43,7 +43,10 @@ const renderComponent = async ({ channel, client, props } = {}) => { await act(() => { result = render( - + , @@ -52,7 +55,10 @@ const renderComponent = async ({ channel, client, props } = {}) => { const justRerender = () => result.rerender( - + , diff --git a/src/constants/limits.ts b/src/constants/limits.ts index ce77669d77..f109e3de03 100644 --- a/src/constants/limits.ts +++ b/src/constants/limits.ts @@ -1,7 +1,5 @@ -export const DEFAULT_INITIAL_CHANNEL_PAGE_SIZE = 25; -export const DEFAULT_NEXT_CHANNEL_PAGE_SIZE = 100; -export const DEFAULT_JUMP_TO_PAGE_SIZE = 100; -export const DEFAULT_THREAD_PAGE_SIZE = 50; +export const DEFAULT_NEXT_CHANNEL_PAGE_SIZE = 25; +export const DEFAULT_JUMP_TO_PAGE_SIZE = 25; +export const DEFAULT_THREAD_PAGE_SIZE = 25; export const DEFAULT_LOAD_PAGE_SCROLL_THRESHOLD = 250; -export const DEFAULT_UPLOAD_SIZE_LIMIT_BYTES = 100 * 1024 * 1024; // 100 MB export const DEFAULT_HIGHLIGHT_DURATION = 500; diff --git a/yarn.lock b/yarn.lock index 80da09e059..fe1ab24781 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8641,11 +8641,6 @@ lodash.deburr@^4.1.0: resolved "https://registry.yarnpkg.com/lodash.deburr/-/lodash.deburr-4.1.0.tgz#ddb1bbb3ef07458c0177ba07de14422cb033ff9b" integrity sha1-3bG7s+8HRYwBd7oH3hRCLLAz/5s= -lodash.defaultsdeep@^4.6.1: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" - integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== - lodash.escaperegexp@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347"