diff --git a/pkg/webui/account/views/app/index.js b/pkg/webui/account/views/app/index.js
index 4366fd5243..b556c5edb4 100644
--- a/pkg/webui/account/views/app/index.js
+++ b/pkg/webui/account/views/app/index.js
@@ -64,29 +64,49 @@ const getScrollRestorationKey = location => {
return `${pathname}${page ? `?page=${page}` : ''}`
}
-const Layout = () => (
- <>
-
-
-
-
-
-
-
-
- >
-)
+const Layout = () => {
+ const darkTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
+
+ const toggleTheme = theme => {
+ const htmlElement = document.documentElement
+
+ if (theme === 'dark') {
+ htmlElement.classList.add('dark')
+ htmlElement.classList.remove('light')
+ } else {
+ htmlElement.classList.add('light')
+ htmlElement.classList.remove('dark')
+ }
+ }
+
+ useEffect(() => {
+ toggleTheme(darkTheme ? 'dark' : 'light')
+ }, [darkTheme])
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+ >
+ )
+}
const AccountRoot = () => {
const user = useSelector(selectUser)
diff --git a/pkg/webui/console/containers/latest-decoded-payload-panel/index.js b/pkg/webui/console/containers/latest-decoded-payload-panel/index.js
index 2eb8503a03..118c8fab24 100644
--- a/pkg/webui/console/containers/latest-decoded-payload-panel/index.js
+++ b/pkg/webui/console/containers/latest-decoded-payload-panel/index.js
@@ -325,6 +325,7 @@ const LatestDecodedPayloadPanel = ({ appId, events, shortCutLinkPath, className,
imageFetching,
isDevice,
modalVisible,
+ darkTheme,
],
)
diff --git a/pkg/webui/console/containers/user-settings-theme/index.js b/pkg/webui/console/containers/user-settings-theme/index.js
index a099ad4e94..71ba5b365f 100644
--- a/pkg/webui/console/containers/user-settings-theme/index.js
+++ b/pkg/webui/console/containers/user-settings-theme/index.js
@@ -33,7 +33,7 @@ import attachPromise from '@ttn-lw/lib/store/actions/attach-promise'
import sharedMessages from '@ttn-lw/lib/shared-messages'
import PropTypes from '@ttn-lw/lib/prop-types'
-import { updateUser } from '@console/store/actions/user'
+import { updateUser, updateUserSuccess } from '@console/store/actions/user'
import { selectUserId } from '@console/store/selectors/logout'
import { selectSelectedUser } from '@console/store/selectors/users'
@@ -54,11 +54,20 @@ const validationSchema = Yup.object().shape({
})
const InnerThemeForm = ({ initialValues }) => {
+ const dispatch = useDispatch()
const { resetForm } = useFormContext()
+ const handleThemeChange = useCallback(
+ value => {
+ dispatch(updateUserSuccess({ console_preferences: { console_theme: value } }))
+ },
+ [dispatch],
+ )
+
const handleDiscardChanges = useCallback(() => {
resetForm(initialValues)
- }, [resetForm, initialValues])
+ dispatch(updateUserSuccess(initialValues))
+ }, [resetForm, initialValues, dispatch])
return (
<>
@@ -68,6 +77,7 @@ const InnerThemeForm = ({ initialValues }) => {
horizontal
spaceBetween
className="m-vert-cs-xxl"
+ onChange={handleThemeChange}
>