Load filtered home activity streams
This commit is contained in:
@@ -5,6 +5,48 @@ use crate::{
|
||||
};
|
||||
use gitea_openapi::apis;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||
pub enum ActivityFilter {
|
||||
#[default]
|
||||
All,
|
||||
Issues,
|
||||
PullRequests,
|
||||
}
|
||||
|
||||
impl ActivityFilter {
|
||||
fn matches(self, activity: &models::Activity) -> bool {
|
||||
use models::activity::OpType;
|
||||
|
||||
match self {
|
||||
Self::All => true,
|
||||
Self::Issues => matches!(
|
||||
activity.op_type,
|
||||
Some(
|
||||
OpType::CreateIssue
|
||||
| OpType::CloseIssue
|
||||
| OpType::ReopenIssue
|
||||
| OpType::CommentIssue
|
||||
)
|
||||
),
|
||||
Self::PullRequests => matches!(
|
||||
activity.op_type,
|
||||
Some(
|
||||
OpType::CreatePullRequest
|
||||
| OpType::MergePullRequest
|
||||
| OpType::AutoMergePullRequest
|
||||
| OpType::ClosePullRequest
|
||||
| OpType::ReopenPullRequest
|
||||
| OpType::CommentPull
|
||||
| OpType::ApprovePullRequest
|
||||
| OpType::RejectPullRequest
|
||||
| OpType::PullReviewDismissed
|
||||
| OpType::PullRequestReadyForReview
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum Target {
|
||||
Repository {
|
||||
@@ -29,7 +71,7 @@ pub enum Target {
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub async fn home(&self, page: i32) -> Result<HomeData> {
|
||||
pub async fn home(&self, page: i32, filter: ActivityFilter) -> Result<HomeData> {
|
||||
if page < 1 {
|
||||
return Err(Error::InvalidInput("page must be positive".into()));
|
||||
}
|
||||
@@ -39,27 +81,51 @@ impl Client {
|
||||
.await?
|
||||
.login
|
||||
.ok_or_else(|| Error::Generated("The server account has no username.".into()))?;
|
||||
let activities = apis::user_api::user_list_activity_feeds(
|
||||
&configuration,
|
||||
&login,
|
||||
Some(true),
|
||||
None,
|
||||
Some(page),
|
||||
Some(DEFAULT_PAGE_SIZE),
|
||||
);
|
||||
let activities = activity_page(&configuration, &login, page);
|
||||
let (activities, heatmap) = tokio::join!(
|
||||
activities,
|
||||
apis::user_api::user_get_heatmap_data(&configuration, &login),
|
||||
);
|
||||
let activities = activities.map_err(Error::generated)?;
|
||||
Ok(HomeData {
|
||||
has_more: activities.len() == DEFAULT_PAGE_SIZE as usize,
|
||||
activities,
|
||||
heatmap: heatmap.map_err(Error::generated)?,
|
||||
})
|
||||
let mut activities = activities?;
|
||||
let heatmap = heatmap.map_err(Error::generated)?;
|
||||
let mut page = page;
|
||||
|
||||
loop {
|
||||
let has_more = activities.len() == DEFAULT_PAGE_SIZE as usize;
|
||||
let filtered: Vec<_> = activities
|
||||
.into_iter()
|
||||
.filter(|activity| filter.matches(activity))
|
||||
.collect();
|
||||
if filter == ActivityFilter::All || !filtered.is_empty() || !has_more {
|
||||
return Ok(HomeData {
|
||||
activities: filtered,
|
||||
heatmap,
|
||||
next_page: has_more.then_some(page + 1),
|
||||
});
|
||||
}
|
||||
page += 1;
|
||||
activities = activity_page(&configuration, &login, page).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn activity_page(
|
||||
configuration: &apis::configuration::Configuration,
|
||||
login: &str,
|
||||
page: i32,
|
||||
) -> Result<Vec<models::Activity>> {
|
||||
apis::user_api::user_list_activity_feeds(
|
||||
configuration,
|
||||
login,
|
||||
Some(true),
|
||||
None,
|
||||
Some(page),
|
||||
Some(DEFAULT_PAGE_SIZE),
|
||||
)
|
||||
.await
|
||||
.map_err(Error::generated)
|
||||
}
|
||||
|
||||
pub fn target(activity: &models::Activity) -> Option<Target> {
|
||||
use models::activity::OpType;
|
||||
|
||||
@@ -205,4 +271,29 @@ mod tests {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn filters_issue_and_pull_request_activity() {
|
||||
let activities = [
|
||||
activity(OpType::CreateIssue, ""),
|
||||
activity(OpType::CreatePullRequest, ""),
|
||||
activity(OpType::PullRequestReadyForReview, ""),
|
||||
activity(OpType::CreateRepo, ""),
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
activities
|
||||
.iter()
|
||||
.filter(|activity| ActivityFilter::Issues.matches(activity))
|
||||
.count(),
|
||||
1
|
||||
);
|
||||
assert_eq!(
|
||||
activities
|
||||
.iter()
|
||||
.filter(|activity| ActivityFilter::PullRequests.matches(activity))
|
||||
.count(),
|
||||
2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ pub struct HistoryCommit {
|
||||
pub struct HomeData {
|
||||
pub activities: Vec<models::Activity>,
|
||||
pub heatmap: Vec<models::UserHeatmapData>,
|
||||
pub has_more: bool,
|
||||
pub next_page: Option<i32>,
|
||||
}
|
||||
|
||||
pub type PullRefs = HashMap<String, Vec<String>>;
|
||||
|
||||
@@ -19,6 +19,7 @@ mod milestones;
|
||||
mod pulls;
|
||||
mod repositories;
|
||||
|
||||
pub use activity::ActivityFilter;
|
||||
pub use domain::{
|
||||
CreateIssue, DEFAULT_PAGE_SIZE, EditIssue, HistoryCommit, HomeData, IssueDetails, IssueDraft,
|
||||
IssueEditorData, IssueQuery, MilestoneDetails, MilestoneDraft, Page, PullDetails, RepositoryId,
|
||||
|
||||
Reference in New Issue
Block a user