diff --git a/app/config/container.php b/app/config/container.php index 0bb233a..cadc815 100644 --- a/app/config/container.php +++ b/app/config/container.php @@ -24,6 +24,7 @@ return [ /** Array of application middlewares */ 'middlewares' => function (ContainerInterface $container): array { return [ + Middlewares\ThemeMiddleware::class, Middlewares\WhoopsMiddleware::class, new HttpMiddlewares\Expires($container->get('http_expires')), ]; diff --git a/app/resources/js/components/application.js b/app/resources/js/components/application.js index 34f312c..8cd83d0 100644 --- a/app/resources/js/components/application.js +++ b/app/resources/js/components/application.js @@ -1,12 +1,21 @@ export default () => ({ theme: 'light', - loading: true, init() { - this.theme = localStorage.theme || (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'); + const [cookie, theme] = document.cookie.match(/theme=(dark|light)/) || [null, null]; + + this.theme = theme || (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'); + + if (cookie === undefined) { + storeThemeCookie(this.theme); + } }, toggleTheme() { this.theme = this.theme == 'light' ? 'dark' : 'light'; }, + + storeThemeCookie(theme) { + document.cookie = `theme=${theme}; expires=Fri, 31 Dec 9999 23:59:59 GMT; SameSite=Lax`; + } }); diff --git a/app/src/Middlewares/ThemeMiddleware.php b/app/src/Middlewares/ThemeMiddleware.php new file mode 100644 index 0000000..6d09faf --- /dev/null +++ b/app/src/Middlewares/ThemeMiddleware.php @@ -0,0 +1,44 @@ +view = $view; + } + + /** Invoke the ThemeMiddleware class. */ + public function __invoke(Request $request, RequestHandler $handler): ResponseInterface + { + $this->view->getEnvironment()->addGlobal('theme', $this->getThemeFromRequest($request)); + + return $handler->handle($request); + } + + /** Determine the theme from the request. */ + private function getThemeFromRequest(Request $request): string + { + if (! isset($request->getCookieParams()['theme'])) { + return 'light'; + } + + if (! in_array($request->getCookieParams()['theme'], self::VALID_THEMES)) { + return 'light'; + } + + return $request->getCookieParams()['theme']; + } +} diff --git a/app/views/components/theme-toggle.twig b/app/views/components/theme-toggle.twig index 5555bd7..18e22f1 100644 --- a/app/views/components/theme-toggle.twig +++ b/app/views/components/theme-toggle.twig @@ -1,5 +1,5 @@
-
- +
+
diff --git a/app/views/layouts/app.twig b/app/views/layouts/app.twig index ca839de..fe086fe 100644 --- a/app/views/layouts/app.twig +++ b/app/views/layouts/app.twig @@ -21,12 +21,8 @@ {{ title }} • {{ config('site_title') }} -
+
{% block content %}{% endblock %}
- -
- -