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:
Kyriakos Z
2022-05-19 11:10:02 +03:00
committed by GitHub
parent 6d6085ed4b
commit fd2a8a36e8
2 changed files with 79 additions and 3 deletions

View File

@@ -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};
}

View File

@@ -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`}