From 8e77ad7204c92c348382466f9131afe547e1965c Mon Sep 17 00:00:00 2001 From: Simon Repp Date: Sat, 20 Apr 2024 23:42:41 +0200 Subject: [PATCH] Render no breadcrumbs and highlight no site tree node on auxiliary pages --- src/editor/endpoints/collection.rs | 2 +- src/editor/endpoints/index.rs | 26 ++++----- src/editor/endpoints/playlist.rs | 2 +- src/editor/endpoints/video.rs | 4 +- src/editor/widgets.rs | 89 ++++++++++++++++++------------ 5 files changed, 70 insertions(+), 53 deletions(-) diff --git a/src/editor/endpoints/collection.rs b/src/editor/endpoints/collection.rs index 1e77563..2d1291f 100644 --- a/src/editor/endpoints/collection.rs +++ b/src/editor/endpoints/collection.rs @@ -415,7 +415,7 @@ pub fn edit_page( let site = context.get_site(); let head_title = collection.title.as_deref().unwrap_or_else(|| collection.slug()); - let html = layout(context, path, &site, &body, head_title); + let html = layout(context, Some(path), &site, &body, head_title); HttpResponse::Ok() .content_type(ContentType::html()) diff --git a/src/editor/endpoints/index.rs b/src/editor/endpoints/index.rs index 699812a..6803927 100644 --- a/src/editor/endpoints/index.rs +++ b/src/editor/endpoints/index.rs @@ -124,7 +124,7 @@ pub async fn index(context: Data>) -> HttpResponse { } } - let html = layout(&context, "", &site, &body, site.title()); + let html = layout(&context, None, &site, &body, site.title()); HttpResponse::Ok() .content_type(ContentType::html()) @@ -237,19 +237,17 @@ fn storage_stats_html(context: &Context, videos: &Vec>) -> String { let total_size_human = human_size(total_size); formatdoc!(r#" -
- - - {slices} - - - {total_size_human} - - + + + {slices} + + + {total_size_human} + + -
    - {list} -
-
+
    + {list} +
"#) } \ No newline at end of file diff --git a/src/editor/endpoints/playlist.rs b/src/editor/endpoints/playlist.rs index 5a91068..7b06fe5 100644 --- a/src/editor/endpoints/playlist.rs +++ b/src/editor/endpoints/playlist.rs @@ -340,7 +340,7 @@ pub fn edit_page( let site = context.get_site(); let head_title = playlist.title.as_deref().unwrap_or_else(|| playlist.slug()); - let html = layout(context, path, &site, &body, head_title); + let html = layout(context, Some(path), &site, &body, head_title); HttpResponse::Ok() .content_type(ContentType::html()) diff --git a/src/editor/endpoints/video.rs b/src/editor/endpoints/video.rs index 5490d34..77d05c1 100644 --- a/src/editor/endpoints/video.rs +++ b/src/editor/endpoints/video.rs @@ -549,7 +549,7 @@ pub fn edit_page( and all versions of the video. If the video lies at the site root it does not remove the site manifest and the site itself, so the site can afterwards be reinitialized again as a collection, - video or video. + playlist or video.

@@ -560,7 +560,7 @@ pub fn edit_page( let site = context.get_site(); let head_title = video.title.as_deref().unwrap_or(video.slug()); - let html = layout(context, path, &site, &body, head_title); + let html = layout(context, Some(path), &site, &body, head_title); HttpResponse::Ok() .content_type(ContentType::html()) diff --git a/src/editor/widgets.rs b/src/editor/widgets.rs index 9a66faa..9ac8878 100644 --- a/src/editor/widgets.rs +++ b/src/editor/widgets.rs @@ -20,7 +20,7 @@ fn collection_tree( breadcrumbs: &mut Vec, collection: &Collection, context: &Context, - path: &str + path: Option<&str> ) -> String { let collection_icon = icons::collection(&context.editor_translations.collection); let playlist_icon = icons::playlist(&context.editor_translations.playlist); @@ -39,13 +39,15 @@ fn collection_tree( .map(|collection| { let collection_path = &collection.path; - let active = path == collection_path; + let active = path.is_some_and(|path| path == collection_path); let href = format!("/collection/{collection_path}"); let node = tree_node(active, context, &collection.errors, &href, &collection_icon, collection.slug(), collection.title.as_deref()); - if active || path - .strip_prefix(&collection.path) - .is_some_and(|rest| rest.starts_with('/')) { + if active || path.is_some_and(|path| + path + .strip_prefix(&collection.path) + .is_some_and(|rest| rest.starts_with('/')) + ) { let label = collection.title.as_deref().unwrap_or_else(|| collection.slug()); let (icon, space) = if active { (collection_icon.as_str(), " ") } else { ("", "") }; breadcrumbs.push(format!(r#"{icon}{space}{label}"#)); @@ -77,13 +79,15 @@ fn collection_tree( .map(|playlist| { let playlist_path = &playlist.path; - let active = path == playlist_path; + let active = path.is_some_and(|path| path == playlist_path); let href = format!("/playlist/{playlist_path}"); let node = tree_node(active, context, &playlist.errors, &href, &playlist_icon, playlist.slug(), playlist.title.as_deref()); - if active || path - .strip_prefix(&playlist.path) - .is_some_and(|rest| rest.starts_with('/')) { + if active || path.is_some_and(|path| + path + .strip_prefix(&playlist.path) + .is_some_and(|rest| rest.starts_with('/')) + ) { let label = playlist.title.as_deref().unwrap_or_else(|| playlist.slug()); let (icon, space) = if active { (playlist_icon.as_str(), " ") } else { ("", "") }; breadcrumbs.push(format!(r#"{icon}{space}{label}"#)); @@ -97,7 +101,7 @@ fn collection_tree( .map(|video| { let video_path = &video.path; - let active = path == video_path; + let active = path.is_some_and(|path| path == video_path); let href = format!("/video/{video_path}"); let node = tree_node(active, context, &video.errors, &href, &video_icon, video.slug(), video.title.as_deref()); @@ -146,7 +150,7 @@ fn collection_tree( .map(|video| { let video_path = &video.path; - let active = path == video_path; + let active = path.is_some_and(|path| path == video_path); let href = format!("/video/{video_path}"); let node = tree_node(active, context, &video.errors, &href, &video_icon, video.slug(), video.title.as_deref()); @@ -258,9 +262,11 @@ pub fn form_textarea( "#) } +/// When path is Some() that signifies we are viewing some node in the site tree. +/// If it's None we are on some auxillary page such as the dashboard or 404 page. pub fn layout( context: &Context, - path: &str, + path: Option<&str>, site: &Site, body: &str, title: &str @@ -339,9 +345,7 @@ pub fn layout( {tree}
- + {breadcrumbs} {body}
@@ -370,7 +374,7 @@ pub fn not_found(context: &Context, message: &str) -> HttpResponse { "#); let site = &context.get_site(); - let html = layout(context, "", site, &body, "Not Found"); + let html = layout(context, None, site, &body, "Not Found"); HttpResponse::Ok() .content_type(ContentType::html()) @@ -379,13 +383,13 @@ pub fn not_found(context: &Context, message: &str) -> HttpResponse { pub fn site_tree( context: &Context, - path: &str, + path: Option<&str>, site: &Site, site_dir: &Path ) -> (String, String) { let mut breadcrumbs = Vec::new(); - let root_active = path == ""; + let root_active = path.is_some_and(|path| path == ""); let root_dir = site_dir.file_name().unwrap().to_string_lossy(); let site_dir = &site_dir.to_string_lossy(); @@ -393,9 +397,12 @@ pub fn site_tree( SiteContent::Collection(collection) => { let t_collection = &context.editor_translations.collection; let collection_icon = icons::collection(t_collection); - let breadcrumb_title = collection.title.as_deref().unwrap_or(t_collection); - let (icon, space) = if root_active { (collection_icon.as_str(), " ") } else { ("", "") }; - breadcrumbs.push(format!(r#"{icon}{space}{breadcrumb_title}"#)); + + if path.is_some() { + let breadcrumb_title = collection.title.as_deref().unwrap_or(t_collection); + let (icon, space) = if root_active { (collection_icon.as_str(), " ") } else { ("", "") }; + breadcrumbs.push(format!(r#"{icon}{space}{breadcrumb_title}"#)); + } let collection_content = collection_tree(&mut breadcrumbs, collection, context, path); @@ -413,16 +420,21 @@ pub fn site_tree( // TODO: Dedicated icon for empty site? let collection_icon = icons::collection(t_empty_site); - breadcrumbs.push(format!(r#"{root_dir}"#)); + if path.is_some() { + breadcrumbs.push(format!(r#"{root_dir}"#)); + } tree_node(root_active, context, &Vec::new(), "/", &collection_icon, site_dir, Some(t_empty_site)) } SiteContent::Playlist(playlist) => { let t_playlist = &context.editor_translations.playlist; let playlist_icon = icons::playlist(t_playlist); - let breadcrumb_title = playlist.title.as_deref().unwrap_or(t_playlist); - let (icon, space) = if root_active { (playlist_icon.as_str(), " ") } else { ("", "") }; - breadcrumbs.push(format!(r#"{icon}{space}{breadcrumb_title}"#)); + + if path.is_some() { + let breadcrumb_title = playlist.title.as_deref().unwrap_or(t_playlist); + let (icon, space) = if root_active { (playlist_icon.as_str(), " ") } else { ("", "") }; + breadcrumbs.push(format!(r#"{icon}{space}{breadcrumb_title}"#)); + } let videos = if playlist.videos.is_empty() { formatdoc!(r#" @@ -447,7 +459,7 @@ pub fn site_tree( .map(|video| { let video_path = &video.path; - let active = path == video_path; + let active = path.is_some_and(|path| path == video_path); let href = format!("/video/{video_path}"); let slug = video.slug(); @@ -480,21 +492,28 @@ pub fn site_tree( let t_video = &context.editor_translations.video; let video_icon = icons::video(t_video); - let breadcrumb_title = video.title.as_deref().unwrap_or(t_video); - let (icon, space) = if root_active { (video_icon.as_str(), " ") } else { ("", "") }; - breadcrumbs.push(format!(r#"{icon}{space}{breadcrumb_title}"#)); + if path.is_some() { + let breadcrumb_title = video.title.as_deref().unwrap_or(t_video); + let (icon, space) = if root_active { (video_icon.as_str(), " ") } else { ("", "") }; + breadcrumbs.push(format!(r#"{icon}{space}{breadcrumb_title}"#)); + } tree_node(root_active, context, &video.errors, "/video/", &video_icon, site_dir, video.title.as_deref()) } }; - let breadcrumbs = breadcrumbs.join(" › "); + let breadcrumbs = if breadcrumbs.is_empty() { + String::new() + } else { + let breadcrumbs_joined = breadcrumbs.join(" › "); + formatdoc!(r#" + + "#) + }; - let sidebar = formatdoc!(r#" - {site_content} - "#); - - (breadcrumbs, sidebar) + (breadcrumbs, site_content) } fn tree_node(