diff --git a/Cargo.lock b/Cargo.lock index 9d3c8b1..6b19dd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -535,9 +535,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" dependencies = [ "libc", ] @@ -1773,9 +1773,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" +checksum = "16833386b02953ca926d19f64af613b9bf742c48dcd5e09b32fbfc9740bf84e2" dependencies = [ "thiserror", "ucd-trie", @@ -1783,9 +1783,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b79d4c71c865a25a4322296122e3924d30bc8ee0834c8bfc8b95f7f054afbfb" +checksum = "7763190f9406839f99e5197afee8c9e759969f7dbfa40ad3b8dbee8757b745b5" dependencies = [ "pest", "pest_generator", @@ -1793,9 +1793,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c435bf1076437b851ebc8edc3a18442796b30f1728ffea6262d59bbe28b077e" +checksum = "249061b22e99973da1f5f5f1410284419e283bb60b79255bf5f42a94b66a2e00" dependencies = [ "pest", "pest_meta", @@ -1806,9 +1806,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745a452f8eb71e39ffd8ee32b3c5f51d03845f99786fa9b68db6ff509c505411" +checksum = "457c310cfc9cf3f22bc58901cc7f0d3410ac5d6298e432a4f9a6138565cb6df6" dependencies = [ "once_cell", "pest", @@ -2555,9 +2555,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" dependencies = [ "itoa 1.0.6", "ryu", @@ -2617,9 +2617,9 @@ checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -3381,7 +3381,7 @@ dependencies = [ [[package]] name = "websurfx" -version = "0.12.3" +version = "0.13.0" dependencies = [ "actix-files", "actix-web", diff --git a/public/static/cookies.js b/public/static/cookies.js new file mode 100644 index 0000000..90cfe3b --- /dev/null +++ b/public/static/cookies.js @@ -0,0 +1,18 @@ +// This function is executed when any page on the website finsihes loading and +// this function retrieves the cookies if it is present on the user's machine. +// If it is available then the saved cookies is display in the cookies tab +// otherwise an appropriate message is displayed if it is not available. +document.addEventListener( + 'DOMContentLoaded', + () => { + try { + let cookie = decodeURIComponent(document.cookie) + document.querySelector('.cookies input').value = + cookie !== '' ? cookie : 'No cookies have been saved on your system' + } catch (error) { + console.error('Error decoding cookie:', error) + document.querySelector('.cookies input').value = 'Error decoding cookie' + } + }, + false +) diff --git a/public/static/settings.js b/public/static/settings.js new file mode 100644 index 0000000..6b18df4 --- /dev/null +++ b/public/static/settings.js @@ -0,0 +1,83 @@ +// This function handles the toggling of selections of all upstream search engines +// options in the settings page under the tab engines. +function toggleAllSelection() { + document + .querySelectorAll('.engine') + .forEach( + (engine_checkbox) => + (engine_checkbox.checked = + document.querySelector('.select_all').checked) + ) +} + +// This function adds the functionality to sidebar buttons to only show settings +// related to that tab. +function setActiveTab(current_tab) { + document + .querySelectorAll('.tab') + .forEach((tab) => tab.classList.remove('active')) + document + .querySelectorAll('.btn') + .forEach((tab) => tab.classList.remove('active')) + current_tab.classList.add('active') + document + .querySelector(`.${current_tab.innerText.toLowerCase().replace(' ', '_')}`) + .classList.add('active') +} + +// This function adds the functionality to save all the user selected preferences +// to be saved in a cookie on the users machine. +function setClientSettings() { + let cookie_dictionary = new Object() + document.querySelectorAll('select').forEach((select_tag) => { + if (select_tag.name === 'themes') { + cookie_dictionary['theme'] = select_tag.value + } else if (select_tag.name === 'colorschemes') { + cookie_dictionary['colorscheme'] = select_tag.value + } + }) + let engines = [] + document.querySelectorAll('.engine').forEach((engine_checkbox) => { + if (engine_checkbox.checked === true) { + engines.push(engine_checkbox.parentNode.parentNode.innerText.trim()) + } + }) + cookie_dictionary['engines'] = engines + let expiration_date = new Date() + expiration_date.setFullYear(expiration_date.getFullYear() + 1) + document.cookie = `appCookie=${JSON.stringify( + cookie_dictionary + )}; expires=${expiration_date.toUTCString()}` + + document.querySelector('.message').innerText = + '✅ The settings have been saved sucessfully!!' + + setTimeout(() => { + document.querySelector('.message').innerText = '' + }, 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() { + let cookie = decodeURIComponent(document.cookie) + + if (cookie !== '') { + let cookie_value = decodeURIComponent(document.cookie) + .split(';') + .map((item) => item.split('=')) + .reduce((acc, [_, v]) => (acc = JSON.parse(v)) && acc, {}) + + let links = Array.from(document.querySelectorAll('link')).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` + } + } + ) + } +} diff --git a/public/static/themes/simple.css b/public/static/themes/simple.css index 17962d0..d9b01ba 100644 --- a/public/static/themes/simple.css +++ b/public/static/themes/simple.css @@ -263,41 +263,243 @@ footer { /* Styles for the about page */ - .about-container article{ - font-size: 1.5rem; - color:var(--fg); - padding-bottom: 10px; - } +.about-container article { + font-size: 1.5rem; + color: var(--fg); + padding-bottom: 10px; +} - .about-container article h1{ - color: var(--2); - font-size: 2.8rem; - } +.about-container article h1 { + color: var(--2); + font-size: 2.8rem; +} - .about-container article div{ - padding-bottom: 15px; - } +.about-container article div { + padding-bottom: 15px; +} - .about-container a{ - color:var(--3); - } +.about-container a { + color: var(--3); +} - .about-container article h2{ - color: var(--3); - font-size: 1.8rem; - padding-bottom: 10px; - } +.about-container article h2 { + color: var(--3); + font-size: 1.8rem; + padding-bottom: 10px; +} - .about-container p{ - color:var(--fg); - font-size: 1.6rem; - padding-bottom: 10px; - } +.about-container p { + color: var(--fg); + font-size: 1.6rem; + padding-bottom: 10px; +} - .about-container h3{ - font-size: 1.5rem; - } +.about-container h3 { + font-size: 1.5rem; +} - .about-container { - width: 80%; - } +.about-container { + width: 80%; +} + +/* Styles for the settings page */ +.settings_container { + display: flex; + justify-content: space-around; + width: 80dvw; +} + +.settings h1 { + color: var(--2); + font-size: 2.5rem; +} + +.settings hr { + border-color: var(--3); + margin: 0.3rem 0 1rem 0; +} + +.settings_container .sidebar { + width: 30%; + cursor: pointer; + font-size: 2rem; + display: flex; + flex-direction: column; + margin-right: 0.5rem; + margin-left: -0.7rem; + padding: 0.7rem; + border-radius: 5px; + font-weight: bold; + margin-bottom: 0.5rem; + color: var(--fg); + text-transform: capitalize; + gap: 1.5rem; +} + +.settings_container .sidebar .btn { + padding: 0.5rem; + border-radius: 0.5rem; +} + +.settings_container .sidebar .btn.active { + background-color: var(--2); +} + +.settings_container .main_container { + width: 70%; + border-left: 1.5px solid var(--3); + padding-left: 3rem; +} + +.settings_container .tab { + display: none; +} + +.settings_container .tab.active { + display: flex; + flex-direction: column; + justify-content: space-around; +} + +.settings_container button { + margin-top: 1rem; + padding: 1rem 2rem; + font-size: 1.5rem; + background: var(--3); + color: var(--bg); + border-radius: 0.5rem; + border: 2px solid transparent; + font-weight: bold; + transition: all 0.1s ease-out; + cursor: pointer; + box-shadow: 5px 5px; + outline: none; +} + +.settings_container button:active { + box-shadow: none; + translate: 5px 5px; +} + +.settings_container .main_container .message { + font-size: 1.5rem; + color: var(--fg); +} + +.settings_container .tab h3 { + font-size: 2rem; + font-weight: bold; + color: var(--4); + margin-top: 1.5rem; + text-transform: capitalize; +} + +.settings_container .tab .description { + font-size: 1.5rem; + margin-bottom: 0.5rem; + color: var(--fg); +} + +.settings_container .user_interface select { + margin: 0.7rem 0; + width: 20rem; + background-color: var(--bg); + color: var(--fg); + padding: 1rem 2rem; + border-radius: 0.5rem; + outline: none; + border: none; + text-transform: capitalize; +} + +.settings_container .user_interface option:hover { + background-color: var(--1); +} + +.settings_container .engines .engine_selection { + display: flex; + flex-direction: column; + justify-content: center; + gap: 1rem; + padding: 1rem 0; +} + +.settings_container .engines .toggle_btn { + color: var(--fg); + font-size: 1.5rem; + display: flex; + gap: 0.5rem; + align-items: center; +} + +.settings_container .engines hr { + margin: 0; +} + +.settings_container .cookies input { + margin: 1rem 0rem; +} + +/* Styles for the toggle button */ +/* The switch - the box around the slider */ +.switch { + position: relative; + display: inline-block; + width: 6rem; + height: 3.4rem; +} + +/* Hide default HTML checkbox */ +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +/* The slider */ +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: var(--bg); + -webkit-transition: 0.4s; + transition: 0.4s; +} + +.slider:before { + position: absolute; + content: ''; + height: 2.6rem; + width: 2.6rem; + left: 0.4rem; + bottom: 0.4rem; + background-color: var(--fg); + -webkit-transition: 0.4s; + transition: 0.4s; +} + +input:checked + .slider { + background-color: var(--3); +} + +input:focus + .slider { + box-shadow: 0 0 1px var(--3); +} + +input:checked + .slider:before { + -webkit-transform: translateX(2.6rem); + -ms-transform: translateX(2.6rem); + transform: translateX(2.6rem); +} + +/* Rounded sliders */ +.slider.round { + border-radius: 3.4rem; +} + +.slider.round:before { + border-radius: 50%; +} diff --git a/public/templates/cookies_tab.html b/public/templates/cookies_tab.html new file mode 100644 index 0000000..4243bfe --- /dev/null +++ b/public/templates/cookies_tab.html @@ -0,0 +1,12 @@ +
+

Cookies

+

+ This is the cookies are saved on your system and it contains the preferences + you chose in the settings page +

+ +

+ The cookies stored are not used by us for any malicious intend or for + tracking you in any way. +

+
diff --git a/public/templates/engines_tab.html b/public/templates/engines_tab.html new file mode 100644 index 0000000..9bb5e1c --- /dev/null +++ b/public/templates/engines_tab.html @@ -0,0 +1,31 @@ +
+

select search engines

+

+ Select the search engines from the list of engines that you want results + from +

+
+
+ + Select All +
+
+
+ + Duckduckgo +
+
+ + Searx +
+
+
diff --git a/public/templates/footer.html b/public/templates/footer.html index db43e6d..24d0d2c 100644 --- a/public/templates/footer.html +++ b/public/templates/footer.html @@ -10,6 +10,7 @@ + diff --git a/public/templates/general_tab.html b/public/templates/general_tab.html new file mode 100644 index 0000000..b83935a --- /dev/null +++ b/public/templates/general_tab.html @@ -0,0 +1,4 @@ +
+

General

+

Coming soon!!

+
diff --git a/public/templates/header.html b/public/templates/header.html index 92053b9..ce12b51 100644 --- a/public/templates/header.html +++ b/public/templates/header.html @@ -1,12 +1,14 @@ - + + Websurfx - + - +
{{>navbar}}
+ diff --git a/public/templates/navbar.html b/public/templates/navbar.html index f5f581f..c369739 100644 --- a/public/templates/navbar.html +++ b/public/templates/navbar.html @@ -1,6 +1,6 @@ diff --git a/public/templates/settings.html b/public/templates/settings.html index 4215d08..3c97213 100644 --- a/public/templates/settings.html +++ b/public/templates/settings.html @@ -1,5 +1,22 @@ {{>header this}} -
-

Page is under construction

+
+

Settings

+
+
+ +
+ {{> general_tab}} {{> user_interface_tab}} {{> engines_tab}} {{> + cookies_tab}} +

+ +
+
+ + {{>footer}} diff --git a/public/templates/user_interface_tab.html b/public/templates/user_interface_tab.html new file mode 100644 index 0000000..51b3237 --- /dev/null +++ b/public/templates/user_interface_tab.html @@ -0,0 +1,27 @@ +
+

select theme

+

+ Select the theme from the available themes to be used in user interface +

+ +

select color scheme

+

+ Select the color scheme for your theme to be used in user interface +

+ +