Add repository file browser
This commit is contained in:
@@ -222,6 +222,51 @@ pub async fn load_branches(
|
||||
Ok(branches)
|
||||
}
|
||||
|
||||
pub async fn load_repository_contents(
|
||||
server: &Server,
|
||||
owner: &str,
|
||||
repository: &str,
|
||||
path: &str,
|
||||
) -> Result<Vec<models::ContentsResponse>, String> {
|
||||
let client =
|
||||
Client::new(&server.url, Some(&server.token)).map_err(|error| error.to_string())?;
|
||||
let configuration = client.configuration();
|
||||
if path.is_empty() {
|
||||
apis::repository_api::repo_get_contents_list(&configuration, owner, repository, None)
|
||||
.await
|
||||
.map_err(|error| error.to_string())
|
||||
} else {
|
||||
apis::repository_api::repo_get_contents_ext(
|
||||
&configuration,
|
||||
owner,
|
||||
repository,
|
||||
path,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map(|contents| contents.dir_contents.unwrap_or_default())
|
||||
.map_err(|error| error.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn load_repository_file(
|
||||
server: &Server,
|
||||
owner: &str,
|
||||
repository: &str,
|
||||
path: &str,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
let client =
|
||||
Client::new(&server.url, Some(&server.token)).map_err(|error| error.to_string())?;
|
||||
apis::repository_api::repo_get_raw_file(&client.configuration(), owner, repository, path, None)
|
||||
.await
|
||||
.map_err(|error| error.to_string())?
|
||||
.bytes()
|
||||
.await
|
||||
.map(|bytes| bytes.to_vec())
|
||||
.map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
pub async fn load_branch_commits(
|
||||
server: &Server,
|
||||
owner: &str,
|
||||
|
||||
@@ -290,6 +290,26 @@ impl GotchaCore {
|
||||
Ok(commit_page(branches, &commits, branch.is_none()))
|
||||
}
|
||||
|
||||
pub async fn repository_contents(
|
||||
&self,
|
||||
owner: String,
|
||||
repository: String,
|
||||
path: String,
|
||||
) -> Result<Vec<RepositoryContentRow>, GotchaError> {
|
||||
Ok(repository_content_rows(
|
||||
load_repository_contents(&self.server()?, &owner, &repository, &path).await?,
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn repository_file(
|
||||
&self,
|
||||
owner: String,
|
||||
repository: String,
|
||||
path: String,
|
||||
) -> Result<Vec<u8>, GotchaError> {
|
||||
Ok(load_repository_file(&self.server()?, &owner, &repository, &path).await?)
|
||||
}
|
||||
|
||||
pub async fn commit_files(
|
||||
&self,
|
||||
owner: String,
|
||||
|
||||
@@ -116,6 +116,14 @@ pub struct FileRow {
|
||||
pub status: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Record)]
|
||||
pub struct RepositoryContentRow {
|
||||
pub name: String,
|
||||
pub path: String,
|
||||
pub kind: String,
|
||||
pub size: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Record)]
|
||||
pub struct DiffLine {
|
||||
pub old_number: String,
|
||||
@@ -422,6 +430,24 @@ pub fn commit_file_rows(files: Vec<models::CommitAffectedFiles>) -> Vec<FileRow>
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn repository_content_rows(
|
||||
contents: Vec<models::ContentsResponse>,
|
||||
) -> Vec<RepositoryContentRow> {
|
||||
let mut rows: Vec<_> = contents
|
||||
.into_iter()
|
||||
.filter_map(|content| {
|
||||
Some(RepositoryContentRow {
|
||||
name: content.name?,
|
||||
path: content.path?,
|
||||
kind: content.r#type.unwrap_or_else(|| "file".into()),
|
||||
size: content.size.unwrap_or_default(),
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
rows.sort_by_key(|row| (row.kind != "dir", row.name.to_lowercase()));
|
||||
rows
|
||||
}
|
||||
|
||||
pub fn diff_page(path: &str, diff: crate::diff::Parsed) -> DiffPage {
|
||||
DiffPage {
|
||||
title: path.rsplit('/').next().unwrap_or(path).into(),
|
||||
@@ -758,6 +784,31 @@ pub fn compact_date(date: Option<&str>) -> String {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn repository_directories_sort_before_files() {
|
||||
let contents = [
|
||||
("z.swift", "file"),
|
||||
("Sources", "dir"),
|
||||
("README.md", "file"),
|
||||
]
|
||||
.into_iter()
|
||||
.map(|(name, kind)| models::ContentsResponse {
|
||||
name: Some(name.into()),
|
||||
path: Some(name.into()),
|
||||
r#type: Some(kind.into()),
|
||||
..Default::default()
|
||||
})
|
||||
.collect();
|
||||
|
||||
assert_eq!(
|
||||
repository_content_rows(contents)
|
||||
.into_iter()
|
||||
.map(|row| row.name)
|
||||
.collect::<Vec<_>>(),
|
||||
["Sources", "README.md", "z.swift"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn maps_heat_levels_and_labels() {
|
||||
let heatmap = vec![
|
||||
|
||||
Reference in New Issue
Block a user