2
2
mirror of https://github.com/mastodon/mastodon-ios synced 2025-04-11 22:58:02 +02:00

Wait for cache to load before reporting results

Contributes to #399 [BUG] Multiple interactions do not collapse into a single notification
This commit is contained in:
shannon 2025-03-04 09:21:21 -05:00
parent ae8af633b3
commit b0b4271202
2 changed files with 64 additions and 40 deletions

View File

@ -198,7 +198,8 @@ final public class GroupedNotificationFeedLoader {
defer {
isFetching = false
}
try await replaceRecordsAfterFiltering(rowViewModels(from: cacheManager.currentResults), canLoadOlder: true)
let currentResults = await cacheManager.currentResults()
try await replaceRecordsAfterFiltering(rowViewModels(from: currentResults), canLoadOlder: true)
}
private func load(_ request: FeedLoadRequest) async throws
@ -225,7 +226,8 @@ extension GroupedNotificationFeedLoader {
guard let cacheManager else { assertionFailure(); return }
do {
cacheManager.updateByInserting(newlyFetched: newlyFetchedResults, at: insertionPoint)
let unfiltered = try rowViewModels(from: cacheManager.currentResults)
let currentResults = await cacheManager.currentResults()
let unfiltered = try rowViewModels(from: currentResults)
let canLoadOlder: Bool? = {
switch insertionPoint {

View File

@ -8,7 +8,7 @@ import MastodonCore
protocol NotificationsCacheManager<T> {
associatedtype T: NotificationsResultType
var currentResults: T? { get }
func currentResults() async -> T?
var currentLastReadMarker: LastReadMarkers.MarkerPosition? { get }
var mostRecentlyFetchedResults: T? { get }
func updateByInserting(newlyFetched: NotificationsResultType, at insertionPoint: GroupedNotificationFeedLoader.FeedLoadRequest.InsertLocation)
@ -40,19 +40,31 @@ class UngroupedNotificationCacheManager: NotificationsCacheManager {
self.userIdentifier = userIdentifier
lastReadMarkerStore = Store.lastReadMarkersStore()
self.cachedNotifications = Store.ungroupedNotificationStore(forKind: feedKind, forUser: userIdentifier)
self.staleResults = cachedNotifications.items
switch feedKind {
case .notificationsAll, .notificationsMentionsOnly:
self.staleMarkers = lastReadMarkerStore.items.first(where: { $0.userGUID == userIdentifier.globallyUniqueUserIdentifier })
case .notificationsWithAccount:
self.staleMarkers = nil
}
staleResults = nil
staleMarkers = nil
self.mostRecentlyFetchedResults = nil
self.mostRecentMarkers = nil
}
var currentResults: T? {
return mostRecentlyFetchedResults ?? staleResults
func currentResults() async -> T? {
if let mostRecentlyFetchedResults {
return mostRecentlyFetchedResults
} else {
do {
switch feedKind {
case .notificationsAll, .notificationsMentionsOnly:
try await lastReadMarkerStore.itemsHaveLoaded()
self.staleMarkers = lastReadMarkerStore.items.first(where: { $0.userGUID == userIdentifier.globallyUniqueUserIdentifier })
case .notificationsWithAccount:
self.staleMarkers = nil
}
try await cachedNotifications.itemsHaveLoaded()
staleResults = cachedNotifications.items
} catch {
debugPrint("error reading notifications cache: \(error)")
}
return mostRecentlyFetchedResults ?? staleResults
}
}
var currentLastReadMarker: LastReadMarkers.MarkerPosition? {
@ -148,15 +160,8 @@ class GroupedNotificationCacheManager: NotificationsCacheManager {
fullAccountStore = Store.notificationRelevantFullAccountStore(forKind: feedKind, forUser: userIdentifier)
partialAccountStore = Store.notificationRelevantPartialAccountStore(forKind: feedKind, forUser: userIdentifier)
statusStore = Store.notificationRelevantStatusStore(forKind: feedKind, forUser: userIdentifier)
staleResults = Mastodon.Entity.GroupedNotificationsResults(notificationGroups: notificationGroupStore.items, fullAccounts: fullAccountStore.items, partialAccounts: partialAccountStore.items, statuses: statusStore.items)
switch feedKind {
case .notificationsAll, .notificationsMentionsOnly:
staleMarkers = lastReadMarkerStore.items.first(where: { $0.userGUID == userIdentifier.globallyUniqueUserIdentifier })
case .notificationsWithAccount:
staleMarkers = nil
}
staleMarkers = nil
staleResults = nil
}
func updateByInserting(newlyFetched: NotificationsResultType, at insertionPoint: GroupedNotificationFeedLoader.FeedLoadRequest.InsertLocation) {
@ -265,15 +270,28 @@ class GroupedNotificationCacheManager: NotificationsCacheManager {
mostRecentMarkers = updatable
}
var currentResults: T? {
func currentResults() async -> T? {
do {
try await lastReadMarkerStore.itemsHaveLoaded()
try await notificationGroupStore.itemsHaveLoaded()
try await fullAccountStore.itemsHaveLoaded()
try await partialAccountStore.itemsHaveLoaded()
try await statusStore.itemsHaveLoaded()
staleMarkers = lastReadMarkerStore.items.first(where: { $0.userGUID == userIdentifier.globallyUniqueUserIdentifier })
staleResults = Mastodon.Entity.GroupedNotificationsResults(notificationGroups: notificationGroupStore.items, fullAccounts: fullAccountStore.items, partialAccounts: partialAccountStore.items, statuses: statusStore.items)
} catch {
debugPrint("error loading notifications caches: \(error)")
}
return mostRecentlyFetchedResults ?? staleResults
}
var currentLastReadMarker: LastReadMarkers.MarkerPosition? {
guard let markers = mostRecentMarkers ?? staleMarkers else {
switch feedKind {
case .notificationsAll, .notificationsMentionsOnly:
return (mostRecentMarkers ?? staleMarkers)?.lastRead(forKind: feedKind)
case .notificationsWithAccount:
return nil
}
return markers.lastRead(forKind: feedKind)
}
func commitToCache() async {
@ -284,22 +302,26 @@ class GroupedNotificationCacheManager: NotificationsCacheManager {
}
}
if let mostRecentlyFetchedResults {
try? await notificationGroupStore
.removeAll()
.insert(mostRecentlyFetchedResults.notificationGroups)
.run()
try? await fullAccountStore
.removeAll()
.insert(mostRecentlyFetchedResults.accounts)
.run()
try? await partialAccountStore
.removeAll()
.insert(mostRecentlyFetchedResults.partialAccounts ?? [])
.run()
try? await statusStore
.removeAll()
.insert(mostRecentlyFetchedResults.statuses)
.run()
do {
try await notificationGroupStore
.removeAll()
.insert(mostRecentlyFetchedResults.notificationGroups)
.run()
try await fullAccountStore
.removeAll()
.insert(mostRecentlyFetchedResults.accounts)
.run()
try await partialAccountStore
.removeAll()
.insert(mostRecentlyFetchedResults.partialAccounts ?? [])
.run()
try await statusStore
.removeAll()
.insert(mostRecentlyFetchedResults.statuses)
.run()
} catch {
debugPrint("error comitting to store \(error)")
}
}
}
}