diff --git a/crates/radicle-tauri/src/commands/repo.rs b/crates/radicle-tauri/src/commands/repo.rs index 76361763d..f3bf5502c 100644 --- a/crates/radicle-tauri/src/commands/repo.rs +++ b/crates/radicle-tauri/src/commands/repo.rs @@ -22,6 +22,13 @@ pub fn list_repos( ctx.list_repos(show) } +#[tauri::command] +pub fn list_repos_summary( + ctx: tauri::State, +) -> Result, Error> { + ctx.list_repos_summary() +} + #[tauri::command] pub fn repo_count(ctx: tauri::State) -> Result { ctx.repo_count() diff --git a/crates/radicle-tauri/src/lib.rs b/crates/radicle-tauri/src/lib.rs index 366c2ea54..73bb81434 100644 --- a/crates/radicle-tauri/src/lib.rs +++ b/crates/radicle-tauri/src/lib.rs @@ -58,6 +58,7 @@ pub fn run() { repo::diff_stats, repo::list_commits, repo::list_repos, + repo::list_repos_summary, repo::repo_by_id, repo::repo_count, repo::repo_readme, diff --git a/crates/radicle-types/bindings/repo/RepoSummary.ts b/crates/radicle-types/bindings/repo/RepoSummary.ts new file mode 100644 index 000000000..a74fa9e0c --- /dev/null +++ b/crates/radicle-types/bindings/repo/RepoSummary.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type RepoSummary = { rid: string; name: string }; diff --git a/crates/radicle-types/src/repo.rs b/crates/radicle-types/src/repo.rs index 08f81e032..4360a6dff 100644 --- a/crates/radicle-types/src/repo.rs +++ b/crates/radicle-types/src/repo.rs @@ -9,6 +9,16 @@ use radicle::{git, identity, issue, patch}; use crate::cobs::Author; use crate::error; +#[derive(Serialize, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export)] +#[ts(export_to = "repo/")] +pub struct RepoSummary { + #[ts(as = "String")] + pub rid: identity::RepoId, + pub name: String, +} + #[derive(Serialize, TS)] #[serde(rename_all = "camelCase")] #[ts(export)] diff --git a/crates/radicle-types/src/traits/repo.rs b/crates/radicle-types/src/traits/repo.rs index 1a98e745e..edfb05175 100644 --- a/crates/radicle-types/src/traits/repo.rs +++ b/crates/radicle-types/src/traits/repo.rs @@ -73,6 +73,31 @@ pub trait Repo: Profile { Ok::<_, Error>(entries) } + fn list_repos_summary(&self) -> Result, Error> { + let profile = self.profile(); + let storage = &profile.storage; + let repos = storage.repositories()?; + let mut entries = Vec::new(); + + for RepositoryInfo { rid, doc, .. } in repos { + let Some(data) = doc + .payload() + .get(&doc::PayloadId::project()) + .and_then(|payload| repo::ProjectPayloadData::try_from((*payload).clone()).ok()) + else { + continue; + }; + entries.push(repo::RepoSummary { + rid, + name: data.name, + }); + } + + entries.sort_by_key(|r| r.name.to_lowercase()); + + Ok::<_, Error>(entries) + } + fn repo_count(&self) -> Result { let profile = self.profile(); let storage = &profile.storage; diff --git a/crates/test-http-api/src/api.rs b/crates/test-http-api/src/api.rs index f42d43174..ecc8f60a0 100644 --- a/crates/test-http-api/src/api.rs +++ b/crates/test-http-api/src/api.rs @@ -63,6 +63,7 @@ pub fn router(ctx: Context) -> Router { .route("/authenticate", post(auth_handler)) .route("/repo_count", post(repo_count_handler)) .route("/list_repos", post(repo_root_handler)) + .route("/list_repos_summary", post(list_repos_summary_handler)) .route("/repo_by_id", post(repo_handler)) .route("/version", post(version_handler)) .route("/diff_stats", post(diff_stats_handler)) @@ -131,6 +132,11 @@ async fn repo_count_handler(State(ctx): State) -> impl IntoResponse { Ok::<_, Error>(Json(repos)) } +async fn list_repos_summary_handler(State(ctx): State) -> impl IntoResponse { + let repos = ctx.list_repos_summary()?; + Ok::<_, Error>(Json(repos)) +} + #[derive(Serialize, Deserialize)] struct RepoBody { pub rid: identity::RepoId,