diff --git a/dist/index.css b/dist/index.css index ebc7f923..22a4e0f4 100644 --- a/dist/index.css +++ b/dist/index.css @@ -172,12 +172,13 @@ body[theme=dark] [color]:not([color=standard]).subtle-background { } #background-wrapper { position: fixed; - inset: 0px; - transform: scale(1.2); + top: var(--safe-area-top); + left: var(--safe-area-left); + right: var(--safe-area-right); + bottom: var(--safe-area-bottom); z-index: 1; pointer-events: none; overflow: hidden; - filter: blur(40px); background: var(--background); } main { @@ -187,6 +188,8 @@ main { content: ""; position: absolute; inset: 0px; + transform: scale(1.2); + filter: blur(40px); z-index: -1; pointer-events: none; } diff --git a/dist/styles.css b/dist/styles.css index e5532e16..84b7ed5a 100644 --- a/dist/styles.css +++ b/dist/styles.css @@ -16,11 +16,11 @@ html { /* ANIMATION -*/ + */ @keyframes slide-up { 0% { - opacity: 0; - transform: translateY(2rem); + opacity: 0; + transform: translateY(2rem); } } @@ -66,9 +66,9 @@ body { --text-info: #0043ce; --highlight-background: linear-gradient( - 45deg, - hsl(30, 100%, 50%), - hsl(40, 100%, 50%) + 45deg, + hsl(30, 100%, 50%), + hsl(40, 100%, 50%) ); --highlight-color: black; @@ -186,11 +186,11 @@ select:not(.tile *), button:hover, select:hover, button.tile.ghost:hover { - background: var(--surface-hover); + background: var(--surface-hover); } [selected]:hover { - background: var(--surface); + background: var(--surface); } } @@ -221,7 +221,7 @@ button.primary { @media (hover: hover) { button.primary:hover { - background: var(--primary-hover); + background: var(--primary-hover); } } @@ -244,7 +244,7 @@ button.ghost { @media (hover: hover) { button.ghost:hover { - background: var(--background-hover); + background: var(--background-hover); } } @@ -260,7 +260,7 @@ button.danger { @media (hover: hover) { button.danger:hover { - background: var(--danger-hover); + background: var(--danger-hover); } } @@ -318,7 +318,7 @@ body { /* TYPE -*/ + */ @font-face { font-family: IBM Plex Sans; @@ -375,8 +375,8 @@ footer { } input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not( - label.tile * - ), +label.tile * +), label.tile, select:not(label.tile *), textarea:not(label.tile *) { @@ -392,8 +392,8 @@ hr { } input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):focus:not( - label.tile * - ):not(.no-outline), +label.tile * +):not(.no-outline), label.tile:has(input:focus), label.tile:has(textarea:focus), textarea:focus:not(label.tile *), @@ -718,8 +718,8 @@ select { article > div { padding-bottom: calc( - var(--menu-height-mobile) + var(--control-height) + - var(--content-padding) + var(--menu-height-mobile) + var(--control-height) + + var(--content-padding) ); } @@ -1013,7 +1013,7 @@ input[type="radio"]:checked::before { /* LAYOUT -*/ + */ /* basic */ body, html { @@ -1021,8 +1021,12 @@ html { flex-direction: column-reverse; margin: 0px; - width: 100%; - height: 100%; + + position: fixed; + top: var(--safe-area-top); + left: var(--safe-area-left); + right: var(--safe-area-right); + bottom: var(--safe-area-bottom); } body, @@ -1069,8 +1073,8 @@ menu { article > div { padding-bottom: calc( - var(--menu-height-mobile) + var(--header-height) + - var(--content-padding) + var(--menu-height-mobile) + var(--header-height) + + var(--content-padding) ); } @@ -1159,91 +1163,91 @@ main { @media (min-width: 640px) { /* basic */ .mobile-only { - display: none !important; + display: none !important; } /* border, outline, etc */ .modal > div { - border: 1px solid var(--surface-border); + border: 1px solid var(--surface-border); } menu, main.split > article:first-of-type { - border-right: 1px solid var(--border); + border-right: 1px solid var(--border); } /* size */ .modal > div { - height: auto; - max-height: 100%; + height: auto; + max-height: 100%; } p, .modal > div { - max-width: var(--max-content-width); + max-width: var(--max-content-width); } .width-content { - max-width: var(--max-content-width) !important; + max-width: var(--max-content-width) !important; } input, label, select, textarea { - max-width: var(--max-input-width); + max-width: var(--max-input-width); } .width-input { - max-width: var(--max-input-width) !important; + max-width: var(--max-input-width) !important; } /* layout */ body { - flex-direction: row; + flex-direction: row; } main.split { - display: grid; - grid-template-columns: var(--split-pane-width-desktop) 1fr; + display: grid; + grid-template-columns: var(--split-pane-width-desktop) 1fr; } article > div { - padding-bottom: calc(var(--content-padding) + var(--control-height)); + padding-bottom: calc(var(--content-padding) + var(--control-height)); } menu { - position: static; + position: static; - width: var(--menu-width-desktop); - height: 100%; + width: var(--menu-width-desktop); + height: 100%; - flex-direction: column; - justify-content: start; - padding-top: 20px; + flex-direction: column; + justify-content: start; + padding-top: 20px; } .tab-link { - width: 100%; - height: var(--control-height); + width: 100%; + height: var(--control-height); - flex-direction: row; - gap: var(--gap-in-tab-links); + flex-direction: row; + gap: var(--gap-in-tab-links); - font-size: 1rem; + font-size: 1rem; } } /* desktop */ @media (min-width: 1024px) { body { - --split-pane-width-desktop: 400px; + --split-pane-width-desktop: 400px; } } /* STATE -*/ + */ [highlight]:not(:hover):not(:active) { color: var(--highlight-color) !important; @@ -1257,11 +1261,11 @@ STATE @keyframes highlight { 30%, 60% { - opacity: 1; + opacity: 1; } 0%, 100% { - opacity: 0.1; + opacity: 0.1; } } @@ -1274,13 +1278,13 @@ STATE 40%, 50%, 90% { - opacity: 1; + opacity: 1; } 10%, 30%, 60%, 80% { - opacity: 0.5; + opacity: 0.5; } } diff --git a/dist/sw.js b/dist/sw.js index 8f6f8d99..eafac3ea 100644 --- a/dist/sw.js +++ b/dist/sw.js @@ -1,4 +1,4 @@ -const VERSION = "2610 Beta 4.2" +const VERSION = "2610 Beta 4.7" function processUrl(event) { const url = event.request.url; diff --git a/dist/version.txt b/dist/version.txt index 914a132f..de2575b2 100644 --- a/dist/version.txt +++ b/dist/version.txt @@ -1 +1 @@ -2610 Beta 4.2 +2610 Beta 4.7 diff --git a/src/Model/Global/settingsModel.ts b/src/Model/Global/settingsModel.ts index c7e8e134..ed239ae8 100644 --- a/src/Model/Global/settingsModel.ts +++ b/src/Model/Global/settingsModel.ts @@ -107,4 +107,5 @@ export enum ThemeSettings { Light = "light", System = "system", Dynamic = "dynamic", + Black = "black", } diff --git a/src/View/Modals/settingsModal.tsx b/src/View/Modals/settingsModal.tsx index a237f180..5b57e49c 100644 --- a/src/View/Modals/settingsModal.tsx +++ b/src/View/Modals/settingsModal.tsx @@ -192,6 +192,10 @@ function SettingsAppearancePane( coreViewModel.translations.settings.themes.dynamic, ThemeSettings.Dynamic, ], + [ + coreViewModel.translations.settings.themes.system, + ThemeSettings.System, + ], [ coreViewModel.translations.settings.themes.dark, ThemeSettings.Dark, @@ -201,8 +205,8 @@ function SettingsAppearancePane( ThemeSettings.Light, ], [ - coreViewModel.translations.settings.themes.system, - ThemeSettings.System, + coreViewModel.translations.settings.themes.black, + ThemeSettings.Black, ], ]), settingsViewModel.theme, diff --git a/src/View/translations.ts b/src/View/translations.ts index 058921bc..583e7602 100644 --- a/src/View/translations.ts +++ b/src/View/translations.ts @@ -98,6 +98,7 @@ const englishTranslations = { dark: "Dark", light: "Light", system: "Device theme", + black: "Black", }, version: "Version", @@ -442,6 +443,7 @@ export const allTranslations: { dark: "Dunkel", light: "Hell", system: "Geräteeinstellung", + black: "Schwarz", }, version: "Version", @@ -754,6 +756,7 @@ export const allTranslations: { dark: "Oscuro", light: "Claro", system: "Según dispositivo", + black: "Negro", }, version: "Versión", diff --git a/src/ViewModel/Global/.settingsViewModel.ts.swp b/src/ViewModel/Global/.settingsViewModel.ts.swp index 6cd580f9..5799794d 100644 Binary files a/src/ViewModel/Global/.settingsViewModel.ts.swp and b/src/ViewModel/Global/.settingsViewModel.ts.swp differ diff --git a/src/ViewModel/Global/settingsViewModel.ts b/src/ViewModel/Global/settingsViewModel.ts index 01a6e7d7..36e49f1c 100644 --- a/src/ViewModel/Global/settingsViewModel.ts +++ b/src/ViewModel/Global/settingsViewModel.ts @@ -53,127 +53,129 @@ export default class SettingsViewModel extends Context { // view applyTheme = (): void => { - let theme: string = this.theme.value; + let theme: string = this.theme.value; + + if (theme == ThemeSettings.System) + theme = SettingsViewModel.getSystemTheme(); - if (theme == ThemeSettings.Dynamic) { - const scene = this.selectDynamicScene(); - this.setScene(scene); - return; - } - - if (theme == ThemeSettings.System) { - theme = SettingsViewModel.getSystemTheme(); - } - - if (theme == ThemeSettings.Dark) { - this.setScene(DynamicSceneNight); - } else { - this.setScene(DynamicSceneDay); - } + switch (theme) { + case ThemeSettings.Dynamic: + const scene = this.selectDynamicScene(); + this.setScene(scene); + break; + case ThemeSettings.Dark: + this.setScene(DynamicSceneNight); + break; + case ThemeSettings.Black: + this.setScene(DynamicSceneBlack); + break; + default: + this.setScene(DynamicSceneDay); + } }; selectDynamicScene = (): DynamicScene => { - let hour = new Date().getHours(); + let hour = new Date().getHours(); - if (hour >= 21 || hour <= 6) { - return DynamicSceneNight; - } else if (hour > 6 && hour < 10) { - return DynamicSceneSunrise; - } else if (hour < 14) { - return DynamicSceneDay; - } else if (hour < 17) { - return DynamicSceneAfternoon; - } else { - return DynamicSceneSunset; - } + if (hour >= 21 || hour <= 6) { + return DynamicSceneNight; + } else if (hour > 6 && hour < 10) { + return DynamicSceneSunrise; + } else if (hour < 14) { + return DynamicSceneDay; + } else if (hour < 17) { + return DynamicSceneAfternoon; + } else { + return DynamicSceneSunset; + } }; setScene = (scene: DynamicScene): void => { - document.body.style.setProperty( - "--backdrop-grass-filter", - `brightness(${scene.brightness})`, - ); + document.body.style.setProperty( + "--backdrop-grass-filter", + `brightness(${scene.brightness})`, + ); - function setSkyColor( - tone: 1 | 2, - hue: number, - saturation: number, - luma: number, - ) { - document.body.style.setProperty( - `--sky-${tone}`, - `hsl(${hue}, ${saturation}%, ${luma}%)`, - ); - } - setSkyColor(1, scene.hue1, scene.saturation, scene.luma); - setSkyColor(2, scene.hue2, scene.saturation - 10, scene.luma - 10); + function setSkyColor( + tone: 1 | 2, + hue: number, + saturation: number, + luma: number, + ) { + document.body.style.setProperty( + `--sky-${tone}`, + `hsl(${hue}, ${saturation}%, ${luma}%)`, + ); + } + setSkyColor(1, scene.hue1, scene.saturation, scene.luma); + setSkyColor(2, scene.hue2, scene.saturation - 10, scene.luma - 10); - document.body.setAttribute("theme", scene.baseTheme); + document.body.setAttribute("theme", scene.baseTheme); }; // exit close = (): void => { - this.coreViewModel.closeContext(this.contextId); + this.coreViewModel.closeContext(this.contextId); }; handleContextClose = (): void => { - this.isShowingSettingsModal.value = false; - if (this.requiresReload.value == true) { - window.location.reload(); - } + this.isShowingSettingsModal.value = false; + if (this.requiresReload.value == true) { + window.location.reload(); + } }; // init constructor(public readonly coreViewModel: CoreViewModel) { - super("settings"); + super("settings"); - this.username.value = coreViewModel.settingsModel.username; - this.usernameInput.value = coreViewModel.settingsModel.username; - this.firstDayOfWeek.value = coreViewModel.settingsModel.firstDayOfWeek; - this.language.value = coreViewModel.settingsModel.language; - this.theme.value = coreViewModel.settingsModel.theme; + this.username.value = coreViewModel.settingsModel.username; + this.usernameInput.value = coreViewModel.settingsModel.username; + this.firstDayOfWeek.value = coreViewModel.settingsModel.firstDayOfWeek; + this.language.value = coreViewModel.settingsModel.language; + this.theme.value = coreViewModel.settingsModel.theme; - // subscriptions - this.firstDayOfWeek.subscribe(this.setFirstDayofWeek); - this.language.subscribeSilent((newValue) => { - this.coreViewModel.settingsModel.setLanguage(newValue); - this.requiresReload.value = true; - }); - this.theme.subscribeSilent((newValue) => { - this.coreViewModel.settingsModel.setTheme(newValue); - }); + // subscriptions + this.firstDayOfWeek.subscribe(this.setFirstDayofWeek); + this.language.subscribeSilent((newValue) => { + this.coreViewModel.settingsModel.setLanguage(newValue); + this.requiresReload.value = true; + }); + this.theme.subscribeSilent((newValue) => { + this.coreViewModel.settingsModel.setTheme(newValue); + }); - // set theme - this.theme.subscribe(() => { - this.applyTheme(); - }); - SettingsViewModel.generateThemeMedia().addEventListener("change", () => - this.applyTheme(), - ); - const seconds = new Date().getSeconds(); - const secondsUntilNewMinute = 60 - seconds; - setTimeout(() => { - setInterval(this.applyTheme, 1000 * 60); - }, secondsUntilNewMinute); + // set theme + this.theme.subscribe(() => { + this.applyTheme(); + }); + SettingsViewModel.generateThemeMedia().addEventListener("change", () => + this.applyTheme(), + ); + const seconds = new Date().getSeconds(); + const secondsUntilNewMinute = 60 - seconds; + setTimeout(() => { + setInterval(this.applyTheme, 1000 * 60); + }, secondsUntilNewMinute); - // keystrokes - this.registerKeyStroke(CommonKeys.CloseOrCancel, this.close); + // keystrokes + this.registerKeyStroke(CommonKeys.CloseOrCancel, this.close); } static generateThemeMedia(): MediaQueryList { - return window.matchMedia("(prefers-color-scheme: dark)"); + return window.matchMedia("(prefers-color-scheme: dark)"); } static getSystemTheme(): string { - const media = SettingsViewModel.generateThemeMedia(); - return media.matches == true ? ThemeSettings.Dark : ThemeSettings.Light; + const media = SettingsViewModel.generateThemeMedia(); + return media.matches == true ? ThemeSettings.Dark : ThemeSettings.Light; } } export enum SettingsModalPages { Appearance, - Regional, - Info, + Regional, + Info, } export interface DynamicScene { @@ -224,3 +226,11 @@ export const DynamicSceneSunset: DynamicScene = { brightness: 0.4, baseTheme: ThemeSettings.Dark, }; +export const DynamicSceneBlack: DynamicScene = { + hue1: 0, + hue2: 0, + saturation: 0, + luma: 0, + brightness: 0, + baseTheme: ThemeSettings.Dark, +}; diff --git a/src/base.css b/src/base.css index 6352d378..03720b56 100644 --- a/src/base.css +++ b/src/base.css @@ -9,17 +9,16 @@ /* Gradient */ #background-wrapper { position: fixed; - - inset: 0px; - transform: scale(1.2); + top: var(--safe-area-top); + left: var(--safe-area-left); + right: var(--safe-area-right); + bottom: var(--safe-area-bottom); z-index: 1; pointer-events: none; overflow: hidden; - filter: blur(40px); - background: var(--background); } @@ -32,6 +31,9 @@ main { position: absolute; inset: 0px; + + transform: scale(1.2); + filter: blur(40px); z-index: -1; pointer-events: none;