@@ -18,7 +18,6 @@ struct PushNotificationListFeature {
1818 @Presents var alert : AlertState < Never > ?
1919 @Presents var sheet : SheetState ?
2020 var notifications : [ PushNotificationItem ] = [ ]
21- var hasMore = false
2221 var nextCursor : PushNotificationCursor ?
2322 var query : PushNotificationQuery
2423 var selectedNotificationId : String ?
@@ -58,6 +57,8 @@ struct PushNotificationListFeature {
5857 case loading( LoadingFeature . Action )
5958
6059 enum ViewAction : Equatable {
60+ case stopObserving
61+ case startObserving
6162 case refresh
6263 case fetchNotifications
6364 case loadNextPage
@@ -79,9 +80,7 @@ struct PushNotificationListFeature {
7980 enum StoreAction : Equatable {
8081 case setAlert
8182 case appendNotifications( [ PushNotificationItem ] , nextCursor: PushNotificationCursor ? )
82- case resetPagination
83- case setHasMore( Bool )
84- case syncNotifications( [ PushNotificationItem ] , nextCursor: PushNotificationCursor ? , hasMore: Bool )
83+ case replaceNotifications( [ PushNotificationItem ] , nextCursor: PushNotificationCursor ? )
8584 case setNotificationHidden( String , Bool )
8685 case setNotificationRead( String , Bool )
8786 }
@@ -98,6 +97,7 @@ struct PushNotificationListFeature {
9897 @Dependency ( \. undoDeletePushNotificationUseCase) var undoDeletePushNotificationUseCase
9998 @Dependency ( \. togglePushNotificationReadUseCase) var togglePushNotificationReadUseCase
10099 @Dependency ( \. updatePushNotificationQueryUseCase) var updatePushNotificationQueryUseCase
100+ @Dependency ( \. date. now) var now
101101
102102 var body : some ReducerOf < Self > {
103103 Scope ( state: \. loading, action: \. loading) {
@@ -116,6 +116,7 @@ struct PushNotificationListFeature {
116116 break
117117 case . binding( \. query. timeFilter) :
118118 state. nextCursor = nil
119+ state. query. referenceDate = now
119120 return refreshForQueryChangeEffect ( query: state. query)
120121 case . binding:
121122 break
@@ -151,23 +152,32 @@ private extension PushNotificationListFeature {
151152 state: inout State
152153 ) -> Effect < Action > {
153154 switch action {
155+ case . stopObserving:
156+ return . cancel( id: CancelID . observeNotifications)
157+ case . startObserving:
158+ return observeNotificationsEffect (
159+ query: state. query,
160+ limit: state. query. pageSize
161+ )
154162 case . refresh:
155163 state. nextCursor = nil
156- return fetchNotificationsEffect (
157- query: state. query,
158- cursor: nil ,
159- existingCount: 0 ,
160- showsIndicator: false
164+ state. query. referenceDate = now
165+ return . concatenate(
166+ . cancel( id: CancelID . observeNotifications) ,
167+ fetchNotificationsPageEffect (
168+ query: state. query,
169+ cursor: nil ,
170+ showsIndicator: false
171+ )
161172 )
162173 case . fetchNotifications:
163174 state. nextCursor = nil
164- return fetchNotificationsEffect ( query: state. query, cursor: nil , existingCount : 0 )
175+ return fetchNotificationsPageEffect ( query: state. query, cursor: nil )
165176 case . loadNextPage:
166- guard state. hasMore , !state. isLoading else { return . none }
167- return fetchNotificationsEffect (
177+ guard state. nextCursor != nil , !state. isLoading else { return . none }
178+ return fetchNotificationsPageEffect (
168179 query: state. query,
169- cursor: state. nextCursor,
170- existingCount: state. notifications. count
180+ cursor: state. nextCursor
171181 )
172182 case . deleteNotification( let item) :
173183 guard state. notifications. contains ( where: { $0. id == item. id } ) else { return . none }
@@ -193,14 +203,17 @@ private extension PushNotificationListFeature {
193203 }
194204 case . toggleSortOption:
195205 state. query. sortOrder = state. query. sortOrder == . latest ? . oldest : . latest
206+ state. query. referenceDate = now
196207 state. nextCursor = nil
197208 return refreshForQueryChangeEffect ( query: state. query)
198209 case . toggleUnreadOnly:
199210 state. query. unreadOnly. toggle ( )
211+ state. query. referenceDate = now
200212 state. nextCursor = nil
201213 return refreshForQueryChangeEffect ( query: state. query)
202214 case . resetFilters:
203215 state. query = . default
216+ state. query. referenceDate = now
204217 state. nextCursor = nil
205218 return refreshForQueryChangeEffect ( query: state. query)
206219 case . selectNotification( let notificationId) :
@@ -242,18 +255,12 @@ private extension PushNotificationListFeature {
242255 incomingNotifications: notifications
243256 ) )
244257 state. nextCursor = nextCursor
245- case . resetPagination:
246- state. notifications = [ ]
247- state. nextCursor = nil
248- case . setHasMore( let value) :
249- state. hasMore = value
250- case . syncNotifications( let notifications, let nextCursor, let hasMore) :
258+ case . replaceNotifications( let notifications, let nextCursor) :
251259 state. notifications = Self . mergedHiddenNotifications (
252260 currentNotifications: state. notifications,
253261 incomingNotifications: notifications
254262 )
255263 state. nextCursor = nextCursor
256- state. hasMore = hasMore
257264 case . setNotificationHidden( let notificationId, let isHidden) :
258265 Self . setNotificationHidden ( & state, notificationId: notificationId, isHidden: isHidden)
259266 case . setNotificationRead( let notificationId, let isRead) :
@@ -268,32 +275,12 @@ private extension PushNotificationListFeature {
268275 func refreshForQueryChangeEffect( query: PushNotificationQuery ) -> Effect < Action > {
269276 . merge(
270277 updateQueryEffect ( query: query) ,
271- fetchNotificationsEffect ( query: query, cursor: nil , existingCount: 0 )
272- )
273- }
274-
275- func fetchNotificationsEffect(
276- query: PushNotificationQuery ,
277- cursor: PushNotificationCursor ? ,
278- existingCount: Int ,
279- showsIndicator: Bool = true
280- ) -> Effect < Action > {
281- let limit = max ( query. pageSize, existingCount)
282- let fetchEffect = fetchNotificationsPageEffect ( query: query, cursor: cursor, showsIndicator: showsIndicator)
283- let observeEffect = observeNotificationsEffect (
284- query: query,
285- limit: max ( limit, existingCount + query. pageSize)
286- )
287-
288- if cursor == nil {
289- return . concatenate(
290- . cancel( id: CancelID . observeNotifications) ,
291- fetchEffect,
292- observeEffect
278+ . concatenate(
279+ . send( . view( . stopObserving) ) ,
280+ fetchNotificationsPageEffect ( query: query, cursor: nil ) ,
281+ . send( . view( . startObserving) )
293282 )
294- }
295-
296- return fetchEffect
283+ )
297284 }
298285
299286 func fetchNotificationsPageEffect(
@@ -307,16 +294,22 @@ private extension PushNotificationListFeature {
307294 }
308295 do {
309296 let page = try await fetchPushNotificationsUseCase. execute ( query, cursor: cursor)
297+ let notifications = page. items. map ( PushNotificationItem . init ( from: ) )
310298 if cursor == nil {
311- await send ( . store( . resetPagination) )
299+ await send (
300+ . store( . replaceNotifications(
301+ notifications,
302+ nextCursor: page. nextCursor
303+ ) )
304+ )
305+ } else {
306+ await send (
307+ . store( . appendNotifications(
308+ notifications,
309+ nextCursor: page. nextCursor
310+ ) )
311+ )
312312 }
313- await send (
314- . store( . appendNotifications(
315- page. items. map ( PushNotificationItem . init ( from: ) ) ,
316- nextCursor: page. nextCursor
317- ) )
318- )
319- await send ( . store( . setHasMore( page. items. count == query. pageSize && page. nextCursor != nil ) ) )
320313 if showsIndicator {
321314 await send ( . loading( . end( target: . default, mode: . delayed) ) )
322315 }
@@ -339,8 +332,7 @@ private extension PushNotificationListFeature {
339332 let publisher = try fetchPushNotificationsUseCase. observe ( query, limit: limit)
340333 for try await page in publisher. values {
341334 let items = page. items. map ( PushNotificationItem . init ( from: ) )
342- let hasMore = items. count == max ( query. pageSize, limit) && page. nextCursor != nil
343- await send ( . store( . syncNotifications( items, nextCursor: page. nextCursor, hasMore: hasMore) ) )
335+ await send ( . store( . replaceNotifications( items, nextCursor: page. nextCursor) ) )
344336 }
345337 } catch is CancellationError {
346338 } catch {
0 commit comments