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:
parent
8d7fe149f5
commit
31f1528c35
|
@ -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
51
App.tsx
|
@ -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>
|
||||||
|
|
||||||
|
|
12
BestList.tsx
12
BestList.tsx
|
@ -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
|
||||||
|
|
27
EditSet.tsx
27
EditSet.tsx
|
@ -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>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
|
@ -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}
|
||||||
|
|
13
SetForm.tsx
13
SetForm.tsx
|
@ -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}
|
||||||
|
|
|
@ -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',
|
||||||
|
|
19
SetList.tsx
19
SetList.tsx
|
@ -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>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -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)
|
||||||
}, []),
|
}, []),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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}} />
|
||||||
)
|
)
|
||||||
|
|
|
@ -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 () => {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
17
use-theme.ts
Normal 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)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user