Feed and notifs improvements (#498)

* Reduce frequency of the notifications sync

* Reduce frequency of home feed polling

* Ensure loading spinner is visible in notifications

* Render notifications loading spinner in the flatlist

* Fixes and performance improvements to notifications

* Render 30+ on notifications if at max

* Fix issue with repeating posts in home feed

* Dont check for unread notifs if we're already at max
This commit is contained in:
Paul Frazee 2023-04-19 20:11:10 -05:00 committed by GitHub
parent b24ba3adc9
commit 04e0ebe8fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 130 additions and 150 deletions

View file

@ -14,6 +14,7 @@ import {usePalette} from 'lib/hooks/usePalette'
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
const LOAD_MORE_ERROR_ITEM = {_reactKey: '__load_more_error__'}
const LOADING_SPINNER = {_reactKey: '__loading_spinner__'}
export const Feed = observer(function Feed({
view,
@ -27,28 +28,42 @@ export const Feed = observer(function Feed({
onScroll?: OnScrollCb
}) {
const pal = usePalette('default')
const [isPTRing, setIsPTRing] = React.useState(false)
const data = React.useMemo(() => {
let feedItems
let feedItems: any[] = []
if (view.isRefreshing && !isPTRing) {
feedItems = [LOADING_SPINNER]
}
if (view.hasLoaded) {
if (view.isEmpty) {
feedItems = [EMPTY_FEED_ITEM]
feedItems = feedItems.concat([EMPTY_FEED_ITEM])
} else {
feedItems = view.notifications
feedItems = feedItems.concat(view.notifications)
}
}
if (view.loadMoreError) {
feedItems = (feedItems || []).concat([LOAD_MORE_ERROR_ITEM])
}
return feedItems
}, [view.hasLoaded, view.isEmpty, view.notifications, view.loadMoreError])
}, [
view.hasLoaded,
view.isEmpty,
view.notifications,
view.loadMoreError,
view.isRefreshing,
isPTRing,
])
const onRefresh = React.useCallback(async () => {
try {
setIsPTRing(true)
await view.refresh()
} catch (err) {
view.rootStore.log.error('Failed to refresh notifications feed', err)
} finally {
setIsPTRing(false)
}
}, [view])
}, [view, setIsPTRing])
const onEndReached = React.useCallback(async () => {
try {
@ -83,6 +98,12 @@ export const Feed = observer(function Feed({
onPress={onPressRetryLoadMore}
/>
)
} else if (item === LOADING_SPINNER) {
return (
<View style={styles.loading}>
<ActivityIndicator size="small" />
</View>
)
}
return <FeedItem item={item} />
},
@ -104,7 +125,9 @@ export const Feed = observer(function Feed({
return (
<View style={s.hContentRegion}>
<CenteredView>
{view.isLoading && !data && <NotificationFeedLoadingPlaceholder />}
{view.isLoading && !data.length && (
<NotificationFeedLoadingPlaceholder />
)}
{view.hasError && (
<ErrorMessage
message={view.error}
@ -112,7 +135,7 @@ export const Feed = observer(function Feed({
/>
)}
</CenteredView>
{data && (
{data.length && (
<FlatList
ref={scrollElRef}
data={data}
@ -121,7 +144,7 @@ export const Feed = observer(function Feed({
ListFooterComponent={FeedFooter}
refreshControl={
<RefreshControl
refreshing={view.isRefreshing}
refreshing={isPTRing}
onRefresh={onRefresh}
tintColor={pal.colors.text}
titleColor={pal.colors.text}
@ -138,6 +161,9 @@ export const Feed = observer(function Feed({
})
const styles = StyleSheet.create({
loading: {
paddingVertical: 20,
},
feedFooter: {paddingTop: 20},
emptyState: {paddingVertical: 40},
})