From b99534ebdfd7b447fe0e4e8f648622911de44b39 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sat, 6 Apr 2024 02:35:06 -0400 Subject: [PATCH 01/13] Add WIP color sliders --- puter-gui.json | 3 +- src/UI/UIWindowThemeDialog.js | 110 ++++++++++++++++++++++++++++++++++ src/css/style.css | 33 +++++++++- src/css/theme.css | 7 +++ src/definitions.js | 3 + src/initgui.js | 27 +++++++++ src/services/ThemeService.js | 34 +++++++++++ 7 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 src/UI/UIWindowThemeDialog.js create mode 100644 src/css/theme.css create mode 100644 src/definitions.js create mode 100644 src/services/ThemeService.js diff --git a/puter-gui.json b/puter-gui.json index 1d3579bc..af7691d9 100644 --- a/puter-gui.json +++ b/puter-gui.json @@ -19,7 +19,8 @@ "css_paths": [ "/css/normalize.css", "/lib/jquery-ui-1.13.2/jquery-ui.min.css", - "/css/style.css" + "/css/style.css", + "/css/theme.css" ], "js_paths": [ "/src/initgui.js", diff --git a/src/UI/UIWindowThemeDialog.js b/src/UI/UIWindowThemeDialog.js new file mode 100644 index 00000000..3eaead6c --- /dev/null +++ b/src/UI/UIWindowThemeDialog.js @@ -0,0 +1,110 @@ +import UIWindow from "./UIWindow.js"; + +const UIWindowThemeDialog = async function UIWindowThemeDialog () { + const services = globalThis.services; + const svc_theme = services.get('theme'); + + const w = await UIWindow({ + title: null, + icon: null, + uid: null, + is_dir: false, + message: 'message', + // body_icon: options.body_icon, + // backdrop: options.backdrop ?? false, + is_resizable: false, + is_droppable: false, + has_head: true, + stay_on_top: true, + selectable_body: false, + draggable_body: true, + allow_context_menu: false, + show_in_taskbar: false, + window_class: 'window-alert', + dominant: true, + body_content: '', + width: 350, + // parent_uuid: options.parent_uuid, + // ...options.window_options, + window_css:{ + height: 'initial', + }, + body_css: { + width: 'initial', + padding: '20px', + 'background-color': 'rgba(231, 238, 245, .95)', + 'backdrop-filter': 'blur(3px)', + } + }); + const w_body = w.querySelector('.window-body'); + + const Slider = ({ name, label, min, max, initial, step }) => { + label = label ?? name; + const wrap = document.createElement('div'); + const el = document.createElement('input'); + wrap.appendChild(el); + el.type = 'range'; + el.min = min; + el.max = max; + el.defaultValue = initial ?? min; + el.step = step ?? 1; + el.classList.add('theme-dialog-slider'); + const label_el = document.createElement('label'); + label_el.textContent = label; + wrap.appendChild(label_el); + + return { + appendTo (parent) { + parent.appendChild(wrap); + return this; + }, + onChange (cb) { + el.addEventListener('input', e => { + e.meta = { label }; + cb(e); + }); + return this; + }, + }; + }; + + const state = {}; + + const slider_ch = (e) => { + state[e.meta.label] = e.target.value; + svc_theme.apply(state); + }; + + Slider({ + name: 'hue', min: 0, max: 360, + initial: svc_theme.get('hue'), + }) + .appendTo(w_body) + .onChange(slider_ch) + ; + Slider({ + name: 'sat', min: 0, max: 100, + initial: svc_theme.get('sat'), + }) + .appendTo(w_body) + .onChange(slider_ch) + ; + Slider({ + name: 'lig', min: 0, max: 100, + initial: svc_theme.get('lig'), + }) + .appendTo(w_body) + .onChange(slider_ch) + ; + Slider({ + name: 'alpha', min: 0, max: 1, step: 0.01, + initial: svc_theme.get('alpha'), + }) + .appendTo(w_body) + .onChange(slider_ch) + ; + + return {}; +} + +export default UIWindowThemeDialog; diff --git a/src/css/style.css b/src/css/style.css index 8553d8fe..81631115 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -3618,4 +3618,35 @@ label { .confirm-user-deletion-password{ width: 100%; margin-bottom: 20px; -} \ No newline at end of file +} + +.theme-dialog-slider { + --webkit-appearance: none; + width: 100%; + height: 25px; + background: #d3d3d3; + outline: none; + opacity: 0.7; + --webkit-transition: .2s; + transition: opacity .2s; +} + +.theme-dialog-slider:hover { + opacity: 1; +} + +.theme-dialog-slider::-webkit-slider-thumb { + --webkit-appearance: none; + appearance: none; + width: 25px; + height: 25px; + background: #04AA6D; + cursor: pointer; +} + +.theme-dialog-slider::-moz-range-thumb { + width: 25px; + height: 25px; + background: #04AA6D; + cursor: pointer; +} diff --git a/src/css/theme.css b/src/css/theme.css new file mode 100644 index 00000000..3438204d --- /dev/null +++ b/src/css/theme.css @@ -0,0 +1,7 @@ +/* used for pseudo-stylesheet */ + +/* + +hue = 320; ss.addRule('.taskbar, .window-head, .window-sidebar', `background-color: hsl(${hue}, 65.1%, 70.78%)`) + +*/ \ No newline at end of file diff --git a/src/definitions.js b/src/definitions.js new file mode 100644 index 00000000..8bca70ef --- /dev/null +++ b/src/definitions.js @@ -0,0 +1,3 @@ +export class Service { + // +}; diff --git a/src/initgui.js b/src/initgui.js index 3e5f340e..c199c288 100644 --- a/src/initgui.js +++ b/src/initgui.js @@ -34,6 +34,31 @@ import update_last_touch_coordinates from './helpers/update_last_touch_coordinat import update_title_based_on_uploads from './helpers/update_title_based_on_uploads.js'; import PuterDialog from './UI/PuterDialog.js'; import determine_active_container_parent from './helpers/determine_active_container_parent.js'; +import { ThemeService } from './services/ThemeService.js'; +import UIWindowThemeDialog from './UI/UIWindowThemeDialog.js'; + +const launch_services = async function () { + const services_l_ = []; + const services_m_ = {}; + globalThis.services = { + get: (name) => services_m_[name], + }; + + const register = (name, instance) => { + services_l_.push([name, instance]); + services_m_[name] = instance; + } + + register('theme', new ThemeService()); + + for (const [_, instance] of services_l_) { + await instance._init(); + } + + setTimeout(() => { + UIWindowThemeDialog(); + }, 1000); +}; window.initgui = async function(){ let url = new URL(window.location); @@ -1947,6 +1972,8 @@ window.initgui = async function(){ // go to home page window.location.replace("/"); }); + + await launch_services(); } function requestOpenerOrigin() { diff --git a/src/services/ThemeService.js b/src/services/ThemeService.js new file mode 100644 index 00000000..01c2903e --- /dev/null +++ b/src/services/ThemeService.js @@ -0,0 +1,34 @@ +import { Service } from "../definitions.js"; + +export class ThemeService extends Service { + async _init () { + this.state = { + sat: 100, + hue: 200, + lig: 70, + alpha: 1, + }; + this.ss = new CSSStyleSheet(); + document.adoptedStyleSheets.push(this.ss); + } + + apply (values) { + this.state = { + ...this.state, + ...values, + }; + this.reload_(); + } + + get (key) { return this.state[key]; } + + reload_ () { + // debugger; + const s = this.state; + this.ss.replace(` + .taskbar, .window-head, .window-sidebar { + background-color: hsla(${s.hue}, ${s.sat}%, ${s.lig}%, ${s.alpha}); + } + `) + } +} From beeeb7bcbfae4b414eb192108b876a4130f96832 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sat, 6 Apr 2024 05:08:38 -0400 Subject: [PATCH 02/13] Tiny fix --- src/UI/UIWindowThemeDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UI/UIWindowThemeDialog.js b/src/UI/UIWindowThemeDialog.js index 3eaead6c..9e5536fb 100644 --- a/src/UI/UIWindowThemeDialog.js +++ b/src/UI/UIWindowThemeDialog.js @@ -71,7 +71,7 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { const state = {}; const slider_ch = (e) => { - state[e.meta.label] = e.target.value; + state[e.meta.name] = e.target.value; svc_theme.apply(state); }; From 178f8516844d92c3b5f50b933e073b989e2f6f51 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 7 Apr 2024 00:28:23 -0400 Subject: [PATCH 03/13] Fix previous fix --- src/UI/UIWindowThemeDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UI/UIWindowThemeDialog.js b/src/UI/UIWindowThemeDialog.js index 9e5536fb..049291ba 100644 --- a/src/UI/UIWindowThemeDialog.js +++ b/src/UI/UIWindowThemeDialog.js @@ -60,7 +60,7 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { }, onChange (cb) { el.addEventListener('input', e => { - e.meta = { label }; + e.meta = { name, label }; cb(e); }); return this; From d1bbbb8e9348deee4d35f3327df182b8f115f7c5 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 7 Apr 2024 02:34:04 -0400 Subject: [PATCH 04/13] Use CSS variables --- src/css/style.css | 65 ++++++++++++++++++++++++++++++++---- src/services/ThemeService.js | 20 +++++++---- 2 files changed, 72 insertions(+), 13 deletions(-) diff --git a/src/css/style.css b/src/css/style.css index 81631115..10d8165d 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -22,6 +22,28 @@ user-select: none; } +:root { + --primary-hue: 231; + --primary-saturation: 100%; + --primary-lightness: 50%; + --primary-alpha: 0.7; + + --window-head-hue: var(--primary-hue); + --window-head-saturation: var(--primary-saturation); + --window-head-lightness: var(--primary-lightness); + --window-head-alpha: var(--primary-alpha); + + --window-sidebar-hue: var(--primary-hue); + --window-sidebar-saturation: var(--primary-saturation); + --window-sidebar-lightness: var(--primary-lightness); + --window-sidebar-alpha: var(--primary-alpha); + + --taskbar-hue: var(--primary-hue); + --taskbar-saturation: var(--primary-saturation); + --taskbar-lightness: var(--primary-lightness); + --taskbar-alpha: var(--primary-alpha); +} + html, body { /* disables two fingers back/forward swipe */ overscroll-behavior-x: none; @@ -827,7 +849,12 @@ span.header-sort-icon img { .window-head { overflow: hidden !important; padding: 0; - background-color: rgba(231, 238, 245, .95); + background-color: hsla( + var(--window-head-hue), + var(--window-head-saturation), + var(--window-head-lightness), + calc(0.5 + 0.5 * var(--window-head-alpha)) + ); filter: grayscale(80%); box-shadow: inset 0px -4px 5px -7px rgb(0 0 0 / 64%); display: flex; @@ -1025,7 +1052,12 @@ span.header-sort-icon img { border-right: 1px solid #CCC; padding: 15px 10px; box-sizing: border-box; - background-color: rgba(231, 238, 245, .95); + background-color: hsla( + var(--window-sidebar-hue), + var(--window-sidebar-saturation), + var(--window-sidebar-lightness), + calc(0.5 + 0.5*var(--window-sidebar-alpha)) + ); overflow-y: scroll; margin-top: 1px; } @@ -2019,7 +2051,12 @@ label { bottom: 0; left: 0; width: 100%; - background-color: rgba(231, 238, 245, .9); + background-color: hsla( + var(--taskbar-hue), + var(--taskbar-saturation), + var(--taskbar-lightness), + calc(0.5 + 0.5*var(--taskbar-alpha)) + ); display: flex; justify-content: center; z-index: 99999; @@ -2126,7 +2163,12 @@ label { @supports ((backdrop-filter: blur())) { .taskbar { - background-color: #ffffff94; + background-color: hsla( + var(--taskbar-hue), + var(--taskbar-saturation), + var(--taskbar-lightness), + var(--taskbar-alpha) + ); backdrop-filter: blur(10px); } @@ -2646,7 +2688,12 @@ label { @supports ((backdrop-filter: blur())) { .window-head { - background-color: rgba(231, 238, 245, .80); + background-color: hsla( + var(--window-head-hue), + var(--window-head-saturation), + var(--window-head-lightness), + var(--window-head-alpha) + ); backdrop-filter: blur(10px); } @@ -2656,7 +2703,13 @@ label { } .window-sidebar { - background-color: rgb(231 238 245 / 91%); + /* background-color: var(--puter-window-background); */ + background-color: hsla( + var(--window-sidebar-hue), + var(--window-sidebar-saturation), + var(--window-sidebar-lightness), + var(--window-sidebar-alpha) + ); backdrop-filter: blur(10px); } diff --git a/src/services/ThemeService.js b/src/services/ThemeService.js index 01c2903e..1b57d938 100644 --- a/src/services/ThemeService.js +++ b/src/services/ThemeService.js @@ -8,8 +8,9 @@ export class ThemeService extends Service { lig: 70, alpha: 1, }; - this.ss = new CSSStyleSheet(); - document.adoptedStyleSheets.push(this.ss); + this.root = document.querySelector(':root'); + // this.ss = new CSSStyleSheet(); + // document.adoptedStyleSheets.push(this.ss); } apply (values) { @@ -25,10 +26,15 @@ export class ThemeService extends Service { reload_ () { // debugger; const s = this.state; - this.ss.replace(` - .taskbar, .window-head, .window-sidebar { - background-color: hsla(${s.hue}, ${s.sat}%, ${s.lig}%, ${s.alpha}); - } - `) + // this.ss.replace(` + // .taskbar, .window-head, .window-sidebar { + // background-color: hsla(${s.hue}, ${s.sat}%, ${s.lig}%, ${s.alpha}); + // } + // `) + // this.root.style.setProperty('--puter-window-background', `hsla(${s.hue}, ${s.sat}%, ${s.lig}%, ${s.alpha})`); + this.root.style.setProperty('--primary-hue', s.hue); + this.root.style.setProperty('--primary-saturation', s.sat + '%'); + this.root.style.setProperty('--primary-lightness', s.lig + '%'); + this.root.style.setProperty('--primary-alpha', s.alpha); } } From 56616058840df6725b227be35d285cbdd2d94307 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 7 Apr 2024 02:53:05 -0400 Subject: [PATCH 05/13] Add ui colors to settings window --- src/UI/Settings/UIWindowSettings.js | 18 ++++++++++++++++++ src/css/style.css | 4 ++-- src/initgui.js | 4 ---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/UI/Settings/UIWindowSettings.js b/src/UI/Settings/UIWindowSettings.js index e155bbd9..6a8560d4 100644 --- a/src/UI/Settings/UIWindowSettings.js +++ b/src/UI/Settings/UIWindowSettings.js @@ -25,6 +25,7 @@ import UIWindowChangeUsername from '../UIWindowChangeUsername.js' import changeLanguage from "../../i18n/i18nChangeLanguage.js" import UIWindowConfirmUserDeletion from './UIWindowConfirmUserDeletion.js'; import UITabAbout from './UITabAbout.js'; +import UIWindowThemeDialog from '../UIWindowThemeDialog.js'; async function UIWindowSettings(options){ return new Promise(async (resolve) => { @@ -39,6 +40,7 @@ async function UIWindowSettings(options){ h += `
${i18n('about')}
`; h += `
${i18n('usage')}
`; h += `
${i18n('account')}
`; + h += `
${i18n('personalization')}
`; h += `
${i18n('language')}
`; h += `
${i18n('clock')}
`; h += ``; @@ -111,6 +113,18 @@ async function UIWindowSettings(options){ h += ``; + // Personalization + h += `
`; + h += `

${i18n('personalization')}

`; + // change password button + h += `
`; + h += `${i18n('ui_colors')}`; + h += `
`; + h += ``; + h += `
`; + h += `
`; + h += `
`; + // Language h += `
`; h += `

${i18n('language')}

`; @@ -306,6 +320,10 @@ async function UIWindowSettings(options){ UIWindowChangeUsername(); }) + $(el_window).find('.change-ui-colors').on('click', function (e) { + UIWindowThemeDialog(); + }) + $(el_window).on('click', '.settings-sidebar-item', function(){ const $this = $(this); const settings = $this.attr('data-settings'); diff --git a/src/css/style.css b/src/css/style.css index 10d8165d..54f1d3b5 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -24,8 +24,8 @@ :root { --primary-hue: 231; - --primary-saturation: 100%; - --primary-lightness: 50%; + --primary-saturation: 50%; + --primary-lightness: 90%; --primary-alpha: 0.7; --window-head-hue: var(--primary-hue); diff --git a/src/initgui.js b/src/initgui.js index c199c288..b5d2afb3 100644 --- a/src/initgui.js +++ b/src/initgui.js @@ -54,10 +54,6 @@ const launch_services = async function () { for (const [_, instance] of services_l_) { await instance._init(); } - - setTimeout(() => { - UIWindowThemeDialog(); - }, 1000); }; window.initgui = async function(){ From c83069bd03ecc05cd8e35e6670ee1ad2aaf053c8 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 7 Apr 2024 02:53:33 -0400 Subject: [PATCH 06/13] Add i18n items --- src/i18n/translations/en.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/i18n/translations/en.js b/src/i18n/translations/en.js index 5375cde5..43de684a 100644 --- a/src/i18n/translations/en.js +++ b/src/i18n/translations/en.js @@ -37,6 +37,7 @@ const en = { change_email: "Change Email", change_language: "Change Language", change_password: "Change Password", + change_ui_colors: "Change UI Colors", change_username: "Change Username", close_all_windows: "Close All Windows", close_all_windows_and_log_out: 'Close Windows and Log Out', @@ -137,6 +138,7 @@ const en = { passwords_do_not_match: '`New Password` and `Confirm New Password` do not match.', paste: 'Paste', paste_into_folder: "Paste Into Folder", + personalization: "Personalization", pick_name_for_website: "Pick a name for your website:", picture: "Picture", plural_suffix: 's', @@ -197,6 +199,7 @@ const en = { trash: 'Trash', type: 'Type', type_confirm_to_delete_account: "Type 'confirm' to delete your account.", + ui_colors: "UI Colors", undo: 'Undo', unlimited: 'Unlimited', unzip: "Unzip", @@ -211,6 +214,7 @@ const en = { yes_release_it: 'Yes, Release It', you_have_been_referred_to_puter_by_a_friend: "You have been referred to Puter by a friend!", zip: "Zip", + storage_puter_used: "used by Puter", } }; From 12fa88b149cb05ef070d86deae4860beb66f47a6 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 7 Apr 2024 03:15:45 -0400 Subject: [PATCH 07/13] Save color settings --- src/services/ThemeService.js | 62 ++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/services/ThemeService.js b/src/services/ThemeService.js index 1b57d938..ca283a7f 100644 --- a/src/services/ThemeService.js +++ b/src/services/ThemeService.js @@ -1,5 +1,10 @@ +import UIAlert from "../UI/UIAlert.js"; import { Service } from "../definitions.js"; +const PUTER_THEME_DATA_FILENAME = '~/.__puter_gui.json'; + +const SAVE_COOLDOWN_TIME = 1000; + export class ThemeService extends Service { async _init () { this.state = { @@ -11,6 +16,46 @@ export class ThemeService extends Service { this.root = document.querySelector(':root'); // this.ss = new CSSStyleSheet(); // document.adoptedStyleSheets.push(this.ss); + + this.save_cooldown_ = undefined; + + let data = undefined; + try { + data = await puter.fs.read(PUTER_THEME_DATA_FILENAME); + if ( typeof data === 'object' ) { + data = await data.text(); + } + } catch (e) { + if ( e.code !== 'subject_does_not_exist' ) { + // TODO: once we have an event log, + // log this error to the event log + console.error(e); + + // We don't show an alert becuase it's likely + // other things also aren't working. + } + } + + if ( data ) try { + data = JSON.parse(data.toString()); + } catch (e) { + data = undefined; + console.error(e); + + UIAlert({ + title: 'Error loading theme data', + message: `Could not parse "${PUTER_THEME_DATA_FILENAME}": ` + + e.message, + }); + } + + if ( data && data.colors ) { + this.state = { + ...this.state, + ...data.colors, + }; + this.reload_(); + } } apply (values) { @@ -19,6 +64,7 @@ export class ThemeService extends Service { ...values, }; this.reload_(); + this.save_(); } get (key) { return this.state[key]; } @@ -37,4 +83,20 @@ export class ThemeService extends Service { this.root.style.setProperty('--primary-lightness', s.lig + '%'); this.root.style.setProperty('--primary-alpha', s.alpha); } + + save_ () { + if ( this.save_cooldown_ ) { + clearTimeout(this.save_cooldown_); + } + this.save_cooldown_ = setTimeout(() => { + this.commit_save_(); + }, SAVE_COOLDOWN_TIME); + } + commit_save_ () { + puter.fs.write(PUTER_THEME_DATA_FILENAME, JSON.stringify( + { colors: this.state }, + undefined, + 4, + )); + } } From 72129ca16f89df323913a6273e6b62db6bc60958 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 7 Apr 2024 03:21:32 -0400 Subject: [PATCH 08/13] Make defaults consistent with original --- src/services/ThemeService.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/services/ThemeService.js b/src/services/ThemeService.js index ca283a7f..4540fc6f 100644 --- a/src/services/ThemeService.js +++ b/src/services/ThemeService.js @@ -8,10 +8,10 @@ const SAVE_COOLDOWN_TIME = 1000; export class ThemeService extends Service { async _init () { this.state = { - sat: 100, - hue: 200, - lig: 70, - alpha: 1, + sat: 41.18, + hue: 210, + lig: 93.33, + alpha: 0.8, }; this.root = document.querySelector(':root'); // this.ss = new CSSStyleSheet(); From 821d33b8d8bd27cc2467f9ac4e54a99a645f0f20 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 7 Apr 2024 04:39:08 -0400 Subject: [PATCH 09/13] Make opacity differences match prod --- src/css/style.css | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/css/style.css b/src/css/style.css index 54f1d3b5..b1b349ea 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -23,10 +23,10 @@ } :root { - --primary-hue: 231; - --primary-saturation: 50%; - --primary-lightness: 90%; - --primary-alpha: 0.7; + --primary-hue: 210; + --primary-saturation: 41.18%; + --primary-lightness: 93.33%; + --primary-alpha: 0.8; --window-head-hue: var(--primary-hue); --window-head-saturation: var(--primary-saturation); @@ -36,12 +36,12 @@ --window-sidebar-hue: var(--primary-hue); --window-sidebar-saturation: var(--primary-saturation); --window-sidebar-lightness: var(--primary-lightness); - --window-sidebar-alpha: var(--primary-alpha); + --window-sidebar-alpha: calc(min(1, 0.11 + var(--primary-alpha))); --taskbar-hue: var(--primary-hue); --taskbar-saturation: var(--primary-saturation); --taskbar-lightness: var(--primary-lightness); - --taskbar-alpha: var(--primary-alpha); + --taskbar-alpha: calc(0.73 * var(--primary-alpha)); } html, body { From 3297940bab1de10774935ba030fbf1ac95f92d58 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 7 Apr 2024 04:53:49 -0400 Subject: [PATCH 10/13] Improve dialog --- src/UI/UIWindowThemeDialog.js | 22 +++++++++++++++++----- src/i18n/translations/en.js | 4 ++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/UI/UIWindowThemeDialog.js b/src/UI/UIWindowThemeDialog.js index 049291ba..cdb560e0 100644 --- a/src/UI/UIWindowThemeDialog.js +++ b/src/UI/UIWindowThemeDialog.js @@ -5,7 +5,7 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { const svc_theme = services.get('theme'); const w = await UIWindow({ - title: null, + title: i18n('ui_colors'), icon: null, uid: null, is_dir: false, @@ -32,7 +32,15 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { body_css: { width: 'initial', padding: '20px', - 'background-color': 'rgba(231, 238, 245, .95)', + // 'background-color': `hsla( + // var(--primary-hue), + // calc(max(var(--primary-saturation) - 15%, 0%)), + // calc(min(100%,var(--primary-lightness) + 20%)), .91)`, + 'background-color': `hsla( + var(--primary-hue), + var(--primary-saturation), + var(--primary-lightness), + var(--primary-alpha))`, 'backdrop-filter': 'blur(3px)', } }); @@ -41,6 +49,9 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { const Slider = ({ name, label, min, max, initial, step }) => { label = label ?? name; const wrap = document.createElement('div'); + const label_el = document.createElement('label'); + label_el.textContent = label; + wrap.appendChild(label_el); const el = document.createElement('input'); wrap.appendChild(el); el.type = 'range'; @@ -49,9 +60,6 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { el.defaultValue = initial ?? min; el.step = step ?? 1; el.classList.add('theme-dialog-slider'); - const label_el = document.createElement('label'); - label_el.textContent = label; - wrap.appendChild(label_el); return { appendTo (parent) { @@ -76,6 +84,7 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { }; Slider({ + label: i18n('coloration'), name: 'hue', min: 0, max: 360, initial: svc_theme.get('hue'), }) @@ -83,6 +92,7 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { .onChange(slider_ch) ; Slider({ + label: i18n('saturation'), name: 'sat', min: 0, max: 100, initial: svc_theme.get('sat'), }) @@ -90,6 +100,7 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { .onChange(slider_ch) ; Slider({ + label: i18n('lightness'), name: 'lig', min: 0, max: 100, initial: svc_theme.get('lig'), }) @@ -97,6 +108,7 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { .onChange(slider_ch) ; Slider({ + label: i18n('transparency'), name: 'alpha', min: 0, max: 1, step: 0.01, initial: svc_theme.get('alpha'), }) diff --git a/src/i18n/translations/en.js b/src/i18n/translations/en.js index 43de684a..d290e168 100644 --- a/src/i18n/translations/en.js +++ b/src/i18n/translations/en.js @@ -43,6 +43,7 @@ const en = { close_all_windows_and_log_out: 'Close Windows and Log Out', change_always_open_with: "Do you want to always open this type of file with", color: 'Color', + hue: 'Hue', confirm_account_for_free_referral_storage_c2a: 'Create an account and confirm your email address to receive 1 GB of free storage. Your friend will get 1 GB of free storage too.', confirm_delete_multiple_items: 'Are you sure you want to permanently delete these items?', confirm_delete_single_item: 'Do you want to permanently delete this item?', @@ -106,6 +107,7 @@ const en = { keep_in_taskbar: 'Keep in Taskbar', language: "Language", license: "License", + lightness: 'Lightness', loading: 'Loading', log_in: "Log In", log_into_another_account_anyway: 'Log into another account anyway', @@ -166,6 +168,7 @@ const en = { replace_all: 'Replace All', resend_confirmation_code: "Re-send Confirmation Code", restore: "Restore", + saturation: 'Saturation', save_account: 'Save account', save_account_to_get_copy_link: "Please create an account to proceed.", save_account_to_publish: 'Please create an account to proceed.', @@ -196,6 +199,7 @@ const en = { terms: "Terms", text_document: 'Text document', tos_fineprint: `By clicking 'Create Free Account' you agree to Puter's {{link=terms}}Terms of Service{{/link}} and {{link=privacy}}Privacy Policy{{/link}}.`, + transparency: "Transparency", trash: 'Trash', type: 'Type', type_confirm_to_delete_account: "Type 'confirm' to delete your account.", From 3f37ef2fada0f348cd29e2bf1b209c67273176f0 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 7 Apr 2024 16:18:59 -0400 Subject: [PATCH 11/13] Fix i18n --- src/UI/UIWindowThemeDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UI/UIWindowThemeDialog.js b/src/UI/UIWindowThemeDialog.js index cdb560e0..f2469000 100644 --- a/src/UI/UIWindowThemeDialog.js +++ b/src/UI/UIWindowThemeDialog.js @@ -84,7 +84,7 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { }; Slider({ - label: i18n('coloration'), + label: i18n('hue'), name: 'hue', min: 0, max: 360, initial: svc_theme.get('hue'), }) From f7916cfa7424d29f6ec62729d3cfa7f6f8ab8599 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 7 Apr 2024 17:19:47 -0400 Subject: [PATCH 12/13] Add option to reset colors --- src/UI/UIWindowThemeDialog.js | 23 +++++++++++++++++++++++ src/i18n/translations/en.js | 1 + src/services/ThemeService.js | 13 +++++++++++++ 3 files changed, 37 insertions(+) diff --git a/src/UI/UIWindowThemeDialog.js b/src/UI/UIWindowThemeDialog.js index f2469000..6f39c142 100644 --- a/src/UI/UIWindowThemeDialog.js +++ b/src/UI/UIWindowThemeDialog.js @@ -46,6 +46,22 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { }); const w_body = w.querySelector('.window-body'); + const Button = ({ label }) => { + const el = document.createElement('button'); + el.textContent = label ?? i18n('reset'); + el.classList.add('button', 'button-block'); + return { + appendTo (parent) { + parent.appendChild(el); + return this; + }, + onPress (cb) { + el.addEventListener('click', cb); + return this; + }, + }; + } + const Slider = ({ name, label, min, max, initial, step }) => { label = label ?? name; const wrap = document.createElement('div'); @@ -83,6 +99,13 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { svc_theme.apply(state); }; + Button({ label: i18n('reset_colors') }) + .appendTo(w_body) + .onPress(() => { + svc_theme.reset(); + }) + ; + Slider({ label: i18n('hue'), name: 'hue', min: 0, max: 360, diff --git a/src/i18n/translations/en.js b/src/i18n/translations/en.js index d290e168..3fed3189 100644 --- a/src/i18n/translations/en.js +++ b/src/i18n/translations/en.js @@ -167,6 +167,7 @@ const en = { replace: 'Replace', replace_all: 'Replace All', resend_confirmation_code: "Re-send Confirmation Code", + reset_colors: "Reset Colors", restore: "Restore", saturation: 'Saturation', save_account: 'Save account', diff --git a/src/services/ThemeService.js b/src/services/ThemeService.js index 4540fc6f..57e2a20c 100644 --- a/src/services/ThemeService.js +++ b/src/services/ThemeService.js @@ -5,6 +5,13 @@ const PUTER_THEME_DATA_FILENAME = '~/.__puter_gui.json'; const SAVE_COOLDOWN_TIME = 1000; +const default_values = { + sat: 41.18, + hue: 210, + lig: 93.33, + alpha: 0.8, +}; + export class ThemeService extends Service { async _init () { this.state = { @@ -58,6 +65,12 @@ export class ThemeService extends Service { } } + reset () { + this.state = default_values; + this.reload_(); + puter.fs.delete(PUTER_THEME_DATA_FILENAME); + } + apply (values) { this.state = { ...this.state, From b1e6e0c25aed763ce1be3d483e89272fae0ec726 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 7 Apr 2024 17:27:09 -0400 Subject: [PATCH 13/13] Fix i18n --- src/UI/UIWindowThemeDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UI/UIWindowThemeDialog.js b/src/UI/UIWindowThemeDialog.js index 6f39c142..6ebcf3d9 100644 --- a/src/UI/UIWindowThemeDialog.js +++ b/src/UI/UIWindowThemeDialog.js @@ -48,7 +48,7 @@ const UIWindowThemeDialog = async function UIWindowThemeDialog () { const Button = ({ label }) => { const el = document.createElement('button'); - el.textContent = label ?? i18n('reset'); + el.textContent = label; el.classList.add('button', 'button-block'); return { appendTo (parent) {