From 6f7ec55091fc143f705922c98f2b0d1c2b959700 Mon Sep 17 00:00:00 2001
From: 4-211 <4-211@example.com>
Date: Fri, 8 May 2026 12:06:57 +0300
Subject: [PATCH] preset system
---
src/css/global.css | 30 +++++--
src/css/settings.css | 57 +++++++++----
src/css/update.css | 24 ------
src/index.html | 13 +--
src/js/main.js | 11 ++-
src/js/settings.js | 14 ----
src/js/storage.js | 195 +++++++++++++++++++++++++++++++++++++------
7 files changed, 246 insertions(+), 98 deletions(-)
delete mode 100644 src/css/update.css
diff --git a/src/css/global.css b/src/css/global.css
index 8bf3928..642ed62 100644
--- a/src/css/global.css
+++ b/src/css/global.css
@@ -1,3 +1,20 @@
+:root {
+ /* --base_bg_color: 10;
+ --base_bg_color_range: 10;
+ --base_bg_saturation: 10%;
+
+ --color_text_white: #fff;
+ --color_text_gray: #999;
+ --surface-000: #000;
+ --surface-100: #222;
+ --surface-200: #333;
+ --surface-300: #444;
+
+ --sans: 'Nunito';
+ --serif: 'Playfair Display';
+ --monospace: monospace; */
+}
+
body {
display: flex;
height: 100vh;
@@ -5,12 +22,13 @@ body {
overflow-y: 0;
align-items: center;
justify-content: center;
- background: #000;
+ background: var(--surface-000) !important;
}
* {
margin: 0;
padding: 0;
color: #fff;
+ /* background: #f002 !important; */
}
#background {
@@ -18,9 +36,9 @@ body {
--base_bg_color_tint_p: calc(var(--base_bg_color) + var(--base_bg_color_range));
--base_bg_color_tint_n: calc(var(--base_bg_color) - var(--base_bg_color_range));
- --c-0-base: hsla(var(--base_bg_color), calc(var(--base_bg_saturation) - 9%), 12%, 1);
- --c-1-base: hsla(var(--base_bg_color_tint_p), calc(var(--base_bg_saturation) - 8%), 12%, 1);
- --c-3-base: hsla(var(--base_bg_color_tint_n), calc(var(--base_bg_saturation) - 6%), 36%, 1);
+ --c-0-base: hsla(var(--base_bg_color), calc(var(--base_bg_saturation) - 9%), calc(var(--base_bg_brightness) + 2%), 1);
+ --c-1-base: hsla(var(--base_bg_color_tint_p), calc(var(--base_bg_saturation) - 8%), calc(var(--base_bg_brightness) + 2%), 1);
+ --c-3-base: hsla(var(--base_bg_color_tint_n), calc(var(--base_bg_saturation) - 6%), calc(var(--base_bg_brightness) + 26%), 1);
height: 100vh;
width: 100vw;
@@ -199,7 +217,7 @@ body {
initial-value: 7%
}
-#background {
+#background.default {
--x-0: 85%;
--y-0: 80%;
--c-0: hsla(var(--base_bg_color), calc(var(--base_bg_saturation) - 9%), 12%, 1);
@@ -212,7 +230,7 @@ body {
--c-3: hsla(var(--base_bg_color_tint_n), calc(var(--base_bg_saturation) - 6%), 36%, 1);
--x-3: 24%;
--y-3: 7%;
- background-color: hsla(0,0%, 0%, 1);
+ background-color: var(--surface-000);
background-image:
radial-gradient(
circle at var(--x-0) var(--y-0), var(--c-0) var(--s-start-0),
diff --git a/src/css/settings.css b/src/css/settings.css
index ee9b179..abcc826 100644
--- a/src/css/settings.css
+++ b/src/css/settings.css
@@ -1,20 +1,47 @@
-#settingsbutton {
+.settings_visual_help {
z-index: 11;
position: fixed;
- bottom: 5px;
- left: 5px;
+ top: 0px;
+ right: 0px;
cursor: pointer;
-
- svg {
- transition: background .2s;
- border-radius: 100px;
- padding: 5px;
- width: 20px !important;
- height: 20px !important;
- fill: rgba(255,255,255,.2) !important;
+ height: 100dvh;
+ width: 40px;
+ display: flex;
+ align-items: center;
+ justify-content: end;
+ padding-left: 50px;
+ cursor: default;
+ >div {
+ cursor: pointer;
+ rotate: -90deg;
+ transform: translateY(98px);
+ transition: transform .2s;
+ gap: 7px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: var(--surface-100);
+ padding: 5px 10px;
+ border-radius: 10px 10px 0 0;
+ border: solid 1px var(--surface-300);
+ border-bottom: none;
+ user-select: none;
}
- svg:hover {
- background: rgba(255,255,255,.1);
+ >div:hover {
+ background: var(--surface-200);
+ }
+ >div:active {
+ background: var(--surface-300);
+ }
+
+ span:not(.icon) {
+ text-wrap: nowrap;
+ font-family: var(--sans);
+ }
+}
+.settings_visual_help:hover {
+ >div {
+ transform: translateY(58px);
}
}
@@ -32,7 +59,7 @@
border: solid 1px rgba(255,255,255,.1);
h2 {
- font-family: 'Playfair Display';
+ font-family: var(--serif);
font-weight: normal;
}
br {
@@ -40,7 +67,7 @@
}
h4 {
margin-top: 10px;
- font-family: 'Nunito';
+ font-family: var(--sans);
/* font-weight: normal; */
}
}
\ No newline at end of file
diff --git a/src/css/update.css b/src/css/update.css
deleted file mode 100644
index 7859ee5..0000000
--- a/src/css/update.css
+++ /dev/null
@@ -1,24 +0,0 @@
-#update {
- position: fixed;
- bottom: 0;
- right: 0;
- font-size: 13px;
- font-family: 'Nunito';
- background: rgba(255,255,255,.1);
- border-radius: 100px;
- margin: 10px;
- display: flex;
- z-index: 20;
- transition: transform .5s;
-} #update > * {
- padding: 5px 10px;
-} #update > a {
- text-decoration: none;
- background: rgba(255,255,255,.1);
- border-radius: 100px;
- cursor: pointer;
-}
-
-#update.hidden {
- transform: translateY(40px);
-}
\ No newline at end of file
diff --git a/src/index.html b/src/index.html
index d171099..7d5f3ec 100644
--- a/src/index.html
+++ b/src/index.html
@@ -19,17 +19,8 @@
Search via Google
-
-
-
+
+
diff --git a/src/js/main.js b/src/js/main.js
index 1eade41..50df5e8 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -1,6 +1,11 @@
window.addEventListener('DOMContentLoaded', async () => {
- clock()
+ select('.settings_visual_help').overwrite(
+ $.div(
+ {onclick: () => settings.open()},
+ $.span('Open settings'),
+ Icons.settings({fill: true, size: 15}),
+ )
+ )
+ if (getFromStorage('active')?.hide_clock == true) clock()
searcher()
- check_update()
- settings.init()
})
diff --git a/src/js/settings.js b/src/js/settings.js
index 8239fb6..8647fae 100644
--- a/src/js/settings.js
+++ b/src/js/settings.js
@@ -1,17 +1,3 @@
-const force_redraw = (element) => {
-
- if (!element) return
- element.classList.toggle('twt')
- var n = document.createTextNode(' ')
- var disp = element.style.display || 'block'
- element.appendChild(n)
- element.style.display = 'none'
-
- setTimeout(() => {
- element.style.display = disp
- n.parentNode.removeChild(n)
- },20)
-}
const settings = {
icons: {
open: ``,
diff --git a/src/js/storage.js b/src/js/storage.js
index 31b1a8c..7093b1a 100644
--- a/src/js/storage.js
+++ b/src/js/storage.js
@@ -1,33 +1,178 @@
-const CookieManager = {
- get: (cname) => {
- let name = cname + "=";
- let decodedCookie = document.cookie;
- let ca = decodedCookie.split(';');
- for(let i = 0; i {
+ const worker = (cname) => {
+ let name = cname + "=";
+ let decodedCookie = document.cookie;
+ let ca = decodedCookie.split(';');
+ for(let i = 0; i {
- const d = new Date();
- d.setTime(d.getTime() + (999*24*60*60*1000));
- let expires = "expires="+ d.toUTCString();
- document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
+ set: (variable_name, value) => {
+ const worker = (cname, cvalue) => {
+ const d = new Date();
+ d.setTime(d.getTime() + (999*24*60*60*1000));
+ let expires = "expires="+ d.toUTCString();
+ document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
+ }
+ worker(variable_name, JSON.stringify({data: value}))
}
}
+/**
+ * @typedef {Object} Bang
+ * @prop {string} keyword
+ * @prop {string} name
+ * @prop {string} url
+ */
-function getFromStorage(variable_name) {
- const c = CookieManager.get(variable_name)
- return c === '' ? null : JSON.parse(c).data
+/**
+ * @typedef {Object} Preset
+ * @prop {number} version
+ * @prop {string} name
+ * @prop {bool} disable_clock
+ * @prop {bool} disable_animations
+ * @prop {"default" | "url" | "color" | "gradient"} background_type // TODO: gradient
+ * @prop {number} base_bg_color
+ * @prop {number} base_bg_saturation
+ * @prop {number} base_bg_color_range
+ * @prop {Bang[]} bangs_override
+ * @prop {string} search_url
+ * @prop {bool} display_suggestions
+ * @prop {bool} display_history
+ * @prop {string} font_sans
+ * @prop {string} font_serif
+ * @prop {string} font_monospace
+ * @prop {string} color_text_white
+ * @prop {string} color_text_gray
+ * @prop {string} s000
+ * @prop {string} s100
+ * @prop {string} s200
+ * @prop {string} s300
+ * @prop {bool} m
+ */
+
+const preset = {
+ /** @type {Preset} */
+ active: {},
+ current_version: 1,
+ migration: () => ([
+ ['version', preset.current_version, 1],
+ ['m', true, 1],
+ ]).forEach(q => preset.active[q[0]] = q.length>2 ? q[1] : (preset.active[q[0]] || q[1])),
+
+ save: () => {
+ preset.migration()
+ storage.set(preset.active.name, preset.active)
+ storage.set('_active', preset.active.name)
+ var list = storage.get('_presets') ? storage.get('_presets') : []
+ if (!list.includes(preset.active.name)) {
+ list.push(preset.active.name)
+ storage.set('_presets', list)
+ }
+ preset.render()
+ },
+ delete: () => {
+ /**@type {string[]} */
+ var list = storage.get('_presets') ? storage.get('_presets') : []
+
+ list[list.indexOf(preset.active.name)] = false
+ list = list.filter(q => q != null)
+ storage.set('_presets', list)
+ preset.load(list.length > 0 ? list[0] : 'Default')
+ },
+ load: preset_name => {
+ if (!preset_name) preset_name = storage.get('_active') ? storage.get('_active') : 'Default'
+
+ var list = storage.get('_presets') ? storage.get('_presets') : []
+ if (!list.includes(preset_name)) {
+ preset.active = preset.default()
+ preset.active.name = preset_name
+ preset.save()
+ } else {
+ preset.active = storage.get(preset_name)
+ preset.save()
+ }
+ },
+
+ render: () => {
+ const force_redraw = (element) => {
+ if (!element) return
+ element.classList.toggle('twt')
+ var n = document.createTextNode(' ')
+ var disp = element.style.display || 'block'
+ element.appendChild(n)
+ element.style.display = 'none'
+ requestAnimationFrame(
+ () => {
+ element.style.display = disp
+ n.parentNode.removeChild(n)
+ }
+ )
+ }
+ const style_override = {
+ s000: 'surface-000',
+ s100: 'surface-100',
+ s200: 'surface-200',
+ s300: 'surface-300',
+ font_sans: 'sans',
+ font_serif: 'serif',
+ font_monospace: 'monospace',
+ }
+
+ const set_style = (element, s) => {
+ s = s.replaceAll('-', '_')
+ const prop_name = Object.keys(style_override).includes(s) ? style_override[s] : s
+ element.style.setProperty('--'+prop_name, ['base_bg_saturation','base_bg_brightness'].includes(s) ? (preset.active[s]+'%') : preset.active[s])
+ }
+
+ select('#background').element.setAttribute('class', preset.active.background_type);
+
+ (['s000', 's100', 's200', 's300', 'font_sans', 'font_serif', 'font_monospace', 'color_text_white', 'color_text_gray',])
+ .forEach(s => set_style(select('body').element, s));
+
+ (['base_bg_color', 'base_bg_saturation', 'base_bg_color_range', 'base_bg_brightness'])
+ .forEach(s => set_style(select('#background').element, s));
+ force_redraw(select('#background').element)
+ },
+
+ /**
+ * @returns {Preset}
+ */
+ default: () => { return {
+ name: 'Defualt',
+ version: preset.current_version,
+ disable_clock: false,
+ disable_animations: false,
+ background_type: 'default',
+ base_bg_color: 10,
+ base_bg_saturation: 10,
+ base_bg_brightness: 10,
+ base_bg_color_range: 10,
+ bangs_override: [
+ {name: 'Google Search AI', keyword: 'ai', url: 'https://www.google.com/search?q={{{s}}}&sourceid=chrome&ie=UTF-8&amc=1&oq={{{s}}}&udm=50&aep=109&cud='}
+ ],
+ search_url: 'https://www.google.com/search?q={{{s}}}',
+ display_suggestions: false,
+ display_history: false,
+ font_sans: 'Nunito',
+ font_serif: 'Playfair Display',
+ font_monospace: 'monospace',
+ color_text_white: '#fff',
+ color_text_gray: '#999',
+ s000: '#000',
+ s100: '#222',
+ s200: '#333',
+ s300: '#444',
+ }}
}
-
-function setToStorage(variable_name, value) {
- CookieManager.set(variable_name, JSON.stringify({data: value}))
-}
\ No newline at end of file