163 lines
5.3 KiB
Rust
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()
|
|
}
|