Skip to content
This repository was archived by the owner on Dec 8, 2025. It is now read-only.

Commit c267b99

Browse files
committed
refactor: update infinite scroll reducer to handle loading state
1 parent 5adf1a9 commit c267b99

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

src/reducers/notifications.ts

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export interface TopicNotificationsState {
44
fullNotifications: NotifyClientTypes.NotifyNotification[]
55
existingIds: Set<string>
66
hasMore: boolean
7+
isLoading: boolean
78
}
89

910
export interface NotificationsState {
@@ -12,11 +13,15 @@ export interface NotificationsState {
1213

1314
export type NotificationsActions =
1415
| {
15-
type: 'FETCH_NOTIFICATIONS'
16+
type: 'FETCH_NOTIFICATIONS_DONE'
1617
notifications: NotifyClientTypes.NotifyNotification[]
1718
topic: string
1819
hasMore: boolean
1920
}
21+
| {
22+
type: 'FETCH_NOTIFICATIONS_LOADING'
23+
topic: string
24+
}
2025
| {
2126
type: 'UNSHIFT_NEW_NOTIFICATIONS'
2227
notifications: NotifyClientTypes.NotifyNotification[]
@@ -32,19 +37,42 @@ export const notificationsReducer = (
3237
): NotificationsState => {
3338
const topicState = state[action.topic] as TopicNotificationsState | undefined
3439

35-
const ids = topicState?.existingIds || new Set<string>()
36-
const filteredNotifications = action.notifications.filter(val => !ids.has(val.id))
37-
const notificationIds = action.notifications.map(notification => notification.id)
40+
function getTopicState(notifications: NotifyClientTypes.NotifyNotification[]) {
41+
const ids = topicState?.existingIds || new Set<string>()
42+
const filteredNotifications = notifications.filter(val => !ids.has(val.id))
43+
const notificationIds = notifications.map(notification => notification.id)
3844

39-
const fullNotifications = topicState?.fullNotifications || []
40-
const newFullIdsSet = new Set(topicState?.existingIds || [])
45+
const fullNotifications = topicState?.fullNotifications || []
46+
const newFullIdsSet = new Set(topicState?.existingIds || [])
4147

42-
for (const val of notificationIds) {
43-
newFullIdsSet.add(val)
48+
for (const val of notificationIds) {
49+
newFullIdsSet.add(val)
50+
}
51+
52+
return {
53+
filteredNotifications,
54+
fullNotifications,
55+
newFullIdsSet
56+
}
4457
}
4558

4659
switch (action.type) {
47-
case 'UNSHIFT_NEW_NOTIFICATIONS':
60+
case 'FETCH_NOTIFICATIONS_LOADING': {
61+
if (topicState) {
62+
return {
63+
...state,
64+
[action.topic]: {
65+
...topicState,
66+
isLoading: true
67+
}
68+
}
69+
}
70+
return state
71+
}
72+
case 'UNSHIFT_NEW_NOTIFICATIONS': {
73+
const { filteredNotifications, fullNotifications, newFullIdsSet } = getTopicState(
74+
action.notifications
75+
)
4876
const unshiftedNotifications = filteredNotifications.concat(fullNotifications)
4977

5078
return {
@@ -53,11 +81,15 @@ export const notificationsReducer = (
5381
...topicState,
5482
existingIds: newFullIdsSet,
5583
fullNotifications: unshiftedNotifications,
56-
hasMore: topicState?.hasMore || false
84+
hasMore: topicState?.hasMore || false,
85+
isLoading: false
5786
}
5887
}
59-
60-
case 'FETCH_NOTIFICATIONS':
88+
}
89+
case 'FETCH_NOTIFICATIONS_DONE': {
90+
const { filteredNotifications, fullNotifications, newFullIdsSet } = getTopicState(
91+
action.notifications
92+
)
6193
const concatenatedNotification = fullNotifications.concat(filteredNotifications)
6294

6395
return {
@@ -66,8 +98,10 @@ export const notificationsReducer = (
6698
...topicState,
6799
existingIds: newFullIdsSet,
68100
fullNotifications: concatenatedNotification,
69-
hasMore: action.hasMore
101+
hasMore: action.hasMore,
102+
isLoading: false
70103
}
71104
}
105+
}
72106
}
73107
}

src/utils/hooks/useNotificationsInfiniteScroll.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,23 @@ export const useNotificationsInfiniteScroll = (topic?: string) => {
1515
const intersectionObserverRef = useRef<HTMLDivElement>(null)
1616
const { notifyClientProxy } = useContext(W3iContext)
1717
const [state, dispatch] = useReducer(notificationsReducer, {})
18-
const [isLoading, setIsLoading] = useState(false)
1918

2019
const nextPageInternal = useCallback(
2120
async (lastMessageId?: string) => {
2221
if (!(notifyClientProxy && topic)) {
2322
return
2423
}
2524

26-
setIsLoading(true)
25+
dispatch({ type: 'FETCH_NOTIFICATIONS_LOADING', topic })
26+
2727
const newNotifications = await notifyClientProxy.getNotificationHistory({
2828
topic,
2929
limit: NOTIFICATION_BATCH_SIZE,
3030
startingAfter: lastMessageId
3131
})
32-
setIsLoading(false)
3332

3433
dispatch({
35-
type: 'FETCH_NOTIFICATIONS',
34+
type: 'FETCH_NOTIFICATIONS_DONE',
3635
notifications: newNotifications.notifications,
3736
hasMore: newNotifications.hasMore,
3837
topic
@@ -61,6 +60,7 @@ export const useNotificationsInfiniteScroll = (topic?: string) => {
6160

6261
const topicState = topic ? state?.[topic] : undefined
6362
const topicNotifications = topicState ? topicState.fullNotifications : []
63+
const isLoading = topicState ? topicState.isLoading : []
6464
const hasMore = topicState ? topicState.hasMore : false
6565

6666
const lastMessageId = topicNotifications.length

0 commit comments

Comments
 (0)