Make the default theme automatically determined by the browser (if possible).
This commit is contained in:
parent
e94f90ceb6
commit
e5eeb2b631
|
@ -5,7 +5,10 @@ release channel, you can take advantage of these new features and fixes.
|
|||
|
||||
## New Features/Changes
|
||||
|
||||
There have been no changes since the last stable release.
|
||||
- **Automatic Theme Selection:** If you haven't set a default theme for either your user account or the AzuraCast public
|
||||
pages, the theme will automatically be determined by the user's browser based on their OS's theme preference (dark or
|
||||
light). You can override this by selecting a default theme in the "Branding" settings, or reset to using browser
|
||||
preference by selecting the "Prefer System Default" option.
|
||||
|
||||
## Code Quality/Technical Changes
|
||||
|
||||
|
|
|
@ -16,8 +16,9 @@ return [
|
|||
'Select a theme to use as a base for station public pages and the login page.'
|
||||
),
|
||||
'choices' => [
|
||||
'light' => __('Light') . ' (' . __('Default') . ')',
|
||||
'dark' => __('Dark'),
|
||||
App\Customization::THEME_BROWSER => __('Prefer System Default'),
|
||||
App\Customization::THEME_LIGHT => __('Light'),
|
||||
App\Customization::THEME_DARK => __('Dark'),
|
||||
],
|
||||
'default' => App\Customization::DEFAULT_THEME,
|
||||
'form_group_class' => 'col-md-6',
|
||||
|
|
|
@ -93,8 +93,9 @@ return [
|
|||
[
|
||||
'label' => __('Site Theme'),
|
||||
'choices' => [
|
||||
'light' => __('Light') . ' (' . __('Default') . ')',
|
||||
'dark' => __('Dark'),
|
||||
App\Customization::THEME_BROWSER => __('Prefer System Default'),
|
||||
App\Customization::THEME_LIGHT => __('Light'),
|
||||
App\Customization::THEME_DARK => __('Dark'),
|
||||
],
|
||||
'default' => App\Customization::DEFAULT_THEME,
|
||||
'form_group_class' => 'col-md-6',
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
&.embed-social {
|
||||
body.embed-social {
|
||||
background: $card-bg !important;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
&.page-minimal {
|
||||
body.page-minimal {
|
||||
background: $body-bg url($public-page-bg);
|
||||
background-size: cover;
|
||||
background-attachment: fixed;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
& {
|
||||
body {
|
||||
background-color: $body-bg;
|
||||
color: $body-color;
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
@import 'common';
|
||||
}
|
||||
|
||||
body.theme-light {
|
||||
@at-root {
|
||||
$theme: 'light';
|
||||
@import 'common-colors';
|
||||
}
|
||||
|
||||
body.theme-dark {
|
||||
[data-theme="dark"] {
|
||||
$theme: 'dark';
|
||||
@import 'common-colors';
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
namespace App\Controller\Frontend\Profile;
|
||||
|
||||
use App\Form\UserProfileForm;
|
||||
use App\Customization;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class ThemeAction
|
||||
|
@ -12,9 +13,23 @@ class ThemeAction
|
|||
public function __invoke(
|
||||
ServerRequest $request,
|
||||
Response $response,
|
||||
UserProfileForm $userProfileForm
|
||||
EntityManagerInterface $em
|
||||
): ResponseInterface {
|
||||
$userProfileForm->switchTheme($request);
|
||||
$user = $request->getUser();
|
||||
|
||||
$currentTheme = $user->getTheme();
|
||||
if (empty($currentTheme)) {
|
||||
$currentTheme = Customization::DEFAULT_THEME;
|
||||
}
|
||||
|
||||
$user->setTheme(
|
||||
(Customization::THEME_LIGHT === $currentTheme)
|
||||
? Customization::THEME_DARK
|
||||
: Customization::THEME_LIGHT
|
||||
);
|
||||
|
||||
$em->persist($user);
|
||||
$em->flush();
|
||||
|
||||
$referrer = $request->getHeaderLine('Referer');
|
||||
return $response->withRedirect(
|
||||
|
|
|
@ -9,8 +9,9 @@ use Psr\Http\Message\ServerRequestInterface;
|
|||
|
||||
class Customization
|
||||
{
|
||||
public const DEFAULT_THEME = 'light';
|
||||
public const DEFAULT_THEME = 'browser';
|
||||
|
||||
public const THEME_BROWSER = 'browser';
|
||||
public const THEME_LIGHT = 'light';
|
||||
public const THEME_DARK = 'dark';
|
||||
|
||||
|
|
|
@ -278,7 +278,7 @@ class Settings
|
|||
* @ORM\Column(name="public_theme", type="string", length=50, nullable=true)
|
||||
*
|
||||
* @OA\Property(example="light")
|
||||
* @Assert\Choice({Customization::THEME_LIGHT, Customization::THEME_DARK})
|
||||
* @Assert\Choice({Customization::THEME_BROWSER, Customization::THEME_LIGHT, Customization::THEME_DARK})
|
||||
* @var string|null Base Theme for Public Pages
|
||||
*/
|
||||
protected $public_theme = Customization::DEFAULT_THEME;
|
||||
|
|
|
@ -58,31 +58,6 @@ class UserProfileForm extends EntityForm
|
|||
return parent::process($request, $user);
|
||||
}
|
||||
|
||||
public function switchTheme(ServerRequest $request): void
|
||||
{
|
||||
$user = $request->getUser();
|
||||
|
||||
$themeField = $this->getField('theme');
|
||||
|
||||
$themeFieldOptions = $themeField->getOptions();
|
||||
$themeOptions = array_keys($themeFieldOptions['choices']);
|
||||
|
||||
$currentTheme = $user->getTheme();
|
||||
if (empty($currentTheme)) {
|
||||
$currentTheme = $themeField->getValue();
|
||||
}
|
||||
|
||||
foreach ($themeOptions as $theme) {
|
||||
if ($theme !== $currentTheme) {
|
||||
$user->setTheme($theme);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->em->persist($user);
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
public function getView(ServerRequest $request): string
|
||||
{
|
||||
$user = $request->getUser();
|
||||
|
|
|
@ -12,11 +12,9 @@
|
|||
* @var App\Environment $environment
|
||||
*/
|
||||
|
||||
$page_class ??= '';
|
||||
$page_class .= ' theme-' . $customization->getTheme();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html data-theme="<?=$customization->getTheme()?>">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
@ -37,7 +35,7 @@ $page_class .= ' theme-' . $customization->getTheme();
|
|||
echo $assets->js();
|
||||
?>
|
||||
</head>
|
||||
<body class="page-full <?=$page_class?> <?php
|
||||
<body class="page-full <?=$page_class ?? ''?> <?php
|
||||
if (!empty($sidebar)): ?>has-sidebar<?php
|
||||
endif; ?>">
|
||||
<?=$assets->inlineJs()?>
|
||||
|
@ -207,5 +205,13 @@ if (null !== $flash && $flash->hasMessages()): ?>
|
|||
</script>
|
||||
<?php
|
||||
endif; ?>
|
||||
|
||||
<script type="text/javascript" nonce="<?=$assets->getCspNonce()?>">
|
||||
let currentTheme = document.documentElement.getAttribute('data-theme');
|
||||
if (currentTheme === 'browser') {
|
||||
currentTheme = (window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';
|
||||
document.documentElement.setAttribute('data-theme', currentTheme);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -13,10 +13,8 @@
|
|||
* @var App\Environment $environment
|
||||
*/
|
||||
|
||||
$page_class ??= '';
|
||||
$page_class .= ' theme-' . $customization->getPublicTheme();
|
||||
?>
|
||||
<html>
|
||||
<html data-theme="<?=$customization->getPublicTheme()?>">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
@ -39,7 +37,7 @@ $page_class .= ' theme-' . $customization->getPublicTheme();
|
|||
?>
|
||||
</head>
|
||||
|
||||
<body class="page-minimal <?=$page_class?>">
|
||||
<body class="page-minimal <?=$page_class ?? ''?>">
|
||||
<?=$assets->inlineJs()?>
|
||||
|
||||
<?=$this->section('content')?>
|
||||
|
@ -67,5 +65,13 @@ if (null !== $flash && $flash->hasMessages()): ?>
|
|||
</script>
|
||||
<?php
|
||||
endif; ?>
|
||||
|
||||
<script type="text/javascript" nonce="<?=$assets->getCspNonce()?>">
|
||||
let currentTheme = document.documentElement.getAttribute('data-theme');
|
||||
if (currentTheme === 'browser') {
|
||||
currentTheme = (window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';
|
||||
document.documentElement.setAttribute('data-theme', currentTheme);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in New Issue