diff --git a/src/state/models/notifications-view.ts b/src/state/models/notifications-view.ts
index b6e3a34881..d74511139f 100644
--- a/src/state/models/notifications-view.ts
+++ b/src/state/models/notifications-view.ts
@@ -14,7 +14,7 @@ import {RootStoreModel} from './root-store'
import {PostThreadViewModel} from './post-thread-view'
import {cleanError} from '../../lib/strings'
-const UNGROUPABLE_REASONS = ['assertion']
+const GROUPABLE_REASONS = ['vote', 'repost', 'follow']
const PAGE_SIZE = 30
const MS_1HR = 1e3 * 60 * 60
const MS_2DAY = MS_1HR * 48
@@ -539,7 +539,7 @@ function groupNotifications(
for (const item of items) {
const ts = +new Date(item.indexedAt)
let grouped = false
- if (!UNGROUPABLE_REASONS.includes(item.reason)) {
+ if (GROUPABLE_REASONS.includes(item.reason)) {
for (const item2 of items2) {
const ts2 = +new Date(item2.indexedAt)
if (
diff --git a/src/view/com/notifications/Feed.tsx b/src/view/com/notifications/Feed.tsx
index 21f54e793f..81a38b95a4 100644
--- a/src/view/com/notifications/Feed.tsx
+++ b/src/view/com/notifications/Feed.tsx
@@ -1,6 +1,6 @@
import React, {MutableRefObject} from 'react'
import {observer} from 'mobx-react-lite'
-import {FlatList, StyleSheet, View} from 'react-native'
+import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native'
import {NotificationsViewModel} from '../../../state/models/notifications-view'
import {FeedItem} from './FeedItem'
import {NotificationFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
@@ -22,11 +22,39 @@ export const Feed = observer(function Feed({
onPressTryAgain?: () => void
onScroll?: OnScrollCb
}) {
+ const data = React.useMemo(() => {
+ let feedItems
+ if (view.hasLoaded) {
+ if (view.isEmpty) {
+ feedItems = [EMPTY_FEED_ITEM]
+ } else {
+ feedItems = view.notifications
+ }
+ }
+ return feedItems
+ }, [view.hasLoaded, view.isEmpty, view.notifications])
+
+ const onRefresh = React.useCallback(async () => {
+ try {
+ await view.refresh()
+ await view.markAllRead()
+ } catch (err) {
+ view.rootStore.log.error('Failed to refresh notifications feed', err)
+ }
+ }, [view])
+ const onEndReached = React.useCallback(async () => {
+ try {
+ await view.loadMore()
+ } catch (err) {
+ view.rootStore.log.error('Failed to load more notifications', err)
+ }
+ }, [view])
+
// TODO optimize renderItem or FeedItem, we're getting this notice from RN: -prf
// VirtualizedList: You have a large list that is slow to update - make sure your
// renderItem function renders components that follow React performance best practices
// like PureComponent, shouldComponentUpdate, etc
- const renderItem = ({item}: {item: any}) => {
+ const renderItem = React.useCallback(({item}: {item: any}) => {
if (item === EMPTY_FEED_ITEM) {
return (
- }
- const onRefresh = async () => {
- try {
- await view.refresh()
- } catch (err) {
- view.rootStore.log.error('Failed to refresh notifications feed', err)
- }
- }
- const onEndReached = async () => {
- try {
- await view.loadMore()
- } catch (err) {
- view.rootStore.log.error('Failed to load more notifications', err)
- }
- }
- let data
- if (view.hasLoaded) {
- if (view.isEmpty) {
- data = [EMPTY_FEED_ITEM]
- } else {
- data = view.notifications
- }
- }
+ }, [])
+
+ const FeedFooter = React.useCallback(
+ () =>
+ view.isLoading ? (
+
+
+
+ ) : (
+
+ ),
+ [view],
+ )
+
return (
{view.isLoading && !data && }
@@ -72,6 +91,7 @@ export const Feed = observer(function Feed({
data={data}
keyExtractor={item => item._reactKey}
renderItem={renderItem}
+ ListFooterComponent={FeedFooter}
refreshing={view.isRefreshing}
onRefresh={onRefresh}
onEndReached={onEndReached}
@@ -84,5 +104,6 @@ export const Feed = observer(function Feed({
})
const styles = StyleSheet.create({
+ feedFooter: {paddingTop: 20},
emptyState: {paddingVertical: 40},
})
diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx
index 63fa14d2c9..b1d67315ac 100644
--- a/src/view/com/posts/Feed.tsx
+++ b/src/view/com/posts/Feed.tsx
@@ -40,27 +40,25 @@ export const Feed = observer(function Feed({
const {track} = useAnalytics()
const [isRefreshing, setIsRefreshing] = React.useState(false)
- // TODO optimize renderItem or FeedItem, we're getting this notice from RN: -prf
- // VirtualizedList: You have a large list that is slow to update - make sure your
- // renderItem function renders components that follow React performance best practices
- // like PureComponent, shouldComponentUpdate, etc
- const renderItem = ({item}: {item: any}) => {
- if (item === EMPTY_FEED_ITEM) {
- return (
-
- )
- } else if (item === ERROR_FEED_ITEM) {
- return (
-
- )
+ const data = React.useMemo(() => {
+ let feedItems: any[] = []
+ if (feed.hasError) {
+ feedItems = feedItems.concat([ERROR_FEED_ITEM])
}
- return
- }
- const onRefresh = async () => {
+ if (feed.hasLoaded) {
+ if (feed.isEmpty) {
+ feedItems = feedItems.concat([EMPTY_FEED_ITEM])
+ } else {
+ feedItems = feedItems.concat(feed.feed)
+ }
+ }
+ return feedItems
+ }, [feed.hasError, feed.hasLoaded, feed.isEmpty, feed.feed])
+
+ // events
+ // =
+
+ const onRefresh = React.useCallback(async () => {
track('Feed:onRefresh')
setIsRefreshing(true)
try {
@@ -69,34 +67,58 @@ export const Feed = observer(function Feed({
feed.rootStore.log.error('Failed to refresh posts feed', err)
}
setIsRefreshing(false)
- }
- const onEndReached = async () => {
+ }, [feed, track, setIsRefreshing])
+ const onEndReached = React.useCallback(async () => {
track('Feed:onEndReached')
try {
await feed.loadMore()
} catch (err) {
feed.rootStore.log.error('Failed to load more posts', err)
}
- }
- let data: any[] = []
- if (feed.hasError) {
- data = data.concat([ERROR_FEED_ITEM])
- }
- if (feed.hasLoaded) {
- if (feed.isEmpty) {
- data = data.concat([EMPTY_FEED_ITEM])
- } else {
- data = data.concat(feed.feed)
- }
- }
- const FeedFooter = () =>
- feed.isLoading ? (
-
-
-
- ) : (
-
- )
+ }, [feed, track])
+
+ // rendering
+ // =
+
+ // TODO optimize renderItem or FeedItem, we're getting this notice from RN: -prf
+ // VirtualizedList: You have a large list that is slow to update - make sure your
+ // renderItem function renders components that follow React performance best practices
+ // like PureComponent, shouldComponentUpdate, etc
+ const renderItem = React.useCallback(
+ ({item}: {item: any}) => {
+ if (item === EMPTY_FEED_ITEM) {
+ return (
+
+ )
+ } else if (item === ERROR_FEED_ITEM) {
+ return (
+
+ )
+ }
+ return
+ },
+ [feed, onPressTryAgain],
+ )
+
+ const FeedFooter = React.useCallback(
+ () =>
+ feed.isLoading ? (
+
+
+
+ ) : (
+
+ ),
+ [feed],
+ )
+
return (
{feed.isLoading && data.length === 0 && (