Replace settings context with theme context

The settings context was having a big performance
impact on the app. We only truly need the theme + color
to be a global context.
This commit is contained in:
Brandon Presley 2022-11-01 16:50:03 +13:00
parent 8d7fe149f5
commit 31f1528c35
15 changed files with 140 additions and 118 deletions

View File

@ -14,6 +14,7 @@ module.exports = {
curly: 'off', curly: 'off',
'react/react-in-jsx-scope': 'off', 'react/react-in-jsx-scope': 'off',
'react-native/no-inline-styles': 'off', 'react-native/no-inline-styles': 'off',
'no-spaced-func': 'off',
}, },
}, },
], ],

51
App.tsx
View File

@ -16,9 +16,8 @@ import {lightColors} from './colors'
import {AppDataSource} from './data-source' import {AppDataSource} from './data-source'
import {settingsRepo} from './db' import {settingsRepo} from './db'
import Routes from './Routes' import Routes from './Routes'
import Settings from './settings'
import {TOAST} from './toast' import {TOAST} from './toast'
import {defaultSettings, SettingsContext} from './use-settings' import {ThemeContext} from './use-theme'
export const CombinedDefaultTheme = { export const CombinedDefaultTheme = {
...NavigationDefaultTheme, ...NavigationDefaultTheme,
@ -44,19 +43,20 @@ const App = () => {
const isDark = useColorScheme() === 'dark' const isDark = useColorScheme() === 'dark'
const [initialized, setInitialized] = useState(false) const [initialized, setInitialized] = useState(false)
const [snackbar, setSnackbar] = useState('') const [snackbar, setSnackbar] = useState('')
const [theme, setTheme] = useState('system')
const [settings, setSettings] = useState<Settings>({ const [color, setColor] = useState<string>(
...defaultSettings, isDark
color: isDark
? CombinedDarkTheme.colors.primary ? CombinedDarkTheme.colors.primary
: CombinedDefaultTheme.colors.primary, : CombinedDefaultTheme.colors.primary,
}) )
useEffect(() => { useEffect(() => {
AppDataSource.initialize().then(async () => { AppDataSource.initialize().then(async () => {
const gotSettings = await settingsRepo.findOne({where: {}}) const settings = await settingsRepo.findOne({where: {}})
console.log(`${App.name}.useEffect:`, {gotSettings}) console.log(`${App.name}.useEffect:`, {gotSettings: settings})
setSettings(gotSettings) setTheme(settings.theme)
setColor(settings.color)
setInitialized(true) setInitialized(true)
}) })
DeviceEventEmitter.addListener(TOAST, ({value}: {value: string}) => { DeviceEventEmitter.addListener(TOAST, ({value}: {value: string}) => {
@ -65,48 +65,43 @@ const App = () => {
}) })
}, []) }, [])
const theme = useMemo(() => { const paperTheme = useMemo(() => {
const darkTheme = settings?.color const darkTheme = color
? { ? {
...CombinedDarkTheme, ...CombinedDarkTheme,
colors: {...CombinedDarkTheme.colors, primary: settings.color}, colors: {...CombinedDarkTheme.colors, primary: color},
} }
: CombinedDarkTheme : CombinedDarkTheme
const lightTheme = settings?.color const lightTheme = color
? { ? {
...CombinedDefaultTheme, ...CombinedDefaultTheme,
colors: {...CombinedDefaultTheme.colors, primary: settings.color}, colors: {...CombinedDefaultTheme.colors, primary: color},
} }
: CombinedDefaultTheme : CombinedDefaultTheme
let value = isDark ? darkTheme : lightTheme let value = isDark ? darkTheme : lightTheme
if (settings?.theme === 'dark') value = darkTheme if (theme === 'dark') value = darkTheme
else if (settings?.theme === 'light') value = lightTheme else if (theme === 'light') value = lightTheme
return value return value
}, [isDark, settings?.theme, settings?.color]) }, [isDark, theme, color])
const settingsContext = useMemo(
() => ({settings, setSettings}),
[settings, setSettings],
)
const action = useMemo( const action = useMemo(
() => ({ () => ({
label: 'Close', label: 'Close',
onPress: () => setSnackbar(''), onPress: () => setSnackbar(''),
color: theme.colors.primary, color: paperTheme.colors.primary,
}), }),
[theme.colors.primary], [paperTheme.colors.primary],
) )
return ( return (
<PaperProvider <PaperProvider
theme={theme} theme={paperTheme}
settings={{icon: props => <MaterialIcon {...props} />}}> settings={{icon: props => <MaterialIcon {...props} />}}>
<NavigationContainer theme={theme}> <NavigationContainer theme={paperTheme}>
{initialized && ( {initialized && (
<SettingsContext.Provider value={settingsContext}> <ThemeContext.Provider value={{theme, setTheme, color, setColor}}>
<Routes /> <Routes />
</SettingsContext.Provider> </ThemeContext.Provider>
)} )}
</NavigationContainer> </NavigationContainer>

View File

@ -7,17 +7,23 @@ import {useCallback, useState} from 'react'
import {FlatList, Image} from 'react-native' import {FlatList, Image} from 'react-native'
import {List} from 'react-native-paper' import {List} from 'react-native-paper'
import {BestPageParams} from './BestPage' import {BestPageParams} from './BestPage'
import {setRepo} from './db' import {setRepo, settingsRepo} from './db'
import DrawerHeader from './DrawerHeader' import DrawerHeader from './DrawerHeader'
import GymSet from './gym-set' import GymSet from './gym-set'
import Page from './Page' import Page from './Page'
import {useSettings} from './use-settings' import Settings from './settings'
export default function BestList() { export default function BestList() {
const [bests, setBests] = useState<GymSet[]>() const [bests, setBests] = useState<GymSet[]>()
const [term, setTerm] = useState('') const [term, setTerm] = useState('')
const navigation = useNavigation<NavigationProp<BestPageParams>>() const navigation = useNavigation<NavigationProp<BestPageParams>>()
const {settings} = useSettings() const [settings, setSettings] = useState<Settings>()
useFocusEffect(
useCallback(() => {
settingsRepo.findOne({where: {}}).then(setSettings)
}, []),
)
const refresh = useCallback(async (value: string) => { const refresh = useCallback(async (value: string) => {
const weights = await setRepo const weights = await setRepo

View File

@ -1,20 +1,31 @@
import {RouteProp, useNavigation, useRoute} from '@react-navigation/native' import {
import {useCallback} from 'react' RouteProp,
useFocusEffect,
useNavigation,
useRoute,
} from '@react-navigation/native'
import {useCallback, useState} from 'react'
import {NativeModules, View} from 'react-native' import {NativeModules, View} from 'react-native'
import {PADDING} from './constants' import {PADDING} from './constants'
import {setRepo} from './db' import {setRepo, settingsRepo} from './db'
import GymSet from './gym-set' import GymSet from './gym-set'
import {HomePageParams} from './home-page-params' import {HomePageParams} from './home-page-params'
import SetForm from './SetForm' import SetForm from './SetForm'
import Settings from './settings'
import StackHeader from './StackHeader' import StackHeader from './StackHeader'
import {toast} from './toast' import {toast} from './toast'
import {useSettings} from './use-settings'
export default function EditSet() { export default function EditSet() {
const {params} = useRoute<RouteProp<HomePageParams, 'EditSet'>>() const {params} = useRoute<RouteProp<HomePageParams, 'EditSet'>>()
const {set} = params const {set} = params
const navigation = useNavigation() const navigation = useNavigation()
const {settings} = useSettings() const [settings, setSettings] = useState<Settings>()
useFocusEffect(
useCallback(() => {
settingsRepo.findOne({where: {}}).then(setSettings)
}, []),
)
const startTimer = useCallback( const startTimer = useCallback(
async (name: string) => { async (name: string) => {
@ -23,9 +34,9 @@ export default function EditSet() {
const milliseconds = (minutes ?? 3) * 60 * 1000 + (seconds ?? 0) * 1000 const milliseconds = (minutes ?? 3) * 60 * 1000 + (seconds ?? 0) * 1000
NativeModules.AlarmModule.timer( NativeModules.AlarmModule.timer(
milliseconds, milliseconds,
!!settings.vibrate, settings.vibrate,
settings.sound, settings.sound,
!!settings.noSound, settings.noSound,
) )
}, },
[settings], [settings],
@ -60,7 +71,7 @@ export default function EditSet() {
<> <>
<StackHeader title="Edit set" /> <StackHeader title="Edit set" />
<View style={{padding: PADDING, flex: 1}}> <View style={{padding: PADDING, flex: 1}}>
<SetForm save={save} set={set} /> {settings && <SetForm settings={settings} save={save} set={set} />}
</View> </View>
</> </>
) )

View File

@ -1,15 +1,20 @@
import {RouteProp, useNavigation, useRoute} from '@react-navigation/native' import {
RouteProp,
useFocusEffect,
useNavigation,
useRoute,
} from '@react-navigation/native'
import {useCallback, useRef, useState} from 'react' import {useCallback, useRef, useState} from 'react'
import {ScrollView, TextInput, View} from 'react-native' import {ScrollView, TextInput, View} from 'react-native'
import DocumentPicker from 'react-native-document-picker' import DocumentPicker from 'react-native-document-picker'
import {Button, Card, TouchableRipple} from 'react-native-paper' import {Button, Card, TouchableRipple} from 'react-native-paper'
import ConfirmDialog from './ConfirmDialog' import ConfirmDialog from './ConfirmDialog'
import {MARGIN, PADDING} from './constants' import {MARGIN, PADDING} from './constants'
import {getNow, planRepo, setRepo} from './db' import {getNow, planRepo, setRepo, settingsRepo} from './db'
import MassiveInput from './MassiveInput' import MassiveInput from './MassiveInput'
import Settings from './settings'
import StackHeader from './StackHeader' import StackHeader from './StackHeader'
import {toast} from './toast' import {toast} from './toast'
import {useSettings} from './use-settings'
import {WorkoutsPageParams} from './WorkoutsPage' import {WorkoutsPageParams} from './WorkoutsPage'
export default function EditWorkout() { export default function EditWorkout() {
@ -31,7 +36,13 @@ export default function EditWorkout() {
const stepsRef = useRef<TextInput>(null) const stepsRef = useRef<TextInput>(null)
const minutesRef = useRef<TextInput>(null) const minutesRef = useRef<TextInput>(null)
const secondsRef = useRef<TextInput>(null) const secondsRef = useRef<TextInput>(null)
const {settings} = useSettings() const [settings, setSettings] = useState<Settings>()
useFocusEffect(
useCallback(() => {
settingsRepo.findOne({where: {}}).then(setSettings)
}, []),
)
const update = async () => { const update = async () => {
await setRepo.update( await setRepo.update(
@ -119,7 +130,7 @@ export default function EditWorkout() {
onChangeText={handleName} onChangeText={handleName}
onSubmitEditing={submitName} onSubmitEditing={submitName}
/> />
{!!settings.steps && ( {settings.steps && (
<MassiveInput <MassiveInput
innerRef={stepsRef} innerRef={stepsRef}
selectTextOnFocus={false} selectTextOnFocus={false}
@ -130,7 +141,7 @@ export default function EditWorkout() {
onSubmitEditing={() => setsRef.current?.focus()} onSubmitEditing={() => setsRef.current?.focus()}
/> />
)} )}
{!!settings.showSets && ( {settings.showSets && (
<MassiveInput <MassiveInput
innerRef={setsRef} innerRef={setsRef}
value={sets} value={sets}
@ -140,7 +151,7 @@ export default function EditWorkout() {
onSubmitEditing={() => minutesRef.current?.focus()} onSubmitEditing={() => minutesRef.current?.focus()}
/> />
)} )}
{!!settings.alarm && ( {settings.alarm && (
<> <>
<MassiveInput <MassiveInput
innerRef={minutesRef} innerRef={minutesRef}
@ -160,7 +171,7 @@ export default function EditWorkout() {
/> />
</> </>
)} )}
{!!settings.images && uri && ( {settings.images && uri && (
<TouchableRipple <TouchableRipple
style={{marginBottom: MARGIN}} style={{marginBottom: MARGIN}}
onPress={changeImage} onPress={changeImage}
@ -168,7 +179,7 @@ export default function EditWorkout() {
<Card.Cover source={{uri}} /> <Card.Cover source={{uri}} />
</TouchableRipple> </TouchableRipple>
)} )}
{!!settings.images && !uri && ( {settings.images && !uri && (
<Button <Button
style={{marginBottom: MARGIN}} style={{marginBottom: MARGIN}}
onPress={changeImage} onPress={changeImage}

View File

@ -7,15 +7,17 @@ import {MARGIN} from './constants'
import {getNow, setRepo} from './db' import {getNow, setRepo} from './db'
import GymSet from './gym-set' import GymSet from './gym-set'
import MassiveInput from './MassiveInput' import MassiveInput from './MassiveInput'
import Settings from './settings'
import {toast} from './toast' import {toast} from './toast'
import {useSettings} from './use-settings'
export default function SetForm({ export default function SetForm({
save, save,
set, set,
settings,
}: { }: {
set: GymSet set: GymSet
save: (set: GymSet) => void save: (set: GymSet) => void
settings: Settings
}) { }) {
const [name, setName] = useState(set.name) const [name, setName] = useState(set.name)
const [reps, setReps] = useState(set.reps.toString()) const [reps, setReps] = useState(set.reps.toString())
@ -28,7 +30,6 @@ export default function SetForm({
end: set.reps.toString().length, end: set.reps.toString().length,
}) })
const [removeImage, setRemoveImage] = useState(false) const [removeImage, setRemoveImage] = useState(false)
const {settings} = useSettings()
const weightRef = useRef<TextInput>(null) const weightRef = useRef<TextInput>(null)
const repsRef = useRef<TextInput>(null) const repsRef = useRef<TextInput>(null)
const unitRef = useRef<TextInput>(null) const unitRef = useRef<TextInput>(null)
@ -113,7 +114,7 @@ export default function SetForm({
onSubmitEditing={handleSubmit} onSubmitEditing={handleSubmit}
innerRef={weightRef} innerRef={weightRef}
/> />
{!!settings.showUnit && ( {settings.showUnit && (
<MassiveInput <MassiveInput
autoCapitalize="none" autoCapitalize="none"
label="Unit" label="Unit"
@ -122,10 +123,10 @@ export default function SetForm({
innerRef={unitRef} innerRef={unitRef}
/> />
)} )}
{typeof set.id === 'number' && !!settings.showDate && ( {typeof set.id === 'number' && settings.showDate && (
<MassiveInput label="Created" disabled value={set.created} /> <MassiveInput label="Created" disabled value={set.created} />
)} )}
{!!settings.images && newImage && ( {settings.images && newImage && (
<TouchableRipple <TouchableRipple
style={{marginBottom: MARGIN}} style={{marginBottom: MARGIN}}
onPress={changeImage} onPress={changeImage}
@ -133,7 +134,7 @@ export default function SetForm({
<Card.Cover source={{uri: newImage}} /> <Card.Cover source={{uri: newImage}} />
</TouchableRipple> </TouchableRipple>
)} )}
{!!settings.images && !newImage && ( {settings.images && !newImage && (
<Button <Button
style={{marginBottom: MARGIN}} style={{marginBottom: MARGIN}}
onPress={changeImage} onPress={changeImage}

View File

@ -5,20 +5,21 @@ import {Divider, List, Menu, Text} from 'react-native-paper'
import {setRepo} from './db' import {setRepo} from './db'
import GymSet from './gym-set' import GymSet from './gym-set'
import {HomePageParams} from './home-page-params' import {HomePageParams} from './home-page-params'
import Settings from './settings'
import {format} from './time' import {format} from './time'
import useDark from './use-dark' import useDark from './use-dark'
import {useSettings} from './use-settings'
export default function SetItem({ export default function SetItem({
item, item,
onRemove, onRemove,
settings,
}: { }: {
item: GymSet item: GymSet
onRemove: () => void onRemove: () => void
settings: Settings
}) { }) {
const [showMenu, setShowMenu] = useState(false) const [showMenu, setShowMenu] = useState(false)
const [anchor, setAnchor] = useState({x: 0, y: 0}) const [anchor, setAnchor] = useState({x: 0, y: 0})
const {settings} = useSettings()
const dark = useDark() const dark = useDark()
const navigation = useNavigation<NavigationProp<HomePageParams>>() const navigation = useNavigation<NavigationProp<HomePageParams>>()
@ -51,14 +52,14 @@ export default function SetItem({
description={`${item.reps} x ${item.weight}${item.unit || 'kg'}`} description={`${item.reps} x ${item.weight}${item.unit || 'kg'}`}
onLongPress={longPress} onLongPress={longPress}
left={() => left={() =>
!!settings.images && settings.images &&
item.image && ( item.image && (
<Image source={{uri: item.image}} style={{height: 75, width: 75}} /> <Image source={{uri: item.image}} style={{height: 75, width: 75}} />
) )
} }
right={() => ( right={() => (
<> <>
{!!settings.showDate && ( {settings.showDate && (
<Text <Text
style={{ style={{
alignSelf: 'center', alignSelf: 'center',

View File

@ -7,12 +7,13 @@ import React, {useCallback, useEffect, useState} from 'react'
import {FlatList} from 'react-native' import {FlatList} from 'react-native'
import {List} from 'react-native-paper' import {List} from 'react-native-paper'
import {Like} from 'typeorm' import {Like} from 'typeorm'
import {getNow, setRepo} from './db' import {getNow, setRepo, settingsRepo} from './db'
import DrawerHeader from './DrawerHeader' import DrawerHeader from './DrawerHeader'
import GymSet from './gym-set' import GymSet from './gym-set'
import {HomePageParams} from './home-page-params' import {HomePageParams} from './home-page-params'
import Page from './Page' import Page from './Page'
import SetItem from './SetItem' import SetItem from './SetItem'
import Settings from './settings'
const limit = 15 const limit = 15
@ -22,6 +23,7 @@ export default function SetList() {
const [offset, setOffset] = useState(0) const [offset, setOffset] = useState(0)
const [term, setTerm] = useState('') const [term, setTerm] = useState('')
const [end, setEnd] = useState(false) const [end, setEnd] = useState(false)
const [settings, setSettings] = useState<Settings>()
const navigation = useNavigation<NavigationProp<HomePageParams>>() const navigation = useNavigation<NavigationProp<HomePageParams>>()
useEffect(() => console.log({sets}), [sets]) useEffect(() => console.log({sets}), [sets])
@ -43,6 +45,7 @@ export default function SetList() {
useFocusEffect( useFocusEffect(
useCallback(() => { useCallback(() => {
refresh(term) refresh(term)
settingsRepo.findOne({where: {}}).then(setSettings)
}, [refresh, term]), }, [refresh, term]),
) )
@ -107,12 +110,14 @@ export default function SetList() {
description="A set is a group of repetitions. E.g. 8 reps of Squats." description="A set is a group of repetitions. E.g. 8 reps of Squats."
/> />
) : ( ) : (
<FlatList settings && (
data={sets} <FlatList
style={{flex: 1}} data={sets}
renderItem={renderItem} style={{flex: 1}}
onEndReached={next} renderItem={renderItem}
/> onEndReached={next}
/>
)
)} )}
</Page> </Page>
</> </>

View File

@ -15,13 +15,12 @@ import Select from './Select'
import Settings from './settings' import Settings from './settings'
import Switch from './Switch' import Switch from './Switch'
import {toast} from './toast' import {toast} from './toast'
import {useSettings} from './use-settings'
export default function SettingsPage() { export default function SettingsPage() {
const [battery, setBattery] = useState(false) const [battery, setBattery] = useState(false)
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] = useState<Settings>({} as Settings)
useEffect(() => { useEffect(() => {
console.log(`${SettingsPage.name}.useEffect:`, {settings}) console.log(`${SettingsPage.name}.useEffect:`, {settings})
@ -30,6 +29,7 @@ export default function SettingsPage() {
useFocusEffect( useFocusEffect(
useCallback(() => { useCallback(() => {
NativeModules.AlarmModule.ignoringBattery(setIgnoring) NativeModules.AlarmModule.ignoringBattery(setIgnoring)
settingsRepo.findOne({where: {}}).then(setSettings)
}, []), }, []),
) )

View File

@ -7,15 +7,15 @@ import {getBestSet} from './best.service'
import {PADDING} from './constants' import {PADDING} from './constants'
import CountMany from './count-many' import CountMany from './count-many'
import {AppDataSource} from './data-source' import {AppDataSource} from './data-source'
import {getNow, setRepo} from './db' import {getNow, setRepo, settingsRepo} from './db'
import GymSet from './gym-set' import GymSet from './gym-set'
import MassiveInput from './MassiveInput' import MassiveInput from './MassiveInput'
import {PlanPageParams} from './plan-page-params' import {PlanPageParams} from './plan-page-params'
import SetForm from './SetForm' import SetForm from './SetForm'
import Settings from './settings'
import StackHeader from './StackHeader' import StackHeader from './StackHeader'
import StartPlanItem from './StartPlanItem' import StartPlanItem from './StartPlanItem'
import {toast} from './toast' import {toast} from './toast'
import {useSettings} from './use-settings'
export default function StartPlan() { export default function StartPlan() {
const {params} = useRoute<RouteProp<PlanPageParams, 'StartPlan'>>() const {params} = useRoute<RouteProp<PlanPageParams, 'StartPlan'>>()
@ -27,7 +27,7 @@ export default function StartPlan() {
const [seconds, setSeconds] = useState(30) const [seconds, setSeconds] = useState(30)
const [best, setBest] = useState<GymSet>() const [best, setBest] = useState<GymSet>()
const [selected, setSelected] = useState(0) const [selected, setSelected] = useState(0)
const {settings} = useSettings() const [settings, setSettings] = useState<Settings>()
const [counts, setCounts] = useState<CountMany[]>() const [counts, setCounts] = useState<CountMany[]>()
const weightRef = useRef<TextInput>(null) const weightRef = useRef<TextInput>(null)
const repsRef = useRef<TextInput>(null) const repsRef = useRef<TextInput>(null)
@ -85,6 +85,7 @@ export default function StartPlan() {
useFocusEffect( useFocusEffect(
useCallback(() => { useCallback(() => {
refresh().then(newCounts => select(0, newCounts)) refresh().then(newCounts => select(0, newCounts))
settingsRepo.findOne({where: {}}).then(setSettings)
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [refresh]), }, [refresh]),
) )
@ -148,7 +149,7 @@ export default function StartPlan() {
innerRef={weightRef} innerRef={weightRef}
blurOnSubmit blurOnSubmit
/> />
{!!settings.showUnit && ( {settings?.showUnit && (
<MassiveInput <MassiveInput
autoCapitalize="none" autoCapitalize="none"
label="Unit" label="Unit"

View File

@ -5,20 +5,20 @@ import {List, Menu, Text} from 'react-native-paper'
import ConfirmDialog from './ConfirmDialog' import ConfirmDialog from './ConfirmDialog'
import {setRepo} from './db' import {setRepo} from './db'
import GymSet from './gym-set' import GymSet from './gym-set'
import {useSettings} from './use-settings'
import {WorkoutsPageParams} from './WorkoutsPage' import {WorkoutsPageParams} from './WorkoutsPage'
export default function WorkoutItem({ export default function WorkoutItem({
item, item,
onRemove, onRemove,
images,
}: { }: {
item: GymSet item: GymSet
onRemove: () => void onRemove: () => void
images: boolean
}) { }) {
const [showMenu, setShowMenu] = useState(false) const [showMenu, setShowMenu] = useState(false)
const [anchor, setAnchor] = useState({x: 0, y: 0}) const [anchor, setAnchor] = useState({x: 0, y: 0})
const [showRemove, setShowRemove] = useState('') const [showRemove, setShowRemove] = useState('')
const {settings} = useSettings()
const navigation = useNavigation<NavigationProp<WorkoutsPageParams>>() const navigation = useNavigation<NavigationProp<WorkoutsPageParams>>()
const remove = useCallback(async () => { const remove = useCallback(async () => {
@ -37,12 +37,8 @@ export default function WorkoutItem({
const description = useMemo(() => { const description = useMemo(() => {
const seconds = item.seconds?.toString().padStart(2, '0') const seconds = item.seconds?.toString().padStart(2, '0')
if (settings.alarm && settings.showSets) return `${item.sets} x ${item.minutes || 0}:${seconds}`
return `${item.sets} x ${item.minutes || 0}:${seconds}` }, [item])
else if (settings.alarm && !settings.showSets)
return `${item.minutes || 0}:${seconds}`
return `${item.sets}`
}, [item, settings])
return ( return (
<> <>
@ -52,7 +48,7 @@ export default function WorkoutItem({
description={description} description={description}
onLongPress={longPress} onLongPress={longPress}
left={() => left={() =>
!!settings.images && images &&
item.image && ( item.image && (
<Image source={{uri: item.image}} style={{height: 75, width: 75}} /> <Image source={{uri: item.image}} style={{height: 75, width: 75}} />
) )

View File

@ -12,7 +12,8 @@ import GymSet from './gym-set'
import SetList from './SetList' import SetList from './SetList'
import WorkoutItem from './WorkoutItem' import WorkoutItem from './WorkoutItem'
import {WorkoutsPageParams} from './WorkoutsPage' import {WorkoutsPageParams} from './WorkoutsPage'
import {setRepo} from './db' import {setRepo, settingsRepo} from './db'
import Settings from './settings'
const limit = 15 const limit = 15
@ -21,6 +22,7 @@ export default function WorkoutList() {
const [offset, setOffset] = useState(0) const [offset, setOffset] = useState(0)
const [term, setTerm] = useState('') const [term, setTerm] = useState('')
const [end, setEnd] = useState(false) const [end, setEnd] = useState(false)
const [settings, setSettings] = useState<Settings>()
const navigation = useNavigation<NavigationProp<WorkoutsPageParams>>() const navigation = useNavigation<NavigationProp<WorkoutsPageParams>>()
const refresh = useCallback(async (value: string) => { const refresh = useCallback(async (value: string) => {
@ -41,14 +43,20 @@ export default function WorkoutList() {
useFocusEffect( useFocusEffect(
useCallback(() => { useCallback(() => {
refresh(term) refresh(term)
settingsRepo.findOne({where: {}}).then(setSettings)
}, [refresh, term]), }, [refresh, term]),
) )
const renderItem = useCallback( const renderItem = useCallback(
({item}: {item: GymSet}) => ( ({item}: {item: GymSet}) => (
<WorkoutItem item={item} key={item.name} onRemove={() => refresh(term)} /> <WorkoutItem
images={settings?.images}
item={item}
key={item.name}
onRemove={() => refresh(term)}
/>
), ),
[refresh, term], [refresh, term, settings?.images],
) )
const next = useCallback(async () => { const next = useCallback(async () => {

View File

@ -1,11 +1,11 @@
import {useColorScheme} from 'react-native' import {useColorScheme} from 'react-native'
import {useSettings} from './use-settings' import {useTheme} from './use-theme'
export default function useDark() { export default function useDark() {
const dark = useColorScheme() === 'dark' const dark = useColorScheme() === 'dark'
const {settings} = useSettings() const {theme} = useTheme()
if (settings.theme === 'dark') return true if (theme === 'dark') return true
if (settings.theme === 'light') return false if (theme === 'light') return false
return dark return dark
} }

View File

@ -1,31 +0,0 @@
import React, {useContext} from 'react'
import {darkColors} from './colors'
import Settings from './settings'
export const defaultSettings: Settings = {
alarm: true,
color: darkColors[0].hex,
date: '',
images: true,
notify: false,
showDate: false,
showSets: true,
showUnit: true,
sound: '',
steps: false,
theme: 'system',
vibrate: true,
noSound: false,
}
export const SettingsContext = React.createContext<{
settings: Settings
setSettings: (value: Settings) => void
}>({
settings: defaultSettings,
setSettings: () => null,
})
export function useSettings() {
return useContext(SettingsContext)
}

17
use-theme.ts Normal file
View File

@ -0,0 +1,17 @@
import {createContext, useContext} from 'react'
export const ThemeContext = createContext<{
theme: string
color: string
setTheme: (value: string) => void
setColor: (value: string) => void
}>({
theme: '',
color: '',
setTheme: () => null,
setColor: () => null,
})
export function useTheme() {
return useContext(ThemeContext)
}