pacco/src/routes/ui/repo.rs
JMARyA 5ae9b80302
Some checks failed
ci/woodpecker/push/build Pipeline failed
refactor
2025-01-18 22:14:02 +01:00

163 lines
5.3 KiB
Rust

use based::request::{RequestContext, StringResponse};
use based::ui::prelude::*;
use maud::{PreEscaped, Render, html};
use rocket::{State, get};
use pacco::pkg::{Repository, arch::Architecture};
use crate::config::Config;
use crate::routes::ui::arch_card;
use super::render;
#[get("/<repo>?<arch>")]
pub async fn repo_ui(
repo: &str,
ctx: RequestContext,
arch: Option<&str>,
config: &State<Config>,
) -> StringResponse {
let arch = arch.map(|x| Architecture::parse(x).unwrap_or(Architecture::any));
let repo = Repository::new(repo).unwrap();
let architectures: Vec<_> = repo.arch().into_iter().map(|x| x.to_string()).collect();
let packages = if let Some(arch) = arch.clone() {
repo.list_pkg_arch(arch)
} else {
repo.list_pkg()
};
// Repository name and architectures
let repo_info = Margin(
Flex(
Div()
.vanish()
.push(Text(&repo.name)._3xl().bold().color(&Gray::_100))
.push_if(config.is_mirrored_repo(&repo.name), || {
Background(
Blue::_500,
Rounded(Margin(
Padding(Text("Mirrored").sm().medium().white())
.x(ScreenValue::_3)
.y(ScreenValue::_1),
))
.size(Size::Full),
)
})
.push(
Screen::medium(Margin(Nothing()).top(ScreenValue::_0)).on(Margin(
Flex(Div().vanish().push_for_each(&architectures, |a: &String| {
html! {
@if let Some(arch) = arch.as_ref() {
@if arch.to_string() == *a {
(arch_card(&a, &repo.name, true))
} @else {
(arch_card(&a, &repo.name, false))
}
} @else {
(arch_card(&a, &repo.name, false))
}
}
}))
.group()
.gap(ScreenValue::_2),
)
.top(ScreenValue::_2)),
)
.push(
Text(&format!("{} packages", packages.len()))
.sm()
.color(&Gray::_100),
),
)
.gap(ScreenValue::_3)
.wrap(Wrap::Wrap)
.full_center()
.group(),
)
.bottom(ScreenValue::_6);
let package_list = SpaceBetween(Div().vanish().push_for_each(&packages, |pkg| {
Animated(
Flex(
Padding(
Hover(Background(Gray::_600, Nothing())).on(Background(
Gray::_700,
Rounded(Shadow::medium(
Link(
&format!("/{}/{pkg}", repo.name),
Div()
.vanish()
.push(FirstLetterCircle(pkg))
.push(Context(Width(
ScreenValue::fit,
Text(&pkg).medium().color(&Gray::_100),
)))
.push_if(
repo.get_pkg_by_name(&pkg)
.map(|x| x.sig_content())
.is_some(),
|| SignedInfo(),
),
)
.use_htmx(),
))
.size(Size::Large),
)),
)
.all(ScreenValue::_4),
)
.items_center()
.gap(ScreenValue::_4),
)
}))
.y(ScreenValue::_4);
let content = Div().vanish().push(repo_info).push(package_list).render();
render(content, &repo.name, ctx).await
}
#[allow(non_snake_case)]
pub fn FirstLetterCircle(name: &str) -> PreEscaped<String> {
Sized(
ScreenValue::_10,
ScreenValue::_10,
Rounded(Background(
Blue::_500,
Flex(
Text(
&name
.chars()
.next()
.unwrap_or_default()
.to_uppercase()
.to_string(),
)
.white()
.semibold(),
)
.full_center()
.group(),
))
.size(Size::Full),
)
.render()
}
#[allow(non_snake_case)]
pub fn SignedInfo() -> PreEscaped<String> {
Padding(
Flex(
Div()
.vanish()
.push(Span("")._2xl().bold().color(&Slate::_300))
.push(Span("Signed").sm().medium().color(&Slate::_300)),
)
.items_center()
.gap(ScreenValue::_2)
.group(),
)
.right(ScreenValue::_4)
.render()
}