stream-chat-react-native-core 5.8.0-beta.7 → 5.8.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/components/ChannelList/ChannelList.js +1 -1
- package/lib/commonjs/components/ChannelList/ChannelList.js.map +1 -1
- package/lib/commonjs/components/ChannelList/ChannelListFooterLoadingIndicator.js +2 -0
- package/lib/commonjs/components/ChannelList/ChannelListFooterLoadingIndicator.js.map +1 -1
- package/lib/commonjs/components/ChannelList/ChannelListMessenger.js +23 -25
- package/lib/commonjs/components/ChannelList/ChannelListMessenger.js.map +1 -1
- package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js +64 -48
- package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
- package/lib/commonjs/contexts/channelsContext/ChannelsContext.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/ChannelList/ChannelList.js +1 -1
- package/lib/module/components/ChannelList/ChannelList.js.map +1 -1
- package/lib/module/components/ChannelList/ChannelListFooterLoadingIndicator.js +2 -0
- package/lib/module/components/ChannelList/ChannelListFooterLoadingIndicator.js.map +1 -1
- package/lib/module/components/ChannelList/ChannelListMessenger.js +23 -25
- package/lib/module/components/ChannelList/ChannelListMessenger.js.map +1 -1
- package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js +64 -48
- package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
- package/lib/module/contexts/channelsContext/ChannelsContext.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/ChannelList/ChannelListMessenger.d.ts +1 -1
- package/lib/typescript/components/ChannelList/hooks/usePaginatedChannels.d.ts +2 -2
- package/lib/typescript/contexts/channelsContext/ChannelsContext.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/ChannelList/ChannelList.tsx +2 -2
- package/src/components/ChannelList/ChannelListFooterLoadingIndicator.tsx +1 -1
- package/src/components/ChannelList/ChannelListMessenger.tsx +9 -7
- package/src/components/ChannelList/hooks/usePaginatedChannels.ts +11 -12
- package/src/contexts/channelsContext/ChannelsContext.tsx +1 -1
- package/src/version.json +1 -1
|
@@ -35,35 +35,35 @@ var usePaginatedChannels = function usePaginatedChannels(_ref) {
|
|
|
35
35
|
setForceUpdate = _ref.setForceUpdate,
|
|
36
36
|
_ref$sort = _ref.sort,
|
|
37
37
|
sort = _ref$sort === void 0 ? {} : _ref$sort;
|
|
38
|
-
var _useChatContext = (0, _ChatContext.useChatContext)(),
|
|
39
|
-
client = _useChatContext.client;
|
|
40
38
|
var _useState = (0, _react.useState)(null),
|
|
41
39
|
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
|
|
42
40
|
channels = _useState2[0],
|
|
43
41
|
setChannels = _useState2[1];
|
|
44
|
-
var _useState3 = (0, _react.useState)(
|
|
42
|
+
var _useState3 = (0, _react.useState)(undefined),
|
|
45
43
|
_useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
var
|
|
49
|
-
var _useState5 = (0, _react.useState)(),
|
|
44
|
+
error = _useState4[0],
|
|
45
|
+
setError = _useState4[1];
|
|
46
|
+
var _useState5 = (0, _react.useState)(false),
|
|
50
47
|
_useState6 = (0, _slicedToArray2["default"])(_useState5, 2),
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
var _useState7 = (0, _react.useState)(
|
|
48
|
+
staticChannelsActive = _useState6[0],
|
|
49
|
+
setStaticChannelsActive = _useState6[1];
|
|
50
|
+
var _useState7 = (0, _react.useState)('queryLocalDB'),
|
|
54
51
|
_useState8 = (0, _slicedToArray2["default"])(_useState7, 2),
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
var
|
|
58
|
-
var isQueryingRef = (0, _react.useRef)(false);
|
|
59
|
-
var _useState9 = (0, _react.useState)('queryLocalDB'),
|
|
52
|
+
activeQueryType = _useState8[0],
|
|
53
|
+
setActiveQueryType = _useState8[1];
|
|
54
|
+
var _useState9 = (0, _react.useState)(false),
|
|
60
55
|
_useState10 = (0, _slicedToArray2["default"])(_useState9, 2),
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
hasNextPage = _useState10[0],
|
|
57
|
+
setHasNextPage = _useState10[1];
|
|
58
|
+
var activeChannels = (0, _ActiveChannelsRefContext.useActiveChannelsRefContext)();
|
|
63
59
|
var isMountedRef = (0, _useIsMountedRef.useIsMountedRef)();
|
|
60
|
+
var _useChatContext = (0, _ChatContext.useChatContext)(),
|
|
61
|
+
client = _useChatContext.client;
|
|
64
62
|
var filtersRef = (0, _react.useRef)(null);
|
|
65
63
|
var sortRef = (0, _react.useRef)(null);
|
|
66
64
|
var activeRequestId = (0, _react.useRef)(0);
|
|
65
|
+
var isQueryingRef = (0, _react.useRef)(false);
|
|
66
|
+
var lastRefresh = (0, _react.useRef)(Date.now());
|
|
67
67
|
var queryChannels = function () {
|
|
68
68
|
var _ref2 = (0, _asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee() {
|
|
69
69
|
var _options$limit;
|
|
@@ -143,54 +143,70 @@ var usePaginatedChannels = function usePaginatedChannels(_ref) {
|
|
|
143
143
|
setChannels(newChannels);
|
|
144
144
|
setStaticChannelsActive(false);
|
|
145
145
|
setHasNextPage(channelQueryResponse.length >= newOptions.limit);
|
|
146
|
-
setError(undefined);
|
|
147
146
|
isQueryingRef.current = false;
|
|
148
|
-
_context.next =
|
|
147
|
+
_context.next = 45;
|
|
149
148
|
break;
|
|
150
|
-
case
|
|
151
|
-
_context.prev =
|
|
149
|
+
case 32:
|
|
150
|
+
_context.prev = 32;
|
|
152
151
|
_context.t0 = _context["catch"](17);
|
|
153
152
|
isQueryingRef.current = false;
|
|
154
|
-
_context.next =
|
|
153
|
+
_context.next = 37;
|
|
155
154
|
return waitSeconds(2);
|
|
156
|
-
case
|
|
155
|
+
case 37:
|
|
157
156
|
if (!isQueryStale()) {
|
|
158
|
-
_context.next =
|
|
157
|
+
_context.next = 39;
|
|
159
158
|
break;
|
|
160
159
|
}
|
|
161
160
|
return _context.abrupt("return");
|
|
162
|
-
case
|
|
161
|
+
case 39:
|
|
163
162
|
if (!(retryCount === MAX_NUMBER_OF_RETRIES && !isQueryingRef.current)) {
|
|
164
|
-
_context.next =
|
|
163
|
+
_context.next = 44;
|
|
165
164
|
break;
|
|
166
165
|
}
|
|
167
166
|
setActiveQueryType(null);
|
|
168
167
|
console.warn(_context.t0);
|
|
169
168
|
setError(new Error("Maximum number of retries reached in queryChannels. Last error message is: " + _context.t0));
|
|
170
169
|
return _context.abrupt("return");
|
|
171
|
-
case
|
|
170
|
+
case 44:
|
|
172
171
|
return _context.abrupt("return", queryChannels(queryType, retryCount + 1));
|
|
173
|
-
case
|
|
172
|
+
case 45:
|
|
174
173
|
setActiveQueryType(null);
|
|
175
|
-
case
|
|
174
|
+
case 46:
|
|
176
175
|
case "end":
|
|
177
176
|
return _context.stop();
|
|
178
177
|
}
|
|
179
|
-
}, _callee, null, [[17,
|
|
178
|
+
}, _callee, null, [[17, 32]]);
|
|
180
179
|
}));
|
|
181
180
|
return function queryChannels() {
|
|
182
181
|
return _ref2.apply(this, arguments);
|
|
183
182
|
};
|
|
184
183
|
}();
|
|
185
|
-
var
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
184
|
+
var refreshList = function () {
|
|
185
|
+
var _ref3 = (0, _asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee2() {
|
|
186
|
+
var now;
|
|
187
|
+
return _regenerator["default"].wrap(function _callee2$(_context2) {
|
|
188
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
189
|
+
case 0:
|
|
190
|
+
now = Date.now();
|
|
191
|
+
if (!(now - lastRefresh.current < RETRY_INTERVAL_IN_MS && error === undefined)) {
|
|
192
|
+
_context2.next = 3;
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
return _context2.abrupt("return");
|
|
196
|
+
case 3:
|
|
197
|
+
lastRefresh.current = Date.now();
|
|
198
|
+
_context2.next = 6;
|
|
199
|
+
return queryChannels('refresh');
|
|
200
|
+
case 6:
|
|
201
|
+
case "end":
|
|
202
|
+
return _context2.stop();
|
|
203
|
+
}
|
|
204
|
+
}, _callee2);
|
|
205
|
+
}));
|
|
206
|
+
return function refreshList() {
|
|
207
|
+
return _ref3.apply(this, arguments);
|
|
208
|
+
};
|
|
209
|
+
}();
|
|
194
210
|
var reloadList = function reloadList() {
|
|
195
211
|
return queryChannels('reload');
|
|
196
212
|
};
|
|
@@ -236,15 +252,15 @@ var usePaginatedChannels = function usePaginatedChannels(_ref) {
|
|
|
236
252
|
}
|
|
237
253
|
} else {
|
|
238
254
|
listener = client.on('connection.changed', function () {
|
|
239
|
-
var
|
|
240
|
-
return _regenerator["default"].wrap(function
|
|
241
|
-
while (1) switch (
|
|
255
|
+
var _ref4 = (0, _asyncToGenerator2["default"])(_regenerator["default"].mark(function _callee3(event) {
|
|
256
|
+
return _regenerator["default"].wrap(function _callee3$(_context3) {
|
|
257
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
242
258
|
case 0:
|
|
243
259
|
if (!event.online) {
|
|
244
|
-
|
|
260
|
+
_context3.next = 4;
|
|
245
261
|
break;
|
|
246
262
|
}
|
|
247
|
-
|
|
263
|
+
_context3.next = 3;
|
|
248
264
|
return refreshList();
|
|
249
265
|
case 3:
|
|
250
266
|
setForceUpdate(function (u) {
|
|
@@ -252,12 +268,12 @@ var usePaginatedChannels = function usePaginatedChannels(_ref) {
|
|
|
252
268
|
});
|
|
253
269
|
case 4:
|
|
254
270
|
case "end":
|
|
255
|
-
return
|
|
271
|
+
return _context3.stop();
|
|
256
272
|
}
|
|
257
|
-
},
|
|
273
|
+
}, _callee3);
|
|
258
274
|
}));
|
|
259
275
|
return function (_x) {
|
|
260
|
-
return
|
|
276
|
+
return _ref4.apply(this, arguments);
|
|
261
277
|
};
|
|
262
278
|
}());
|
|
263
279
|
reloadList();
|
|
@@ -273,7 +289,7 @@ var usePaginatedChannels = function usePaginatedChannels(_ref) {
|
|
|
273
289
|
hasNextPage: hasNextPage,
|
|
274
290
|
loadingChannels: activeQueryType === 'queryLocalDB' ? true : (activeQueryType === 'reload' || activeQueryType === null) && channels === null,
|
|
275
291
|
loadingNextPage: activeQueryType === 'loadChannels',
|
|
276
|
-
loadNextPage:
|
|
292
|
+
loadNextPage: queryChannels,
|
|
277
293
|
refreshing: activeQueryType === 'refresh',
|
|
278
294
|
refreshList: refreshList,
|
|
279
295
|
reloadList: reloadList,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["waitSeconds","seconds","Promise","resolve","setTimeout","ONE_SECOND_IN_MS","DEFAULT_OPTIONS","message_limit","MAX_NUMBER_OF_RETRIES","RETRY_INTERVAL_IN_MS","usePaginatedChannels","enableOfflineSupport","filters","options","setForceUpdate","sort","useChatContext","client","useState","channels","setChannels","staticChannelsActive","setStaticChannelsActive","activeChannels","useActiveChannelsRefContext","error","setError","hasNextPage","setHasNextPage","lastRefresh","useRef","Date","now","isQueryingRef","activeQueryType","setActiveQueryType","isMountedRef","useIsMountedRef","filtersRef","sortRef","activeRequestId","queryChannels","queryType","retryCount","current","hasUpdatedData","JSON","stringify","some","Boolean","isQueryStale","currentRequestId","undefined","newOptions","limit","MAX_QUERY_CHANNELS_LIMIT","offset","length","activeChannelIds","cid","id","push","skipInitialization","channelQueryResponse","newChannels","map","c","existingChannel","console","warn","Error","loadNextPage","refreshList","reloadList","filterStr","useMemo","sortStr","useEffect","loadOfflineChannels","user","channelsFromDB","getChannelsForFilterSort","currentUserId","hydrateActiveChannels","offlineMode","e","listener","DBSyncManager","onSyncStatusChange","syncStatus","dbSyncStatus","getSyncStatus","on","event","online","u","unsubscribe","loadingChannels","loadingNextPage","refreshing"],"sources":["usePaginatedChannels.ts"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\n\nimport type { Channel, ChannelFilters, ChannelOptions, ChannelSort } from 'stream-chat';\n\nimport { useActiveChannelsRefContext } from '../../../contexts/activeChannelsRefContext/ActiveChannelsRefContext';\n\nimport { useChatContext } from '../../../contexts/chatContext/ChatContext';\nimport { useIsMountedRef } from '../../../hooks/useIsMountedRef';\n\nimport { getChannelsForFilterSort } from '../../../store/apis/getChannelsForFilterSort';\nimport type { DefaultStreamChatGenerics } from '../../../types/types';\nimport { ONE_SECOND_IN_MS } from '../../../utils/date';\nimport { DBSyncManager } from '../../../utils/DBSyncManager';\nimport { MAX_QUERY_CHANNELS_LIMIT } from '../utils';\n\nconst waitSeconds = (seconds: number) =>\n new Promise((resolve) => {\n setTimeout(resolve, seconds * ONE_SECOND_IN_MS);\n });\n\ntype Parameters<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =\n {\n enableOfflineSupport: boolean;\n filters: ChannelFilters<StreamChatGenerics>;\n options: ChannelOptions;\n setForceUpdate: React.Dispatch<React.SetStateAction<number>>;\n sort: ChannelSort<StreamChatGenerics>;\n };\n\nconst DEFAULT_OPTIONS = {\n message_limit: 10,\n};\n\nconst MAX_NUMBER_OF_RETRIES = 3;\nconst RETRY_INTERVAL_IN_MS = 5000;\n\ntype QueryType = 'queryLocalDB' | 'reload' | 'refresh' | 'loadChannels';\n\nexport type QueryChannels = (queryType?: QueryType, retryCount?: number) => Promise<void>;\n\nexport const usePaginatedChannels = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>({\n enableOfflineSupport,\n filters = {},\n options = DEFAULT_OPTIONS,\n setForceUpdate,\n sort = {},\n}: Parameters<StreamChatGenerics>) => {\n const { client } = useChatContext<StreamChatGenerics>();\n const [channels, setChannels] = useState<Channel<StreamChatGenerics>[] | null>(null);\n const [staticChannelsActive, setStaticChannelsActive] = useState<boolean>(false);\n const activeChannels = useActiveChannelsRefContext();\n const [error, setError] = useState<Error>();\n const [hasNextPage, setHasNextPage] = useState(true);\n const lastRefresh = useRef(Date.now());\n const isQueryingRef = useRef(false);\n const [activeQueryType, setActiveQueryType] = useState<QueryType | null>('queryLocalDB');\n const isMountedRef = useIsMountedRef();\n const filtersRef = useRef<typeof filters | null>(null);\n const sortRef = useRef<typeof sort | null>(null);\n const activeRequestId = useRef<number>(0);\n\n const queryChannels: QueryChannels = async (\n queryType: QueryType = 'loadChannels',\n retryCount = 0,\n ): Promise<void> => {\n if (!client || !isMountedRef.current) return;\n\n const hasUpdatedData =\n queryType === 'loadChannels' ||\n queryType === 'refresh' ||\n [\n JSON.stringify(filtersRef.current) !== JSON.stringify(filters),\n JSON.stringify(sortRef.current) !== JSON.stringify(sort),\n ].some(Boolean);\n\n const isQueryStale = () => !isMountedRef || activeRequestId.current !== currentRequestId;\n\n /**\n * We don't need to make another call to query channels if we don't\n * have new data for the query to include\n * */\n if (!hasUpdatedData) {\n if (activeQueryType === null) return;\n }\n\n filtersRef.current = filters;\n sortRef.current = sort;\n isQueryingRef.current = true;\n setError(undefined);\n activeRequestId.current++;\n const currentRequestId = activeRequestId.current;\n setActiveQueryType(queryType);\n\n const newOptions = {\n limit: options?.limit ?? MAX_QUERY_CHANNELS_LIMIT,\n offset:\n queryType === 'loadChannels' && !staticChannelsActive && channels ? channels.length : 0,\n ...options,\n };\n\n try {\n const activeChannelIds: string[] = [];\n for (const cid in client.activeChannels) {\n if (client.activeChannels[cid].id) {\n // @ts-ignore\n activeChannelIds.push(client.activeChannels[cid].id);\n }\n }\n\n // TODO: Think about the implications of this.\n const channelQueryResponse = await client.queryChannels(filters, sort, newOptions, {\n skipInitialization: enableOfflineSupport ? activeChannelIds : activeChannels.current,\n });\n if (isQueryStale() || !isMountedRef.current) {\n return;\n }\n\n const newChannels =\n queryType === 'loadChannels' && !staticChannelsActive && channels\n ? [...channels, ...channelQueryResponse]\n : channelQueryResponse.map((c) => {\n const existingChannel = client.activeChannels[c.cid];\n if (existingChannel) {\n return existingChannel;\n }\n\n return c;\n });\n\n setChannels(newChannels);\n setStaticChannelsActive(false);\n setHasNextPage(channelQueryResponse.length >= newOptions.limit);\n setError(undefined);\n isQueryingRef.current = false;\n } catch (err: unknown) {\n isQueryingRef.current = false;\n await waitSeconds(2);\n\n if (isQueryStale()) {\n return;\n }\n\n // querying.current check is needed in order to make sure the next query call doesnt flick an error\n // state and then succeed (reconnect case)\n if (retryCount === MAX_NUMBER_OF_RETRIES && !isQueryingRef.current) {\n setActiveQueryType(null);\n console.warn(err);\n\n setError(\n new Error(\n `Maximum number of retries reached in queryChannels. Last error message is: ${err}`,\n ),\n );\n return;\n }\n\n return queryChannels(queryType, retryCount + 1);\n }\n\n setActiveQueryType(null);\n };\n\n const loadNextPage = hasNextPage ? queryChannels : undefined;\n\n const refreshList = () => {\n const now = Date.now();\n // Only allow pull-to-refresh 5 seconds after last successful refresh.\n if (now - lastRefresh.current < RETRY_INTERVAL_IN_MS && error === undefined) {\n return;\n }\n\n lastRefresh.current = Date.now();\n return queryChannels('refresh');\n };\n\n const reloadList = () => queryChannels('reload');\n\n /**\n * Equality check using stringified filters/sort ensure that we don't make un-necessary queryChannels api calls\n * for the scenario:\n *\n * <ChannelList\n * filters={{\n * members: { $in: ['vishal'] }\n * }}\n * ...\n * />\n *\n * Here we have passed filters as inline object, which means on every re-render of\n * parent component, ChannelList will receive new object reference (even though value is same), which\n * in return will trigger useEffect. To avoid this, we can add a value check.\n */\n const filterStr = useMemo(() => JSON.stringify(filters), [filters]);\n const sortStr = useMemo(() => JSON.stringify(sort), [sort]);\n\n useEffect(() => {\n const loadOfflineChannels = () => {\n if (!client?.user?.id) return;\n\n try {\n const channelsFromDB = getChannelsForFilterSort({\n currentUserId: client.user.id,\n filters,\n sort,\n });\n\n if (channelsFromDB) {\n setChannels(\n client.hydrateActiveChannels(channelsFromDB, {\n offlineMode: true,\n }),\n );\n setStaticChannelsActive(true);\n }\n } catch (e) {\n console.warn('Failed to get channels from database: ', e);\n }\n\n setActiveQueryType(null);\n };\n\n let listener: ReturnType<typeof DBSyncManager.onSyncStatusChange>;\n if (enableOfflineSupport) {\n // Any time DB is synced, we need to update the UI with local DB channels first,\n // and then call queryChannels to ensure any new channels are added to UI.\n listener = DBSyncManager.onSyncStatusChange((syncStatus) => {\n if (syncStatus) {\n loadOfflineChannels();\n reloadList();\n }\n });\n // On start, load the channels from local db.\n loadOfflineChannels();\n\n // If db is already synced (sync api and pending api calls), then\n // right away call queryChannels.\n const dbSyncStatus = DBSyncManager.getSyncStatus();\n if (dbSyncStatus) {\n reloadList();\n }\n } else {\n listener = client.on('connection.changed', async (event) => {\n if (event.online) {\n await refreshList();\n setForceUpdate((u) => u + 1);\n }\n });\n\n reloadList();\n }\n\n return () => listener?.unsubscribe?.();\n }, [filterStr, sortStr]);\n\n return {\n channels,\n error,\n hasNextPage,\n loadingChannels:\n activeQueryType === 'queryLocalDB'\n ? true\n : (activeQueryType === 'reload' || activeQueryType === null) && channels === null,\n loadingNextPage: activeQueryType === 'loadChannels',\n loadNextPage,\n refreshing: activeQueryType === 'refresh',\n refreshList,\n reloadList,\n // Although channels can be null, there is no practical case where channels will be null\n // when setChannels is used. setChannels is only recommended to be used for overriding\n // event handler. Thus instead of adding if check for channels === null, its better to\n // simply reassign types here.\n setChannels,\n staticChannelsActive,\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["waitSeconds","seconds","Promise","resolve","setTimeout","ONE_SECOND_IN_MS","DEFAULT_OPTIONS","message_limit","MAX_NUMBER_OF_RETRIES","RETRY_INTERVAL_IN_MS","usePaginatedChannels","enableOfflineSupport","filters","options","setForceUpdate","sort","useState","channels","setChannels","undefined","error","setError","staticChannelsActive","setStaticChannelsActive","activeQueryType","setActiveQueryType","hasNextPage","setHasNextPage","activeChannels","useActiveChannelsRefContext","isMountedRef","useIsMountedRef","useChatContext","client","filtersRef","useRef","sortRef","activeRequestId","isQueryingRef","lastRefresh","Date","now","queryChannels","queryType","retryCount","current","hasUpdatedData","JSON","stringify","some","Boolean","isQueryStale","currentRequestId","newOptions","limit","MAX_QUERY_CHANNELS_LIMIT","offset","length","activeChannelIds","cid","id","push","skipInitialization","channelQueryResponse","newChannels","map","c","existingChannel","console","warn","Error","refreshList","reloadList","filterStr","useMemo","sortStr","useEffect","loadOfflineChannels","user","channelsFromDB","getChannelsForFilterSort","currentUserId","hydrateActiveChannels","offlineMode","e","listener","DBSyncManager","onSyncStatusChange","syncStatus","dbSyncStatus","getSyncStatus","on","event","online","u","unsubscribe","loadingChannels","loadingNextPage","loadNextPage","refreshing"],"sources":["usePaginatedChannels.ts"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\n\nimport type { Channel, ChannelFilters, ChannelOptions, ChannelSort } from 'stream-chat';\n\nimport { useActiveChannelsRefContext } from '../../../contexts/activeChannelsRefContext/ActiveChannelsRefContext';\n\nimport { useChatContext } from '../../../contexts/chatContext/ChatContext';\nimport { useIsMountedRef } from '../../../hooks/useIsMountedRef';\n\nimport { getChannelsForFilterSort } from '../../../store/apis/getChannelsForFilterSort';\nimport type { DefaultStreamChatGenerics } from '../../../types/types';\nimport { ONE_SECOND_IN_MS } from '../../../utils/date';\nimport { DBSyncManager } from '../../../utils/DBSyncManager';\nimport { MAX_QUERY_CHANNELS_LIMIT } from '../utils';\n\nconst waitSeconds = (seconds: number) =>\n new Promise((resolve) => {\n setTimeout(resolve, seconds * ONE_SECOND_IN_MS);\n });\n\ntype Parameters<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =\n {\n enableOfflineSupport: boolean;\n filters: ChannelFilters<StreamChatGenerics>;\n options: ChannelOptions;\n setForceUpdate: React.Dispatch<React.SetStateAction<number>>;\n sort: ChannelSort<StreamChatGenerics>;\n };\n\nconst DEFAULT_OPTIONS = {\n message_limit: 10,\n};\n\nconst MAX_NUMBER_OF_RETRIES = 3;\nconst RETRY_INTERVAL_IN_MS = 5000;\n\ntype QueryType = 'queryLocalDB' | 'reload' | 'refresh' | 'loadChannels';\n\nexport type QueryChannels = (queryType?: QueryType, retryCount?: number) => Promise<void>;\n\nexport const usePaginatedChannels = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>({\n enableOfflineSupport,\n filters = {},\n options = DEFAULT_OPTIONS,\n setForceUpdate,\n sort = {},\n}: Parameters<StreamChatGenerics>) => {\n const [channels, setChannels] = useState<Channel<StreamChatGenerics>[] | null>(null);\n const [error, setError] = useState<Error | undefined>(undefined);\n const [staticChannelsActive, setStaticChannelsActive] = useState<boolean>(false);\n const [activeQueryType, setActiveQueryType] = useState<QueryType | null>('queryLocalDB');\n const [hasNextPage, setHasNextPage] = useState<boolean>(false);\n\n const activeChannels = useActiveChannelsRefContext();\n const isMountedRef = useIsMountedRef();\n const { client } = useChatContext<StreamChatGenerics>();\n\n const filtersRef = useRef<typeof filters | null>(null);\n const sortRef = useRef<typeof sort | null>(null);\n const activeRequestId = useRef<number>(0);\n const isQueryingRef = useRef(false);\n const lastRefresh = useRef(Date.now());\n\n const queryChannels: QueryChannels = async (\n queryType: QueryType = 'loadChannels',\n retryCount = 0,\n ): Promise<void> => {\n if (!client || !isMountedRef.current) return;\n\n const hasUpdatedData =\n queryType === 'loadChannels' ||\n queryType === 'refresh' ||\n [\n JSON.stringify(filtersRef.current) !== JSON.stringify(filters),\n JSON.stringify(sortRef.current) !== JSON.stringify(sort),\n ].some(Boolean);\n\n const isQueryStale = () => !isMountedRef || activeRequestId.current !== currentRequestId;\n\n /**\n * We don't need to make another call to query channels if we don't\n * have new data for the query to include\n * */\n if (!hasUpdatedData) {\n if (activeQueryType === null) return;\n }\n\n filtersRef.current = filters;\n sortRef.current = sort;\n isQueryingRef.current = true;\n setError(undefined);\n activeRequestId.current++;\n const currentRequestId = activeRequestId.current;\n setActiveQueryType(queryType);\n\n const newOptions = {\n limit: options?.limit ?? MAX_QUERY_CHANNELS_LIMIT,\n offset:\n queryType === 'loadChannels' && !staticChannelsActive && channels ? channels.length : 0,\n ...options,\n };\n\n try {\n const activeChannelIds: string[] = [];\n for (const cid in client.activeChannels) {\n if (client.activeChannels[cid].id) {\n // @ts-ignore\n activeChannelIds.push(client.activeChannels[cid].id);\n }\n }\n\n // TODO: Think about the implications of this.\n const channelQueryResponse = await client.queryChannels(filters, sort, newOptions, {\n skipInitialization: enableOfflineSupport ? activeChannelIds : activeChannels.current,\n });\n if (isQueryStale() || !isMountedRef.current) {\n return;\n }\n\n const newChannels =\n queryType === 'loadChannels' && !staticChannelsActive && channels\n ? [...channels, ...channelQueryResponse]\n : channelQueryResponse.map((c) => {\n const existingChannel = client.activeChannels[c.cid];\n if (existingChannel) {\n return existingChannel;\n }\n\n return c;\n });\n\n setChannels(newChannels);\n setStaticChannelsActive(false);\n setHasNextPage(channelQueryResponse.length >= newOptions.limit);\n isQueryingRef.current = false;\n } catch (err: unknown) {\n isQueryingRef.current = false;\n await waitSeconds(2);\n\n if (isQueryStale()) {\n return;\n }\n\n // querying.current check is needed in order to make sure the next query call doesnt flick an error\n // state and then succeed (reconnect case)\n if (retryCount === MAX_NUMBER_OF_RETRIES && !isQueryingRef.current) {\n setActiveQueryType(null);\n console.warn(err);\n\n setError(\n new Error(\n `Maximum number of retries reached in queryChannels. Last error message is: ${err}`,\n ),\n );\n return;\n }\n\n return queryChannels(queryType, retryCount + 1);\n }\n\n setActiveQueryType(null);\n };\n\n const refreshList = async () => {\n const now = Date.now();\n // Only allow pull-to-refresh 5 seconds after last successful refresh.\n if (now - lastRefresh.current < RETRY_INTERVAL_IN_MS && error === undefined) {\n return;\n }\n\n lastRefresh.current = Date.now();\n await queryChannels('refresh');\n };\n\n const reloadList = () => queryChannels('reload');\n\n /**\n * Equality check using stringified filters/sort ensure that we don't make un-necessary queryChannels api calls\n * for the scenario:\n *\n * <ChannelList\n * filters={{\n * members: { $in: ['vishal'] }\n * }}\n * ...\n * />\n *\n * Here we have passed filters as inline object, which means on every re-render of\n * parent component, ChannelList will receive new object reference (even though value is same), which\n * in return will trigger useEffect. To avoid this, we can add a value check.\n */\n const filterStr = useMemo(() => JSON.stringify(filters), [filters]);\n const sortStr = useMemo(() => JSON.stringify(sort), [sort]);\n\n useEffect(() => {\n const loadOfflineChannels = () => {\n if (!client?.user?.id) return;\n\n try {\n const channelsFromDB = getChannelsForFilterSort({\n currentUserId: client.user.id,\n filters,\n sort,\n });\n\n if (channelsFromDB) {\n setChannels(\n client.hydrateActiveChannels(channelsFromDB, {\n offlineMode: true,\n }),\n );\n setStaticChannelsActive(true);\n }\n } catch (e) {\n console.warn('Failed to get channels from database: ', e);\n }\n\n setActiveQueryType(null);\n };\n\n let listener: ReturnType<typeof DBSyncManager.onSyncStatusChange>;\n if (enableOfflineSupport) {\n // Any time DB is synced, we need to update the UI with local DB channels first,\n // and then call queryChannels to ensure any new channels are added to UI.\n listener = DBSyncManager.onSyncStatusChange((syncStatus) => {\n if (syncStatus) {\n loadOfflineChannels();\n reloadList();\n }\n });\n // On start, load the channels from local db.\n loadOfflineChannels();\n\n // If db is already synced (sync api and pending api calls), then\n // right away call queryChannels.\n const dbSyncStatus = DBSyncManager.getSyncStatus();\n if (dbSyncStatus) {\n reloadList();\n }\n } else {\n listener = client.on('connection.changed', async (event) => {\n if (event.online) {\n await refreshList();\n setForceUpdate((u) => u + 1);\n }\n });\n\n reloadList();\n }\n\n return () => listener?.unsubscribe?.();\n }, [filterStr, sortStr]);\n\n return {\n channels,\n error,\n hasNextPage,\n loadingChannels:\n activeQueryType === 'queryLocalDB'\n ? true\n : (activeQueryType === 'reload' || activeQueryType === null) && channels === null,\n loadingNextPage: activeQueryType === 'loadChannels',\n loadNextPage: queryChannels,\n refreshing: activeQueryType === 'refresh',\n refreshList,\n reloadList,\n // Although channels can be null, there is no practical case where channels will be null\n // when setChannels is used. setChannels is only recommended to be used for overriding\n // event handler. Thus instead of adding if check for channels === null, its better to\n // simply reassign types here.\n setChannels,\n staticChannelsActive,\n };\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ChannelsContext","React","createContext","DEFAULT_BASE_CONTEXT_VALUE","ChannelsProvider","children","value","useChannelsContext","contextValue","useContext","isTestEnvironment","Error","withChannelsContext","Component","WithChannelsContextComponent","props","channelsContext","displayName","getDisplayName"],"sources":["ChannelsContext.tsx"],"sourcesContent":["import React, { PropsWithChildren, useContext } from 'react';\n\nimport type { FlatListProps } from 'react-native';\nimport type { FlatList } from 'react-native-gesture-handler';\n\nimport type { ChannelPreviewMutedStatusProps } from 'src/components/ChannelPreview/ChannelPreviewMutedStatus';\n\nimport type { Channel } from 'stream-chat';\n\nimport type { HeaderErrorProps } from '../../components/ChannelList/ChannelListHeaderErrorIndicator';\nimport type { QueryChannels } from '../../components/ChannelList/hooks/usePaginatedChannels';\nimport type { ChannelAvatarProps } from '../../components/ChannelPreview/ChannelAvatar';\nimport type { ChannelPreviewMessageProps } from '../../components/ChannelPreview/ChannelPreviewMessage';\nimport type { ChannelPreviewMessengerProps } from '../../components/ChannelPreview/ChannelPreviewMessenger';\nimport type { ChannelPreviewStatusProps } from '../../components/ChannelPreview/ChannelPreviewStatus';\nimport type { ChannelPreviewTitleProps } from '../../components/ChannelPreview/ChannelPreviewTitle';\nimport type { ChannelPreviewUnreadCountProps } from '../../components/ChannelPreview/ChannelPreviewUnreadCount';\nimport type { EmptyStateProps } from '../../components/Indicators/EmptyStateIndicator';\nimport type { LoadingErrorProps } from '../../components/Indicators/LoadingErrorIndicator';\nimport type { LoadingProps } from '../../components/Indicators/LoadingIndicator';\nimport type { DefaultStreamChatGenerics, UnknownType } from '../../types/types';\nimport { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue';\n\nimport { getDisplayName } from '../utils/getDisplayName';\nimport { isTestEnvironment } from '../utils/isTestEnvironment';\n\nexport type ChannelsContextValue<\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n> = {\n /**\n * Besides the existing default behavior of the ChannelListMessenger component, you can attach\n * additional props to the underlying React Native FlatList.\n *\n * You can find list of all the available FlatList props here - https://facebook.github.io/react-native/docs/flatlist#props\n *\n * **EXAMPLE:**\n *\n * ```\n * <ChannelListMessenger\n * channels={channels}\n * additionalFlatListProps={{ bounces: true }}\n * />\n * ```\n *\n * **Note:** Don't use `additionalFlatListProps` to access the FlatList ref, use `setFlatListRef`\n */\n additionalFlatListProps: Partial<FlatListProps<Channel<StreamChatGenerics>>>;\n /**\n * Channels can be either an array of channels or a promise which resolves to an array of channels\n */\n channels: Channel<StreamChatGenerics>[] | null;\n /**\n * Custom indicator to use when channel list is empty\n *\n * Default: [EmptyStateIndicator](https://getstream.io/chat/docs/sdk/reactnative/core-components/channel/#emptystateindicator)\n * */\n EmptyStateIndicator: React.ComponentType<EmptyStateProps>;\n /**\n * Custom loading indicator to display at bottom of the list, while loading further pages\n *\n * Default: [ChannelListFooterLoadingIndicator](https://getstream.io/chat/docs/sdk/reactnative/contexts/channels-context/#footerloadingindicator)\n */\n FooterLoadingIndicator: React.ComponentType;\n /**\n * Incremental number change to force update the FlatList\n */\n forceUpdate: number;\n /**\n * Whether or not the FlatList has another page to render\n */\n hasNextPage: boolean;\n /**\n * Custom indicator to display error at top of list, if loading/pagination error occurs\n *\n * Default: [ChannelListHeaderErrorIndicator](https://getstream.io/chat/docs/sdk/reactnative/contexts/channels-context/#headererrorindicator)\n */\n HeaderErrorIndicator: React.ComponentType<HeaderErrorProps>;\n /**\n * Custom indicator to display network-down error at top of list, if there is connectivity issue\n *\n * Default: [ChannelListHeaderNetworkDownIndicator](https://getstream.io/chat/docs/sdk/reactnative/contexts/channels-context/#headernetworkdownindicator)\n */\n HeaderNetworkDownIndicator: React.ComponentType;\n /**\n * Initial channels query loading state, triggers the LoadingIndicator\n */\n loadingChannels: boolean;\n /**\n * Custom indicator to use when there is error in fetching channels\n *\n * Default: [LoadingErrorIndicator](https://getstream.io/chat/docs/sdk/reactnative/contexts/channels-context/#loadingerrorindicator)\n * */\n LoadingErrorIndicator: React.ComponentType<LoadingErrorProps>;\n /**\n * Custom loading indicator to use on Channel List\n *\n * */\n LoadingIndicator: React.ComponentType<Pick<LoadingProps, 'listType'>>;\n /**\n * Whether or not additional channels are being loaded, triggers the FooterLoadingIndicator\n */\n loadingNextPage: boolean;\n /**\n * The React Native FlatList threshold to fetch more data\n * @see See loadMoreThreshold [doc](https://facebook.github.io/react-native/docs/flatlist#onendreachedthreshold)\n * */\n loadMoreThreshold: number;\n /**\n * Loads the next page of `channels`, which is present as a required prop\n */\n loadNextPage: QueryChannels | undefined;\n /**\n * Max number to display within notification badge. Default: 255 and it cannot be higher than that for now due to backend limitations\n */\n maxUnreadCount: number;\n /**\n * Number of skeletons that should show when loading. Default: 6\n */\n numberOfSkeletons: number;\n /**\n * Custom UI component to display individual channel list items\n *\n * Default: [ChannelPreviewMessenger](https://getstream.io/chat/docs/sdk/reactnative/ui-components/channel-preview-messenger/)\n */\n Preview: React.ComponentType<ChannelPreviewMessengerProps<StreamChatGenerics>>;\n /**\n * Triggered when the channel list is refreshing, displays a loading spinner at the top of the list\n */\n refreshing: boolean;\n /**\n * Function to refresh the channel list that is similar to `reloadList`, but it doesn't wipe out existing channels\n * from UI before loading the new ones\n */\n refreshList: () => void | Promise<void>;\n /**\n * Removes all the existing channels from UI and loads fresh channels\n * */\n reloadList: () => Promise<void>;\n // /**\n // * Function to set the currently active channel, acts as a bridge between ChannelList and Channel components\n // *\n // * @param channel A channel object\n // */\n // setActiveChannel?: (channel: Channel<StreamChatGenerics>) => void;\n /**\n * Function to gain access to the inner FlatList ref\n *\n * **Example:**\n *\n * ```\n * <ChannelListMessenger\n * setFlatListRef={(ref) => {\n * // Use ref for your own good\n * }}\n * ```\n */\n setFlatListRef: (ref: FlatList<Channel<StreamChatGenerics>> | null) => void;\n /**\n * Custom UI component to display loading channel skeletons\n *\n * Default: [Skeleton](https://getstream.io/chat/docs/sdk/reactnative/contexts/channels-context/#skeleton)\n */\n Skeleton: React.ComponentType;\n /**\n * Error in channels query, if any\n */\n error?: Error;\n ListHeaderComponent?: React.ComponentType;\n /**\n * Function to set the currently active channel, acts as a bridge between ChannelList and Channel components\n *\n * @param channel A channel object\n */\n onSelect?: (channel: Channel<StreamChatGenerics>) => void;\n /**\n * Custom UI component to render preview avatar.\n *\n * **Default** [ChannelAvatar](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelAvatar.tsx)\n */\n PreviewAvatar?: React.ComponentType<ChannelAvatarProps<StreamChatGenerics>>;\n /**\n * Custom UI component to render preview of latest message on channel.\n *\n * **Default** [ChannelPreviewMessage](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewMessage.tsx)\n */\n PreviewMessage?: React.ComponentType<ChannelPreviewMessageProps<StreamChatGenerics>>;\n /**\n * Custom UI component to render muted status.\n *\n * **Default** [ChannelMutedStatus](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewMutedStatus.tsx)\n */\n PreviewMutedStatus?: React.ComponentType<ChannelPreviewMutedStatusProps<StreamChatGenerics>>;\n /**\n * Custom UI component to render preview avatar.\n *\n * **Default** [ChannelPreviewStatus](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewStatus.tsx)\n */\n PreviewStatus?: React.ComponentType<ChannelPreviewStatusProps<StreamChatGenerics>>;\n /**\n * Custom UI component to render preview avatar.\n *\n * **Default** [ChannelPreviewTitle](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewTitle.tsx)\n */\n PreviewTitle?: React.ComponentType<ChannelPreviewTitleProps<StreamChatGenerics>>;\n /**\n * Custom UI component to render preview avatar.\n *\n * **Default** [ChannelPreviewUnreadCount](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewUnreadCount.tsx)\n */\n PreviewUnreadCount?: React.ComponentType<ChannelPreviewUnreadCountProps<StreamChatGenerics>>;\n};\n\nexport const ChannelsContext = React.createContext(\n DEFAULT_BASE_CONTEXT_VALUE as ChannelsContextValue,\n);\n\nexport const ChannelsProvider = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>({\n children,\n value,\n}: PropsWithChildren<{\n value: ChannelsContextValue<StreamChatGenerics>;\n}>) => (\n <ChannelsContext.Provider value={value as unknown as ChannelsContextValue}>\n {children}\n </ChannelsContext.Provider>\n);\n\nexport const useChannelsContext = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>() => {\n const contextValue = useContext(\n ChannelsContext,\n ) as unknown as ChannelsContextValue<StreamChatGenerics>;\n\n if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) {\n throw new Error(\n `The useChannelsContext hook was called outside of the ChannelsContext provider. Make sure you have configured ChannelList component correctly - https://getstream.io/chat/docs/sdk/reactnative/basics/hello_stream_chat/#channel-list`,\n );\n }\n\n return contextValue;\n};\n/**\n * Typescript currently does not support partial inference so if ChatContext\n * typing is desired while using the HOC withChannelContext the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withChannelsContext = <\n P extends UnknownType,\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>(\n Component: React.ComponentType<P>,\n): React.FC<Omit<P, keyof ChannelsContextValue<StreamChatGenerics>>> => {\n const WithChannelsContextComponent = (\n props: Omit<P, keyof ChannelsContextValue<StreamChatGenerics>>,\n ) => {\n const channelsContext = useChannelsContext<StreamChatGenerics>();\n\n return <Component {...(props as P)} {...channelsContext} />;\n };\n WithChannelsContextComponent.displayName = `WithChannelsContext${getDisplayName(Component)}`;\n return WithChannelsContextComponent;\n};\n"],"mappings":";;;;;;;AAAA;AAqBA;AAEA;AACA;AAA+D;EAAA;AAAA;AAAA;AA4LxD,IAAMA,eAAe,GAAGC,iBAAK,CAACC,aAAa,CAChDC,mDAA0B,CAC3B;AAAC;AAEK,IAAMC,gBAAgB,GAAG,SAAnBA,gBAAgB;EAAA,IAG3BC,QAAQ,QAARA,QAAQ;IACRC,KAAK,QAALA,KAAK;EAAA,OAIL,gCAAC,eAAe,CAAC,QAAQ;IAAC,KAAK,EAAEA,KAAyC;IAAA;IAAA;MAAA;MAAA;MAAA;IAAA;EAAA,GACvED,QAAQ,CACgB;AAAA,CAC5B;AAAC;AAEK,IAAME,kBAAkB,GAAG,SAArBA,kBAAkB,GAExB;EACL,IAAMC,YAAY,GAAG,IAAAC,iBAAU,EAC7BT,eAAe,CACuC;EAExD,IAAIQ,YAAY,KAAKL,mDAA0B,IAAI,CAAC,IAAAO,oCAAiB,GAAE,EAAE;IACvE,MAAM,IAAIC,KAAK,yOAEd;EACH;EAEA,OAAOH,YAAY;AACrB,CAAC;AAAC;AAMK,IAAMI,mBAAmB,GAAG,SAAtBA,mBAAmB,CAI9BC,SAAiC,EACqC;EACtE,IAAMC,4BAA4B,GAAG,SAA/BA,4BAA4B,CAChCC,KAA8D,EAC3D;IACH,IAAMC,eAAe,GAAGT,kBAAkB,EAAsB;IAEhE,OAAO,gCAAC,SAAS,gCAAMQ,KAAK,EAAYC,eAAe;MAAA;MAAA;QAAA;QAAA;QAAA;MAAA;IAAA,GAAI;EAC7D,CAAC;EACDF,4BAA4B,CAACG,WAAW,2BAAyB,IAAAC,8BAAc,EAACL,SAAS,CAAG;EAC5F,OAAOC,4BAA4B;AACrC,CAAC;AAAC"}
|
|
1
|
+
{"version":3,"names":["ChannelsContext","React","createContext","DEFAULT_BASE_CONTEXT_VALUE","ChannelsProvider","children","value","useChannelsContext","contextValue","useContext","isTestEnvironment","Error","withChannelsContext","Component","WithChannelsContextComponent","props","channelsContext","displayName","getDisplayName"],"sources":["ChannelsContext.tsx"],"sourcesContent":["import React, { PropsWithChildren, useContext } from 'react';\n\nimport type { FlatListProps } from 'react-native';\nimport type { FlatList } from 'react-native-gesture-handler';\n\nimport type { ChannelPreviewMutedStatusProps } from 'src/components/ChannelPreview/ChannelPreviewMutedStatus';\n\nimport type { Channel } from 'stream-chat';\n\nimport type { HeaderErrorProps } from '../../components/ChannelList/ChannelListHeaderErrorIndicator';\nimport type { QueryChannels } from '../../components/ChannelList/hooks/usePaginatedChannels';\nimport type { ChannelAvatarProps } from '../../components/ChannelPreview/ChannelAvatar';\nimport type { ChannelPreviewMessageProps } from '../../components/ChannelPreview/ChannelPreviewMessage';\nimport type { ChannelPreviewMessengerProps } from '../../components/ChannelPreview/ChannelPreviewMessenger';\nimport type { ChannelPreviewStatusProps } from '../../components/ChannelPreview/ChannelPreviewStatus';\nimport type { ChannelPreviewTitleProps } from '../../components/ChannelPreview/ChannelPreviewTitle';\nimport type { ChannelPreviewUnreadCountProps } from '../../components/ChannelPreview/ChannelPreviewUnreadCount';\nimport type { EmptyStateProps } from '../../components/Indicators/EmptyStateIndicator';\nimport type { LoadingErrorProps } from '../../components/Indicators/LoadingErrorIndicator';\nimport type { LoadingProps } from '../../components/Indicators/LoadingIndicator';\nimport type { DefaultStreamChatGenerics, UnknownType } from '../../types/types';\nimport { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue';\n\nimport { getDisplayName } from '../utils/getDisplayName';\nimport { isTestEnvironment } from '../utils/isTestEnvironment';\n\nexport type ChannelsContextValue<\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n> = {\n /**\n * Besides the existing default behavior of the ChannelListMessenger component, you can attach\n * additional props to the underlying React Native FlatList.\n *\n * You can find list of all the available FlatList props here - https://facebook.github.io/react-native/docs/flatlist#props\n *\n * **EXAMPLE:**\n *\n * ```\n * <ChannelListMessenger\n * channels={channels}\n * additionalFlatListProps={{ bounces: true }}\n * />\n * ```\n *\n * **Note:** Don't use `additionalFlatListProps` to access the FlatList ref, use `setFlatListRef`\n */\n additionalFlatListProps: Partial<FlatListProps<Channel<StreamChatGenerics>>>;\n /**\n * Channels can be either an array of channels or a promise which resolves to an array of channels\n */\n channels: Channel<StreamChatGenerics>[] | null;\n /**\n * Custom indicator to use when channel list is empty\n *\n * Default: [EmptyStateIndicator](https://getstream.io/chat/docs/sdk/reactnative/core-components/channel/#emptystateindicator)\n * */\n EmptyStateIndicator: React.ComponentType<EmptyStateProps>;\n /**\n * Custom loading indicator to display at bottom of the list, while loading further pages\n *\n * Default: [ChannelListFooterLoadingIndicator](https://getstream.io/chat/docs/sdk/reactnative/contexts/channels-context/#footerloadingindicator)\n */\n FooterLoadingIndicator: React.ComponentType;\n /**\n * Incremental number change to force update the FlatList\n */\n forceUpdate: number;\n /**\n * Whether or not the FlatList has another page to render\n */\n hasNextPage: boolean;\n /**\n * Custom indicator to display error at top of list, if loading/pagination error occurs\n *\n * Default: [ChannelListHeaderErrorIndicator](https://getstream.io/chat/docs/sdk/reactnative/contexts/channels-context/#headererrorindicator)\n */\n HeaderErrorIndicator: React.ComponentType<HeaderErrorProps>;\n /**\n * Custom indicator to display network-down error at top of list, if there is connectivity issue\n *\n * Default: [ChannelListHeaderNetworkDownIndicator](https://getstream.io/chat/docs/sdk/reactnative/contexts/channels-context/#headernetworkdownindicator)\n */\n HeaderNetworkDownIndicator: React.ComponentType;\n /**\n * Initial channels query loading state, triggers the LoadingIndicator\n */\n loadingChannels: boolean;\n /**\n * Custom indicator to use when there is error in fetching channels\n *\n * Default: [LoadingErrorIndicator](https://getstream.io/chat/docs/sdk/reactnative/contexts/channels-context/#loadingerrorindicator)\n * */\n LoadingErrorIndicator: React.ComponentType<LoadingErrorProps>;\n /**\n * Custom loading indicator to use on Channel List\n *\n * */\n LoadingIndicator: React.ComponentType<Pick<LoadingProps, 'listType'>>;\n /**\n * Whether or not additional channels are being loaded, triggers the FooterLoadingIndicator\n */\n loadingNextPage: boolean;\n /**\n * The React Native FlatList threshold to fetch more data\n * @see See loadMoreThreshold [doc](https://facebook.github.io/react-native/docs/flatlist#onendreachedthreshold)\n * */\n loadMoreThreshold: number;\n /**\n * Loads the next page of `channels`, which is present as a required prop\n */\n loadNextPage: QueryChannels;\n /**\n * Max number to display within notification badge. Default: 255 and it cannot be higher than that for now due to backend limitations\n */\n maxUnreadCount: number;\n /**\n * Number of skeletons that should show when loading. Default: 6\n */\n numberOfSkeletons: number;\n /**\n * Custom UI component to display individual channel list items\n *\n * Default: [ChannelPreviewMessenger](https://getstream.io/chat/docs/sdk/reactnative/ui-components/channel-preview-messenger/)\n */\n Preview: React.ComponentType<ChannelPreviewMessengerProps<StreamChatGenerics>>;\n /**\n * Triggered when the channel list is refreshing, displays a loading spinner at the top of the list\n */\n refreshing: boolean;\n /**\n * Function to refresh the channel list that is similar to `reloadList`, but it doesn't wipe out existing channels\n * from UI before loading the new ones\n */\n refreshList: () => void | Promise<void>;\n /**\n * Removes all the existing channels from UI and loads fresh channels\n * */\n reloadList: () => Promise<void>;\n // /**\n // * Function to set the currently active channel, acts as a bridge between ChannelList and Channel components\n // *\n // * @param channel A channel object\n // */\n // setActiveChannel?: (channel: Channel<StreamChatGenerics>) => void;\n /**\n * Function to gain access to the inner FlatList ref\n *\n * **Example:**\n *\n * ```\n * <ChannelListMessenger\n * setFlatListRef={(ref) => {\n * // Use ref for your own good\n * }}\n * ```\n */\n setFlatListRef: (ref: FlatList<Channel<StreamChatGenerics>> | null) => void;\n /**\n * Custom UI component to display loading channel skeletons\n *\n * Default: [Skeleton](https://getstream.io/chat/docs/sdk/reactnative/contexts/channels-context/#skeleton)\n */\n Skeleton: React.ComponentType;\n /**\n * Error in channels query, if any\n */\n error?: Error;\n ListHeaderComponent?: React.ComponentType;\n /**\n * Function to set the currently active channel, acts as a bridge between ChannelList and Channel components\n *\n * @param channel A channel object\n */\n onSelect?: (channel: Channel<StreamChatGenerics>) => void;\n /**\n * Custom UI component to render preview avatar.\n *\n * **Default** [ChannelAvatar](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelAvatar.tsx)\n */\n PreviewAvatar?: React.ComponentType<ChannelAvatarProps<StreamChatGenerics>>;\n /**\n * Custom UI component to render preview of latest message on channel.\n *\n * **Default** [ChannelPreviewMessage](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewMessage.tsx)\n */\n PreviewMessage?: React.ComponentType<ChannelPreviewMessageProps<StreamChatGenerics>>;\n /**\n * Custom UI component to render muted status.\n *\n * **Default** [ChannelMutedStatus](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewMutedStatus.tsx)\n */\n PreviewMutedStatus?: React.ComponentType<ChannelPreviewMutedStatusProps<StreamChatGenerics>>;\n /**\n * Custom UI component to render preview avatar.\n *\n * **Default** [ChannelPreviewStatus](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewStatus.tsx)\n */\n PreviewStatus?: React.ComponentType<ChannelPreviewStatusProps<StreamChatGenerics>>;\n /**\n * Custom UI component to render preview avatar.\n *\n * **Default** [ChannelPreviewTitle](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewTitle.tsx)\n */\n PreviewTitle?: React.ComponentType<ChannelPreviewTitleProps<StreamChatGenerics>>;\n /**\n * Custom UI component to render preview avatar.\n *\n * **Default** [ChannelPreviewUnreadCount](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelPreview/ChannelPreviewUnreadCount.tsx)\n */\n PreviewUnreadCount?: React.ComponentType<ChannelPreviewUnreadCountProps<StreamChatGenerics>>;\n};\n\nexport const ChannelsContext = React.createContext(\n DEFAULT_BASE_CONTEXT_VALUE as ChannelsContextValue,\n);\n\nexport const ChannelsProvider = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>({\n children,\n value,\n}: PropsWithChildren<{\n value: ChannelsContextValue<StreamChatGenerics>;\n}>) => (\n <ChannelsContext.Provider value={value as unknown as ChannelsContextValue}>\n {children}\n </ChannelsContext.Provider>\n);\n\nexport const useChannelsContext = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>() => {\n const contextValue = useContext(\n ChannelsContext,\n ) as unknown as ChannelsContextValue<StreamChatGenerics>;\n\n if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) {\n throw new Error(\n `The useChannelsContext hook was called outside of the ChannelsContext provider. Make sure you have configured ChannelList component correctly - https://getstream.io/chat/docs/sdk/reactnative/basics/hello_stream_chat/#channel-list`,\n );\n }\n\n return contextValue;\n};\n/**\n * Typescript currently does not support partial inference so if ChatContext\n * typing is desired while using the HOC withChannelContext the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withChannelsContext = <\n P extends UnknownType,\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>(\n Component: React.ComponentType<P>,\n): React.FC<Omit<P, keyof ChannelsContextValue<StreamChatGenerics>>> => {\n const WithChannelsContextComponent = (\n props: Omit<P, keyof ChannelsContextValue<StreamChatGenerics>>,\n ) => {\n const channelsContext = useChannelsContext<StreamChatGenerics>();\n\n return <Component {...(props as P)} {...channelsContext} />;\n };\n WithChannelsContextComponent.displayName = `WithChannelsContext${getDisplayName(Component)}`;\n return WithChannelsContextComponent;\n};\n"],"mappings":";;;;;;;AAAA;AAqBA;AAEA;AACA;AAA+D;EAAA;AAAA;AAAA;AA4LxD,IAAMA,eAAe,GAAGC,iBAAK,CAACC,aAAa,CAChDC,mDAA0B,CAC3B;AAAC;AAEK,IAAMC,gBAAgB,GAAG,SAAnBA,gBAAgB;EAAA,IAG3BC,QAAQ,QAARA,QAAQ;IACRC,KAAK,QAALA,KAAK;EAAA,OAIL,gCAAC,eAAe,CAAC,QAAQ;IAAC,KAAK,EAAEA,KAAyC;IAAA;IAAA;MAAA;MAAA;MAAA;IAAA;EAAA,GACvED,QAAQ,CACgB;AAAA,CAC5B;AAAC;AAEK,IAAME,kBAAkB,GAAG,SAArBA,kBAAkB,GAExB;EACL,IAAMC,YAAY,GAAG,IAAAC,iBAAU,EAC7BT,eAAe,CACuC;EAExD,IAAIQ,YAAY,KAAKL,mDAA0B,IAAI,CAAC,IAAAO,oCAAiB,GAAE,EAAE;IACvE,MAAM,IAAIC,KAAK,yOAEd;EACH;EAEA,OAAOH,YAAY;AACrB,CAAC;AAAC;AAMK,IAAMI,mBAAmB,GAAG,SAAtBA,mBAAmB,CAI9BC,SAAiC,EACqC;EACtE,IAAMC,4BAA4B,GAAG,SAA/BA,4BAA4B,CAChCC,KAA8D,EAC3D;IACH,IAAMC,eAAe,GAAGT,kBAAkB,EAAsB;IAEhE,OAAO,gCAAC,SAAS,gCAAMQ,KAAK,EAAYC,eAAe;MAAA;MAAA;QAAA;QAAA;QAAA;MAAA;IAAA,GAAI;EAC7D,CAAC;EACDF,4BAA4B,CAACG,WAAW,2BAAyB,IAAAC,8BAAc,EAACL,SAAS,CAAG;EAC5F,OAAOC,4BAA4B;AACrC,CAAC;AAAC"}
|
package/lib/module/version.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { ChannelsContextValue } from '../../contexts/channelsContext/ChannelsContext';
|
|
3
3
|
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
4
|
-
export declare type ChannelListMessengerPropsWithContext<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Omit<ChannelsContextValue<StreamChatGenerics>, '
|
|
4
|
+
export declare type ChannelListMessengerPropsWithContext<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Omit<ChannelsContextValue<StreamChatGenerics>, 'HeaderErrorIndicator' | 'HeaderNetworkDownIndicator' | 'maxUnreadCount' | 'numberOfSkeletons' | 'onSelect' | 'Preview' | 'PreviewTitle' | 'PreviewStatus' | 'PreviewAvatar' | 'previewMessage' | 'Skeleton'>;
|
|
5
5
|
export declare type ChannelListMessengerProps<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Partial<ChannelListMessengerPropsWithContext<StreamChatGenerics>>;
|
|
6
6
|
/**
|
|
7
7
|
* This UI component displays the preview list of channels and handles Channel navigation. It
|
|
@@ -16,9 +16,9 @@ export declare const usePaginatedChannels: <StreamChatGenerics extends DefaultSt
|
|
|
16
16
|
hasNextPage: boolean;
|
|
17
17
|
loadingChannels: boolean;
|
|
18
18
|
loadingNextPage: boolean;
|
|
19
|
-
loadNextPage: QueryChannels
|
|
19
|
+
loadNextPage: QueryChannels;
|
|
20
20
|
refreshing: boolean;
|
|
21
|
-
refreshList: () => Promise<void
|
|
21
|
+
refreshList: () => Promise<void>;
|
|
22
22
|
reloadList: () => Promise<void>;
|
|
23
23
|
setChannels: import("react").Dispatch<import("react").SetStateAction<Channel<StreamChatGenerics>[] | null>>;
|
|
24
24
|
staticChannelsActive: boolean;
|
|
@@ -97,7 +97,7 @@ export declare type ChannelsContextValue<StreamChatGenerics extends DefaultStrea
|
|
|
97
97
|
/**
|
|
98
98
|
* Loads the next page of `channels`, which is present as a required prop
|
|
99
99
|
*/
|
|
100
|
-
loadNextPage: QueryChannels
|
|
100
|
+
loadNextPage: QueryChannels;
|
|
101
101
|
/**
|
|
102
102
|
* Max number to display within notification badge. Default: 255 and it cannot be higher than that for now due to backend limitations
|
|
103
103
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stream-chat-react-native-core",
|
|
3
3
|
"description": "The official React Native and Expo components for Stream Chat, a service for building chat applications",
|
|
4
|
-
"version": "5.8.
|
|
4
|
+
"version": "5.8.1-beta.1",
|
|
5
5
|
"author": {
|
|
6
6
|
"company": "Stream.io Inc",
|
|
7
7
|
"name": "Stream.io Inc"
|
|
@@ -215,8 +215,8 @@ export const ChannelList = <
|
|
|
215
215
|
ListHeaderComponent,
|
|
216
216
|
LoadingErrorIndicator = LoadingErrorIndicatorDefault,
|
|
217
217
|
LoadingIndicator = ChannelListLoadingIndicator,
|
|
218
|
-
// https://
|
|
219
|
-
loadMoreThreshold =
|
|
218
|
+
// https://stackoverflow.com/a/60666252/10826415
|
|
219
|
+
loadMoreThreshold = 0.1,
|
|
220
220
|
lockChannelOrder = false,
|
|
221
221
|
maxUnreadCount = 255,
|
|
222
222
|
numberOfSkeletons = 6,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
2
2
|
// RNGR's FlatList ist currently breaking the pull-to-refresh behaviour on Android
|
|
3
3
|
// See https://github.com/software-mansion/react-native-gesture-handler/issues/598
|
|
4
4
|
import { FlatList, RefreshControl, StyleSheet, View } from 'react-native';
|
|
@@ -26,7 +26,6 @@ export type ChannelListMessengerPropsWithContext<
|
|
|
26
26
|
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
27
27
|
> = Omit<
|
|
28
28
|
ChannelsContextValue<StreamChatGenerics>,
|
|
29
|
-
| 'hasNextPage'
|
|
30
29
|
| 'HeaderErrorIndicator'
|
|
31
30
|
| 'HeaderNetworkDownIndicator'
|
|
32
31
|
| 'maxUnreadCount'
|
|
@@ -84,6 +83,7 @@ const ChannelListMessengerWithContext = <
|
|
|
84
83
|
>(
|
|
85
84
|
props: ChannelListMessengerPropsWithContext<StreamChatGenerics>,
|
|
86
85
|
) => {
|
|
86
|
+
const onEndReachedCalledDuringCurrentScrollRef = useRef<boolean>(false);
|
|
87
87
|
const {
|
|
88
88
|
additionalFlatListProps,
|
|
89
89
|
channels,
|
|
@@ -91,6 +91,7 @@ const ChannelListMessengerWithContext = <
|
|
|
91
91
|
error,
|
|
92
92
|
FooterLoadingIndicator,
|
|
93
93
|
forceUpdate,
|
|
94
|
+
hasNextPage,
|
|
94
95
|
ListHeaderComponent,
|
|
95
96
|
loadingChannels,
|
|
96
97
|
LoadingErrorIndicator,
|
|
@@ -151,14 +152,12 @@ const ChannelListMessengerWithContext = <
|
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
const onEndReached = () => {
|
|
154
|
-
if (
|
|
155
|
+
if (!onEndReachedCalledDuringCurrentScrollRef.current && hasNextPage) {
|
|
155
156
|
loadNextPage();
|
|
157
|
+
onEndReachedCalledDuringCurrentScrollRef.current = true;
|
|
156
158
|
}
|
|
157
159
|
};
|
|
158
160
|
|
|
159
|
-
const ListFooterComponent = () =>
|
|
160
|
-
channels?.length && ListHeaderComponent ? <ListHeaderComponent /> : null;
|
|
161
|
-
|
|
162
161
|
if (loadingChannels) {
|
|
163
162
|
return <LoadingIndicator listType='channel' />;
|
|
164
163
|
}
|
|
@@ -182,9 +181,10 @@ const ChannelListMessengerWithContext = <
|
|
|
182
181
|
)
|
|
183
182
|
}
|
|
184
183
|
ListFooterComponent={loadingNextPage ? <FooterLoadingIndicator /> : undefined}
|
|
185
|
-
ListHeaderComponent={
|
|
184
|
+
ListHeaderComponent={ListHeaderComponent}
|
|
186
185
|
onEndReached={onEndReached}
|
|
187
186
|
onEndReachedThreshold={loadMoreThreshold}
|
|
187
|
+
onMomentumScrollBegin={() => (onEndReachedCalledDuringCurrentScrollRef.current = false)}
|
|
188
188
|
ref={setFlatListRef}
|
|
189
189
|
refreshControl={<RefreshControl onRefresh={refreshList} refreshing={refreshing} />}
|
|
190
190
|
renderItem={renderItem}
|
|
@@ -219,6 +219,7 @@ export const ChannelListMessenger = <
|
|
|
219
219
|
error,
|
|
220
220
|
FooterLoadingIndicator,
|
|
221
221
|
forceUpdate,
|
|
222
|
+
hasNextPage,
|
|
222
223
|
ListHeaderComponent,
|
|
223
224
|
loadingChannels,
|
|
224
225
|
LoadingErrorIndicator,
|
|
@@ -241,6 +242,7 @@ export const ChannelListMessenger = <
|
|
|
241
242
|
error,
|
|
242
243
|
FooterLoadingIndicator,
|
|
243
244
|
forceUpdate,
|
|
245
|
+
hasNextPage,
|
|
244
246
|
ListHeaderComponent,
|
|
245
247
|
loadingChannels,
|
|
246
248
|
LoadingErrorIndicator,
|
|
@@ -47,19 +47,21 @@ export const usePaginatedChannels = <
|
|
|
47
47
|
setForceUpdate,
|
|
48
48
|
sort = {},
|
|
49
49
|
}: Parameters<StreamChatGenerics>) => {
|
|
50
|
-
const { client } = useChatContext<StreamChatGenerics>();
|
|
51
50
|
const [channels, setChannels] = useState<Channel<StreamChatGenerics>[] | null>(null);
|
|
51
|
+
const [error, setError] = useState<Error | undefined>(undefined);
|
|
52
52
|
const [staticChannelsActive, setStaticChannelsActive] = useState<boolean>(false);
|
|
53
|
-
const activeChannels = useActiveChannelsRefContext();
|
|
54
|
-
const [error, setError] = useState<Error>();
|
|
55
|
-
const [hasNextPage, setHasNextPage] = useState(true);
|
|
56
|
-
const lastRefresh = useRef(Date.now());
|
|
57
|
-
const isQueryingRef = useRef(false);
|
|
58
53
|
const [activeQueryType, setActiveQueryType] = useState<QueryType | null>('queryLocalDB');
|
|
54
|
+
const [hasNextPage, setHasNextPage] = useState<boolean>(false);
|
|
55
|
+
|
|
56
|
+
const activeChannels = useActiveChannelsRefContext();
|
|
59
57
|
const isMountedRef = useIsMountedRef();
|
|
58
|
+
const { client } = useChatContext<StreamChatGenerics>();
|
|
59
|
+
|
|
60
60
|
const filtersRef = useRef<typeof filters | null>(null);
|
|
61
61
|
const sortRef = useRef<typeof sort | null>(null);
|
|
62
62
|
const activeRequestId = useRef<number>(0);
|
|
63
|
+
const isQueryingRef = useRef(false);
|
|
64
|
+
const lastRefresh = useRef(Date.now());
|
|
63
65
|
|
|
64
66
|
const queryChannels: QueryChannels = async (
|
|
65
67
|
queryType: QueryType = 'loadChannels',
|
|
@@ -132,7 +134,6 @@ export const usePaginatedChannels = <
|
|
|
132
134
|
setChannels(newChannels);
|
|
133
135
|
setStaticChannelsActive(false);
|
|
134
136
|
setHasNextPage(channelQueryResponse.length >= newOptions.limit);
|
|
135
|
-
setError(undefined);
|
|
136
137
|
isQueryingRef.current = false;
|
|
137
138
|
} catch (err: unknown) {
|
|
138
139
|
isQueryingRef.current = false;
|
|
@@ -162,9 +163,7 @@ export const usePaginatedChannels = <
|
|
|
162
163
|
setActiveQueryType(null);
|
|
163
164
|
};
|
|
164
165
|
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
const refreshList = () => {
|
|
166
|
+
const refreshList = async () => {
|
|
168
167
|
const now = Date.now();
|
|
169
168
|
// Only allow pull-to-refresh 5 seconds after last successful refresh.
|
|
170
169
|
if (now - lastRefresh.current < RETRY_INTERVAL_IN_MS && error === undefined) {
|
|
@@ -172,7 +171,7 @@ export const usePaginatedChannels = <
|
|
|
172
171
|
}
|
|
173
172
|
|
|
174
173
|
lastRefresh.current = Date.now();
|
|
175
|
-
|
|
174
|
+
await queryChannels('refresh');
|
|
176
175
|
};
|
|
177
176
|
|
|
178
177
|
const reloadList = () => queryChannels('reload');
|
|
@@ -263,7 +262,7 @@ export const usePaginatedChannels = <
|
|
|
263
262
|
? true
|
|
264
263
|
: (activeQueryType === 'reload' || activeQueryType === null) && channels === null,
|
|
265
264
|
loadingNextPage: activeQueryType === 'loadChannels',
|
|
266
|
-
loadNextPage,
|
|
265
|
+
loadNextPage: queryChannels,
|
|
267
266
|
refreshing: activeQueryType === 'refresh',
|
|
268
267
|
refreshList,
|
|
269
268
|
reloadList,
|
|
@@ -108,7 +108,7 @@ export type ChannelsContextValue<
|
|
|
108
108
|
/**
|
|
109
109
|
* Loads the next page of `channels`, which is present as a required prop
|
|
110
110
|
*/
|
|
111
|
-
loadNextPage: QueryChannels
|
|
111
|
+
loadNextPage: QueryChannels;
|
|
112
112
|
/**
|
|
113
113
|
* Max number to display within notification badge. Default: 255 and it cannot be higher than that for now due to backend limitations
|
|
114
114
|
*/
|
package/src/version.json
CHANGED