Fix #260: Add Auto theme preference to set theme automatically. (#835)

* Auto theme preference added

* Fix lint

* Add and use AUTO from consts

* Add shared custom hook to get current theme

* Moved up 'Auto' choice

* AUTO -> AUTO_THEME_ID & extract useCurrentTheme to file

* Liberalise theme setting

* Add tests
This commit is contained in:
Yash Jipkate
2021-03-21 22:49:43 +05:30
committed by GitHub
parent fa479f0a9a
commit 3e0e11c01e
8 changed files with 235 additions and 8 deletions
+14
View File
@@ -0,0 +1,14 @@
import { useSelector } from 'react-redux'
import useMediaQuery from '@material-ui/core/useMediaQuery'
import themes from './index'
import { AUTO_THEME_ID } from '../consts'
export default () => {
const prefersLightMode = useMediaQuery('(prefers-color-scheme: light)')
return useSelector((state) => {
if (state.theme === AUTO_THEME_ID) {
return prefersLightMode ? themes.LightTheme : themes.DarkTheme
}
return themes[state.theme] || themes.DarkTheme
})
}
+120
View File
@@ -0,0 +1,120 @@
import React from 'react'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import mediaQuery from 'css-mediaquery'
import { renderHook } from '@testing-library/react-hooks'
import useCurrentTheme from './useCurrentTheme'
import { themeReducer } from '../reducers/themeReducer'
import { AUTO_THEME_ID } from '../consts'
function createMatchMedia(theme) {
return (query) => ({
matches: mediaQuery.match(query, { 'prefers-color-scheme': theme }),
addListener: () => {},
removeListener: () => {},
})
}
describe('useCurrentTheme', () => {
describe('with user preference theme as light', () => {
beforeAll(() => {
window.matchMedia = createMatchMedia('light')
})
it('sets theme as light in auto mode', () => {
const { result } = renderHook(() => useCurrentTheme(), {
wrapper: ({ children }) => (
<Provider store={createStore(themeReducer, { theme: AUTO_THEME_ID })}>
{children}
</Provider>
),
})
expect(result.current.themeName).toMatch('Light')
})
it('sets theme as dark', () => {
const { result } = renderHook(() => useCurrentTheme(), {
wrapper: ({ children }) => (
<Provider store={createStore(themeReducer, { theme: 'DarkTheme' })}>
{children}
</Provider>
),
})
expect(result.current.themeName).toMatch('Dark')
})
it('sets theme as light', () => {
const { result } = renderHook(() => useCurrentTheme(), {
wrapper: ({ children }) => (
<Provider store={createStore(themeReducer, { theme: 'LightTheme' })}>
{children}
</Provider>
),
})
expect(result.current.themeName).toMatch('Light')
})
it('sets theme as spotify-ish', () => {
const { result } = renderHook(() => useCurrentTheme(), {
wrapper: ({ children }) => (
<Provider
store={createStore(themeReducer, { theme: 'SpotifyTheme' })}
>
{children}
</Provider>
),
})
expect(result.current.themeName).toMatch('Spotify-ish')
})
})
describe('with user preference theme as dark', () => {
beforeAll(() => {
window.matchMedia = createMatchMedia('dark')
})
it('sets theme as dark in auto mode', () => {
const { result } = renderHook(() => useCurrentTheme(), {
wrapper: ({ children }) => (
<Provider store={createStore(themeReducer, { theme: AUTO_THEME_ID })}>
{children}
</Provider>
),
})
expect(result.current.themeName).toMatch('Dark')
})
it('sets theme as dark', () => {
const { result } = renderHook(() => useCurrentTheme(), {
wrapper: ({ children }) => (
<Provider store={createStore(themeReducer, { theme: 'DarkTheme' })}>
{children}
</Provider>
),
})
expect(result.current.themeName).toMatch('Dark')
})
it('sets theme as light', () => {
const { result } = renderHook(() => useCurrentTheme(), {
wrapper: ({ children }) => (
<Provider store={createStore(themeReducer, { theme: 'LightTheme' })}>
{children}
</Provider>
),
})
expect(result.current.themeName).toMatch('Light')
})
it('sets theme as spotify-ish', () => {
const { result } = renderHook(() => useCurrentTheme(), {
wrapper: ({ children }) => (
<Provider
store={createStore(themeReducer, { theme: 'SpotifyTheme' })}
>
{children}
</Provider>
),
})
expect(result.current.themeName).toMatch('Spotify-ish')
})
})
})