From d48201021e28221733ed7471a37f205e49bda5be Mon Sep 17 00:00:00 2001 From: Milim Date: Thu, 15 Aug 2024 14:19:06 +0200 Subject: [PATCH] update frontend to account for search engine selection changes --- public/static/cookies.js | 51 ++-------- public/static/settings.js | 95 +----------------- src/config.rs | 20 ---- src/engines/mod.rs | 2 - src/server/router.rs | 44 +++------ src/server/routes/search.rs | 18 ++-- src/templates/partials/header.rs | 9 +- src/templates/partials/settings_tabs/mod.rs | 1 - .../partials/settings_tabs/user_interface.rs | 96 ------------------- src/templates/views/about.rs | 16 +--- src/templates/views/index.rs | 4 +- src/templates/views/not_found.rs | 4 +- src/templates/views/search.rs | 10 +- src/templates/views/settings.rs | 8 +- 14 files changed, 43 insertions(+), 335 deletions(-) delete mode 100644 src/templates/partials/settings_tabs/user_interface.rs diff --git a/public/static/cookies.js b/public/static/cookies.js index 3525c5b..a01137e 100644 --- a/public/static/cookies.js +++ b/public/static/cookies.js @@ -10,51 +10,18 @@ * @returns {void} */ function setClientSettingsOnPage(cookie) { - let cookie_value = cookie - .split(';') - .map((item) => item.split('=')) - .reduce((acc, [_, v]) => (acc = JSON.parse(v)) && acc, {}) - // Loop through all select tags and add their values to the cookie dictionary - document.querySelectorAll('select').forEach((select_tag) => { - switch (select_tag.name) { - case 'themes': - select_tag.value = cookie_value['theme'] - break - case 'colorschemes': - select_tag.value = cookie_value['colorscheme'] - break - case 'animations': - select_tag.value = cookie_value['animation'] - break - case 'safe_search_levels': - select_tag.value = cookie_value['safe_search_level'] - break + let engines = document.querySelectorAll('.engine') + + document.querySelector('.select_all').checked = true + + engines.forEach((engine) => { + engine.checked = cookie[engine.parentNode.parentNode.innerText.trim()]; + if (!engine.checked) { + document.querySelector('.select_all').checked = false } }) - let engines = document.querySelectorAll('.engine') - let engines_cookie = cookie_value['engines'] - if (engines_cookie.length === engines.length) { - document.querySelector('.select_all').checked = true - engines.forEach((engine_checkbox) => { - engine_checkbox.checked = true - }) - } else { - engines.forEach((engines_checkbox) => { - engines_checkbox.checked = false - }) - engines_cookie.forEach((engine_name) => { - engines.forEach((engine_checkbox) => { - if ( - engine_checkbox.parentNode.parentNode.innerText.trim() === - engine_name.trim() - ) { - engine_checkbox.checked = true - } - }) - }) - } } /** @@ -78,7 +45,7 @@ document.addEventListener( if (cookie.length) { document.querySelector('.cookies input').value = cookie // This function displays the user provided settings on the settings page. - setClientSettingsOnPage(cookie) + setClientSettingsOnPage(JSON.parse(cookie.replace("appCookie=", ""))) } else { document.querySelector('.cookies input').value = 'No cookies have been saved on your system' diff --git a/public/static/settings.js b/public/static/settings.js index b8d8f88..008136c 100644 --- a/public/static/settings.js +++ b/public/static/settings.js @@ -7,8 +7,8 @@ function toggleAllSelection() { .querySelectorAll('.engine') .forEach( (engine_checkbox) => - (engine_checkbox.checked = - document.querySelector('.select_all').checked), + (engine_checkbox.checked = + document.querySelector('.select_all').checked), ) } @@ -41,35 +41,10 @@ function setClientSettings() { // Create an object to store the user's preferences let cookie_dictionary = new Object() - // Loop through all select tags and add their values to the cookie dictionary - document.querySelectorAll('select').forEach((select_tag) => { - switch (select_tag.name) { - case 'themes': - cookie_dictionary['theme'] = select_tag.value - break - case 'colorschemes': - cookie_dictionary['colorscheme'] = select_tag.value - break - case 'animations': - cookie_dictionary['animation'] = select_tag.value || null - break - case 'safe_search_levels': - cookie_dictionary['safe_search_level'] = Number(select_tag.value) - break - } - }) - - // Loop through all engine checkboxes and add their values to the cookie dictionary - let engines = [] - document.querySelectorAll('.engine').forEach((engine_checkbox) => { - if (engine_checkbox.checked) { - engines.push(engine_checkbox.parentNode.parentNode.innerText.trim()) - } + cookie_dictionary[engine_checkbox.parentNode.parentNode.innerText.trim()] = engine_checkbox.checked }) - cookie_dictionary['engines'] = engines - // Set the expiration date for the cookie to 1 year from the current date let expiration_date = new Date() expiration_date.setFullYear(expiration_date.getFullYear() + 1) @@ -89,67 +64,3 @@ function setClientSettings() { }, 10000) } -/** - * This functions gets the saved cookies if it is present on the user's machine If it - * is available then it is parsed and converted to an object which is then used to - * retrieve the preferences that the user had selected previously and is then loaded in the - * website otherwise the function does nothing and the default server side settings are loaded. - */ -function getClientSettings() { - // Get the appCookie from the user's machine - let cookie = decodeURIComponent(document.cookie) - - // If the cookie is not empty, parse it and use it to set the user's preferences - if (cookie.length) { - let cookie_value = cookie - .split(';') - .map((item) => item.split('=')) - .reduce((acc, [_, v]) => (acc = JSON.parse(v)) && acc, {}) - - let links = Array.from(document.querySelectorAll('link')) - - // A check to determine whether the animation link exists under the head tag or not. - // If it does not exists then create and add a new animation link under the head tag - // and update the other link tags href according to the settings provided by the user - // via the UI. On the other hand if it does exist then just update all the link tags - // href according to the settings provided by the user via the UI. - if (!links.some((item) => item.href.includes('static/animations'))) { - if (cookie_value['animation']) { - let animation_link = document.createElement('link') - animation_link.href = `static/animations/${cookie_value['animation']}.css` - animation_link.rel = 'stylesheet' - animation_link.type = 'text/css' - document.querySelector('head').appendChild(animation_link) - } - // Loop through all link tags and update their href values to match the user's preferences - links.forEach((item) => { - if (item.href.includes('static/themes')) { - item.href = `static/themes/${cookie_value['theme']}.css` - } else if (item.href.includes('static/colorschemes')) { - item.href = `static/colorschemes/${cookie_value['colorscheme']}.css` - } - }) - } else { - // Loop through all link tags and update their href values to match the user's preferences - links.forEach((item) => { - if (item.href.includes('static/themes')) { - item.href = `static/themes/${cookie_value['theme']}.css` - } else if (item.href.includes('static/colorschemes')) { - item.href = `static/colorschemes/${cookie_value['colorscheme']}.css` - } else if ( - item.href.includes('static/animations') && - cookie_value['animation'] - ) { - item.href = `static/colorschemes/${cookie_value['animation']}.css` - } - }) - if (!cookie_value['animation']) { - document - .querySelector('head') - .removeChild( - links.filter((item) => item.href.includes('static/animations')), - ) - } - } - } -} diff --git a/src/config.rs b/src/config.rs index 7addc5c..1c8da5c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,8 +10,6 @@ pub struct Config { pub port: u16, /// It stores the parsed ip address option on which the server should launch pub binding_ip: String, - /// It stores the theming options for the website. - pub style: Style, /// Memory cache invalidation time pub cache_expiry_time: u64, /// It stores the option to whether enable or disable logs. @@ -32,19 +30,6 @@ pub struct Config { pub pool_idle_connection_timeout: u8, } -/// A struct holding style config -#[derive(Default, Debug, Clone, Deserialize, Serialize)] -pub struct Style { - /// It stores the parsed theme option used to set a theme for the website. - pub theme: String, - /// It stores the parsed colorscheme option used to set a colorscheme for the - /// theme being used. - pub colorscheme: String, - /// It stores the parsed animation option used to set an animation for the - /// theme being used. - pub animation: Option, -} - /// Configuration options for the rate limiter middleware. pub struct RateLimiter { /// The number of request that are allowed within a provided time limit. @@ -58,11 +43,6 @@ impl Default for Config { Self { port: 8080, binding_ip: "127.0.0.1".into(), - style: Style { - theme: "simple".into(), - colorscheme: "catppuccin-mocha".into(), - animation: Some("simple-frosted-glow".into()), - }, cache_expiry_time: 600, logging: true, debug: false, diff --git a/src/engines/mod.rs b/src/engines/mod.rs index 667332c..80f1ea7 100644 --- a/src/engines/mod.rs +++ b/src/engines/mod.rs @@ -26,7 +26,6 @@ pub struct Engines { duckduckgo: bool, librex: bool, mojeek: bool, - search_result_parser: bool, searx: bool, startpage: bool, } @@ -39,7 +38,6 @@ impl Default for Engines { duckduckgo: true, librex: true, mojeek: true, - search_result_parser: true, searx: true, startpage: true, } diff --git a/src/server/router.rs b/src/server/router.rs index 12da172..07698d3 100644 --- a/src/server/router.rs +++ b/src/server/router.rs @@ -11,30 +11,18 @@ use tokio::fs::read_to_string; /// Handles the route of index page or main page of the `crabbysearch` meta search engine website. #[get("/")] -pub async fn index(config: web::Data) -> Result> { - Ok(HttpResponse::Ok().content_type(ContentType::html()).body( - crate::templates::views::index::index( - &config.style.colorscheme, - &config.style.theme, - &config.style.animation, - ) - .0, - )) +pub async fn index() -> Result> { + Ok(HttpResponse::Ok() + .content_type(ContentType::html()) + .body(crate::templates::views::index::index().0)) } /// Handles the route of any other accessed route/page which is not provided by the /// website essentially the 404 error page. -pub async fn not_found( - config: web::Data, -) -> Result> { - Ok(HttpResponse::Ok().content_type(ContentType::html()).body( - crate::templates::views::not_found::not_found( - &config.style.colorscheme, - &config.style.theme, - &config.style.animation, - ) - .0, - )) +pub async fn not_found() -> Result> { + Ok(HttpResponse::Ok() + .content_type(ContentType::html()) + .body(crate::templates::views::not_found::not_found().0)) } /// Handles the route of robots.txt page of the `crabbysearch` meta search engine website. @@ -49,15 +37,10 @@ pub async fn robots_data(_req: HttpRequest) -> Result) -> Result> { - Ok(HttpResponse::Ok().content_type(ContentType::html()).body( - crate::templates::views::about::about( - &config.style.colorscheme, - &config.style.theme, - &config.style.animation, - ) - .0, - )) +pub async fn about() -> Result> { + Ok(HttpResponse::Ok() + .content_type(ContentType::html()) + .body(crate::templates::views::about::about().0)) } /// Handles the route of settings page of the `crabbysearch` meta search engine website. @@ -67,9 +50,6 @@ pub async fn settings( ) -> Result> { Ok(HttpResponse::Ok().content_type(ContentType::html()).body( crate::templates::views::settings::settings( - &config.style.colorscheme, - &config.style.theme, - &config.style.animation, &config .upstream_search_engines .list() diff --git a/src/server/routes/search.rs b/src/server/routes/search.rs index 25aa14b..e5f1196 100644 --- a/src/server/routes/search.rs +++ b/src/server/routes/search.rs @@ -45,10 +45,11 @@ pub async fn search( let cookie = req.cookie("appCookie"); + log::info!("{cookie:?}"); + // Get search settings using the user's cookie or from the server's config let search_settings: crate::engines::Engines = cookie - .and_then(|cookie_value| serde_json::from_str(cookie_value.value()).ok()) - .inspect(|e| log::info!("{e:?}")) + .and_then(|cookie_value| serde_json::from_str(&cookie_value.value().to_lowercase()).ok()) .unwrap_or_default(); // Closure wrapping the results function capturing local references @@ -99,16 +100,9 @@ pub async fn search( cache.cache_results(&results_list, &cache_keys); } - Ok(HttpResponse::Ok().content_type(ContentType::html()).body( - crate::templates::views::search::search( - &config.style.colorscheme, - &config.style.theme, - &config.style.animation, - query, - &results.0, - ) - .0, - )) + Ok(HttpResponse::Ok() + .content_type(ContentType::html()) + .body(crate::templates::views::search::search(query, &results.0).0)) } /// Fetches the results for a query and page. It First checks the redis cache, if that diff --git a/src/templates/partials/header.rs b/src/templates/partials/header.rs index b88e5cb..43dfe80 100644 --- a/src/templates/partials/header.rs +++ b/src/templates/partials/header.rs @@ -13,7 +13,7 @@ use maud::{html, Markup, PreEscaped, DOCTYPE}; /// # Returns /// /// It returns the compiled html markup code for the header as a result. -pub fn header(colorscheme: &str, theme: &str, animation: &Option) -> Markup { +pub fn header() -> Markup { html!( (DOCTYPE) html lang="en" @@ -22,11 +22,8 @@ pub fn header(colorscheme: &str, theme: &str, animation: &Option) -> Mar title{"crabbysearch"} meta charset="UTF-8"; meta name="viewport" content="width=device-width, initial-scale=1"; - link href=(format!("static/colorschemes/{colorscheme}.css")) rel="stylesheet" type="text/css"; - link href=(format!("static/themes/{theme}.css")) rel="stylesheet" type="text/css"; - @if animation.is_some() { - link href=(format!("static/animations/{}.css", animation.as_ref().unwrap())) rel="stylesheet" type="text/css"; - } + link href=("static/colorschemes/monokai.css") rel="stylesheet" type="text/css"; + link href=("static/themes/simple.css") rel="stylesheet" type="text/css"; } (PreEscaped("")) diff --git a/src/templates/partials/settings_tabs/mod.rs b/src/templates/partials/settings_tabs/mod.rs index b8f42dc..2154977 100644 --- a/src/templates/partials/settings_tabs/mod.rs +++ b/src/templates/partials/settings_tabs/mod.rs @@ -3,4 +3,3 @@ pub mod cookies; pub mod engines; -pub mod user_interface; diff --git a/src/templates/partials/settings_tabs/user_interface.rs b/src/templates/partials/settings_tabs/user_interface.rs deleted file mode 100644 index b191a55..0000000 --- a/src/templates/partials/settings_tabs/user_interface.rs +++ /dev/null @@ -1,96 +0,0 @@ -//! A module that handles the user interface tab for setting page view in the `crabbysearch` frontend. - -use crate::handler::{file_path, FileType}; -use maud::{html, Markup}; -use std::fs::read_dir; - -/// A helper function that helps in building the list of all available colorscheme/theme/animation -/// names present in the colorschemes, animations and themes folder respectively by excluding the -/// ones that have already been selected via the config file. -/// -/// # Arguments -/// -/// * `style_type` - It takes the style type of the values `theme` and `colorscheme` as an -/// argument. -/// * `selected_style` - It takes the currently selected style value provided via the config file -/// as an argument. -/// -/// # Error -/// -/// Returns a list of colorscheme/theme names as a vector of tuple strings on success otherwise -/// returns a standard error message. -fn style_option_list( - style_type: &str, - selected_style: &str, -) -> Result, Box> { - let mut style_option_names: Vec<(String, String)> = Vec::new(); - for file in read_dir(format!( - "{}static/{}/", - file_path(FileType::Theme)?, - style_type, - ))? { - let style_name = file?.file_name().to_str().unwrap().replace(".css", ""); - if selected_style != style_name { - style_option_names.push((style_name.clone(), style_name.replace('-', " "))); - } - } - - if style_type == "animations" { - style_option_names.push((String::default(), "none".to_owned())) - } - - Ok(style_option_names) -} - -/// A functions that handles the html code for the user interface tab for the settings page for the search page. -/// -/// # Error -/// -/// It returns the compiled html markup code for the user interface tab on success otherwise -/// returns a standard error message. -pub fn user_interface( - theme: &str, - colorscheme: &str, - animation: &Option, -) -> Result> { - Ok(html!( - div class="user_interface tab"{ - h1{"User Interface"} - h3{"select theme"} - p class="description"{ - "Select the theme from the available themes to be used in user interface" - } - select name="themes"{ - // Sets the user selected theme name from the config file as the first option in the selection list. - option value=(theme){(theme.replace('-', " "))} - @for (k,v) in style_option_list("themes", theme)?{ - option value=(k){(v)} - } - } - h3{"select color scheme"} - p class="description"{ - "Select the color scheme for your theme to be used in user interface" - } - select name="colorschemes"{ - // Sets the user selected colorscheme name from the config file as the first option in the selection list. - option value=(colorscheme){(colorscheme.replace('-', " "))} - @for (k,v) in style_option_list("colorschemes", colorscheme)?{ - option value=(k){(v)} - } - } - h3{"select animation"} - p class="description"{ - "Select the animation for your theme to be used in user interface" - } - select name="animations"{ - @let default_animation = &String::default(); - @let animation = animation.as_ref().unwrap_or(default_animation); - // Sets the user selected animation name from the config file as the first option in the selection list. - option value=(animation){(animation.replace('-'," "))} - @for (k,v) in style_option_list("animations", animation)?{ - option value=(k){(v)} - } - } - } - )) -} diff --git a/src/templates/views/about.rs b/src/templates/views/about.rs index ccc4c4d..0de3e91 100644 --- a/src/templates/views/about.rs +++ b/src/templates/views/about.rs @@ -14,16 +14,7 @@ use crate::templates::partials::{footer::footer, header::header}; /// # Returns /// /// It returns the compiled html markup code as a result. -pub fn about(colorscheme: &str, theme: &str, animation: &Option) -> Markup { - let logo_svg = r#" - - - - - - - - "#; +pub fn about() -> Markup { let feature_lightning = r#" "#; @@ -43,12 +34,9 @@ pub fn about(colorscheme: &str, theme: &str, animation: &Option) -> Mark "#; html!( - (header(colorscheme, theme, animation)) + (header()) main class="about-container"{ article { - div class="logo-container" { - (PreEscaped(logo_svg)) - } div class="text-block" { h3 class="text-block-title" {"Why crabbysearch?"} diff --git a/src/templates/views/index.rs b/src/templates/views/index.rs index bb8a9f0..bcf5809 100644 --- a/src/templates/views/index.rs +++ b/src/templates/views/index.rs @@ -14,9 +14,9 @@ use crate::templates::partials::{bar::bar, footer::footer, header::header}; /// # Returns /// /// It returns the compiled html markup code as a result. -pub fn index(colorscheme: &str, theme: &str, animation: &Option) -> Markup { +pub fn index() -> Markup { html!( - (header(colorscheme, theme, animation)) + (header()) main class="search-container"{ (bar(&String::default())) (PreEscaped("")) diff --git a/src/templates/views/not_found.rs b/src/templates/views/not_found.rs index f893cc9..f5730a4 100644 --- a/src/templates/views/not_found.rs +++ b/src/templates/views/not_found.rs @@ -13,9 +13,9 @@ use maud::{html, Markup}; /// # Returns /// /// It returns the compiled html markup code as a result. -pub fn not_found(colorscheme: &str, theme: &str, animation: &Option) -> Markup { +pub fn not_found() -> Markup { html!( - (header(colorscheme, theme, animation)) + (header()) main class="error_container"{ img src="images/robot-404.svg" alt="Image of broken robot."; .error_content{ diff --git a/src/templates/views/search.rs b/src/templates/views/search.rs index d38217d..38821c4 100644 --- a/src/templates/views/search.rs +++ b/src/templates/views/search.rs @@ -19,15 +19,9 @@ use crate::{ /// # Returns /// /// It returns the compiled html markup code as a result. -pub fn search( - colorscheme: &str, - theme: &str, - animation: &Option, - query: &str, - search_results: &SearchResults, -) -> Markup { +pub fn search(query: &str, search_results: &SearchResults) -> Markup { html!( - (header(colorscheme, theme, animation)) + (header()) main class="results"{ (search_bar(&search_results.engine_errors_info, search_results.safe_search_level, query)) .results_aggregated{ diff --git a/src/templates/views/settings.rs b/src/templates/views/settings.rs index d09e42c..9d7fc40 100644 --- a/src/templates/views/settings.rs +++ b/src/templates/views/settings.rs @@ -5,7 +5,7 @@ use maud::{html, Markup}; use crate::templates::partials::{ footer::footer, header::header, - settings_tabs::{cookies::cookies, engines::engines, user_interface::user_interface}, + settings_tabs::{cookies::cookies, engines::engines}, }; /// A function that handles the html code for the settings page view in the search engine frontend. @@ -23,13 +23,10 @@ use crate::templates::partials::{ /// This function returns a compiled html markup code on success otherwise returns a standard error /// message. pub fn settings( - colorscheme: &str, - theme: &str, - animation: &Option, engine_names: &Vec<(&'static str, bool)>, ) -> Result> { Ok(html!( - (header(colorscheme, theme, animation)) + (header()) main class="settings"{ h1{"Settings"} hr; @@ -41,7 +38,6 @@ pub fn settings( .btn onclick="setActiveTab(this)"{"cookies"} } .main_container{ - (user_interface(theme, colorscheme, animation)?) (engines(&engine_names)) (cookies()) p class="message"{}