From 4ad695eed6c2a3fa7fb164c4a0e4972dab2691d2 Mon Sep 17 00:00:00 2001 From: Lukas Stabe Date: Fri, 25 Sep 2020 05:23:23 +0200 Subject: [wip] client-side color-scheme handling --- src/auth.rs | 2 - src/file_upload.rs | 15 -- src/listing.rs | 12 -- src/main.rs | 15 +- src/renderer.rs | 604 +++++------------------------------------------------ src/themes.rs | 227 +------------------- 6 files changed, 56 insertions(+), 819 deletions(-) (limited to 'src') diff --git a/src/auth.rs b/src/auth.rs index e3eec89..5d01568 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -120,8 +120,6 @@ fn build_unauthorized_response( &return_path, None, None, - state.default_color_scheme, - state.default_color_scheme, false, false, &state.favicon_route, diff --git a/src/file_upload.rs b/src/file_upload.rs index 394afbc..3f713cd 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -12,7 +12,6 @@ use std::{ use crate::errors::{self, ContextualError}; use crate::listing::{self, SortingMethod, SortingOrder}; use crate::renderer; -use crate::themes::ColorScheme; /// Create future to save file. fn save_file( @@ -109,7 +108,6 @@ fn handle_multipart( pub fn upload_file( req: HttpRequest, payload: actix_web::web::Payload, - default_color_scheme: ColorScheme, uses_random_route: bool, favicon_route: String, ) -> Pin>>> { @@ -121,7 +119,6 @@ pub fn upload_file( }; let query_params = listing::extract_query_parameters(&req); - let color_scheme = query_params.theme.unwrap_or(default_color_scheme); let upload_path = match query_params.path.clone() { Some(path) => match path.strip_prefix(Component::RootDir) { Ok(stripped_path) => stripped_path.to_owned(), @@ -137,8 +134,6 @@ pub fn upload_file( &return_path, query_params.sort, query_params.order, - color_scheme, - default_color_scheme, uses_random_route, &favicon_route, )); @@ -158,8 +153,6 @@ pub fn upload_file( &return_path, query_params.sort, query_params.order, - color_scheme, - default_color_scheme, uses_random_route, &favicon_route, )); @@ -179,8 +172,6 @@ pub fn upload_file( &return_path, query_params.sort, query_params.order, - color_scheme, - default_color_scheme, uses_random_route, &favicon_route, )); @@ -205,8 +196,6 @@ pub fn upload_file( &return_path, query_params.sort, query_params.order, - color_scheme, - default_color_scheme, uses_random_route, &favicon_route, ), @@ -222,8 +211,6 @@ fn create_error_response( return_path: &str, sorting_method: Option, sorting_order: Option, - color_scheme: ColorScheme, - default_color_scheme: ColorScheme, uses_random_route: bool, favicon_route: &str, ) -> future::Ready> { @@ -238,8 +225,6 @@ fn create_error_response( return_path, sorting_method, sorting_order, - color_scheme, - default_color_scheme, true, !uses_random_route, &favicon_route, diff --git a/src/listing.rs b/src/listing.rs index d14a188..40c84b3 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -15,7 +15,6 @@ use strum_macros::{Display, EnumString}; use crate::archive::CompressionMethod; use crate::errors::{self, ContextualError}; use crate::renderer; -use crate::themes::ColorScheme; const FRAGMENT: &AsciiSet = &CONTROLS.add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); @@ -25,7 +24,6 @@ pub struct QueryParameters { pub path: Option, pub sort: Option, pub order: Option, - pub theme: Option, qrcode: Option, download: Option, } @@ -153,7 +151,6 @@ pub fn directory_listing( file_upload: bool, random_route: Option, favicon_route: String, - default_color_scheme: ColorScheme, show_qrcode: bool, upload_route: String, tar_enabled: bool, @@ -323,8 +320,6 @@ pub fn directory_listing( } } - let color_scheme = query_params.theme.unwrap_or(default_color_scheme); - if let Some(compression_method) = query_params.download { if !compression_method.is_enabled(tar_enabled, zip_enabled) { return Ok(ServiceResponse::new( @@ -338,8 +333,6 @@ pub fn directory_listing( "/", None, None, - color_scheme, - default_color_scheme, false, false, &favicon_route, @@ -393,13 +386,10 @@ pub fn directory_listing( .content_type("text/html; charset=utf-8") .body( renderer::page( - serve_path, entries, is_root, query_params.sort, query_params.order, - default_color_scheme, - color_scheme, show_qrcode, file_upload, &upload_route, @@ -421,7 +411,6 @@ pub fn extract_query_parameters(req: &HttpRequest) -> QueryParameters { sort: query.sort, order: query.order, download: query.download, - theme: query.theme, qrcode: query.qrcode.to_owned(), path: query.path.clone(), }, @@ -432,7 +421,6 @@ pub fn extract_query_parameters(req: &HttpRequest) -> QueryParameters { sort: None, order: None, download: None, - theme: None, qrcode: None, path: None, } diff --git a/src/main.rs b/src/main.rs index 1830a70..ffb393b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -284,7 +284,6 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { let no_symlinks = conf.no_symlinks; let random_route = conf.random_route.clone(); let favicon_route = conf.favicon_route.clone(); - let default_color_scheme = conf.default_color_scheme; let show_qrcode = conf.show_qrcode; let file_upload = conf.file_upload; let tar_enabled = conf.tar_enabled; @@ -314,7 +313,6 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { file_upload, random_route.clone(), favicon_route.clone(), - default_color_scheme, show_qrcode, u_r.clone(), tar_enabled, @@ -330,17 +328,10 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { let favicon_route = conf.favicon_route.clone(); if let Some(serve_path) = serve_path { if conf.file_upload { - let default_color_scheme = conf.default_color_scheme; // Allow file upload app.service( web::resource(&upload_route).route(web::post().to(move |req, payload| { - file_upload::upload_file( - req, - payload, - default_color_scheme, - uses_random_route, - favicon_route.clone(), - ) + file_upload::upload_file(req, payload, uses_random_route, favicon_route.clone()) })), ) // Handle directories @@ -358,11 +349,9 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { async fn error_404(req: HttpRequest) -> HttpResponse { let err_404 = ContextualError::RouteNotFoundError(req.path().to_string()); let conf = req.app_data::().unwrap(); - let default_color_scheme = conf.default_color_scheme; let uses_random_route = conf.random_route.is_some(); let favicon_route = conf.favicon_route.clone(); let query_params = listing::extract_query_parameters(&req); - let color_scheme = query_params.theme.unwrap_or(default_color_scheme); errors::log_error_chain(err_404.to_string()); @@ -373,8 +362,6 @@ async fn error_404(req: HttpRequest) -> HttpResponse { "/", query_params.sort, query_params.order, - color_scheme, - default_color_scheme, false, !uses_random_route, &favicon_route, diff --git a/src/renderer.rs b/src/renderer.rs index 43cb222..dedd028 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -12,13 +12,10 @@ use crate::themes::ColorScheme; /// Renders the file listing #[allow(clippy::too_many_arguments)] pub fn page( - serve_path: &str, entries: Vec, is_root: bool, sort_method: Option, sort_order: Option, - default_color_scheme: ColorScheme, - color_scheme: ColorScheme, show_qrcode: bool, file_upload: bool, upload_route: &str, @@ -28,14 +25,7 @@ pub fn page( tar_enabled: bool, zip_enabled: bool, ) -> Markup { - let upload_action = build_upload_action( - upload_route, - encoded_dir, - sort_method, - sort_order, - color_scheme, - default_color_scheme, - ); + let upload_action = build_upload_action(upload_route, encoded_dir, sort_method, sort_order); let title_path = breadcrumbs .iter() @@ -46,8 +36,25 @@ pub fn page( html! { (DOCTYPE) html { - (page_header(&title_path, color_scheme, file_upload, favicon_route)) + (page_header(&title_path, file_upload, favicon_route)) body#drop-container { + (PreEscaped(r#" + + "#)) + @if file_upload { div.drag-form { div.drag-title { @@ -55,7 +62,7 @@ pub fn page( } } } - (color_scheme_selector(sort_method, sort_order, color_scheme, default_color_scheme, serve_path, show_qrcode)) + (color_scheme_selector(show_qrcode)) div.container { span#top { } h1.title { @@ -64,7 +71,7 @@ pub fn page( // wrapped in span so the text doesn't shift slightly when it turns into a link span { (el.name) } } @else { - a.directory href=(parametrized_link(&el.link, sort_method, sort_order, color_scheme, default_color_scheme)) { + a.directory href=(parametrized_link(&el.link, sort_method, sort_order)) { (el.name) } } @@ -76,7 +83,7 @@ pub fn page( div.download { @for compression_method in CompressionMethod::iter() { @if compression_method.is_enabled(tar_enabled, zip_enabled) { - (archive_button(compression_method, sort_method, sort_order, color_scheme, default_color_scheme)) + (archive_button(compression_method, sort_method, sort_order)) } } } @@ -95,23 +102,23 @@ pub fn page( } table { thead { - th.name { (build_link("name", "Name", sort_method, sort_order, color_scheme, default_color_scheme)) } - th.size { (build_link("size", "Size", sort_method, sort_order, color_scheme, default_color_scheme)) } - th.date { (build_link("date", "Last modification", sort_method, sort_order, color_scheme, default_color_scheme)) } + th.name { (build_link("name", "Name", sort_method, sort_order)) } + th.size { (build_link("size", "Size", sort_method, sort_order)) } + th.date { (build_link("date", "Last modification", sort_method, sort_order)) } } tbody { @if !is_root { tr { td colspan="3" { span.root-chevron { (chevron_left()) } - a.root href=(parametrized_link("../", sort_method, sort_order, color_scheme, default_color_scheme)) { + a.root href=(parametrized_link("../", sort_method, sort_order)) { "Parent directory" } } } } @for entry in entries { - (entry_row(entry, sort_method, sort_order, color_scheme, default_color_scheme)) + (entry_row(entry, sort_method, sort_order)) } } } @@ -130,8 +137,6 @@ fn build_upload_action( encoded_dir: &str, sort_method: Option, sort_order: Option, - color_scheme: ColorScheme, - default_color_scheme: ColorScheme, ) -> String { let mut upload_action = format!("{}?path={}", upload_route, encoded_dir); if let Some(sorting_method) = sort_method { @@ -140,22 +145,12 @@ fn build_upload_action( if let Some(sorting_order) = sort_order { upload_action = format!("{}&order={}", upload_action, &sorting_order); } - if color_scheme != default_color_scheme { - upload_action = format!("{}&theme={}", upload_action, color_scheme.to_slug()); - } upload_action } /// Partial: color scheme selector -fn color_scheme_selector( - sort_method: Option, - sort_order: Option, - active_color_scheme: ColorScheme, - default_color_scheme: ColorScheme, - serve_path: &str, - show_qrcode: bool, -) -> Markup { +fn color_scheme_selector(show_qrcode: bool) -> Markup { html! { nav { @if show_qrcode { @@ -174,14 +169,8 @@ fn color_scheme_selector( } ul.theme { @for color_scheme in ColorScheme::iter() { - @if active_color_scheme == color_scheme { - li.active { - (color_scheme_link(sort_method, sort_order, color_scheme, default_color_scheme, serve_path)) - } - } @else { - li { - (color_scheme_link(sort_method, sort_order, color_scheme, default_color_scheme, serve_path)) - } + li { + (color_scheme_link(color_scheme)) } } } @@ -190,25 +179,12 @@ fn color_scheme_selector( } } -/// Partial: color scheme link -fn color_scheme_link( - sort_method: Option, - sort_order: Option, - color_scheme: ColorScheme, - default_color_scheme: ColorScheme, - serve_path: &str, -) -> Markup { - let link = parametrized_link( - serve_path, - sort_method, - sort_order, - color_scheme, - default_color_scheme, - ); +// /// Partial: color scheme link +fn color_scheme_link(color_scheme: ColorScheme) -> Markup { let title = format!("Switch to {} theme", color_scheme); html! { - a href=(link) title=(title) { + a href=(format!("javascript:updateColorScheme(\"{}\")", color_scheme.to_slug())) title=(title) { (color_scheme) " " @if color_scheme.is_dark() { @@ -225,25 +201,16 @@ fn archive_button( compress_method: CompressionMethod, sort_method: Option, sort_order: Option, - color_scheme: ColorScheme, - default_color_scheme: ColorScheme, ) -> Markup { - let link = - if sort_method.is_none() && sort_order.is_none() && color_scheme == default_color_scheme { - format!("?download={}", compress_method) - } else { - format!( - "{}&download={}", - parametrized_link( - "", - sort_method, - sort_order, - color_scheme, - default_color_scheme - ), - compress_method - ) - }; + let link = if sort_method.is_none() && sort_order.is_none() { + format!("?download={}", compress_method) + } else { + format!( + "{}&download={}", + parametrized_link("", sort_method, sort_order,), + compress_method + ) + }; let text = format!("Download .{}", compress_method.extension()); @@ -268,8 +235,6 @@ fn parametrized_link( link: &str, sort_method: Option, sort_order: Option, - color_scheme: ColorScheme, - default_color_scheme: ColorScheme, ) -> String { if let Some(method) = sort_method { if let Some(order) = sort_order { @@ -280,22 +245,10 @@ fn parametrized_link( order ); - if color_scheme != default_color_scheme { - return format!("{}&theme={}", parametrized_link, color_scheme.to_slug()); - } - return parametrized_link; } } - if color_scheme != default_color_scheme { - return format!( - "{}?theme={}", - make_link_with_trailing_slash(&link), - color_scheme.to_slug() - ); - } - make_link_with_trailing_slash(&link) } @@ -305,8 +258,6 @@ fn build_link( title: &str, sort_method: Option, sort_order: Option, - color_scheme: ColorScheme, - default_color_scheme: ColorScheme, ) -> Markup { let mut link = format!("?sort={}&order=asc", name); let mut help = format!("Sort by {} in ascending order", name); @@ -326,10 +277,6 @@ fn build_link( } }; - if color_scheme != default_color_scheme { - link = format!("{}&theme={}", &link, color_scheme.to_slug()); - } - html! { span class=(class) { span.chevron { (chevron) } @@ -343,15 +290,13 @@ fn entry_row( entry: Entry, sort_method: Option, sort_order: Option, - color_scheme: ColorScheme, - default_color_scheme: ColorScheme, ) -> Markup { html! { tr { td { p { @if entry.is_dir() { - a.directory href=(parametrized_link(&entry.link, sort_method, sort_order, color_scheme, default_color_scheme)) { + a.directory href=(parametrized_link(&entry.link, sort_method, sort_order)) { (entry.name) "/" } } @else if entry.is_file() { @@ -366,7 +311,7 @@ fn entry_row( } } } @else if entry.is_symlink() { - a.symlink href=(parametrized_link(&entry.link, sort_method, sort_order, color_scheme, default_color_scheme)) { + a.symlink href=(parametrized_link(&entry.link, sort_method, sort_order)) { (entry.name) span.symlink-symbol { "⇢" } } } @@ -395,441 +340,12 @@ fn entry_row( } } +lazy_static::lazy_static! { + static ref CSS_TEXT: String = grass::from_string(include_str!("../data/style.scss").to_string(), &grass::Options::default()).unwrap(); +} /// Partial: CSS -fn css(color_scheme: ColorScheme) -> Markup { - let theme = color_scheme.get_theme(); - - let css = format!(" - html {{ - font-smoothing: antialiased; - text-rendering: optimizeLegibility; - width: 100%; - height: 100%; - }} - body {{ - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\"Helvetica Neue\", Helvetica, Arial, sans-serif; - font-weight: 300; - color: {text_color}; - background: {background}; - position: relative; - min-height: 100%; - }} - .container {{ - padding: 1.5rem 5rem; - }} - .title {{ - word-break: break-word; - }} - a {{ - text-decoration: none; - }} - a.root, a.root:visited, .root-chevron {{ - font-weight: bold; - color: {root_link_color}; - }} - a:hover {{ - text-decoration: underline; - }} - a.directory, a.directory:visited {{ - font-weight: bold; - color: {directory_link_color}; - }} - a.file, a.file:visited, .error-back, .error-back:visited {{ - color: {file_link_color}; - }} - a.symlink, a.symlink:visited {{ - color: {symlink_link_color}; - }} - a.directory:hover {{ - color: {directory_link_color}; - }} - a.file:hover {{ - color: {file_link_color}; - }} - a.symlink:hover {{ - color: {symlink_link_color}; - }} - .symlink-symbol {{ - display: inline-block; - border: 1px solid {symlink_link_color}; - margin-left: 0.5rem; - border-radius: .2rem; - padding: 0 0.1rem; - }} - nav {{ - padding: 0 5rem; - display: flex; - justify-content: flex-end; - }} - nav > div {{ - position: relative; - margin-left: 0.5rem; - }} - nav p {{ - padding: 0.5rem 1rem; - width: 8rem; - text-align: center; - background: {switch_theme_background}; - color: {change_theme_link_color}; - }} - nav p + * {{ - display: none; - position: absolute; - left: 0; - right: 0; - top: 100%; - animation: show 0.5s ease; - }} - @keyframes show {{ - from {{ - opacity: 0; - }} - to {{ - opacity: 1; - }} - }} - nav > div::hover p {{ - cursor: pointer; - color: {switch_theme_link_color}; - }} - nav > div:hover p + * {{ - display: block; - border-top: 1px solid {switch_theme_border}; - }} - nav .qrcode {{ - padding: 0.5rem; - background: {switch_theme_background}; - }} - nav .qrcode img {{ - display: block; - }} - nav .theme {{ - margin: 0; - padding: 0; - list-style-type: none; - }} - nav .theme li {{ - width: 100%; - background: {switch_theme_background}; - }} - nav .theme li a {{ - display: block; - width: 100%; - padding: 0.5rem 0; - text-align: center; - color: {switch_theme_link_color}; - }} - nav .theme li a:visited {{ - color: {switch_theme_link_color}; - }} - nav .theme li a::hover {{ - text-decoration: underline; - color: {change_theme_link_color_hover}; - }} - nav .theme li.active a {{ - font-weight: bold; - color: {switch_theme_active}; - }} - p {{ - margin: 0; - padding: 0; - }} - h1 {{ - margin-top: 0; - font-size: 1.5rem; - }} - table {{ - margin-top: 2rem; - width: 100%; - border: 0; - table-layout: auto; - background: {table_background}; - }} - table thead tr th, - table tbody tr td {{ - padding: 0.5625rem 0.625rem; - font-size: 0.875rem; - color: {table_text_color}; - text-align: left; - line-height: 1.125rem; - }} - table thead tr th {{ - padding: 0.5rem 0.625rem 0.625rem; - font-weight: bold; - }} - table thead th.size {{ - width: 6em; - }} - table thead th.date {{ - width: 15em; - }} - table tbody tr:nth-child(odd) {{ - background: {odd_row_background}; - }} - table tbody tr:nth-child(even) {{ - background: {even_row_background}; - }} - table thead {{ - background: {table_header_background}; - }} - table tbody tr:hover {{ - background: {active_row_color}; - }} - td.size-cell {{ - text-align: right; - }} - td.date-cell {{ - display: flex; - justify-content: space-between; - }} - .at {{ - color: {at_color}; - }} - .history {{ - color: {date_text_color}; - }} - .file-entry {{ - display: flex; - justify-content: space-between; - }} - span.size {{ - border-radius: 1rem; - background: {size_background_color}; - padding: 0 0.25rem; - font-size: 0.7rem; - color: {size_text_color} - }} - .mobile-info {{ - display: none; - }} - th a, th a:visited, .chevron {{ - color: {table_header_text_color}; - }} - .chevron, .root-chevron {{ - margin-right: .5rem; - font-size: 1.2em; - font-weight: bold; - }} - th span.active a, th span.active span {{ - color: {table_header_active_color}; - }} - .back {{ - position: fixed; - width: 3.8rem; - height: 3.8rem; - align-items: center; - justify-content: center; - bottom: 3rem; - right: 3.75rem; - background: {back_button_background}; - border-radius: 100%; - box-shadow: 0 0 8px -4px #888888; - color: {back_button_link_color}; - display: none; - }} - .back:visited {{ - color: {back_button_link_color}; - }} - .back:hover {{ - color: {back_button_link_color_hover}; - font-weight: bold; - text-decoration: none; - background: {back_button_background_hover}; - }} - .toolbar {{ - display: flex; - justify-content: space-between; - flex-wrap: wrap; - }} - .download {{ - margin-top: 1rem; - padding: 0.125rem; - display: flex; - flex-direction: row; - align-items: flex-start; - flex-wrap: wrap; - }} - .download a, .download a:visited {{ - color: {download_button_link_color}; - }} - .download a {{ - background: {download_button_background}; - padding: 0.5rem; - border-radius: 0.2rem; - }} - .download a:hover {{ - background: {download_button_background_hover}; - color: {download_button_link_color_hover}; - }} - .download a:not(:last-of-type) {{ - margin-right: 1rem; - }} - .upload {{ - margin-top: 1rem; - display: flex; - justify-content: flex-end; - }} - .upload p {{ - font-size: 0.8rem; - margin-bottom: 1rem; - color: {upload_text_color}; - }} - .upload form {{ - padding: 1rem; - border: 1px solid {upload_form_border_color}; - background: {upload_form_background}; - }} - .upload button {{ - background: {upload_button_background}; - padding: 0.5rem; - border-radius: 0.2rem; - color: {upload_button_text_color}; - border: none; - }} - .upload div {{ - display: flex; - align-items: baseline; - justify-content: space-between; - }} - .drag-form {{ - display: none; - background: {drag_background}; - position: absolute; - border: 0.5rem dashed {drag_border_color}; - width: calc(100% - 1rem); - height: calc(100% - 1rem); - text-align: center; - z-index: 2; - }} - .drag-title {{ - position: fixed; - color: {drag_text_color}; - top: 50%; - width: 100%; - text-align: center; - }} - .error {{ - margin: 2rem; - }} - .error p {{ - margin: 1rem 0; - font-size: 0.9rem; - word-break: break-all; - }} - .error p:first-of-type {{ - font-size: 1.25rem; - color: {error_color}; - margin-bottom: 2rem; - }} - .error p:nth-of-type(2) {{ - font-weight: bold; - }} - .error-nav {{ - margin-top: 4rem; - }} - @media (max-width: 760px) {{ - nav {{ - padding: 0 2.5rem; - }} - .container {{ - padding: 1.5rem 2.5rem; - }} - h1 {{ - font-size: 1.4em; - }} - td:not(:nth-child(1)), th:not(:nth-child(1)){{ - display: none; - }} - .mobile-info {{ - display: block; - }} - table tbody tr td {{ - padding-top: 0; - padding-bottom: 0; - }} - a.directory {{ - display: block; - padding: 0.5625rem 0; - }} - .file-entry {{ - align-items: center; - }} - a.root, a.file, a.symlink {{ - display: inline-block; - flex: 1; - padding: 0.5625rem 0; - }} - a.symlink {{ - width: 100%; - }} - .back {{ - display: flex; - }} - .back {{ - right: 1.5rem; - }} - }} - @media (max-width: 600px) {{ - h1 {{ - font-size: 1.375em; - }} - }} - @media (max-width: 400px) {{ - nav {{ - padding: 0 0.5rem; - }} - .container {{ - padding: 0.5rem; - }} - h1 {{ - font-size: 1.375em; - }} - .back {{ - right: 1.5rem; - }} - }}", background = theme.background, - text_color = theme.text_color, - directory_link_color = theme.directory_link_color, - file_link_color = theme.file_link_color, - symlink_link_color = theme.symlink_link_color, - table_background = theme.table_background, - table_text_color = theme.table_text_color, - table_header_background = theme.table_header_background, - table_header_text_color = theme.table_header_text_color, - table_header_active_color = theme.table_header_active_color, - active_row_color = theme.active_row_color, - odd_row_background = theme.odd_row_background, - even_row_background = theme.even_row_background, - root_link_color = theme.root_link_color, - download_button_background = theme.download_button_background, - download_button_background_hover = theme.download_button_background_hover, - download_button_link_color = theme.download_button_link_color, - download_button_link_color_hover = theme.download_button_link_color_hover, - back_button_background = theme.back_button_background, - back_button_background_hover = theme.back_button_background_hover, - back_button_link_color = theme.back_button_link_color, - back_button_link_color_hover = theme.back_button_link_color_hover, - date_text_color = theme.date_text_color, - at_color = theme.at_color, - switch_theme_background = theme.switch_theme_background, - switch_theme_link_color = theme.switch_theme_link_color, - switch_theme_active = theme.switch_theme_active, - switch_theme_border = theme.switch_theme_border, - change_theme_link_color = theme.change_theme_link_color, - change_theme_link_color_hover = theme.change_theme_link_color_hover, - upload_text_color = theme.upload_text_color, - upload_form_border_color = theme.upload_form_border_color, - upload_form_background = theme.upload_form_background, - upload_button_background = theme.upload_button_background, - upload_button_text_color = theme.upload_button_text_color, - drag_background = theme.drag_background, - drag_border_color = theme.drag_border_color, - drag_text_color = theme.drag_text_color, - size_background_color = theme.size_background_color, - size_text_color = theme.size_text_color, - error_color = theme.error_color); - PreEscaped(css) +fn css() -> Markup { + PreEscaped(CSS_TEXT.clone()) } /// Partial: up arrow @@ -853,12 +369,7 @@ fn chevron_down() -> Markup { } /// Partial: page header -fn page_header( - title: &str, - color_scheme: ColorScheme, - file_upload: bool, - favicon_route: &str, -) -> Markup { +fn page_header(title: &str, file_upload: bool, favicon_route: &str) -> Markup { html! { head { meta charset="utf-8"; @@ -867,7 +378,8 @@ fn page_header( link rel="icon" type="image/svg+xml" href={ "/" (favicon_route) }; title { (title) } - style { (css(color_scheme)) } + style { (css()) } + @if file_upload { (PreEscaped(r#" @@ -150,6 +153,14 @@ fn build_upload_action( upload_action } +const THEMES: &[(&str, &str)] = &[ + ("Default (light/dark)", "default"), + ("Squirrel (light)", "squirrel"), + ("Archlinux (dark)", "archlinux"), + ("Zenburn (dark)", "zenburn"), + ("Monokai (dark)", "monokai"), +]; + /// Partial: color scheme selector fn color_scheme_selector(show_qrcode: bool) -> Markup { html! { @@ -169,8 +180,8 @@ fn color_scheme_selector(show_qrcode: bool) -> Markup { "Change theme..." } ul.theme { - @for color_scheme in ColorScheme::iter() { - li { + @for color_scheme in THEMES { + li.(format!("theme_{}", color_scheme.1)) { (color_scheme_link(color_scheme)) } } @@ -181,18 +192,12 @@ fn color_scheme_selector(show_qrcode: bool) -> Markup { } // /// Partial: color scheme link -fn color_scheme_link(color_scheme: ColorScheme) -> Markup { - let title = format!("Switch to {} theme", color_scheme); +fn color_scheme_link(color_scheme: &(&str, &str)) -> Markup { + let title = format!("Switch to {} theme", color_scheme.0); html! { - a href=(format!("javascript:updateColorScheme(\"{}\")", color_scheme.to_slug())) title=(title) { - (color_scheme) - " " - @if color_scheme.is_dark() { - "(dark)" - } @else { - "(light)" - } + a href=(format!("javascript:updateColorScheme(\"{}\")", color_scheme.1)) title=(title) { + (color_scheme.0) } } } diff --git a/src/themes.rs b/src/themes.rs deleted file mode 100644 index 1b6707b..0000000 --- a/src/themes.rs +++ /dev/null @@ -1,36 +0,0 @@ -use serde::Deserialize; -use structopt::clap::arg_enum; -use strum_macros::EnumIter; - -arg_enum! { - #[derive(PartialEq, Deserialize, Clone, EnumIter, Copy)] - #[serde(rename_all = "lowercase")] - pub enum ColorScheme { - Archlinux, - Zenburn, - Monokai, - Squirrel, - } -} - -impl ColorScheme { - /// Returns the name identifying the theme - pub fn to_slug(self) -> &'static str { - match self { - ColorScheme::Archlinux => "archlinux", - ColorScheme::Zenburn => "zenburn", - ColorScheme::Monokai => "monokai", - ColorScheme::Squirrel => "squirrel", - } - } - - /// Returns wether a color scheme is dark - pub fn is_dark(self) -> bool { - match self { - ColorScheme::Archlinux => true, - ColorScheme::Zenburn => true, - ColorScheme::Monokai => true, - ColorScheme::Squirrel => false, - } - } -} -- cgit v1.2.3 From ab7ef2285520f31ea9b173939312982b387f4e15 Mon Sep 17 00:00:00 2001 From: Lukas Stabe Date: Sat, 26 Sep 2020 06:28:57 +0200 Subject: appease cargo fmt --- src/main.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 1f63e10..22d5f6a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -251,10 +251,7 @@ async fn run() -> Result<(), ContextualError> { &format!("/{}", inside_config.favicon_route), web::get().to(favicon), ) - .route( - &format!("/{}", inside_config.css_route), - web::get().to(css), - ) + .route(&format!("/{}", inside_config.css_route), web::get().to(css)) .configure(|c| configure_app(c, &inside_config)) .default_service(web::get().to(error_404)) }) @@ -337,7 +334,13 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { // Allow file upload app.service( web::resource(&upload_route).route(web::post().to(move |req, payload| { - file_upload::upload_file(req, payload, uses_random_route, favicon_route.clone(), css_route.clone()) + file_upload::upload_file( + req, + payload, + uses_random_route, + favicon_route.clone(), + css_route.clone(), + ) })), ) // Handle directories -- cgit v1.2.3 From f8b74203b7457fbf0482ec9e10266b370b1bfeab Mon Sep 17 00:00:00 2001 From: Lukas Stabe Date: Sat, 26 Sep 2020 23:07:24 +0200 Subject: compile scss at build time --- src/main.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 22d5f6a..2886a2c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -388,12 +388,9 @@ async fn favicon() -> impl Responder { .message_body(logo.into()) } -lazy_static::lazy_static! { - static ref CSS_TEXT: String = grass::from_string(include_str!("../data/style.scss").to_string(), &grass::Options::default()).unwrap(); -} - async fn css() -> impl Responder { + let css = include_str!(concat!(env!("OUT_DIR"), "/style.css")); web::HttpResponse::Ok() .set(ContentType(mime::TEXT_CSS)) - .body(&*CSS_TEXT) + .message_body(css.into()) } -- cgit v1.2.3 From 47895cad827180787a8f305ddac0372d2dbd266a Mon Sep 17 00:00:00 2001 From: Lukas Stabe Date: Thu, 1 Oct 2020 18:08:05 +0200 Subject: restore default theme cli option and add default theme dark option --- src/args.rs | 26 ++++++++++++++++++++++++++ src/auth.rs | 2 ++ src/file_upload.rs | 17 +++++++++++++++++ src/listing.rs | 6 ++++++ src/main.rs | 18 ++++++++++++++++++ src/renderer.rs | 14 ++++++++++---- 6 files changed, 79 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/args.rs b/src/args.rs index 78f9ce3..dc160d0 100644 --- a/src/args.rs +++ b/src/args.rs @@ -5,6 +5,7 @@ use structopt::StructOpt; use crate::auth; use crate::errors::ContextualError; +use crate::renderer; /// Possible characters for random routes const ROUTE_ALPHABET: [char; 16] = [ @@ -66,6 +67,26 @@ struct CLIArgs { #[structopt(short = "P", long = "no-symlinks")] no_symlinks: bool, + /// Default color scheme + #[structopt( + short = "c", + long = "color-scheme", + default_value = "squirrel", + possible_values = &renderer::THEME_SLUGS, + case_insensitive = true, + )] + color_scheme: String, + + /// Default color scheme + #[structopt( + short = "d", + long = "color-scheme-dark", + default_value = "archlinux", + possible_values = &renderer::THEME_SLUGS, + case_insensitive = true, + )] + color_scheme_dark: String, + /// Enable QR code display #[structopt(short = "q", long = "qrcode")] qrcode: bool, @@ -169,6 +190,9 @@ pub fn parse_args() -> crate::MiniserveConfig { let favicon_route = nanoid::nanoid!(10, &ROUTE_ALPHABET); let css_route = nanoid::nanoid!(10, &ROUTE_ALPHABET); + let default_color_scheme = args.color_scheme; + let default_color_scheme_dark = args.color_scheme_dark; + let path_explicitly_chosen = args.path.is_some(); let port = match args.port { @@ -187,6 +211,8 @@ pub fn parse_args() -> crate::MiniserveConfig { random_route, favicon_route, css_route, + default_color_scheme, + default_color_scheme_dark, index: args.index, overwrite_files: args.overwrite_files, show_qrcode: args.qrcode, diff --git a/src/auth.rs b/src/auth.rs index 3233e22..a2dfe60 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -124,6 +124,8 @@ fn build_unauthorized_response( false, &state.favicon_route, &state.css_route, + &state.default_color_scheme, + &state.default_color_scheme_dark, ) .into_string() } diff --git a/src/file_upload.rs b/src/file_upload.rs index 3afa755..14aadfc 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -111,6 +111,8 @@ pub fn upload_file( uses_random_route: bool, favicon_route: String, css_route: String, + default_color_scheme: &str, + default_color_scheme_dark: &str, ) -> Pin>>> { let conf = req.app_data::().unwrap(); let return_path = if let Some(header) = req.headers().get(header::REFERER) { @@ -138,6 +140,8 @@ pub fn upload_file( uses_random_route, &favicon_route, &css_route, + default_color_scheme, + default_color_scheme_dark, )); } }; @@ -158,6 +162,8 @@ pub fn upload_file( uses_random_route, &favicon_route, &css_route, + default_color_scheme, + default_color_scheme_dark, )); } }; @@ -178,10 +184,15 @@ pub fn upload_file( uses_random_route, &favicon_route, &css_route, + default_color_scheme, + default_color_scheme_dark, )); } }; let overwrite_files = conf.overwrite_files; + let default_color_scheme = conf.default_color_scheme.clone(); + let default_color_scheme_dark = conf.default_color_scheme_dark.clone(); + Box::pin( actix_multipart::Multipart::new(req.headers(), payload) .map_err(ContextualError::MultipartError) @@ -203,6 +214,8 @@ pub fn upload_file( uses_random_route, &favicon_route, &css_route, + &default_color_scheme, + &default_color_scheme_dark, ), }), ) @@ -219,6 +232,8 @@ fn create_error_response( uses_random_route: bool, favicon_route: &str, css_route: &str, + default_color_scheme: &str, + default_color_scheme_dark: &str, ) -> future::Ready> { errors::log_error_chain(description.to_string()); future::ok( @@ -235,6 +250,8 @@ fn create_error_response( !uses_random_route, &favicon_route, &css_route, + default_color_scheme, + default_color_scheme_dark, ) .into_string(), ), diff --git a/src/listing.rs b/src/listing.rs index 322de73..755b026 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -152,6 +152,8 @@ pub fn directory_listing( random_route: Option, favicon_route: String, css_route: String, + default_color_scheme: &str, + default_color_scheme_dark: &str, show_qrcode: bool, upload_route: String, tar_enabled: bool, @@ -338,6 +340,8 @@ pub fn directory_listing( false, &favicon_route, &css_route, + default_color_scheme, + default_color_scheme_dark, ) .into_string(), ), @@ -397,6 +401,8 @@ pub fn directory_listing( &upload_route, &favicon_route, &css_route, + default_color_scheme, + default_color_scheme_dark, &encoded_dir, breadcrumbs, tar_enabled, diff --git a/src/main.rs b/src/main.rs index 2886a2c..b947004 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,6 +58,12 @@ pub struct MiniserveConfig { /// Randomly generated css route pub css_route: String, + /// Default color scheme + pub default_color_scheme: String, + + /// Default dark mode color scheme + pub default_color_scheme_dark: String, + /// The name of a directory index file to serve, like "index.html" /// /// Normally, when miniserve serves a directory, it creates a listing for that directory. @@ -285,6 +291,8 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { let random_route = conf.random_route.clone(); let favicon_route = conf.favicon_route.clone(); let css_route = conf.css_route.clone(); + let default_color_scheme = conf.default_color_scheme.clone(); + let default_color_scheme_dark = conf.default_color_scheme_dark.clone(); let show_qrcode = conf.show_qrcode; let file_upload = conf.file_upload; let tar_enabled = conf.tar_enabled; @@ -315,6 +323,8 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { random_route.clone(), favicon_route.clone(), css_route.clone(), + &default_color_scheme, + &default_color_scheme_dark, show_qrcode, u_r.clone(), tar_enabled, @@ -329,6 +339,10 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { let favicon_route = conf.favicon_route.clone(); let css_route = conf.css_route.clone(); + + let default_color_scheme = conf.default_color_scheme.clone(); + let default_color_scheme_dark = conf.default_color_scheme_dark.clone(); + if let Some(serve_path) = serve_path { if conf.file_upload { // Allow file upload @@ -340,6 +354,8 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { uses_random_route, favicon_route.clone(), css_route.clone(), + &default_color_scheme, + &default_color_scheme_dark, ) })), ) @@ -376,6 +392,8 @@ async fn error_404(req: HttpRequest) -> HttpResponse { !uses_random_route, &favicon_route, &css_route, + &conf.default_color_scheme, + &conf.default_color_scheme_dark, ) .into_string(), ) diff --git a/src/renderer.rs b/src/renderer.rs index 2ebe214..61e382e 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -20,6 +20,8 @@ pub fn page( upload_route: &str, favicon_route: &str, css_route: &str, + default_color_scheme: &str, + default_color_scheme_dark: &str, encoded_dir: &str, breadcrumbs: Vec, tar_enabled: bool, @@ -37,7 +39,7 @@ pub fn page( (DOCTYPE) html { (page_header(&title_path, file_upload, favicon_route, css_route)) - body#drop-container { + body#drop-container.(format!("default_theme_{}", default_color_scheme)).(format!("default_theme_dark_{}", default_color_scheme_dark)) { (PreEscaped(r#"