Remove redundant Color context

Settings already stores the color set by the user.
This commit is contained in:
Brandon Presley 2022-10-31 21:32:33 +13:00
parent 13ca9cef3e
commit 1a53fa324b
9 changed files with 76 additions and 90 deletions

70
App.tsx
View File

@ -11,14 +11,13 @@ import {
Provider as PaperProvider, Provider as PaperProvider,
} from 'react-native-paper' } from 'react-native-paper'
import MaterialIcon from 'react-native-vector-icons/MaterialIcons' import MaterialIcon from 'react-native-vector-icons/MaterialIcons'
import {Color} from './color'
import {lightColors} from './colors' import {lightColors} from './colors'
import {AppDataSource} from './data-source' import {AppDataSource} from './data-source'
import {settingsRepo} from './db' import {settingsRepo} from './db'
import MassiveSnack from './MassiveSnack' import MassiveSnack from './MassiveSnack'
import Routes from './Routes' import Routes from './Routes'
import Settings from './settings' import Settings from './settings'
import {SettingsContext} from './use-settings' import {defaultSettings, SettingsContext} from './use-settings'
export const CombinedDefaultTheme = { export const CombinedDefaultTheme = {
...NavigationDefaultTheme, ...NavigationDefaultTheme,
@ -43,61 +42,60 @@ export const CombinedDarkTheme = {
const App = () => { const App = () => {
const isDark = useColorScheme() === 'dark' const isDark = useColorScheme() === 'dark'
const [initialized, setInitialized] = useState(false) const [initialized, setInitialized] = useState(false)
const [settings, setSettings] = useState<Settings>() const [settings, setSettings] = useState<Settings>({
const [color, setColor] = useState( ...defaultSettings,
isDark color: isDark
? CombinedDarkTheme.colors.primary.toUpperCase() ? CombinedDarkTheme.colors.primary
: CombinedDefaultTheme.colors.primary.toUpperCase(), : CombinedDefaultTheme.colors.primary,
) })
useEffect(() => { useEffect(() => {
AppDataSource.initialize().then(async () => { AppDataSource.initialize().then(async () => {
const gotSettings = await settingsRepo.findOne({where: {}}) const gotSettings = await settingsRepo.findOne({where: {}})
console.log(`${App.name}.useEffect:`, {gotSettings}) console.log(`${App.name}.useEffect:`, {gotSettings})
setSettings(gotSettings) setSettings(gotSettings)
if (gotSettings.color) setColor(gotSettings.color)
setInitialized(true) setInitialized(true)
}) })
}, [setColor]) }, [])
const theme = useMemo(() => { const theme = useMemo(() => {
const darkTheme = { const darkTheme = settings?.color
...CombinedDarkTheme, ? {
colors: {...CombinedDarkTheme.colors, primary: color}, ...CombinedDarkTheme,
} colors: {...CombinedDarkTheme.colors, primary: settings.color},
const lightTheme = { }
...CombinedDefaultTheme, : CombinedDarkTheme
colors: {...CombinedDefaultTheme.colors, primary: color}, const lightTheme = settings?.color
} ? {
...CombinedDefaultTheme,
colors: {...CombinedDefaultTheme.colors, primary: settings.color},
}
: CombinedDefaultTheme
let value = isDark ? darkTheme : lightTheme let value = isDark ? darkTheme : lightTheme
if (settings?.theme === 'dark') value = darkTheme if (settings?.theme === 'dark') value = darkTheme
else if (settings?.theme === 'light') value = lightTheme else if (settings?.theme === 'light') value = lightTheme
return value return value
}, [color, isDark, settings]) }, [isDark, settings?.theme, settings?.color])
const settingsContext = useMemo( const settingsContext = useMemo(
() => ({settings, setSettings}), () => ({settings, setSettings}),
[settings, setSettings], [settings, setSettings],
) )
const colorContext = useMemo(() => ({color, setColor}), [color, setColor])
return ( return (
<Color.Provider value={colorContext}> <PaperProvider
<PaperProvider theme={theme}
theme={theme} settings={{icon: props => <MaterialIcon {...props} />}}>
settings={{icon: props => <MaterialIcon {...props} />}}> <NavigationContainer theme={theme}>
<NavigationContainer theme={theme}> <MassiveSnack>
<MassiveSnack> {initialized && (
{initialized && ( <SettingsContext.Provider value={settingsContext}>
<SettingsContext.Provider value={settingsContext}> <Routes />
<Routes /> </SettingsContext.Provider>
</SettingsContext.Provider> )}
)} </MassiveSnack>
</MassiveSnack> </NavigationContainer>
</NavigationContainer> </PaperProvider>
</PaperProvider>
</Color.Provider>
) )
} }

View File

@ -1,8 +1,8 @@
import {useTheme} from '@react-navigation/native'
import * as shape from 'd3-shape' import * as shape from 'd3-shape'
import {View} from 'react-native' import {View} from 'react-native'
import {Grid, LineChart, XAxis, YAxis} from 'react-native-svg-charts' import {Grid, LineChart, XAxis, YAxis} from 'react-native-svg-charts'
import {CombinedDarkTheme, CombinedDefaultTheme} from './App' import {CombinedDarkTheme, CombinedDefaultTheme} from './App'
import {useColor} from './color'
import {MARGIN, PADDING} from './constants' import {MARGIN, PADDING} from './constants'
import GymSet from './gym-set' import GymSet from './gym-set'
import useDark from './use-dark' import useDark from './use-dark'
@ -18,7 +18,7 @@ export default function Chart({
xFormat: (value: any, index: number) => string xFormat: (value: any, index: number) => string
yFormat: (value: any) => string yFormat: (value: any) => string
}) { }) {
const {color} = useColor() const {colors} = useTheme()
const dark = useDark() const dark = useDark()
const axesSvg = { const axesSvg = {
fontSize: 10, fontSize: 10,
@ -46,7 +46,7 @@ export default function Chart({
contentInset={verticalContentInset} contentInset={verticalContentInset}
curve={shape.curveBasis} curve={shape.curveBasis}
svg={{ svg={{
stroke: color, stroke: colors.primary,
}}> }}>
<Grid /> <Grid />
</LineChart> </LineChart>

View File

@ -1,11 +1,13 @@
import {ComponentProps} from 'react' import {ComponentProps} from 'react'
import {FAB} from 'react-native-paper' import {FAB, useTheme} from 'react-native-paper'
import {useColor} from './color'
import {lightColors} from './colors' import {lightColors} from './colors'
export default function MassiveFab(props: Partial<ComponentProps<typeof FAB>>) { export default function MassiveFab(props: Partial<ComponentProps<typeof FAB>>) {
const {color} = useColor() const {colors} = useTheme()
const fabColor = lightColors.map(lightColor => lightColor.hex).includes(color)
const fabColor = lightColors
.map(lightColor => lightColor.hex)
.includes(colors.primary)
? 'black' ? 'black'
: undefined : undefined
@ -17,7 +19,7 @@ export default function MassiveFab(props: Partial<ComponentProps<typeof FAB>>) {
position: 'absolute', position: 'absolute',
right: 10, right: 10,
bottom: 10, bottom: 10,
backgroundColor: color, backgroundColor: colors.primary,
}} }}
{...props} {...props}
/> />

View File

@ -4,7 +4,6 @@ import {useCallback, useEffect, useMemo, useState} from 'react'
import {NativeModules, ScrollView} from 'react-native' import {NativeModules, ScrollView} from 'react-native'
import DocumentPicker from 'react-native-document-picker' import DocumentPicker from 'react-native-document-picker'
import {Button} from 'react-native-paper' import {Button} from 'react-native-paper'
import {useColor} from './color'
import {darkColors, lightColors} from './colors' import {darkColors, lightColors} from './colors'
import ConfirmDialog from './ConfirmDialog' import ConfirmDialog from './ConfirmDialog'
import {MARGIN} from './constants' import {MARGIN} from './constants'
@ -22,7 +21,6 @@ export default function SettingsPage() {
const [ignoring, setIgnoring] = useState(false) const [ignoring, setIgnoring] = useState(false)
const [term, setTerm] = useState('') const [term, setTerm] = useState('')
const {settings, setSettings} = useSettings() const {settings, setSettings} = useSettings()
const {color, setColor} = useColor()
const {toast} = useSnackbar() const {toast} = useSnackbar()
useEffect(() => { useEffect(() => {
@ -174,8 +172,8 @@ export default function SettingsPage() {
if (!'theme'.includes(term.toLowerCase())) return null if (!'theme'.includes(term.toLowerCase())) return null
return ( return (
<Picker <Picker
style={{color}} style={{color: settings.color}}
dropdownIconColor={color} dropdownIconColor={settings.color}
selectedValue={settings.theme} selectedValue={settings.theme}
onValueChange={changeTheme}> onValueChange={changeTheme}>
<Picker.Item value="system" label="Follow system theme" /> <Picker.Item value="system" label="Follow system theme" />
@ -183,7 +181,12 @@ export default function SettingsPage() {
<Picker.Item value="light" label="Light theme" /> <Picker.Item value="light" label="Light theme" />
</Picker> </Picker>
) )
}, [term, color, changeTheme, settings.theme]) }, [term, settings.color, changeTheme, settings.theme])
const changeColor = useCallback((value: string) => {
setSettings({...settings, color: value})
settingsRepo.update({}, {color: value})
}, [])
return ( return (
<> <>
@ -206,10 +209,10 @@ export default function SettingsPage() {
{theme} {theme}
{'color'.includes(term.toLowerCase()) && ( {'color'.includes(term.toLowerCase()) && (
<Picker <Picker
style={{color, marginTop: -10}} style={{color: settings.color, marginTop: -10}}
dropdownIconColor={color} dropdownIconColor={settings.color}
selectedValue={color} selectedValue={settings.color}
onValueChange={value => setColor(value)}> onValueChange={changeColor}>
{lightColors.concat(darkColors).map(colorOption => ( {lightColors.concat(darkColors).map(colorOption => (
<Picker.Item <Picker.Item
key={colorOption.hex} key={colorOption.hex}
@ -222,8 +225,8 @@ export default function SettingsPage() {
)} )}
{'date format'.includes(term.toLowerCase()) && ( {'date format'.includes(term.toLowerCase()) && (
<Picker <Picker
style={{color, marginTop: -10}} style={{color: settings.color, marginTop: -10}}
dropdownIconColor={color} dropdownIconColor={settings.color}
selectedValue={settings.date} selectedValue={settings.date}
onValueChange={changeDate}> onValueChange={changeDate}>
<Picker.Item value="%Y-%m-%d %H:%M" label="1990-12-24 15:05" /> <Picker.Item value="%Y-%m-%d %H:%M" label="1990-12-24 15:05" />

View File

@ -1,7 +1,6 @@
import React, {useCallback, useState} from 'react' import React, {useCallback, useState} from 'react'
import {GestureResponderEvent, ListRenderItemInfo, View} from 'react-native' import {GestureResponderEvent, ListRenderItemInfo, View} from 'react-native'
import {List, Menu, RadioButton} from 'react-native-paper' import {List, Menu, RadioButton, useTheme} from 'react-native-paper'
import {useColor} from './color'
import CountMany from './count-many' import CountMany from './count-many'
import {setRepo} from './db' import {setRepo} from './db'
@ -13,7 +12,7 @@ interface Props extends ListRenderItemInfo<CountMany> {
export default function StartPlanItem(props: Props) { export default function StartPlanItem(props: Props) {
const {index, item, onSelect, selected, onUndo} = props const {index, item, onSelect, selected, onUndo} = props
const {color} = useColor() const {colors} = useTheme()
const [anchor, setAnchor] = useState({x: 0, y: 0}) const [anchor, setAnchor] = useState({x: 0, y: 0})
const [showMenu, setShowMenu] = useState(false) const [showMenu, setShowMenu] = useState(false)
@ -48,7 +47,7 @@ export default function StartPlanItem(props: Props) {
onPress={() => onSelect(index)} onPress={() => onSelect(index)}
value={index.toString()} value={index.toString()}
status={selected === index ? 'checked' : 'unchecked'} status={selected === index ? 'checked' : 'unchecked'}
color={color} color={colors.primary}
/> />
</View> </View>
)} )}

View File

@ -1,8 +1,7 @@
import {useMemo} from 'react' import {useMemo} from 'react'
import {Pressable} from 'react-native' import {Pressable} from 'react-native'
import {Switch as PaperSwitch, Text} from 'react-native-paper' import {Switch as PaperSwitch, Text, useTheme} from 'react-native-paper'
import {CombinedDarkTheme, CombinedDefaultTheme} from './App' import {CombinedDarkTheme, CombinedDefaultTheme} from './App'
import {useColor} from './color'
import {colorShade} from './colors' import {colorShade} from './colors'
import {MARGIN} from './constants' import {MARGIN} from './constants'
import useDark from './use-dark' import useDark from './use-dark'
@ -18,20 +17,20 @@ export default function Switch({
onPress: () => void onPress: () => void
children: string children: string
}) { }) {
const {color} = useColor() const {colors} = useTheme()
const dark = useDark() const dark = useDark()
const track = useMemo(() => { const track = useMemo(() => {
if (dark) if (dark)
return { return {
false: CombinedDarkTheme.colors.placeholder, false: CombinedDarkTheme.colors.placeholder,
true: colorShade(color, -40), true: colorShade(colors.primary, -40),
} }
return { return {
false: CombinedDefaultTheme.colors.placeholder, false: CombinedDefaultTheme.colors.placeholder,
true: colorShade(color, -40), true: colorShade(colors.primary, -40),
} }
}, [dark, color]) }, [dark, colors.primary])
return ( return (
<Pressable <Pressable
@ -43,7 +42,7 @@ export default function Switch({
}}> }}>
<PaperSwitch <PaperSwitch
trackColor={track} trackColor={track}
color={color} color={colors.primary}
style={{marginRight: MARGIN}} style={{marginRight: MARGIN}}
value={value} value={value}
onValueChange={onValueChange} onValueChange={onValueChange}

View File

@ -1,11 +0,0 @@
import React, {useContext} from 'react'
export const Color = React.createContext({
color: '',
setColor: (_value: string) => {},
})
export const useColor = () => {
const context = useContext(Color)
return context
}

View File

@ -1,13 +1,10 @@
import {NavigationContainer} from '@react-navigation/native' import {NavigationContainer} from '@react-navigation/native'
import React from 'react' import React from 'react'
import {Provider as PaperProvider} from 'react-native-paper' import {Provider as PaperProvider} from 'react-native-paper'
import {Color} from './color'
import {lightColors} from './colors'
import MassiveSnack from './MassiveSnack' import MassiveSnack from './MassiveSnack'
import {defaultSettings, SettingsContext} from './use-settings' import {defaultSettings, SettingsContext} from './use-settings'
import MaterialIcon from 'react-native-vector-icons/MaterialIcons' import MaterialIcon from 'react-native-vector-icons/MaterialIcons'
const color = lightColors[0].hex
export const setColor = jest.fn() export const setColor = jest.fn()
const settings = defaultSettings const settings = defaultSettings
export const setSettings = jest.fn() export const setSettings = jest.fn()
@ -17,13 +14,11 @@ export const MockProviders = ({
}: { }: {
children: JSX.Element | JSX.Element[] children: JSX.Element | JSX.Element[]
}) => ( }) => (
<Color.Provider value={{color, setColor}}> <PaperProvider settings={{icon: props => <MaterialIcon {...props} />}}>
<PaperProvider settings={{icon: props => <MaterialIcon {...props} />}}> <SettingsContext.Provider value={{settings, setSettings}}>
<SettingsContext.Provider value={{settings, setSettings}}> <MassiveSnack>
<MassiveSnack> <NavigationContainer>{children}</NavigationContainer>
<NavigationContainer>{children}</NavigationContainer> </MassiveSnack>
</MassiveSnack> </SettingsContext.Provider>
</SettingsContext.Provider> </PaperProvider>
</PaperProvider>
</Color.Provider>
) )

View File

@ -1,9 +1,10 @@
import React, {useContext} from 'react' import React, {useContext} from 'react'
import {darkColors} from './colors'
import Settings from './settings' import Settings from './settings'
export const defaultSettings: Settings = { export const defaultSettings: Settings = {
alarm: true, alarm: true,
color: '', color: darkColors[0].hex,
date: '', date: '',
images: true, images: true,
notify: false, notify: false,