mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-29 11:41:01 +00:00
Notifications: Load more newer pages
This commit is contained in:
parent
c5e43394c8
commit
cf6a2f845f
2 changed files with 47 additions and 16 deletions
|
@ -1,9 +1,10 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public enum Notifications: Endpoint {
|
public enum Notifications: Endpoint {
|
||||||
case notifications(sinceId: String?,
|
case notifications(minId: String?,
|
||||||
maxId: String?,
|
maxId: String?,
|
||||||
types: [String]?)
|
types: [String]?,
|
||||||
|
limit: Int)
|
||||||
case clear
|
case clear
|
||||||
|
|
||||||
public func path() -> String {
|
public func path() -> String {
|
||||||
|
@ -17,8 +18,9 @@ public enum Notifications: Endpoint {
|
||||||
|
|
||||||
public func queryItems() -> [URLQueryItem]? {
|
public func queryItems() -> [URLQueryItem]? {
|
||||||
switch self {
|
switch self {
|
||||||
case let .notifications(sinceId, maxId, types):
|
case let .notifications(mindId, maxId, types, limit):
|
||||||
var params = makePaginationParam(sinceId: sinceId, maxId: maxId, mindId: nil) ?? []
|
var params = makePaginationParam(sinceId: nil, maxId: maxId, mindId: mindId) ?? []
|
||||||
|
params.append(.init(name: "limit", value: String(limit)))
|
||||||
if let types {
|
if let types {
|
||||||
for type in types {
|
for type in types {
|
||||||
params.append(.init(name: "exclude_types[]", value: type))
|
params.append(.init(name: "exclude_types[]", value: type))
|
||||||
|
|
|
@ -16,6 +16,10 @@ class NotificationsViewModel: ObservableObject {
|
||||||
case error(error: Error)
|
case error(error: Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Constants {
|
||||||
|
static let notificationLimit: Int = 30
|
||||||
|
}
|
||||||
|
|
||||||
public enum Tab: LocalizedStringKey, CaseIterable {
|
public enum Tab: LocalizedStringKey, CaseIterable {
|
||||||
case all = "notifications.tab.all"
|
case all = "notifications.tab.all"
|
||||||
case mentions = "notifications.tab.mentions"
|
case mentions = "notifications.tab.mentions"
|
||||||
|
@ -60,17 +64,15 @@ class NotificationsViewModel: ObservableObject {
|
||||||
if consolidatedNotifications.isEmpty {
|
if consolidatedNotifications.isEmpty {
|
||||||
state = .loading
|
state = .loading
|
||||||
let notifications: [Models.Notification] =
|
let notifications: [Models.Notification] =
|
||||||
try await client.get(endpoint: Notifications.notifications(sinceId: nil,
|
try await client.get(endpoint: Notifications.notifications(minId: nil,
|
||||||
maxId: nil,
|
maxId: nil,
|
||||||
types: queryTypes))
|
types: queryTypes,
|
||||||
|
limit: Constants.notificationLimit))
|
||||||
consolidatedNotifications = notifications.consolidated(selectedType: selectedType)
|
consolidatedNotifications = notifications.consolidated(selectedType: selectedType)
|
||||||
nextPageState = notifications.count < 15 ? .none : .hasNextPage
|
nextPageState = notifications.count < Constants.notificationLimit ? .none : .hasNextPage
|
||||||
} else if let first = consolidatedNotifications.first {
|
} else if let firstId = consolidatedNotifications.first?.id {
|
||||||
var newNotifications: [Models.Notification] =
|
var newNotifications: [Models.Notification] = await fetchNewPages(minId: firstId, maxPages: 10)
|
||||||
try await client.get(endpoint: Notifications.notifications(sinceId: first.id,
|
nextPageState = consolidatedNotifications.notificationCount < Constants.notificationLimit ? .none : .hasNextPage
|
||||||
maxId: nil,
|
|
||||||
types: queryTypes))
|
|
||||||
nextPageState = consolidatedNotifications.notificationCount < 15 ? .none : .hasNextPage
|
|
||||||
newNotifications = newNotifications.filter { notification in
|
newNotifications = newNotifications.filter { notification in
|
||||||
!consolidatedNotifications.contains(where: { $0.id == notification.id })
|
!consolidatedNotifications.contains(where: { $0.id == notification.id })
|
||||||
}
|
}
|
||||||
|
@ -91,18 +93,45 @@ class NotificationsViewModel: ObservableObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func fetchNewPages(minId: String, maxPages: Int) async -> [Models.Notification] {
|
||||||
|
guard let client else { return [] }
|
||||||
|
var pagesLoaded = 0
|
||||||
|
var allNotifications: [Models.Notification] = []
|
||||||
|
var latestMinId = minId
|
||||||
|
do {
|
||||||
|
while let newNotifications: [Models.Notification] =
|
||||||
|
try await client.get(endpoint: Notifications.notifications(minId: latestMinId,
|
||||||
|
maxId: nil,
|
||||||
|
types: queryTypes,
|
||||||
|
limit: Constants.notificationLimit)),
|
||||||
|
!newNotifications.isEmpty,
|
||||||
|
pagesLoaded < maxPages
|
||||||
|
{
|
||||||
|
pagesLoaded += 1
|
||||||
|
|
||||||
|
allNotifications.insert(contentsOf: newNotifications, at: 0)
|
||||||
|
latestMinId = newNotifications.first?.id ?? ""
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return allNotifications
|
||||||
|
}
|
||||||
|
return allNotifications
|
||||||
|
}
|
||||||
|
|
||||||
func fetchNextPage() async {
|
func fetchNextPage() async {
|
||||||
guard let client else { return }
|
guard let client else { return }
|
||||||
do {
|
do {
|
||||||
guard let lastId = consolidatedNotifications.last?.notificationIds.last 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(minId: nil,
|
||||||
maxId: lastId,
|
maxId: lastId,
|
||||||
types: queryTypes))
|
types: queryTypes,
|
||||||
|
limit: Constants.notificationLimit))
|
||||||
consolidatedNotifications.append(contentsOf: newNotifications.consolidated(selectedType: selectedType))
|
consolidatedNotifications.append(contentsOf: newNotifications.consolidated(selectedType: selectedType))
|
||||||
await currentAccount?.fetchFollowerRequests()
|
await currentAccount?.fetchFollowerRequests()
|
||||||
state = .display(notifications: consolidatedNotifications, nextPageState: newNotifications.count < 15 ? .none : .hasNextPage)
|
state = .display(notifications: consolidatedNotifications,
|
||||||
|
nextPageState: newNotifications.count < Constants.notificationLimit ? .none : .hasNextPage)
|
||||||
} catch {
|
} catch {
|
||||||
state = .error(error: error)
|
state = .error(error: error)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue