Add paginated panel loading

This commit is contained in:
Georg Bauer
2026-07-31 15:02:21 +02:00
parent 228879da15
commit 33f9eb809c
11 changed files with 1104 additions and 290 deletions

View File

@@ -8,6 +8,7 @@ final class IssuesViewController: RefreshingTableViewController {
private var rows: [IssueRow] = []
private var filterOptions: IssueFilterOptions?
private var filterTask: Task<Void, Never>?
private var currentPage: UInt32 = 0
private lazy var filterButton = UIBarButtonItem(
image: context.symbol("line.3.horizontal.decrease.circle")
)
@@ -45,17 +46,38 @@ final class IssuesViewController: RefreshingTableViewController {
}
private func loadIssues(refreshing: Bool) {
beginLoading(refreshing: refreshing)
loadIssues(page: 1, refreshing: refreshing)
}
override func loadMoreContent() {
loadIssues(page: currentPage + 1, refreshing: false)
}
private func loadIssues(page: UInt32, refreshing: Bool) {
if page == 1 {
resetPagination()
beginLoading(refreshing: refreshing)
}
loadingTask?.cancel()
loadingTask = Task {
do {
rows = try await context.core.issues(owner: owner, repository: repository)
let result = try await context.core.issues(
owner: owner,
repository: repository,
page: page
)
if page == 1 { rows = result.rows } else { rows.append(contentsOf: result.rows) }
currentPage = page
finishPagination(hasMore: result.hasMore)
tableView.reloadData()
updateEmptyState()
} catch {
if !Task.isCancelled { show(error: error) }
if !Task.isCancelled {
show(error: error)
failPagination()
}
}
endLoading()
if page == 1 { endLoading() }
}
}
@@ -335,6 +357,7 @@ final class MilestonesViewController: RefreshingTableViewController {
private let owner: String
private let repository: String
private var rows: [MilestoneRow] = []
private var currentPage: UInt32 = 0
init(context: AppContext, owner: String, repository: String) {
self.context = context
@@ -356,11 +379,29 @@ final class MilestonesViewController: RefreshingTableViewController {
}
override func loadContent(refreshing: Bool) {
beginLoading(refreshing: refreshing)
loadPage(1, refreshing: refreshing)
}
override func loadMoreContent() {
loadPage(currentPage + 1, refreshing: false)
}
private func loadPage(_ page: UInt32, refreshing: Bool) {
if page == 1 {
resetPagination()
beginLoading(refreshing: refreshing)
}
loadingTask?.cancel()
loadingTask = Task {
do {
rows = try await context.core.milestones(owner: owner, repository: repository)
let result = try await context.core.milestones(
owner: owner,
repository: repository,
page: page
)
if page == 1 { rows = result.rows } else { rows.append(contentsOf: result.rows) }
currentPage = page
finishPagination(hasMore: result.hasMore)
tableView.reloadData()
tableView.backgroundView = rows.isEmpty
? EmptyBackgroundView(
@@ -369,9 +410,12 @@ final class MilestonesViewController: RefreshingTableViewController {
)
: nil
} catch {
if !Task.isCancelled { show(error: error) }
if !Task.isCancelled {
show(error: error)
failPagination()
}
}
endLoading()
if page == 1 { endLoading() }
}
}
@@ -412,6 +456,7 @@ final class MilestoneViewController: RefreshingTableViewController {
private let repository: String
private let id: Int64
private var page: MilestonePage?
private var currentPage: UInt32 = 0
init(context: AppContext, owner: String, repository: String, id: Int64) {
self.context = context
@@ -435,21 +480,45 @@ final class MilestoneViewController: RefreshingTableViewController {
}
override func loadContent(refreshing: Bool) {
beginLoading(refreshing: refreshing)
loadPage(1, refreshing: refreshing)
}
override func loadMoreContent() {
loadPage(currentPage + 1, refreshing: false)
}
private func loadPage(_ requestedPage: UInt32, refreshing: Bool) {
if requestedPage == 1 {
resetPagination()
beginLoading(refreshing: refreshing)
}
loadingTask?.cancel()
loadingTask = Task {
do {
page = try await context.core.milestone(
let result = try await context.core.milestone(
owner: owner,
repository: repository,
id: id
id: id,
page: requestedPage
)
if requestedPage == 1 {
page = result
} else {
page?.issues.append(contentsOf: result.issues)
page?.pulls.append(contentsOf: result.pulls)
page?.hasMore = result.hasMore
}
currentPage = requestedPage
finishPagination(hasMore: result.hasMore)
title = page?.milestone.title
tableView.reloadData()
} catch {
if !Task.isCancelled { show(error: error) }
if !Task.isCancelled {
show(error: error)
failPagination()
}
}
endLoading()
if requestedPage == 1 { endLoading() }
}
}
@@ -584,6 +653,7 @@ final class PullsViewController: RefreshingTableViewController {
private var rows: [PullRow] = []
private var filterOptions: PullFilterOptions?
private var filterTask: Task<Void, Never>?
private var currentPage: UInt32 = 0
init(context: AppContext) {
self.context = context
@@ -626,11 +696,25 @@ final class PullsViewController: RefreshingTableViewController {
}
private func loadPulls(refreshing: Bool) {
beginLoading(refreshing: refreshing)
loadPulls(page: 1, refreshing: refreshing)
}
override func loadMoreContent() {
loadPulls(page: currentPage + 1, refreshing: false)
}
private func loadPulls(page: UInt32, refreshing: Bool) {
if page == 1 {
resetPagination()
beginLoading(refreshing: refreshing)
}
loadingTask?.cancel()
loadingTask = Task {
do {
rows = try await context.core.pulls()
let result = try await context.core.pulls(page: page)
if page == 1 { rows = result.rows } else { rows.append(contentsOf: result.rows) }
currentPage = page
finishPagination(hasMore: result.hasMore)
tableView.reloadData()
let status = context.core.settings().pullStatus
tableView.backgroundView = rows.isEmpty
@@ -642,9 +726,12 @@ final class PullsViewController: RefreshingTableViewController {
)
: nil
} catch {
if !Task.isCancelled { show(error: error) }
if !Task.isCancelled {
show(error: error)
failPagination()
}
}
endLoading()
if page == 1 { endLoading() }
}
}
@@ -783,6 +870,7 @@ final class CommitsViewController: RefreshingTableViewController {
private var contents: [RepositoryContentRow] = []
private var branch: String?
private var mode = Mode.history
private var currentPage: UInt32 = 0
init(context: AppContext, owner: String, repository: String) {
self.context = context
@@ -808,7 +896,19 @@ final class CommitsViewController: RefreshingTableViewController {
}
override func loadContent(refreshing: Bool) {
beginLoading(refreshing: refreshing)
loadPage(1, refreshing: refreshing)
}
override func loadMoreContent() {
guard mode == .history else { return }
loadPage(currentPage + 1, refreshing: false)
}
private func loadPage(_ requestedPage: UInt32, refreshing: Bool) {
if requestedPage == 1 {
resetPagination()
beginLoading(refreshing: refreshing)
}
loadingTask?.cancel()
loadingTask = Task {
do {
@@ -817,8 +917,11 @@ final class CommitsViewController: RefreshingTableViewController {
page = try await context.core.commits(
owner: owner,
repository: repository,
branch: branch
branch: branch,
pages: requestedPage
)
currentPage = requestedPage
finishPagination(hasMore: page?.hasMore ?? false)
updateBranchMenu()
case .files:
contents = try await context.core.repositoryContents(
@@ -830,9 +933,12 @@ final class CommitsViewController: RefreshingTableViewController {
tableView.reloadData()
updateEmptyView()
} catch {
if !Task.isCancelled { show(error: error) }
if !Task.isCancelled {
show(error: error)
failPagination()
}
}
endLoading()
if requestedPage == 1 { endLoading() }
}
}