Fix: consolidated notifications (#461)

* Fix consolidated notifications pagination

* Only group followers on All notifications screen
This commit is contained in:
Jérôme Danthinne 2023-01-28 09:04:35 +01:00 committed by GitHub
parent 1983ae0f48
commit ffcb0574cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -65,7 +65,7 @@ class NotificationsViewModel: ObservableObject {
maxId: nil,
types: queryTypes))
self.notifications = notifications
consolidatedNotifications = notifications.consolidated()
consolidatedNotifications = notifications.consolidated(selectedType: selectedType)
nextPageState = notifications.count < 15 ? .none : .hasNextPage
} else if let first = consolidatedNotifications.first {
var newNotifications: [Models.Notification] =
@ -77,7 +77,10 @@ class NotificationsViewModel: ObservableObject {
!consolidatedNotifications.contains(where: { $0.id == notification.id })
}
notifications.append(contentsOf: newNotifications)
consolidatedNotifications.insert(contentsOf: newNotifications.consolidated(), at: 0)
consolidatedNotifications.insert(
contentsOf: newNotifications.consolidated(selectedType: selectedType),
at: 0
)
}
withAnimation {
state = .display(notifications: consolidatedNotifications,
@ -91,13 +94,13 @@ class NotificationsViewModel: ObservableObject {
func fetchNextPage() async {
guard let client else { return }
do {
guard let lastId = consolidatedNotifications.last?.id else { return }
guard let lastId = consolidatedNotifications.last?.notificationIds.last else { return }
state = .display(notifications: consolidatedNotifications, nextPageState: .loadingNextPage)
let newNotifications: [Models.Notification] =
try await client.get(endpoint: Notifications.notifications(sinceId: nil,
maxId: lastId,
types: queryTypes))
consolidatedNotifications.append(contentsOf: newNotifications.consolidated())
consolidatedNotifications.append(contentsOf: newNotifications.consolidated(selectedType: selectedType))
notifications.append(contentsOf: newNotifications)
state = .display(notifications: consolidatedNotifications, nextPageState: newNotifications.count < 15 ? .none : .hasNextPage)
} catch {
@ -118,10 +121,10 @@ class NotificationsViewModel: ObservableObject {
{
if let selectedType, event.notification.type == selectedType.rawValue {
notifications.insert(event.notification, at: 0)
consolidatedNotifications = notifications.consolidated()
consolidatedNotifications = notifications.consolidated(selectedType: selectedType)
} else if selectedType == nil {
notifications.insert(event.notification, at: 0)
consolidatedNotifications = notifications.consolidated()
consolidatedNotifications = notifications.consolidated(selectedType: selectedType)
}
state = .display(notifications: consolidatedNotifications, nextPageState: .hasNextPage)
}
@ -129,14 +132,16 @@ class NotificationsViewModel: ObservableObject {
}
struct ConsolidatedNotification: Identifiable {
let id: String
let notificationIds: [String]
let type: Models.Notification.NotificationType
let createdAt: ServerDate
let accounts: [Account]
let status: Status?
var id: String? { notificationIds.first }
static func placeholder() -> ConsolidatedNotification {
.init(id: UUID().uuidString,
.init(notificationIds: [UUID().uuidString],
type: .favourite,
createdAt: "2022-12-16T10:20:54.000Z",
accounts: [.placeholder()],
@ -149,19 +154,19 @@ struct ConsolidatedNotification: Identifiable {
}
extension Array where Element == Models.Notification {
func consolidated() -> [ConsolidatedNotification] {
func consolidated(selectedType: Models.Notification.NotificationType?) -> [ConsolidatedNotification] {
Dictionary(grouping: self) { notification -> String? in
guard let supportedType = notification.supportedType else { return nil }
switch supportedType {
case .follow:
case .follow where selectedType != .follow:
// Always group followers
return supportedType.rawValue
case .reblog, .favourite:
// Group boosts and favourites by status
return "\(supportedType.rawValue)-\(notification.status?.id ?? "")"
case .follow_request, .poll, .status, .update, .mention:
// Never group those
default:
// Never group remaining ones
return notification.id
}
}
@ -171,7 +176,7 @@ extension Array where Element == Models.Notification {
let supportedType = notification.supportedType
else { return nil }
return ConsolidatedNotification(id: notification.id,
return ConsolidatedNotification(notificationIds: notifications.map(\.id),
type: supportedType,
createdAt: notification.createdAt,
accounts: notifications.map(\.account),