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

@@ -173,18 +173,36 @@ impl GotchaCore {
save_preferences(&state.preferences).map_err(Into::into)
}
pub async fn home(&self) -> Result<HomePage, GotchaError> {
pub async fn home(&self, page: u32) -> Result<HomePage, GotchaError> {
let server = self.server()?;
let name = server.name.clone();
Ok(home_page(name, load_home(&server).await?))
Ok(home_page(
name,
load_home(&server, valid_page(page)?).await?,
))
}
pub async fn repositories(&self) -> Result<Vec<RepositoryRow>, GotchaError> {
pub async fn repositories(&self, page: u32) -> Result<RepositoryListPage, GotchaError> {
let server = self.server()?;
let repositories = load_repositories(&server).await?;
let page_number = valid_page(page)?;
let repositories = load_repositories(&server, page_number).await?;
let mut state = self.state.lock().unwrap();
state.repositories = repositories;
Ok(self.repository_rows(&state))
if page_number == 1 {
state.repositories.clear();
}
for repository in repositories.items {
if let Some(existing) = state.repositories.iter_mut().find(|candidate| {
candidate.owner == repository.owner && candidate.name == repository.name
}) {
*existing = repository;
} else {
state.repositories.push(repository);
}
}
Ok(RepositoryListPage {
rows: self.repository_rows(&state),
has_more: repositories.has_more,
})
}
pub fn toggle_favorite(
@@ -209,7 +227,8 @@ impl GotchaCore {
&self,
owner: String,
repository: String,
) -> Result<Vec<IssueRow>, GotchaError> {
page: u32,
) -> Result<IssueListPage, GotchaError> {
let server = self.server()?;
let (status, filter) = {
let state = self.state.lock().unwrap();
@@ -224,17 +243,20 @@ impl GotchaCore {
)
};
let labels: Vec<_> = filter.labels.into_iter().collect();
Ok(issue_rows(
&load_issues(
&server,
&owner,
&repository,
&status,
&labels,
&filter.milestone,
)
.await?,
))
let page = load_issues(
&server,
&owner,
&repository,
&status,
&labels,
&filter.milestone,
valid_page(page)?,
)
.await?;
Ok(IssueListPage {
rows: issue_rows(&page.items),
has_more: page.has_more,
})
}
pub async fn issue_filters(
@@ -317,9 +339,17 @@ impl GotchaCore {
owner: String,
repository: String,
number: i64,
page: u32,
) -> Result<IssuePage, GotchaError> {
Ok(issue_page(
load_issue(&self.server()?, &owner, &repository, number).await?,
load_issue(
&self.server()?,
&owner,
&repository,
number,
valid_page(page)?,
)
.await?,
))
}
@@ -387,10 +417,14 @@ impl GotchaCore {
&self,
owner: String,
repository: String,
) -> Result<Vec<MilestoneRow>, GotchaError> {
Ok(milestone_rows(
&load_milestones(&self.server()?, &owner, &repository).await?,
))
page: u32,
) -> Result<MilestoneListPage, GotchaError> {
let page =
load_milestones_page(&self.server()?, &owner, &repository, valid_page(page)?).await?;
Ok(MilestoneListPage {
rows: milestone_rows(&page.items),
has_more: page.has_more,
})
}
pub async fn milestone(
@@ -398,9 +432,10 @@ impl GotchaCore {
owner: String,
repository: String,
id: i64,
page: u32,
) -> Result<MilestonePage, GotchaError> {
Ok(milestone_page(
load_milestone(&self.server()?, &owner, &repository, id).await?,
load_milestone(&self.server()?, &owner, &repository, id, valid_page(page)?).await?,
))
}
@@ -449,7 +484,7 @@ impl GotchaCore {
save_preferences(&state.preferences).map_err(Into::into)
}
pub async fn pulls(&self) -> Result<Vec<PullRow>, GotchaError> {
pub async fn pulls(&self, page: u32) -> Result<PullListPage, GotchaError> {
let server = self.server()?;
let (status, filter) = {
let state = self.state.lock().unwrap();
@@ -463,9 +498,11 @@ impl GotchaCore {
.unwrap_or_default(),
)
};
Ok(pull_rows(
&load_pulls(&server, &status, &filter.milestone).await?,
))
let page = load_pulls(&server, &status, &filter.milestone, valid_page(page)?).await?;
Ok(PullListPage {
rows: pull_rows(&page.items),
has_more: page.has_more,
})
}
pub async fn pull(
@@ -473,9 +510,17 @@ impl GotchaCore {
owner: String,
repository: String,
number: i64,
page: u32,
) -> Result<PullPage, GotchaError> {
Ok(pull_page(
load_pull(&self.server()?, &owner, &repository, number).await?,
load_pull(
&self.server()?,
&owner,
&repository,
number,
valid_page(page)?,
)
.await?,
))
}
@@ -484,6 +529,7 @@ impl GotchaCore {
owner: String,
repository: String,
branch: Option<String>,
pages: u32,
) -> Result<CommitPage, GotchaError> {
let server = self.server()?;
let default_branch = self
@@ -497,10 +543,17 @@ impl GotchaCore {
.unwrap_or_else(|| "main".into());
let branches = load_branches(&server, &owner, &repository, &default_branch).await?;
let commits = match branch.as_deref() {
Some(branch) => load_branch_commits(&server, &owner, &repository, branch).await?,
None => load_all_commits(&server, &owner, &repository, &branches).await?,
Some(branch) => {
load_branch_commits(&server, &owner, &repository, branch, pages.max(1)).await?
}
None => load_all_commits(&server, &owner, &repository, &branches, pages.max(1)).await?,
};
Ok(commit_page(branches, &commits, branch.is_none()))
Ok(commit_page(
branches,
&commits.items,
branch.is_none(),
commits.has_more,
))
}
pub async fn repository_contents(
@@ -574,6 +627,13 @@ fn validate_repository<'a>(
Ok((owner, repository))
}
fn valid_page(page: u32) -> Result<i32, GotchaError> {
(page > 0)
.then(|| i32::try_from(page).ok())
.flatten()
.ok_or_else(|| "Invalid page number.".into())
}
impl GotchaCore {
fn server(&self) -> Result<Server, GotchaError> {
let state = self.state.lock().unwrap();