From 8501cf1c7d1e86dda332f7538f17428966379d82 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Mon, 12 Dec 2022 11:22:54 -0600 Subject: [PATCH] Add 'loading more' spinner to feeds --- src/view/com/posts/Feed.tsx | 17 ++++++++++++++++- src/view/com/util/ViewSelector.tsx | 15 +++++++++------ src/view/screens/Profile.tsx | 14 +++++++++++++- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx index 9e261638..59b529dc 100644 --- a/src/view/com/posts/Feed.tsx +++ b/src/view/com/posts/Feed.tsx @@ -1,6 +1,12 @@ import React, {MutableRefObject} from 'react' import {observer} from 'mobx-react-lite' -import {View, FlatList, StyleProp, ViewStyle} from 'react-native' +import { + ActivityIndicator, + View, + FlatList, + StyleProp, + ViewStyle, +} from 'react-native' import {PostFeedLoadingPlaceholder} from '../util/LoadingPlaceholder' import {EmptyState} from '../util/EmptyState' import {ErrorMessage} from '../util/ErrorMessage' @@ -57,6 +63,14 @@ export const Feed = observer(function Feed({ data = [COMPOSE_PROMPT_ITEM].concat(feed.feed) } } + const FeedFooter = () => + feed.isLoading ? ( + + + + ) : ( + + ) return ( {!data && } @@ -75,6 +89,7 @@ export const Feed = observer(function Feed({ data={data} keyExtractor={item => item._reactKey} renderItem={renderItem} + ListFooterComponent={FeedFooter} refreshing={feed.isRefreshing} contentContainerStyle={{paddingBottom: 100}} onRefresh={onRefresh} diff --git a/src/view/com/util/ViewSelector.tsx b/src/view/com/util/ViewSelector.tsx index b2d69571..264a9086 100644 --- a/src/view/com/util/ViewSelector.tsx +++ b/src/view/com/util/ViewSelector.tsx @@ -1,9 +1,8 @@ -import React, {useEffect, useState, useMemo} from 'react' -import {FlatList, StyleSheet, View} from 'react-native' +import React, {useEffect, useState} from 'react' +import {FlatList, View} from 'react-native' import {Selector} from './Selector' import {HorzSwipe} from './gestures/HorzSwipe' import {useAnimatedValue} from '../../lib/useAnimatedValue' -import {useStores} from '../../../state' const HEADER_ITEM = {_reactKey: '__header__'} const SELECTOR_ITEM = {_reactKey: '__selector__'} @@ -16,6 +15,7 @@ export function ViewSelector({ swipeEnabled, renderHeader, renderItem, + ListFooterComponent, onSelectView, onRefresh, onEndReached, @@ -26,11 +26,15 @@ export function ViewSelector({ swipeEnabled?: boolean renderHeader?: () => JSX.Element renderItem: (item: any) => JSX.Element + ListFooterComponent?: + | React.ComponentType + | React.ReactElement + | null + | undefined onSelectView?: (viewIndex: number) => void onRefresh?: () => void onEndReached?: (info: {distanceFromEnd: number}) => void }) { - const store = useStores() const [selectedIndex, setSelectedIndex] = useState(0) const panX = useAnimatedValue(0) @@ -83,6 +87,7 @@ export function ViewSelector({ data={data} keyExtractor={item => item._reactKey} renderItem={renderItemInternal} + ListFooterComponent={ListFooterComponent} stickyHeaderIndices={STICKY_HEADER_INDICES} refreshing={refreshing} onRefresh={onRefresh} @@ -91,5 +96,3 @@ export function ViewSelector({ ) } - -const styles = StyleSheet.create({}) diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx index 2425579a..14a9af4c 100644 --- a/src/view/screens/Profile.tsx +++ b/src/view/screens/Profile.tsx @@ -1,5 +1,5 @@ import React, {useEffect, useState, useMemo} from 'react' -import {StyleSheet, Text, View} from 'react-native' +import {ActivityIndicator, StyleSheet, Text, View} from 'react-native' import {observer} from 'mobx-react-lite' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {ViewSelector} from '../com/util/ViewSelector' @@ -97,6 +97,7 @@ export const Profile = observer(({navIdx, visible, params}: ScreenParams) => { return } let renderItem + let Footer let items: any[] = [] if (uiState) { if (uiState.isInitialLoading) { @@ -132,6 +133,8 @@ export const Profile = observer(({navIdx, visible, params}: ScreenParams) => { } if (!uiState.feed.hasMore) { items = items.concat([END_ITEM]) + } else { + Footer = LoadingMoreFooter } renderItem = (item: any) => { if (item === END_ITEM) { @@ -246,6 +249,7 @@ export const Profile = observer(({navIdx, visible, params}: ScreenParams) => { items={items} renderHeader={renderHeader} renderItem={renderItem} + ListFooterComponent={Footer} refreshing={uiState.isRefreshing || false} onSelectView={onSelectView} onRefresh={onRefresh} @@ -258,6 +262,14 @@ export const Profile = observer(({navIdx, visible, params}: ScreenParams) => { ) }) +function LoadingMoreFooter() { + return ( + + + + ) +} + const styles = StyleSheet.create({ container: { flexDirection: 'column',