feat: implement theme detection logic

This commit is contained in:
Bohdan Triapitsyn
2025-12-17 12:57:09 +02:00
parent 29f7d9fd48
commit 2d048624bc
3 changed files with 56 additions and 11 deletions
+31 -2
View File
@@ -9,6 +9,25 @@
<meta name="theme-color" content="#151313" />
<link rel="preload" href="/ibm-plex-mono-latin-600-normal.woff2" as="font" type="font/woff2" crossorigin />
<title>OpenChamber Desktop</title>
<script>
// Blocking script to detect and apply theme before first paint
(function() {
var themeMode = localStorage.getItem('themeMode');
var isDark;
if (themeMode === 'dark') {
isDark = true;
} else if (themeMode === 'light') {
isDark = false;
} else {
// 'system' or not set - use system preference
isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
}
document.documentElement.classList.add(isDark ? 'dark' : 'light');
document.documentElement.style.setProperty('color-scheme', isDark ? 'dark' : 'light');
// Store for use in inline styles
window.__INITIAL_THEME_DARK__ = isDark;
})();
</script>
<style>
@font-face {
font-family: 'IBM Plex Mono';
@@ -17,9 +36,13 @@
src: url('/ibm-plex-mono-latin-600-normal.woff2') format('woff2');
font-display: block;
}
:root {
/* Theme-aware color scheme */
html.dark {
color-scheme: dark;
}
html.light {
color-scheme: light;
}
html,
body,
#root {
@@ -30,7 +53,13 @@
margin: 0;
font-family: 'IBM Plex Mono', monospace;
background-color: transparent;
color: #ffffff;
}
/* Theme-aware text colors for loading screen */
html.dark body {
color: #CECDC3; /* Flexoki dark foreground */
}
html.light body {
color: #100F0F; /* Flexoki light foreground */
}
.loading {
display: flex;
+1 -1
View File
@@ -2847,7 +2847,7 @@ dependencies = [
[[package]]
name = "openchamber-desktop"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"anyhow",
"axum",
+24 -8
View File
@@ -60,20 +60,36 @@
</script>
<script>
// Blocking script to detect and apply theme before first paint
(function() {
try {
var themeMode = localStorage.getItem('themeMode');
var variant = localStorage.getItem('selectedThemeVariant');
var useSystem = localStorage.getItem('useSystemTheme');
if (!variant || (variant !== 'light' && variant !== 'dark')) {
if (useSystem === null || useSystem === 'true') {
variant = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
} else {
variant = 'dark';
}
var isDark;
// Check themeMode first (new storage key)
if (themeMode === 'dark') {
isDark = true;
} else if (themeMode === 'light') {
isDark = false;
} else if (themeMode === 'system' || useSystem === null || useSystem === 'true') {
// System preference
isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
} else if (variant === 'light' || variant === 'dark') {
// Legacy storage key fallback
isDark = variant === 'dark';
} else {
// Default to system
isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
}
document.documentElement.setAttribute('data-splash-variant', variant === 'light' ? 'light' : 'dark');
// Apply theme class and data attribute
document.documentElement.classList.add(isDark ? 'dark' : 'light');
document.documentElement.setAttribute('data-splash-variant', isDark ? 'dark' : 'light');
document.documentElement.style.setProperty('color-scheme', isDark ? 'dark' : 'light');
} catch (error) {
console.warn('Failed to apply splash variant:', error);
console.warn('Failed to apply theme:', error);
}
})();
</script>