This commit is contained in:
parent
7aed380e21
commit
77f1c27981
4 changed files with 125 additions and 80 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -152,7 +152,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
|||
[[package]]
|
||||
name = "based"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.hydrar.de/jmarya/based?branch=ui#1e0ab7e0dcd42c304146376176d15ff34784bb34"
|
||||
source = "git+https://git.hydrar.de/jmarya/based?branch=ui#cdaabccd9eb701c5f0050def9706fc167137a481"
|
||||
dependencies = [
|
||||
"bcrypt",
|
||||
"chrono",
|
||||
|
@ -257,9 +257,9 @@ checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.12"
|
||||
version = "1.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "755717a7de9ec452bf7f3f1a3099085deabd7f2962b861dae91ecd7a365903d2"
|
||||
checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
|
|
@ -27,3 +27,7 @@ contact.email = "mail@example.com"
|
|||
[project.sub.name]
|
||||
name = "Sub Project"
|
||||
description = "Sub Project"
|
||||
|
||||
[project.sub.name.sub.subname]
|
||||
name = "Sub Sub Project"
|
||||
description = "Sub Sub Project"
|
||||
|
|
|
@ -29,3 +29,15 @@ impl Config {
|
|||
toml::from_str(&content).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_prj(c: &ProjectConfig, path: &str) -> Option<Project> {
|
||||
let paths: Vec<_> = path.split("/").filter(|x| !x.is_empty()).collect();
|
||||
let name = paths.first()?.to_string();
|
||||
|
||||
if paths.len() == 1 {
|
||||
return c.get(&name).cloned();
|
||||
} else {
|
||||
let sub_prj = c.get(&name)?.sub.as_ref()?;
|
||||
get_prj(sub_prj, &paths[1..].join("/"))
|
||||
}
|
||||
}
|
||||
|
|
183
src/main.rs
183
src/main.rs
|
@ -3,12 +3,12 @@ use std::path::Path;
|
|||
use based::asset::AssetRoutes;
|
||||
use based::page;
|
||||
use based::request::{RequestContext, StringResponse};
|
||||
use based::ui::components::{Shell, Tabs};
|
||||
use based::ui::components::{Breadcrumb, Shell, Tabs};
|
||||
use based::ui::prelude::*;
|
||||
use based::ui::primitives::flex::Row;
|
||||
use based::ui::primitives::Optional;
|
||||
use config::{Project, ProjectConfig};
|
||||
use maud::Render;
|
||||
use config::{get_prj, Project, ProjectConfig};
|
||||
use maud::{PreEscaped, Render};
|
||||
use rocket::fs::NamedFile;
|
||||
use rocket::request::FromSegments;
|
||||
use rocket::{get, launch, routes, State};
|
||||
|
@ -61,11 +61,10 @@ pub async fn project_page(
|
|||
) -> Option<StringResponse> {
|
||||
let mut prj = c.get(path.segments.first()?);
|
||||
for p in &path.segments[1..] {
|
||||
println!(" --> {p}");
|
||||
prj = prj.as_ref()?.sub.as_ref()?.get(p);
|
||||
}
|
||||
|
||||
Some(render_project(shell, ctx, prj?, path.to_str()).await)
|
||||
Some(render_project(shell, ctx, prj?, c, path.to_str()).await)
|
||||
}
|
||||
|
||||
#[get("/static/<file>")]
|
||||
|
@ -85,100 +84,130 @@ pub async fn main_page(
|
|||
let first = keys.first().unwrap();
|
||||
let prj = c.get(*first).unwrap();
|
||||
|
||||
render_project(shell, ctx, prj, format!("{first}/")).await
|
||||
render_project(shell, ctx, prj, c, format!("{first}/")).await
|
||||
} else {
|
||||
// TODO : root project overview
|
||||
site::gen_site(c, ctx).await
|
||||
}
|
||||
}
|
||||
|
||||
pub fn info_tab(prj: &Project, root: &str) -> PreEscaped<String> {
|
||||
Flex(
|
||||
Div()
|
||||
.vanish()
|
||||
.push(Rounded(
|
||||
Background(Padding(Code(&prj.description)).all(ScreenValue::_4)).color(Gray::_900),
|
||||
))
|
||||
.push(Optional(prj.website.as_deref(), |website| {
|
||||
Link(website, Text(&format!("Website: {website}")))
|
||||
}))
|
||||
.push(Optional(prj.documentation.as_deref(), |docs| {
|
||||
Link(docs, Text(&format!("Documentation: {docs}")))
|
||||
}))
|
||||
.push(Optional(prj.since.as_deref(), |since| {
|
||||
Text(&format!("Since: {since}"))
|
||||
}))
|
||||
.push(Optional(prj.contact.as_ref(), |contact| {
|
||||
Div()
|
||||
.vanish()
|
||||
.push(Text("Contact").large())
|
||||
.push(Text(&format!(
|
||||
"eMail: {}",
|
||||
contact
|
||||
.email
|
||||
.as_ref()
|
||||
.map(|x| x.as_str())
|
||||
.unwrap_or_default()
|
||||
)))
|
||||
}))
|
||||
.push(Optional(prj.sub.as_ref(), |sub| {
|
||||
let mut prj_links = Vec::new();
|
||||
|
||||
for key in sub.keys() {
|
||||
prj_links.push(key);
|
||||
}
|
||||
|
||||
Div()
|
||||
.vanish()
|
||||
.push(Text("Sub projects").large())
|
||||
.push_for_each(&prj_links, |link: &_| {
|
||||
Width(
|
||||
ScreenValue::fit,
|
||||
Button(Link(
|
||||
&format!("/prj/{root}{link}"),
|
||||
Text(&prj.sub.as_ref().unwrap().get(*link).unwrap().name),
|
||||
)),
|
||||
)
|
||||
})
|
||||
})),
|
||||
)
|
||||
.gap(ScreenValue::_2)
|
||||
.direction(Direction::Column)
|
||||
.render()
|
||||
}
|
||||
|
||||
fn up_to(keyword: &str, v: &[&str], separator: &str) -> String {
|
||||
let index = v.iter().position(|s| *s == keyword).unwrap_or(v.len());
|
||||
v[..index + 1].join(separator)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn ProjectIcon(prj: &Project) -> PreEscaped<String> {
|
||||
Row(vec![
|
||||
Optional(prj.icon.as_ref(), |icon| Image(icon).alt("Project Icon")),
|
||||
Text(&prj.name)._2xl().render(),
|
||||
])
|
||||
.gap(ScreenValue::_4)
|
||||
.full_center()
|
||||
.render()
|
||||
}
|
||||
|
||||
pub async fn render_project(
|
||||
shell: &State<Shell>,
|
||||
ctx: RequestContext,
|
||||
prj: &Project,
|
||||
root: String,
|
||||
c: &State<ProjectConfig>,
|
||||
mut root: String,
|
||||
) -> StringResponse {
|
||||
let title = format!("{} - Umbrella ☂️", prj.name);
|
||||
|
||||
if !root.is_empty() && !root.ends_with('/') {
|
||||
root.push_str("/");
|
||||
}
|
||||
|
||||
let root_paths: Vec<_> = root.split("/").filter(|x| !x.is_empty()).collect();
|
||||
|
||||
let bc: Vec<_> = root_paths
|
||||
.iter()
|
||||
.map(|x| {
|
||||
let prj_path = up_to(x, &root_paths, "/");
|
||||
|
||||
(
|
||||
ProjectIcon(&get_prj(c, &prj_path).unwrap()).0,
|
||||
format!("/prj/{}", prj_path),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
println!("{bc:?}");
|
||||
|
||||
page!(
|
||||
shell,
|
||||
ctx,
|
||||
title,
|
||||
Div()
|
||||
.vanish()
|
||||
.push(
|
||||
Margin(
|
||||
Row(vec![
|
||||
Optional(prj.icon.as_ref(), |icon| Image(icon).alt("Project Icon")),
|
||||
Text(&prj.name)._2xl().render()
|
||||
])
|
||||
.gap(ScreenValue::_4)
|
||||
.full_center()
|
||||
)
|
||||
.top(ScreenValue::_6)
|
||||
.bottom(ScreenValue::_2)
|
||||
)
|
||||
.push(Width(
|
||||
ScreenValue::fit,
|
||||
Margin(Breadcrumb(bc))
|
||||
.top(ScreenValue::_6)
|
||||
.bottom(ScreenValue::_2)
|
||||
.x(ScreenValue::auto)
|
||||
))
|
||||
.push(
|
||||
Padding(
|
||||
Tabs()
|
||||
.add_tab(
|
||||
"info",
|
||||
Text("📜 Info").medium(),
|
||||
Flex(
|
||||
Div()
|
||||
.vanish()
|
||||
.push(Text(&prj.description))
|
||||
.push(Optional(prj.website.as_deref(), |website| Link(
|
||||
website,
|
||||
Text(&format!("Website: {website}"))
|
||||
)))
|
||||
.push(Optional(prj.documentation.as_deref(), |docs| Link(
|
||||
docs,
|
||||
Text(&format!("Documentation: {docs}"))
|
||||
)))
|
||||
.push(Optional(prj.since.as_deref(), |since| Text(&format!(
|
||||
"Since: {since}"
|
||||
))))
|
||||
.push(Optional(prj.contact.as_ref(), |contact| {
|
||||
Div().vanish().push(Text("Contact").large()).push(Text(
|
||||
&format!(
|
||||
"eMail: {}",
|
||||
contact
|
||||
.email
|
||||
.as_ref()
|
||||
.map(|x| x.as_str())
|
||||
.unwrap_or_default()
|
||||
),
|
||||
))
|
||||
}))
|
||||
.push(Optional(prj.sub.as_ref(), |sub| {
|
||||
let mut prj_links = Vec::new();
|
||||
|
||||
for key in sub.keys() {
|
||||
prj_links.push(key);
|
||||
}
|
||||
|
||||
Div()
|
||||
.vanish()
|
||||
.push(Text("Sub projects").large())
|
||||
.push_for_each(&prj_links, |link: &_| {
|
||||
Link(
|
||||
&format!("/prj/{root}{link}"),
|
||||
Text(
|
||||
&prj.sub
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get(*link)
|
||||
.unwrap()
|
||||
.name,
|
||||
),
|
||||
)
|
||||
})
|
||||
}))
|
||||
)
|
||||
.gap(ScreenValue::_2)
|
||||
.direction(Direction::Column)
|
||||
)
|
||||
.add_tab("info", Text("📜 Info").medium(), info_tab(prj, &root))
|
||||
.add_tab(
|
||||
"invest",
|
||||
Text("💵 Invest").medium(),
|
||||
|
|
Loading…
Add table
Reference in a new issue