diff --git a/web/index.html b/web/index.html
index b223fc9..08ad6fd 100644
--- a/web/index.html
+++ b/web/index.html
@@ -143,6 +143,9 @@ blockquote[type="cite"],
.tags-menu .menu-list a {
padding: 0.25em 0.5em;
}
+.tags-menu .tag-indent {
+ padding-left: 1em;
+}
.navbar {
border: none;
}
diff --git a/web/src/lib.rs b/web/src/lib.rs
index 2186ec7..759eca8 100644
--- a/web/src/lib.rs
+++ b/web/src/lib.rs
@@ -1235,6 +1235,24 @@ fn view_desktop(model: &Model) -> Node {
pager,
} => view_search_results(&query, results.as_slice(), *count, pager),
};
+ fn view_tag_li(display_name: &str, indent: usize, t: &Tag) -> Node {
+ li![a![
+ attrs! {
+ At::Href => urls::search(&format!("tag:{}", t.name), 0)
+ },
+ style! {
+ St::BackgroundColor => t.bg_color,
+ St::Color => t.fg_color,
+ },
+ (0..indent).map(|_| span![C!["tag-indent"], ""]),
+ display_name
+ ]]
+ }
+ fn matches(a: &[&str], b: &[&str]) -> usize {
+ std::iter::zip(a.iter(), b.iter())
+ .take_while(|(a, b)| a == b)
+ .count()
+ }
div![
C!["desktop-main-content"],
aside![
@@ -1242,16 +1260,38 @@ fn view_desktop(model: &Model) -> Node {
p![C!["menu-label"], "Tags"],
ul![
C!["menu-list"],
- model.tags.as_ref().map(|tags| tags.iter().map(|t| li![a![
- attrs! {
- At::Href => urls::search(&format!("tag:{}", t.name), 0)
- },
- style! {
- St::BackgroundColor => t.bg_color,
- St::Color => t.fg_color,
- },
- &t.name
- ]]))
+ model.tags.as_ref().map(|tags| {
+ let mut lis = Vec::new();
+ let mut last = Vec::new();
+ for t in tags {
+ let parts: Vec<_> = t.name.split('/').collect();
+ let mut n = matches(&last, &parts);
+ if t.name.starts_with("ZZCrap/Free") {
+ info!("n: {n}, parts: {parts:?} last: {last:?}");
+ }
+ if n <= parts.len() - 2 && parts.len() > 1 {
+ // Synthesize fake tags for proper indenting.
+ for i in n..parts.len() - 1 {
+ let display_name = parts[n];
+ lis.push(view_tag_li(
+ &display_name,
+ n,
+ &Tag {
+ name: parts[..i + 1].join("/"),
+ bg_color: "#000".to_string(),
+ fg_color: "#fff".to_string(),
+ },
+ ));
+ }
+ last = parts[..parts.len() - 1].to_vec();
+ n = parts.len() - 1;
+ }
+ let display_name = parts[n];
+ lis.push(view_tag_li(&display_name, n, t));
+ last = parts;
+ }
+ lis
+ })
]
],
div![