Format TUI commit activity previews
This commit is contained in:
@@ -70,6 +70,20 @@ pub enum Target {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct CommitActivity {
|
||||
pub count: usize,
|
||||
pub commits: Vec<ActivityCommit>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct ActivityCommit {
|
||||
pub sha: String,
|
||||
pub message: String,
|
||||
pub author: String,
|
||||
pub timestamp: String,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub async fn activities(
|
||||
&self,
|
||||
@@ -205,6 +219,28 @@ pub fn target(activity: &models::Activity) -> Option<Target> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn commit_activity(activity: &models::Activity) -> Option<CommitActivity> {
|
||||
let payload: serde_json::Value = serde_json::from_str(activity.content.as_deref()?).ok()?;
|
||||
let mut commits = field(&payload, "Commits")
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter_map(activity_commit)
|
||||
.collect::<Vec<_>>();
|
||||
if commits.is_empty()
|
||||
&& let Some(commit) = field(&payload, "HeadCommit").and_then(activity_commit)
|
||||
{
|
||||
commits.push(commit);
|
||||
}
|
||||
(!commits.is_empty()).then(|| CommitActivity {
|
||||
count: field(&payload, "Len")
|
||||
.and_then(serde_json::Value::as_u64)
|
||||
.and_then(|count| usize::try_from(count).ok())
|
||||
.unwrap_or(commits.len()),
|
||||
commits,
|
||||
})
|
||||
}
|
||||
|
||||
fn issue_number(activity: &models::Activity) -> Option<i64> {
|
||||
activity
|
||||
.comment
|
||||
@@ -233,13 +269,14 @@ fn url_number(url: &str) -> Option<i64> {
|
||||
|
||||
fn commit_sha(content: &str) -> Option<String> {
|
||||
let payload: serde_json::Value = serde_json::from_str(content).ok()?;
|
||||
payload.get("HeadCommit").and_then(find_sha).or_else(|| {
|
||||
payload
|
||||
.get("Commits")?
|
||||
.as_array()?
|
||||
.last()
|
||||
.and_then(find_sha)
|
||||
})
|
||||
field(&payload, "HeadCommit")
|
||||
.and_then(find_sha)
|
||||
.or_else(|| {
|
||||
field(&payload, "Commits")?
|
||||
.as_array()?
|
||||
.last()
|
||||
.and_then(find_sha)
|
||||
})
|
||||
}
|
||||
|
||||
fn find_sha(value: &serde_json::Value) -> Option<String> {
|
||||
@@ -252,6 +289,35 @@ fn find_sha(value: &serde_json::Value) -> Option<String> {
|
||||
})
|
||||
}
|
||||
|
||||
fn activity_commit(value: &serde_json::Value) -> Option<ActivityCommit> {
|
||||
let sha = find_sha(value).unwrap_or_default();
|
||||
let message = string_field(value, "Message")
|
||||
.unwrap_or_default()
|
||||
.to_string();
|
||||
(!sha.is_empty() || !message.is_empty()).then(|| ActivityCommit {
|
||||
sha,
|
||||
message,
|
||||
author: string_field(value, "AuthorName")
|
||||
.or_else(|| string_field(value, "CommitterName"))
|
||||
.unwrap_or_default()
|
||||
.to_string(),
|
||||
timestamp: string_field(value, "Timestamp")
|
||||
.unwrap_or_default()
|
||||
.to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
fn string_field<'a>(value: &'a serde_json::Value, name: &str) -> Option<&'a str> {
|
||||
field(value, name).and_then(serde_json::Value::as_str)
|
||||
}
|
||||
|
||||
fn field<'a>(value: &'a serde_json::Value, name: &str) -> Option<&'a serde_json::Value> {
|
||||
value
|
||||
.as_object()?
|
||||
.iter()
|
||||
.find_map(|(key, value)| key.eq_ignore_ascii_case(name).then_some(value))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -299,6 +365,36 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decodes_forgejo_commit_activity_for_presentation() {
|
||||
let activity = activity(
|
||||
OpType::CommitRepo,
|
||||
r#"{
|
||||
"Commits": [{
|
||||
"Sha1": "0123456789abcdef",
|
||||
"Message": "Fix the preview\n\nDetails",
|
||||
"AuthorName": "Octo Cat",
|
||||
"Timestamp": "2026-08-04T19:04:30+02:00"
|
||||
}],
|
||||
"HeadCommit": {"Sha1": "0123456789abcdef"},
|
||||
"Len": 1
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
commit_activity(&activity),
|
||||
Some(CommitActivity {
|
||||
count: 1,
|
||||
commits: vec![ActivityCommit {
|
||||
sha: "0123456789abcdef".into(),
|
||||
message: "Fix the preview\n\nDetails".into(),
|
||||
author: "Octo Cat".into(),
|
||||
timestamp: "2026-08-04T19:04:30+02:00".into(),
|
||||
}],
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn filters_issue_and_pull_request_activity() {
|
||||
let activities = [
|
||||
|
||||
Reference in New Issue
Block a user