mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 16:59:12 +00:00
feat(web): add theme toggle to navbar (#1540)
* feat(web): add theme toggle to navbar * refactor: move OS theme detection to App.tsx * fix: disallowed unused variables * fix: removed unused variable * refactor: check for os color scheme in SettingsContextDefaults * refactor: remove unnecessary iconTheme variable * fix: add title tag to button
This commit is contained in:
parent
28172cfba6
commit
3dab295387
3 changed files with 42 additions and 5 deletions
|
@ -3,6 +3,7 @@
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { useEffect } from "react";
|
||||||
import { RouterProvider } from "@tanstack/react-router"
|
import { RouterProvider } from "@tanstack/react-router"
|
||||||
import { QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { Toaster } from "react-hot-toast";
|
import { Toaster } from "react-hot-toast";
|
||||||
|
@ -10,7 +11,7 @@ import { Portal } from "react-portal";
|
||||||
import { Router } from "@app/routes";
|
import { Router } from "@app/routes";
|
||||||
import { routerBasePath } from "@utils";
|
import { routerBasePath } from "@utils";
|
||||||
import { queryClient } from "@api/QueryClient";
|
import { queryClient } from "@api/QueryClient";
|
||||||
import { AuthContext } from "@utils/Context";
|
import { AuthContext, SettingsContext } from "@utils/Context";
|
||||||
|
|
||||||
declare module '@tanstack/react-router' {
|
declare module '@tanstack/react-router' {
|
||||||
interface Register {
|
interface Register {
|
||||||
|
@ -19,6 +20,18 @@ declare module '@tanstack/react-router' {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
|
const [ , setSettings] = SettingsContext.use();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const themeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
const handleThemeChange = (e: MediaQueryListEvent) => {
|
||||||
|
setSettings(prevState => ({ ...prevState, darkTheme: e.matches }));
|
||||||
|
};
|
||||||
|
|
||||||
|
themeMediaQuery.addEventListener('change', handleThemeChange);
|
||||||
|
return () => themeMediaQuery.removeEventListener('change', handleThemeChange);
|
||||||
|
}, [setSettings]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<Portal>
|
<Portal>
|
||||||
|
|
|
@ -10,14 +10,38 @@ import { Menu, Transition } from "@headlessui/react";
|
||||||
import { classNames } from "@utils";
|
import { classNames } from "@utils";
|
||||||
|
|
||||||
import { RightNavProps } from "./_shared";
|
import { RightNavProps } from "./_shared";
|
||||||
import { Cog6ToothIcon, ArrowLeftOnRectangleIcon } from "@heroicons/react/24/outline";
|
|
||||||
import {Link} from "@tanstack/react-router";
|
import { Cog6ToothIcon, ArrowLeftOnRectangleIcon, MoonIcon, SunIcon } from "@heroicons/react/24/outline";
|
||||||
|
import { Link } from "@tanstack/react-router";
|
||||||
|
import { SettingsContext } from "@utils/Context";
|
||||||
|
|
||||||
export const RightNav = (props: RightNavProps) => {
|
export const RightNav = (props: RightNavProps) => {
|
||||||
|
const [settings, setSettings] = SettingsContext.use();
|
||||||
|
|
||||||
|
const toggleTheme = () => {
|
||||||
|
setSettings(prevState => ({
|
||||||
|
...prevState,
|
||||||
|
darkTheme: !prevState.darkTheme
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="hidden sm:block">
|
<div className="hidden sm:block">
|
||||||
<div className="ml-4 flex items-center sm:ml-6">
|
<div className="ml-4 flex items-center sm:ml-6">
|
||||||
<Menu as="div" className="ml-3 relative">
|
<div className="mt-1 items-center">
|
||||||
|
<button
|
||||||
|
onClick={toggleTheme}
|
||||||
|
className="p-1 rounded-full focus:outline-none focus:none transition duration-100 ease-out transform hover:bg-gray-200 dark:hover:bg-gray-800 hover:scale-100"
|
||||||
|
title={settings.darkTheme ? "Switch to light mode (currently dark mode)" : "Switch to dark mode (currently light mode)"}
|
||||||
|
>
|
||||||
|
{settings.darkTheme ? (
|
||||||
|
<MoonIcon className="h-4 w-4 text-gray-500 transition duration-100 ease-out transform" aria-hidden="true" />
|
||||||
|
) : (
|
||||||
|
<SunIcon className="h-4 w-4 text-gray-600" aria-hidden="true" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<Menu as="div" className="ml-2 relative">
|
||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<Menu.Button
|
<Menu.Button
|
||||||
|
|
|
@ -35,7 +35,7 @@ export type FilterListState = {
|
||||||
const SettingsContextDefaults: SettingsType = {
|
const SettingsContextDefaults: SettingsType = {
|
||||||
debug: false,
|
debug: false,
|
||||||
checkForUpdates: true,
|
checkForUpdates: true,
|
||||||
darkTheme: true,
|
darkTheme: window.matchMedia('(prefers-color-scheme: dark)').matches,
|
||||||
scrollOnNewLog: false,
|
scrollOnNewLog: false,
|
||||||
indentLogLines: false,
|
indentLogLines: false,
|
||||||
hideWrappedText: false
|
hideWrappedText: false
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue