Fix: consolidated notifications (#461)
* Fix consolidated notifications pagination * Only group followers on All notifications screen
This commit is contained in:
parent
1983ae0f48
commit
ffcb0574cc
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue