pre-load dark theme on server if user's system theme is dark and website's theme is auto

This commit is contained in:
E. S. 2024-11-03 18:19:53 +03:00
parent 679e9e2f5e
commit 4211df5125
4 changed files with 31 additions and 13 deletions

View File

@ -38,6 +38,8 @@ function render($f, ...$vars): void {
if ($theme != 'auto' && !themeExists($theme)) if ($theme != 'auto' && !themeExists($theme))
$theme = 'auto'; $theme = 'auto';
$is_system_theme_dark = $theme == 'auto' && isUserSystemThemeDark();
$layout_ctx = skin('base'); $layout_ctx = skin('base');
$lang = []; $lang = [];
@ -52,6 +54,7 @@ function render($f, ...$vars): void {
$html = $layout_ctx->layout( $html = $layout_ctx->layout(
static: $SkinState->static, static: $SkinState->static,
theme: $theme, theme: $theme,
is_system_theme_dark: $is_system_theme_dark,
title: $title, title: $title,
opts: $SkinState->options, opts: $SkinState->options,
js: $js, js: $js,

View File

@ -109,13 +109,15 @@ var ThemeSwitcher = (function() {
}); });
var left = names.length; var left = names.length;
names.forEach(function(name) { if (names.length) {
StaticManager.loadStyle(name, 'dark', once(function(e) { names.forEach(function (name) {
left--; StaticManager.loadStyle(name, 'dark', once(function (e) {
if (left === 0) left--;
callback(); if (left === 0)
})); callback();
}) }));
})
} else callback();
} }
/** /**
@ -162,11 +164,15 @@ var ThemeSwitcher = (function() {
var prevSystemState = systemState; var prevSystemState = systemState;
systemState = dark; systemState = dark;
if (modes[currentModeIndex] !== 'auto') if (modes[currentModeIndex] !== 'auto') {
unsetCookie('theme-system-value');
return; return;
}
if (systemState !== prevSystemState) if (systemState !== prevSystemState) {
changeTheme(systemState); changeTheme(systemState);
setCookie('theme-system-value', dark ? 'dark' : 'light');
}
}; };
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) { window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
@ -186,6 +192,11 @@ var ThemeSwitcher = (function() {
} }
currentModeIndex = (currentModeIndex + 1) % modes.length; currentModeIndex = (currentModeIndex + 1) % modes.length;
if (modes[currentModeIndex] !== 'auto')
unsetCookie('theme-system-value');
else
setCookie('theme-system-value', systemState ? 'dark' : 'light');
switch (modes[currentModeIndex]) { switch (modes[currentModeIndex]) {
case 'auto': case 'auto':
if (systemState !== null && systemState !== isDarkModeApplied()) if (systemState !== null && systemState !== isDarkModeApplied())

View File

@ -39,3 +39,7 @@ function getUserTheme(): string {
$val = 'auto'; $val = 'auto';
return $val; return $val;
} }
function isUserSystemThemeDark(): bool {
return ($_COOKIE['theme-system-value'] ?? '') === 'dark';
}

View File

@ -5,7 +5,7 @@ namespace skin\base;
use SkinContext; use SkinContext;
use Stringable; use Stringable;
function layout($ctx, $title, $unsafe_body, $static, $meta, $js, $opts, $unsafe_lang, $theme, $exec_time, $admin_email, $svg_defs) { function layout($ctx, $title, $unsafe_body, $static, $meta, $js, $opts, $unsafe_lang, $theme, $is_system_theme_dark, $exec_time, $admin_email, $svg_defs) {
global $config; global $config;
$app_config = jsonEncode([ $app_config = jsonEncode([
'domain' => $config['domain'], 'domain' => $config['domain'],
@ -30,7 +30,7 @@ return <<<HTML
<title>{$title}</title> <title>{$title}</title>
<script type="text/javascript">window.appConfig = {$app_config};</script> <script type="text/javascript">window.appConfig = {$app_config};</script>
{$ctx->meta($meta)} {$ctx->meta($meta)}
{$ctx->renderStatic($static, $theme)} {$ctx->renderStatic($static, $theme, $is_system_theme_dark)}
</head> </head>
<body{$ctx->if_true($body_class, ' class="'.implode(' ', $body_class).'"')}> <body{$ctx->if_true($body_class, ' class="'.implode(' ', $body_class).'"')}>
{$ctx->if_true($svg_defs, fn() => $ctx->renderSVGIcons($svg_defs))} {$ctx->if_true($svg_defs, fn() => $ctx->renderSVGIcons($svg_defs))}
@ -120,10 +120,10 @@ function meta($ctx, $meta) {
}, $meta)); }, $meta));
} }
function renderStatic($ctx, $static, $theme) { function renderStatic($ctx, $static, $theme, $is_system_theme_dark) {
global $config; global $config;
$html = []; $html = [];
$dark = $theme == 'dark'; $dark = $theme == 'dark' || $is_system_theme_dark;
$ctx->styleNames = []; $ctx->styleNames = [];
foreach ($static as $name) { foreach ($static as $name) {
// javascript // javascript