mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-09-08 18:58:07 +00:00
Fix: consolidated notifications (#461)
* Fix consolidated notifications pagination * Only group followers on All notifications screen
This commit is contained in:
parent
1983ae0f48
commit
ffcb0574cc
1 changed files with 18 additions and 13 deletions
|
@ -65,7 +65,7 @@ class NotificationsViewModel: ObservableObject {
|
||||||
maxId: nil,
|
maxId: nil,
|
||||||
types: queryTypes))
|
types: queryTypes))
|
||||||
self.notifications = notifications
|
self.notifications = notifications
|
||||||
consolidatedNotifications = notifications.consolidated()
|
consolidatedNotifications = notifications.consolidated(selectedType: selectedType)
|
||||||
nextPageState = notifications.count < 15 ? .none : .hasNextPage
|
nextPageState = notifications.count < 15 ? .none : .hasNextPage
|
||||||
} else if let first = consolidatedNotifications.first {
|
} else if let first = consolidatedNotifications.first {
|
||||||
var newNotifications: [Models.Notification] =
|
var newNotifications: [Models.Notification] =
|
||||||
|
@ -77,7 +77,10 @@ class NotificationsViewModel: ObservableObject {
|
||||||
!consolidatedNotifications.contains(where: { $0.id == notification.id })
|
!consolidatedNotifications.contains(where: { $0.id == notification.id })
|
||||||
}
|
}
|
||||||
notifications.append(contentsOf: newNotifications)
|
notifications.append(contentsOf: newNotifications)
|
||||||
consolidatedNotifications.insert(contentsOf: newNotifications.consolidated(), at: 0)
|
consolidatedNotifications.insert(
|
||||||
|
contentsOf: newNotifications.consolidated(selectedType: selectedType),
|
||||||
|
at: 0
|
||||||
|
)
|
||||||
}
|
}
|
||||||
withAnimation {
|
withAnimation {
|
||||||
state = .display(notifications: consolidatedNotifications,
|
state = .display(notifications: consolidatedNotifications,
|
||||||
|
@ -91,13 +94,13 @@ class NotificationsViewModel: ObservableObject {
|
||||||
func fetchNextPage() async {
|
func fetchNextPage() async {
|
||||||
guard let client else { return }
|
guard let client else { return }
|
||||||
do {
|
do {
|
||||||
guard let lastId = consolidatedNotifications.last?.id else { return }
|
guard let lastId = consolidatedNotifications.last?.notificationIds.last else { return }
|
||||||
state = .display(notifications: consolidatedNotifications, nextPageState: .loadingNextPage)
|
state = .display(notifications: consolidatedNotifications, nextPageState: .loadingNextPage)
|
||||||
let newNotifications: [Models.Notification] =
|
let newNotifications: [Models.Notification] =
|
||||||
try await client.get(endpoint: Notifications.notifications(sinceId: nil,
|
try await client.get(endpoint: Notifications.notifications(sinceId: nil,
|
||||||
maxId: lastId,
|
maxId: lastId,
|
||||||
types: queryTypes))
|
types: queryTypes))
|
||||||
consolidatedNotifications.append(contentsOf: newNotifications.consolidated())
|
consolidatedNotifications.append(contentsOf: newNotifications.consolidated(selectedType: selectedType))
|
||||||
notifications.append(contentsOf: newNotifications)
|
notifications.append(contentsOf: newNotifications)
|
||||||
state = .display(notifications: consolidatedNotifications, nextPageState: newNotifications.count < 15 ? .none : .hasNextPage)
|
state = .display(notifications: consolidatedNotifications, nextPageState: newNotifications.count < 15 ? .none : .hasNextPage)
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -118,10 +121,10 @@ class NotificationsViewModel: ObservableObject {
|
||||||
{
|
{
|
||||||
if let selectedType, event.notification.type == selectedType.rawValue {
|
if let selectedType, event.notification.type == selectedType.rawValue {
|
||||||
notifications.insert(event.notification, at: 0)
|
notifications.insert(event.notification, at: 0)
|
||||||
consolidatedNotifications = notifications.consolidated()
|
consolidatedNotifications = notifications.consolidated(selectedType: selectedType)
|
||||||
} else if selectedType == nil {
|
} else if selectedType == nil {
|
||||||
notifications.insert(event.notification, at: 0)
|
notifications.insert(event.notification, at: 0)
|
||||||
consolidatedNotifications = notifications.consolidated()
|
consolidatedNotifications = notifications.consolidated(selectedType: selectedType)
|
||||||
}
|
}
|
||||||
state = .display(notifications: consolidatedNotifications, nextPageState: .hasNextPage)
|
state = .display(notifications: consolidatedNotifications, nextPageState: .hasNextPage)
|
||||||
}
|
}
|
||||||
|
@ -129,14 +132,16 @@ class NotificationsViewModel: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ConsolidatedNotification: Identifiable {
|
struct ConsolidatedNotification: Identifiable {
|
||||||
let id: String
|
let notificationIds: [String]
|
||||||
let type: Models.Notification.NotificationType
|
let type: Models.Notification.NotificationType
|
||||||
let createdAt: ServerDate
|
let createdAt: ServerDate
|
||||||
let accounts: [Account]
|
let accounts: [Account]
|
||||||
let status: Status?
|
let status: Status?
|
||||||
|
|
||||||
|
var id: String? { notificationIds.first }
|
||||||
|
|
||||||
static func placeholder() -> ConsolidatedNotification {
|
static func placeholder() -> ConsolidatedNotification {
|
||||||
.init(id: UUID().uuidString,
|
.init(notificationIds: [UUID().uuidString],
|
||||||
type: .favourite,
|
type: .favourite,
|
||||||
createdAt: "2022-12-16T10:20:54.000Z",
|
createdAt: "2022-12-16T10:20:54.000Z",
|
||||||
accounts: [.placeholder()],
|
accounts: [.placeholder()],
|
||||||
|
@ -149,19 +154,19 @@ struct ConsolidatedNotification: Identifiable {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Array where Element == Models.Notification {
|
extension Array where Element == Models.Notification {
|
||||||
func consolidated() -> [ConsolidatedNotification] {
|
func consolidated(selectedType: Models.Notification.NotificationType?) -> [ConsolidatedNotification] {
|
||||||
Dictionary(grouping: self) { notification -> String? in
|
Dictionary(grouping: self) { notification -> String? in
|
||||||
guard let supportedType = notification.supportedType else { return nil }
|
guard let supportedType = notification.supportedType else { return nil }
|
||||||
|
|
||||||
switch supportedType {
|
switch supportedType {
|
||||||
case .follow:
|
case .follow where selectedType != .follow:
|
||||||
// Always group followers
|
// Always group followers
|
||||||
return supportedType.rawValue
|
return supportedType.rawValue
|
||||||
case .reblog, .favourite:
|
case .reblog, .favourite:
|
||||||
// Group boosts and favourites by status
|
// Group boosts and favourites by status
|
||||||
return "\(supportedType.rawValue)-\(notification.status?.id ?? "")"
|
return "\(supportedType.rawValue)-\(notification.status?.id ?? "")"
|
||||||
case .follow_request, .poll, .status, .update, .mention:
|
default:
|
||||||
// Never group those
|
// Never group remaining ones
|
||||||
return notification.id
|
return notification.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +176,7 @@ extension Array where Element == Models.Notification {
|
||||||
let supportedType = notification.supportedType
|
let supportedType = notification.supportedType
|
||||||
else { return nil }
|
else { return nil }
|
||||||
|
|
||||||
return ConsolidatedNotification(id: notification.id,
|
return ConsolidatedNotification(notificationIds: notifications.map(\.id),
|
||||||
type: supportedType,
|
type: supportedType,
|
||||||
createdAt: notification.createdAt,
|
createdAt: notification.createdAt,
|
||||||
accounts: notifications.map(\.account),
|
accounts: notifications.map(\.account),
|
||||||
|
|
Loading…
Reference in a new issue