forked from Ivasoft/mattermost-mobile
MM-40081: adds pull to refresh in threads (#6284)
Adds pull to refresh functionality in global threads lists, both in all and unread threads. Refreshing fetches either all newer threads, or in the case we have no threads in store, the first page of threads.
This commit is contained in:
@@ -412,3 +412,68 @@ export async function fetchNewThreads(
|
||||
|
||||
return {error: false, models};
|
||||
}
|
||||
|
||||
export async function fetchRefreshThreads(
|
||||
serverUrl: string,
|
||||
teamId: string,
|
||||
unread = false,
|
||||
prepareRecordsOnly = false,
|
||||
): Promise<{error: unknown; models?: Model[]}> {
|
||||
const options: FetchThreadsOptions = {
|
||||
unread,
|
||||
deleted: true,
|
||||
perPage: 60,
|
||||
};
|
||||
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
|
||||
if (!operator) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
|
||||
const newestThread = await getNewestThreadInTeam(operator.database, teamId, unread);
|
||||
options.since = newestThread ? newestThread.lastReplyAt : 0;
|
||||
|
||||
let response: {
|
||||
error: unknown;
|
||||
data?: Thread[];
|
||||
} = {
|
||||
error: undefined,
|
||||
data: [],
|
||||
};
|
||||
|
||||
let pages;
|
||||
|
||||
// in the case of global threads: if we have no threads in the DB fetch just one page
|
||||
if (options.since === 0 && !unread) {
|
||||
pages = 1;
|
||||
}
|
||||
|
||||
response = await fetchBatchThreads(serverUrl, teamId, options, pages);
|
||||
|
||||
const {error: nErr, data} = response;
|
||||
|
||||
if (nErr) {
|
||||
return {error: nErr};
|
||||
}
|
||||
|
||||
if (!data?.length) {
|
||||
return {error: false, models: []};
|
||||
}
|
||||
|
||||
const loadedInGlobalThreads = !unread;
|
||||
const {error, models} = await processReceivedThreads(serverUrl, data, teamId, loadedInGlobalThreads, true);
|
||||
|
||||
if (!error && !prepareRecordsOnly && models?.length) {
|
||||
try {
|
||||
await operator.batchRecords(models);
|
||||
} catch (err) {
|
||||
if (__DEV__) {
|
||||
throw err;
|
||||
}
|
||||
return {error: true};
|
||||
}
|
||||
}
|
||||
|
||||
return {error: false, models};
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React, {useCallback, useEffect, useMemo, useState, useRef} from 'react';
|
||||
import {FlatList, StyleSheet} from 'react-native';
|
||||
|
||||
import {fetchThreads} from '@actions/remote/thread';
|
||||
import {fetchRefreshThreads, fetchThreads} from '@actions/remote/thread';
|
||||
import Loading from '@components/loading';
|
||||
import {General} from '@constants';
|
||||
import {useServerUrl} from '@context/server';
|
||||
@@ -55,6 +55,7 @@ const ThreadsList = ({
|
||||
const hasFetchedOnce = useRef(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [endReached, setEndReached] = useState(false);
|
||||
const [isRefreshing, setRefreshing] = useState(false);
|
||||
|
||||
const noThreads = !threads?.length;
|
||||
const lastThread = threads?.length > 0 ? threads[threads.length - 1] : null;
|
||||
@@ -105,6 +106,14 @@ const ThreadsList = ({
|
||||
return null;
|
||||
}, [isLoading, tab, theme, endReached]);
|
||||
|
||||
const handleRefresh = useCallback(() => {
|
||||
setRefreshing(true);
|
||||
|
||||
fetchRefreshThreads(serverUrl, teamId, tab === 'unreads').finally(() => {
|
||||
setRefreshing(false);
|
||||
});
|
||||
}, [serverUrl, teamId]);
|
||||
|
||||
const handleEndReached = useCallback(() => {
|
||||
if (!lastThread || tab === 'unreads' || endReached) {
|
||||
return;
|
||||
@@ -143,12 +152,14 @@ const ThreadsList = ({
|
||||
unreadsCount={unreadsCount}
|
||||
/>
|
||||
<FlatList
|
||||
contentContainerStyle={styles.messagesContainer}
|
||||
data={threads}
|
||||
ListEmptyComponent={listEmptyComponent}
|
||||
ListFooterComponent={listFooterComponent}
|
||||
contentContainerStyle={styles.messagesContainer}
|
||||
data={threads}
|
||||
maxToRenderPerBatch={10}
|
||||
onEndReached={handleEndReached}
|
||||
onRefresh={handleRefresh}
|
||||
refreshing={isRefreshing}
|
||||
removeClippedSubviews={true}
|
||||
renderItem={renderItem}
|
||||
testID={`${testID}.flat_list`}
|
||||
|
||||
Reference in New Issue
Block a user