Memoize the most expensive parts of SettingsPage

This commit is contained in:
Brandon Presley 2023-01-01 13:39:10 +13:00
parent 5335f4afbc
commit 86f01eb002
1 changed files with 114 additions and 98 deletions

View File

@ -30,7 +30,6 @@ export default function SettingsPage() {
const [formatOptions, setFormatOptions] = useState<string[]>(twelveHours) const [formatOptions, setFormatOptions] = useState<string[]>(twelveHours)
const [importing, setImporting] = useState(false) const [importing, setImporting] = useState(false)
const {reset} = useNavigation<NavigationProp<DrawerParamList>>() const {reset} = useNavigation<NavigationProp<DrawerParamList>>()
const today = new Date()
const {watch, setValue} = useForm<Settings>({ const {watch, setValue} = useForm<Settings>({
defaultValues: () => settingsRepo.findOne({where: {}}), defaultValues: () => settingsRepo.findOne({where: {}}),
@ -80,32 +79,9 @@ export default function SettingsPage() {
[settings], [settings],
) )
const changeString = useCallback( const filter = useCallback(
async (key: keyof Settings, value: string) => { ({name}) => name.toLowerCase().includes(term.toLowerCase()),
setValue(key, value) [term],
await settingsRepo.save({...settings, [key]: value})
switch (key) {
case 'date':
return toast('Changed date format')
case 'darkColor':
setDarkColor(value)
return toast('Set primary color for dark mode.')
case 'lightColor':
setLightColor(value)
return toast('Set primary color for light mode.')
case 'vibrate':
return toast('Set primary color for light mode.')
case 'sound':
return toast('Sound will play after rest timers.')
case 'theme':
setTheme(value as string)
if (value === 'dark') toast('Theme will always be dark.')
else if (value === 'light') toast('Theme will always be light.')
else if (value === 'system') toast('Theme will follow system.')
return
}
},
[settings, setTheme, setDarkColor, setLightColor, setValue],
) )
const changeBoolean = useCallback( const changeBoolean = useCallback(
@ -163,7 +139,42 @@ export default function SettingsPage() {
[changeBoolean], [changeBoolean],
) )
const selects: Input<string>[] = [ const switchesMarkup = useMemo(
() => switches.filter(filter).map(s => renderSwitch(s)),
[filter, switches, renderSwitch],
)
const changeString = useCallback(
async (key: keyof Settings, value: string) => {
setValue(key, value)
await settingsRepo.save({...settings, [key]: value})
switch (key) {
case 'date':
return toast('Changed date format')
case 'darkColor':
setDarkColor(value)
return toast('Set primary color for dark mode.')
case 'lightColor':
setLightColor(value)
return toast('Set primary color for light mode.')
case 'vibrate':
return toast('Set primary color for light mode.')
case 'sound':
return toast('Sound will play after rest timers.')
case 'theme':
setTheme(value as string)
if (value === 'dark') toast('Theme will always be dark.')
else if (value === 'light') toast('Theme will always be light.')
else if (value === 'system') toast('Theme will follow system.')
return
}
},
[settings, setTheme, setDarkColor, setLightColor, setValue],
)
const selects: Input<string>[] = useMemo(() => {
const today = new Date()
return [
{name: 'Theme', value: theme, items: themeOptions, key: 'theme'}, {name: 'Theme', value: theme, items: themeOptions, key: 'theme'},
{ {
name: 'Dark color', name: 'Dark color',
@ -187,6 +198,7 @@ export default function SettingsPage() {
key: 'date', key: 'date',
}, },
] ]
}, [settings.date, darkColor, formatOptions, theme, lightColor])
const renderSelect = useCallback( const renderSelect = useCallback(
(item: Input<string>) => ( (item: Input<string>) => (
@ -201,6 +213,11 @@ export default function SettingsPage() {
[changeString], [changeString],
) )
const selectsMarkup = useMemo(
() => selects.filter(filter).map(renderSelect),
[filter, selects, renderSelect],
)
const confirmImport = useCallback(async () => { const confirmImport = useCallback(async () => {
setImporting(false) setImporting(false)
await AppDataSource.destroy() await AppDataSource.destroy()
@ -222,14 +239,8 @@ export default function SettingsPage() {
toast('Database exported. Check downloads.') toast('Database exported. Check downloads.')
}, []) }, [])
const filter = useCallback(
({name}) => name.toLowerCase().includes(term.toLowerCase()),
[term],
)
const buttons = useMemo( const buttons = useMemo(
() => () => [
[
{ {
name: 'Alarm sound', name: 'Alarm sound',
element: ( element: (
@ -267,8 +278,13 @@ export default function SettingsPage() {
</Button> </Button>
), ),
}, },
].filter(filter), ],
[changeSound, exportDatabase, soundString, filter], [changeSound, exportDatabase, soundString],
)
const buttonsMarkup = useMemo(
() => buttons.filter(filter).map(b => b.element),
[buttons, filter],
) )
return ( return (
@ -277,9 +293,9 @@ export default function SettingsPage() {
<Page term={term} search={setTerm} style={{flexGrow: 0}}> <Page term={term} search={setTerm} style={{flexGrow: 0}}>
<View style={{marginTop: MARGIN}}> <View style={{marginTop: MARGIN}}>
{switches.filter(filter).map(s => renderSwitch(s))} {switchesMarkup}
{selects.filter(filter).map(s => renderSelect(s))} {selectsMarkup}
{buttons.map(b => b.element)} {buttonsMarkup}
</View> </View>
</Page> </Page>