preset system

This commit is contained in:
4-211 2026-05-08 12:06:57 +03:00
parent 415542b8c3
commit 6f7ec55091
7 changed files with 246 additions and 98 deletions

View file

@ -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),

View file

@ -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; */
}
}

View file

@ -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);
}

View file

@ -19,17 +19,8 @@
<p>Search via Google</p>
</div>
<input type="text" id="search_ddd" autocorrect="off" autocomplete="off" autofocus>
<div id="settingsbutton"></div>
<!-- <div id="settingsui">
<h2>Settings</h2>
<h4>Color</h4>
<input type="range" name="hue" id="s_hue" min="0" max="255" step="1">
<h4>Saturation</h4>
<input type="range" name="hue" id="s_hue" min="0" max="80" step="1">
<h4>Range</h4>
<input type="range" name="hue" id="s_hue" min="0" max="255" step="1">
</div> -->
<div id="update" class="hidden"><span>update available</span> <a href="https://github.com/ktnk-dev/LittleHome">download</a></div>
<div class="settings_visual_help">
</div>
<script src="lib/sinya.lib.js"></script>
<script src="lib/gicons.lib.js"></script>
<script src="js/storage.js"></script>

View file

@ -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()
})

View file

@ -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: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M422.46-81.87q-23.2 0-40.29-15.35-17.08-15.35-20.08-38.04l-10-73.74q-11.09-4.78-22.79-11.08-11.69-6.29-21.26-13.09l-68.26 28q-21.45 9.24-43.15 1.87t-33.67-27.57l-58.05-100.87q-11.98-19.96-7.11-42.53 4.87-22.58 23.33-37.06l59.76-45.5q-.76-5.54-.76-10.58V-480q0-5.04.25-11.09.25-6.04 1.01-14.08l-59.26-43.76q-18.7-14.48-23.7-36.81-5-22.33 6.98-43.02l57.55-100.13q11.97-19.96 33.8-27.45 21.83-7.49 43.28 1.75l69.98 29q8.57-6.8 18.9-12.73 10.34-5.92 23.17-11.2l10-75.98q3-22.93 20.33-38.28 17.34-15.35 40.54-15.35h114.58q23.2 0 40.29 15.35 17.08 15.35 20.08 38.28l10 74.48q12.09 4.78 22.29 10.95 10.19 6.18 19.76 14.48l70.26-29q21.45-9.24 43.15-1.75t33.67 27.45l57.55 100.13q11.98 20.19 6.98 42.77-5 22.58-23.7 37.06l-62 45.76q.76 6.04.76 10.83V-480q0 7.54-.12 12.84-.12 5.29-1.14 10.83l61 44.76q18.7 14.48 23.7 37.06 5 22.58-6.98 42.77l-58.05 100.87q-11.97 19.96-33.8 27.45-21.83 7.49-43.28-1.75l-68.48-29q-8.07 6.3-17.4 11.84-9.34 5.55-24.17 12.83l-10 74.24q-3 22.69-20.08 38.04-17.09 15.35-40.29 15.35H422.46ZM478.78-345q56 0 95.5-39.5t39.5-95.5q0-56-39.5-95.5t-95.5-39.5q-56.26 0-95.63 39.5T343.78-480q0 56 39.37 95.5t95.63 39.5Z"/></svg>`,

View file

@ -1,33 +1,178 @@
const CookieManager = {
get: (cname) => {
let name = cname + "=";
let decodedCookie = document.cookie;
let ca = decodedCookie.split(';');
for(let i = 0; i <ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
const storage = {
get: (variable_name) => {
const worker = (cname) => {
let name = cname + "=";
let decodedCookie = document.cookie;
let ca = decodedCookie.split(';');
for(let i = 0; i <ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
return "";
const c = worker(variable_name)
return c === '' ? null : JSON.parse(c).data
},
set: (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=/";
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}))
}