1
Fork 0

Add user preference for changing theme

This commit is contained in:
viktorstrate 2022-02-07 23:27:04 +01:00
parent 98f4dcb1e0
commit c9d59a634e
No known key found for this signature in database
GPG Key ID: 3F855605109C1E8A
5 changed files with 84 additions and 6 deletions

View File

@ -18,7 +18,7 @@ export const SectionTitle = ({ children, nospace }: SectionTitleProps) => {
return (
<h2
className={classNames(
'pb-1 border-b border-gray-200 text-xl mb-5',
'pb-1 border-b border-gray-200 dark:border-[#3B3B3B] text-xl mb-5',
!nospace && 'mt-6'
)}
>

View File

@ -1,6 +1,6 @@
import { useMutation, useQuery } from '@apollo/client'
import gql from 'graphql-tag'
import React, { useMemo } from 'react'
import React, { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
import { LanguageTranslation } from '../../__generated__/globalTypes'
@ -16,6 +16,8 @@ import {
changeUserPreferencesVariables,
} from './__generated__/changeUserPreferences'
import { myUserPreferences } from './__generated__/myUserPreferences'
import { TranslationFn } from '../../localization'
import { changeTheme, getTheme } from '../../theme'
const languagePreferences = [
{ key: 1, label: 'English', flag: 'uk', value: LanguageTranslation.English },
@ -47,6 +49,24 @@ const languagePreferences = [
},
]
const themePreferences = (t: TranslationFn) => [
{
key: 1,
label: t('settings.user_preferences.theme.auto.label', 'Same as system'),
value: 'auto',
},
{
key: 2,
label: t('settings.user_preferences.theme.light.label', 'Light'),
value: 'light',
},
{
key: 2,
label: t('settings.user_preferences.theme.dark.label', 'Dark'),
value: 'dark',
},
]
const CHANGE_USER_PREFERENCES = gql`
mutation changeUserPreferences($language: String) {
changeUserPreferences(language: $language) {
@ -86,6 +106,12 @@ const UserPreferencesWrapper = styled.div`
const UserPreferences = () => {
const { t } = useTranslation()
const [theme, setTheme] = useState(getTheme())
const changeStateTheme = (value: string) => {
changeTheme(value)
setTheme(value)
}
const { data } = useQuery<myUserPreferences>(MY_USER_PREFERENCES)
@ -109,7 +135,7 @@ const UserPreferences = () => {
{t('settings.user_preferences.title', 'User preferences')}
</SectionTitle>
<LogoutButton />
<label id="user_pref_change_language_field">
<label htmlFor="user_pref_change_language_field">
<InputLabelTitle>
{t(
'settings.user_preferences.change_language.label',
@ -140,6 +166,23 @@ const UserPreferences = () => {
selected={data?.myUserPreferences.language || undefined}
disabled={loadingPrefs}
/>
<label htmlFor="user_pref_change_theme_field">
<InputLabelTitle>
{t('settings.user_preferences.theme.title', 'Theme preferences')}
</InputLabelTitle>
<InputLabelDescription>
{t(
'settings.user_preferences.theme.description',
'Change the appearance of the website'
)}
</InputLabelDescription>
</label>
<Dropdown
id="user_pref_change_theme_field"
items={themePreferences(t)}
setSelected={changeStateTheme}
selected={theme}
/>
</UserPreferencesWrapper>
)
}

View File

@ -12,7 +12,8 @@ html {
font-family: 'Source Sans Pro', sans-serif;
}
body.dark {
body.dark,
html.dark {
@apply bg-dark-bg text-dark-text;
}

View File

@ -7,11 +7,13 @@ import client from './apolloClient'
import { ApolloProvider } from '@apollo/client'
import { BrowserRouter as Router } from 'react-router-dom'
import { setupLocalization } from './localization'
import { updateTheme } from './theme'
import * as serviceWorkerRegistration from './serviceWorkerRegistration'
import './index.css'
import { SidebarProvider } from './components/sidebar/Sidebar'
updateTheme()
setupLocalization()
const Main = () => (
@ -24,8 +26,6 @@ const Main = () => (
</ApolloProvider>
)
document.getElementsByTagName('body')[0].classList.add('dark')
ReactDOM.render(<Main />, document.getElementById('root'))
serviceWorkerRegistration.register()

34
ui/src/theme.ts Normal file
View File

@ -0,0 +1,34 @@
export const updateTheme = () => {
if (
localStorage.theme === 'dark' ||
(!('theme' in localStorage) &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
}
export const changeTheme = (value: string) => {
if (value == 'light') {
localStorage.theme = 'light'
} else if (value == 'dark') {
localStorage.theme = 'dark'
} else {
// use OS preference
localStorage.removeItem('theme')
}
updateTheme()
}
export const getTheme = () => {
if (localStorage.theme == 'light') {
return 'light'
} else if (localStorage.theme == 'dark') {
return 'dark'
} else {
return 'auto'
}
}