diff --git a/public/static/colorschemes/catppuccin-mocha.css b/public/static/colorschemes/catppuccin-mocha.css index 6432155..d2c1075 100644 --- a/public/static/colorschemes/catppuccin-mocha.css +++ b/public/static/colorschemes/catppuccin-mocha.css @@ -2,10 +2,8 @@ --bg: #1e1e2e; --fg: #cdd6f4; --1: #45475a; - --1_1: #4f5169; --2: #f38ba8; --3: #a6e3a1; - --3_1: #7ce073; --4: #f9e2af; --5: #89b4fa; --6: #f5c2e7; diff --git a/public/static/settings.js b/public/static/settings.js index 0af04bf..0c8c0f1 100644 --- a/public/static/settings.js +++ b/public/static/settings.js @@ -1,130 +1,32 @@ -function toggleSelectOptions(elem, state) { - elem.classList.remove("invalid"); - try { elem.parentElement.querySelector('.errTxt').remove();} catch (error) {} - let options = elem.querySelector('.options'); - const pos = elem.getBoundingClientRect(); - const windowWidth = document.getElementsByTagName("body")[0].clientHeight; - if(pos.y + 250 > windowWidth) { - options.style.bottom = '40px'; - } else { options.style.bottom = null } - options.style.display = state != 'close' ? getComputedStyle(options).display == 'none' ? 'block': 'none' : 'none'; -} - -let selectElements = document.querySelectorAll('.custom-select'); -Array.from(selectElements).forEach(element => { - element.childNodes[0].nodeValue = (element.hasAttribute('data-multiple') ? element.getAttribute('data-placeholder') : element.getAttribute('data-default')); - element.addEventListener('click', (e) => {if (e.target === element) toggleSelectOptions(element)}); - element.addEventListener('focusout', (e) => {if (e.target === element) toggleSelectOptions(element, 'close')}); -}); - -function removeSelectOption(elem, optionId) { - let option = document.querySelector('#'+optionId); - let selectDiv = option.closest('.custom-select'); - let input = document.querySelector(`[name="${selectDiv.getAttribute('data-input')}"]`); - elem.parentElement.remove(); - option.removeAttribute('selected'); - option.querySelector('svg').remove(); - input.value = input.value.replace(option.getAttribute('data-value') ? option.getAttribute('data-value') + "," : '', ''); -} - -function multiSelectClickHandler(elem) { - let selectDiv = elem.closest('.custom-select'); - let input = document.querySelector(`[name="${selectDiv.getAttribute('data-input')}"]`); - if (!elem.hasAttribute('selected')) { - document.querySelector('#'+elem.closest(".custom-select").getAttribute("data-showDivId")).innerHTML += - `${elem.innerText} - - - - `; - elem.setAttribute('selected', ''); - elem.innerHTML = `${elem.innerText} - ` - - // Code where value in inserted into input - input.value += elem.getAttribute('data-value') ? elem.getAttribute('data-value') + "," : ''; - } else { - // similar to removeSelectOption method - document.querySelector('#'+elem.getAttribute('id')+'-selected').remove(); - elem.removeAttribute('selected'); - elem.querySelector('svg').remove(); - - input.value = input.value.replace(elem.getAttribute('data-value') ? elem.getAttribute('data-value') + "," : '', ''); - } - -} - -function singleSelectClickHandler(elem) { - let selectDiv = elem.closest('.custom-select'); - let selectedOption = selectDiv.querySelector('span[selected]'); - let input = document.querySelector(`[name="${selectDiv.getAttribute('data-input')}"]`); - if (!elem.hasAttribute('selected')) { - if (selectedOption != null) { - selectedOption.removeAttribute('selected'); - selectedOption.querySelector('svg').remove(); - } - elem.setAttribute('selected', ''); - elem.innerHTML = `${elem.innerText} - ` - // Code where value is inserted to input - input.value = elem.getAttribute('data-value') ? elem.getAttribute('data-value') : ''; - selectDiv.childNodes[0].nodeValue = elem.innerText; - } else { - elem.removeAttribute('selected'); - elem.querySelector('svg').remove(); - selectDiv.childNodes[0].nodeValue = selectDiv.getAttribute('data-default'); - - input.value = ""; - } - selectDiv.blur(); -} - -let multiSelectOptions = document.querySelectorAll('.custom-select[data-multiple="1"]>.options span'); -for (let i = 0; i < multiSelectOptions.length; i++) { - multiSelectOptions[i].addEventListener('click', () => {multiSelectClickHandler(multiSelectOptions[i])}); - multiSelectOptions[i].setAttribute('id', 'option-'+i.toString()); -} - -let singleSelectOptions = document.querySelectorAll('.custom-select:not([data-multiple="1"])>.options span'); -for (let i = 0; i < singleSelectOptions.length; i++) { - singleSelectOptions[i].addEventListener('click', () => {singleSelectClickHandler(singleSelectOptions[i])}); - singleSelectOptions[i].setAttribute('id', 'option-'+i.toString()); -} - +// UI: Method for selecting all search engines function selectAllHandler(elem) { - let options = elem.parentElement.querySelectorAll('.custom-select[data-multiple="1"]>.options span'); - Array.from(options).forEach((option) => { - try { - let selectedShownElem = document.getElementById(option.getAttribute('id')+'-selected'); - removeSelectOption(selectedShownElem.querySelector('span'), option.getAttribute('id')) - } catch (err) {} - if (elem.innerText == 'select all') { option.click() }; - }); - elem.innerText = elem.innerText == 'select all' ? 'deselect all' : 'select all' -} - - -// On settings form submit -function submitSettings() { - let form = document.settings; - document.querySelectorAll('.errTxt').forEach(e => e.remove()); - for(let i = 0; i < form.elements.length; i++) { - let input = form.elements[i]; - if (input.value == "" && input.hasAttribute('required')) { - let elem = input.parentElement.querySelector('[takeInput]') - let errTxt = document.createElement('p') - errTxt.classList.add('errTxt') - errTxt.innerText = 'This setting can\'t be empty!!' - elem.classList.add('invalid'); - elem.parentElement.insertBefore(errTxt, elem); + let span = elem.parentElement.querySelector('span'); + let mainInput = document.getElementsByName('searchEng')[0]; + let prevStateSelectAll = span.innerText == 'Select all' ? true : false; + document.querySelectorAll('.searchEng-elem').forEach(engine => { + if (prevStateSelectAll) { + engine.querySelector('input[type="checkbox"]').checked = true; + } else { + engine.querySelector('input[type="checkbox"]').checked = false; } + }) + if (prevStateSelectAll) { + let getValues = () => { + let value = "" + document.querySelectorAll('[data-isCheckbox]:not([data-value="all"])').forEach(elem => { + value += elem.getAttribute("data-value") + ","; + }); + return value; + } + mainInput.value = getValues(); + } else { + mainInput.value = ''; } - return false; + span.innerText = prevStateSelectAll ? 'Deselect all' : 'Select all'; } + +// UI: Filter settings as per category document.querySelectorAll('.settings-sidebar .set-name').forEach(filter => { let target = filter.getAttribute('data-detailId'); filter.addEventListener('click', () => { @@ -145,29 +47,70 @@ document.querySelectorAll('.settings-sidebar .set-name').forEach(filter => { }) }) -function fadeOut(element) { - var op = 1; // initial opacity - var timer = setInterval(function () { - if (op <= 0.1){ - clearInterval(timer); - element.style.display = 'none'; - element.classList.add('fade'); + +// On settings form submit +function submitSettings() { + let form = document.settings; + let stopProceeding = false; + document.querySelectorAll('.errTxt').forEach(e => e.remove()); + for(let i = 0; i < form.elements.length; i++) { + let input = form.elements[i]; + if (input.value == "" && input.hasAttribute('required')) { + stopProceeding = true; + let elem = input.parentElement.querySelector('[takeInput]') + let errTxt = document.createElement('p') + errTxt.classList.add('errTxt') + errTxt.innerText = 'This setting can\'t be empty!!' + elem.classList.add('invalid'); + elem.parentElement.insertBefore(errTxt, elem); + let sidebarElement = input.closest('.set-item').getAttribute('data-id') + document.querySelector(`.settings-sidebar .set-name[data-detailId="${sidebarElement}`).click(); + stopProceeding = true; } - element.style.opacity = op; - element.style.filter = 'alpha(opacity=' + op * 100 + ")"; - op -= op * 0.1; - }, 50); + } + if (!stopProceeding) { + var expiration_date = new Date(); + expiration_date.setFullYear(expiration_date.getFullYear() + 1); + let formData = new FormData(document.querySelector('form')); + for (var [key, value] of formData.entries()) { + document.cookie = `${key}=${value}; expires=${expiration_date.toUTCString()}` + } + } else { return false; } + // On settings saved successfully + alert("Settings saved succssfully!"); + window.location.reload(); } -function fadeIn(element) { - var op = 0.1; // initial opacity - element.style.display = 'block'; - var timer = setInterval(function () { - if (op >= 1){ - clearInterval(timer); +// Autoload existing settings +function loadUserSettings() { + let inputs = ["searchEng", "theme", "color-sch"] + var keyValuePairs = document.cookie.split(';'); + for(var i = 0; i < keyValuePairs.length; i++) { + var name = keyValuePairs[i].substring(0, keyValuePairs[i].indexOf('=')); + var value = keyValuePairs[i].substring(keyValuePairs[i].indexOf('=')+1); + name = name.trim(); + if (!inputs.includes(name)) { return; } + let input = document.getElementsByName(name)[0]; + input.value = value; + if (name == "searchEng") { + // Unload all checked engine + document.querySelectorAll(".searchEng-elem input[type=checkbox]").forEach(e => { + e.checked = false; + }) + value = value.replace(" ", ""); + value.split(",").forEach(val => { + if (!val) {return} + document.querySelector(`[data-isCheckbox][data-value="${val}"]`). + parentElement.querySelector('input').checked = true + }) + } else { + // Unload all selected options + document.querySelector(`[data-input="${name}"] .options span[data-value="${value}"]`). + removeAttribute('selected'); + singleSelectClickHandler(document.querySelector(`.options span[data-value="${value}"]`)); } - element.style.opacity = op; - element.style.filter = 'alpha(opacity=' + op * 100 + ")"; - op += op * 0.1; - }, 10); + } + } + +loadUserSettings(); diff --git a/public/static/themes/simple.css b/public/static/themes/simple.css index 61776ae..013259e 100644 --- a/public/static/themes/simple.css +++ b/public/static/themes/simple.css @@ -302,6 +302,7 @@ footer { width: 80%; } +/* css for settings page t */ .settings { margin: 2rem; width: 80%; @@ -323,6 +324,7 @@ footer { .settings-view { display: flex; flex: 1 0 auto; + margin: 1.5rem 0; } .settings-sidebar { @@ -339,16 +341,17 @@ footer { padding: .7rem; border-radius: 5px; font-weight: bold; + margin-bottom: .5rem; } .settings-sidebar .set-name:hover, .settings-sidebar .set-name.active { - background-color: var(--1_1); + background-color: rgba(255, 255, 255, 0.15); + } .settings-detail { border-left: 1.5px solid var(--3); padding-left: 3rem; - margin-top: .7rem; } .settings-detail .set-item { @@ -367,6 +370,7 @@ footer { margin-bottom: .5rem; } +/* css for custom select */ .custom-select, .options { font-size: 1.5rem; background-color: var(--bg); @@ -411,7 +415,7 @@ footer { } .options span:hover { - background-color: var(--1_1); + background-color: var(--1); } .selected-multiple-option { @@ -447,23 +451,21 @@ footer { background: var(--3); color: var(--bg); border-radius: .5rem; - border: 1px solid transparent; + border: 2px solid transparent; font-weight: bold; - transition: background .5s ease-in; + transition: all .1s ease-out; cursor: pointer; -} - -.settings .submit-btn:hover { - border: 1px solid var(--bg); - background: var(--3_1); - box-shadow: 0px 0px 2px 2px var(--fg); + box-shadow: 5px 5px; } .settings .submit-btn:active { outline: none; - border: 2px solid var(--bg); + box-shadow: none; + translate: 5px 5px; } +/* Css for error text */ + .errTxt { color: white; background: red; @@ -471,4 +473,112 @@ footer { border-radius: 5px; font-size: 1.3rem; width: max-content; -} \ No newline at end of file +} + +/* Css for toggle element */ + +label, +label::before, +label::after { + transition: 200ms all ease-in-out 50ms; + box-sizing: border-box; + backface-visibility: hidden; +} + +input[type="checkbox"] { + display: none; +} + +/*Button is :CHECKED*/ + +input[type="checkbox"]:checked ~ div[data-isCheckbox] { + background: rgba(73,168,68,1); + box-shadow: 0 0 2px rgba(73,168,68,1); +} + +input[type="checkbox"]:checked ~ div[data-isCheckbox] label { + left: 25px; + transform: rotate(360deg); +} + + +/*shared*/ + +div[data-isCheckbox], +label { + border-radius: 50px; +} + + +/*'un':checked state*/ + +div[data-isCheckbox] { + height: 25px; + width: 50px; + background: rgba(43, 43, 43, 1); + position: relative; + box-shadow: 0 0 2px rgba(43,43,43,1); + +} + +label { + height: 20px; + width: 20px; + background: rgba(255, 255, 255, 1); + position: absolute; + top: 3px; + left: 3px; + cursor: pointer; +} + +label::before { + content: ''; + height: 15px; + width: 3px; + position: absolute; + top: calc(50% - 8px); + left: calc(50% - 1.5px); + transform: rotate(45deg); +} + +label::after { + content: ''; + height: 3px; + width: 15px; + position: absolute; + top: calc(50% - 2.5px); + left: calc(50% - 8px); + transform: rotate(45deg); +} + +label::before, +label::after{ + background: rgba(43,43,43,1); + border-radius: 5px; +} + +/* pesduo class on toggle */ + +input[type="checkbox"]:checked ~ div label::before{ + height: 15px; + top: calc(55% - 8px); + left: calc(60% - 2px); + background: rgba(73,168,68,1); +} + +input[type="checkbox"]:checked ~ div label::after{ + width: 7px; + top: calc(95% - 7px); + left: calc(22.5% - 2px); + background: rgba(73,168,68,1); +} + +.searchEng-elem { + display: flex; + gap: 3rem; + align-items: center; + font-size: 1.5rem; + margin: 1rem 0; +} + +.settings-sidebar .set-name[data-detailId="theme"] \ No newline at end of file diff --git a/public/static/ui_plugins.js b/public/static/ui_plugins.js new file mode 100644 index 0000000..53dddb5 --- /dev/null +++ b/public/static/ui_plugins.js @@ -0,0 +1,110 @@ +/* + Select plugin + Note: Only for single select option + Usage example: + ``` + +