426a121f23b76660d4e726c990a4ce183c1c0384 / frogue / src / views / refs.rs
Raw
use actix_web::HttpResponse;
use maud::{Markup, Render, html};
use super::{
Page,
components::{RepositoryChrome, RepositoryTab},
repositories::RefSummary,
};
pub(super) struct RefsBody<'a> {
owner: &'a str,
slug: &'a str,
visibility: &'a str,
default_branch: &'a str,
branches: &'a [RefSummary],
tags: &'a [RefSummary],
viewer: Option<&'a str>,
}
impl Render for RefsBody<'_> {
fn render(&self) -> Markup {
html! {
(RepositoryChrome {
owner: self.owner,
slug: self.slug,
visibility: self.visibility,
default_branch: self.default_branch,
current_tab: RepositoryTab::Refs,
is_owner: self.viewer == Some(self.owner),
})
h3 { "Branches (" (self.branches.len()) ")" }
(RefList {
owner: self.owner,
slug: self.slug,
refs: self.branches,
})
h3 { "Tags (" (self.tags.len()) ")" }
(RefList {
owner: self.owner,
slug: self.slug,
refs: self.tags,
})
}
}
}
/// A branch or tag listing, or a note that there is nothing to list.
pub(super) struct RefList<'a> {
pub(super) owner: &'a str,
pub(super) slug: &'a str,
pub(super) refs: &'a [RefSummary],
}
impl Render for RefList<'_> {
fn render(&self) -> Markup {
html! {
@if self.refs.is_empty() {
p class="empty" { "Nothing here yet." }
} @else {
ul class="refs" {
@for reference in self.refs {
li {
// The name leads into the ref's commit history:
// a ref names a line of work, and the history
// is what that line says.
code class="ref-name" {
a href=(format!(
"/~{}/{}/commits/{}",
self.owner, self.slug, reference.name
)) {
(reference.name)
}
}
// The hash beneath the name leads to the commit
// itself rather than to where the ref stands:
// what a hash names is a moment, and it is
// addressed by its full self.
code class="hash" {
a href=(format!(
"/~{}/{}/commit/{}",
self.owner, self.slug, reference.full_hash
)) {
(reference.hash)
}
}
span class="author" { (reference.author) }
span class="subject" { (reference.subject) }
}
}
}
}
}
}
}
/// The page listing every branch and tag of `owner`'s repository `slug`.
pub fn refs(
viewer: Option<&str>,
owner: &str,
slug: &str,
visibility: &'static str,
default_branch: &str,
branches: &[RefSummary],
tags: &[RefSummary],
) -> HttpResponse {
Page {
title: format!("~{owner}/{slug}: Refs - Frogue"),
viewer: viewer.map(str::to_string),
extra_head: None,
body: RefsBody {
owner,
slug,
visibility,
default_branch,
branches,
tags,
viewer,
},
}
.into_response()
}