From fd2a8a36e862abc6c563cb7e41c0b163a7ecd1f9 Mon Sep 17 00:00:00 2001 From: Kyriakos Z <3829551+koox00@users.noreply.github.com> Date: Thu, 19 May 2022 11:10:02 +0300 Subject: [PATCH] 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. --- app/actions/remote/thread.ts | 65 +++++++++++++++++++ .../threads_list/threads_list.tsx | 17 ++++- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/app/actions/remote/thread.ts b/app/actions/remote/thread.ts index 66d9254c2b..b1d87aa764 100644 --- a/app/actions/remote/thread.ts +++ b/app/actions/remote/thread.ts @@ -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}; +} diff --git a/app/screens/global_threads/threads_list/threads_list.tsx b/app/screens/global_threads/threads_list/threads_list.tsx index 487140f0a3..018148f379 100644 --- a/app/screens/global_threads/threads_list/threads_list.tsx +++ b/app/screens/global_threads/threads_list/threads_list.tsx @@ -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} />