From b0b804eae14e7eb6ba60bbd43c605d1288c379c8 Mon Sep 17 00:00:00 2001 From: Brandon Presley Date: Sat, 1 Oct 2022 16:01:07 +1300 Subject: [PATCH] Use react context for settings Closes #81 --- BestList.tsx | 3 ++- EditSet.tsx | 39 ++++++++++++++++++--------------- EditWorkout.tsx | 3 ++- Routes.tsx | 53 ++++++++++++++++++++++++--------------------- SetForm.tsx | 3 ++- SetItem.tsx | 14 +++--------- SetList.tsx | 11 ++++------ SettingsPage.tsx | 7 ++++-- WorkoutItem.tsx | 3 +++ settings.service.ts | 7 ++---- settings.ts | 2 +- use-settings.ts | 18 +++++++++++++++ 12 files changed, 92 insertions(+), 71 deletions(-) create mode 100644 use-settings.ts diff --git a/BestList.tsx b/BestList.tsx index 069cceb..1133ad0 100644 --- a/BestList.tsx +++ b/BestList.tsx @@ -10,12 +10,13 @@ import {getBestReps, getBestWeights} from './best.service'; import {BestPageParams} from './BestPage'; import Page from './Page'; import Set from './set'; -import {settings} from './settings.service'; +import {useSettings} from './use-settings'; export default function BestList() { const [bests, setBests] = useState([]); const [search, setSearch] = useState(''); const navigation = useNavigation>(); + const {settings} = useSettings(); const refresh = useCallback(async () => { const weights = await getBestWeights(search); diff --git a/EditSet.tsx b/EditSet.tsx index 833de7a..17ebb0a 100644 --- a/EditSet.tsx +++ b/EditSet.tsx @@ -13,13 +13,15 @@ import {SnackbarContext} from './MassiveSnack'; import Set from './set'; import {addSet, updateSet} from './set.service'; import SetForm from './SetForm'; -import {getSettings, settings, updateSettings} from './settings.service'; +import {getSettings, updateSettings} from './settings.service'; +import {useSettings} from './use-settings'; export default function EditSet() { const {params} = useRoute>(); const {set, count, workouts} = params; const navigation = useNavigation(); const {toast} = useContext(SnackbarContext); + const {settings, setSettings} = useSettings(); useFocusEffect( useCallback(() => { @@ -35,23 +37,26 @@ export default function EditSet() { headerRight: null, title, }); - }, [navigation, set, count]), + }, [navigation, set, count, settings.newSet]), ); - const startTimer = useCallback(async (value: Set) => { - if (!settings.alarm) return; - const milliseconds = - Number(value.minutes) * 60 * 1000 + Number(value.seconds) * 1000; - NativeModules.AlarmModule.timer( - milliseconds, - !!settings.vibrate, - settings.sound, - ); - const next = new Date(); - next.setTime(next.getTime() + milliseconds); - await updateSettings({...settings, nextAlarm: next.toISOString()}); - await getSettings(); - }, []); + const startTimer = useCallback( + async (value: Set) => { + if (!settings.alarm) return; + const milliseconds = + Number(value.minutes) * 60 * 1000 + Number(value.seconds) * 1000; + NativeModules.AlarmModule.timer( + milliseconds, + !!settings.vibrate, + settings.sound, + ); + const next = new Date(); + next.setTime(next.getTime() + milliseconds); + await updateSettings({...settings, nextAlarm: next.toISOString()}); + setSettings(await getSettings()); + }, + [settings, setSettings], + ); const update = useCallback( async (value: Set) => { @@ -75,7 +80,7 @@ export default function EditSet() { toast("Great work King, that's a new record!", 3000); navigation.goBack(); }, - [navigation, startTimer, set, toast], + [navigation, startTimer, set, toast, settings], ); const save = useCallback( diff --git a/EditWorkout.tsx b/EditWorkout.tsx index 928e1da..9ea8e82 100644 --- a/EditWorkout.tsx +++ b/EditWorkout.tsx @@ -14,7 +14,7 @@ import MassiveInput from './MassiveInput'; import {SnackbarContext} from './MassiveSnack'; import {updatePlanWorkouts} from './plan.service'; import {addSet, updateManySet, updateSetImage} from './set.service'; -import {settings} from './settings.service'; +import {useSettings} from './use-settings'; import {WorkoutsPageParams} from './WorkoutsPage'; export default function EditWorkout() { @@ -37,6 +37,7 @@ export default function EditWorkout() { const stepsRef = useRef(null); const minutesRef = useRef(null); const secondsRef = useRef(null); + const {settings} = useSettings(); useFocusEffect( useCallback(() => { diff --git a/Routes.tsx b/Routes.tsx index af0a6a9..b7ab016 100644 --- a/Routes.tsx +++ b/Routes.tsx @@ -9,27 +9,28 @@ import {DrawerParamList} from './drawer-param-list'; import HomePage from './HomePage'; import PlanPage from './PlanPage'; import Route from './route'; -import {getSettings, settings} from './settings.service'; +import Settings from './settings'; +import {getSettings} from './settings.service'; import SettingsPage from './SettingsPage'; +import {SettingsContext} from './use-settings'; import WorkoutsPage from './WorkoutsPage'; const Drawer = createDrawerNavigator(); export default function Routes() { - const [migrated, setMigrated] = useState(false); + const [settings, setSettings] = useState(); const dark = useColorScheme() === 'dark'; const {setColor} = useContext(CustomTheme); useEffect(() => { - runMigrations() - .then(getSettings) - .then(() => { - setMigrated(true); - if (settings.color) setColor(settings.color); - }); + runMigrations().then(async () => { + const gotSettings = await getSettings(); + setSettings(gotSettings); + if (gotSettings.color) setColor(gotSettings.color); + }); }, [setColor]); - if (!migrated) return null; + if (!settings) return null; const routes: Route[] = [ {name: 'Home', component: HomePage, icon: 'home'}, @@ -40,21 +41,23 @@ export default function Routes() { ]; return ( - - {routes.map(route => ( - , - }} - /> - ))} - + + + {routes.map(route => ( + , + }} + /> + ))} + + ); } diff --git a/SetForm.tsx b/SetForm.tsx index 96290d1..9f6bf4f 100644 --- a/SetForm.tsx +++ b/SetForm.tsx @@ -8,7 +8,7 @@ import MassiveInput from './MassiveInput'; import {SnackbarContext} from './MassiveSnack'; import Set from './set'; import {getSets} from './set.service'; -import {settings} from './settings.service'; +import {useSettings} from './use-settings'; export default function SetForm({ save, @@ -31,6 +31,7 @@ export default function SetForm({ }); const [removeImage, setRemoveImage] = useState(false); const {toast} = useContext(SnackbarContext); + const {settings} = useSettings(); const weightRef = useRef(null); const repsRef = useRef(null); const unitRef = useRef(null); diff --git a/SetItem.tsx b/SetItem.tsx index 81b20bd..7071dad 100644 --- a/SetItem.tsx +++ b/SetItem.tsx @@ -5,24 +5,22 @@ import {Divider, List, Menu, Text} from 'react-native-paper'; import {HomePageParams} from './home-page-params'; import Set from './set'; import {deleteSet} from './set.service'; +import {useSettings} from './use-settings'; export default function SetItem({ item, onRemove, dates, setDates, - images, - setImages, }: { item: Set; onRemove: () => void; dates: boolean; setDates: (value: boolean) => void; - images: boolean; - setImages: (value: boolean) => void; }) { const [showMenu, setShowMenu] = useState(false); const [anchor, setAnchor] = useState({x: 0, y: 0}); + const {settings} = useSettings(); const navigation = useNavigation>(); const remove = useCallback(async () => { @@ -51,11 +49,6 @@ export default function SetItem({ setShowMenu(false); }, [dates, setDates]); - const toggleImages = useCallback(() => { - setImages(!images); - setShowMenu(false); - }, [images, setImages]); - return ( <> - images && + !!settings.images && item.image && ( ) @@ -86,7 +79,6 @@ export default function SetItem({ visible={showMenu} onDismiss={() => setShowMenu(false)}> - diff --git a/SetList.tsx b/SetList.tsx index bde767a..fd02a9c 100644 --- a/SetList.tsx +++ b/SetList.tsx @@ -14,7 +14,7 @@ import {getTodaysPlan} from './plan.service'; import Set from './set'; import {countToday, defaultSet, getSets, getToday} from './set.service'; import SetItem from './SetItem'; -import {settings} from './settings.service'; +import {useSettings} from './use-settings'; const limit = 15; @@ -27,7 +27,7 @@ export default function SetList() { const [search, setSearch] = useState(''); const [end, setEnd] = useState(false); const [dates, setDates] = useState(false); - const [images, setImages] = useState(true); + const {settings} = useSettings(); const navigation = useNavigation>(); const predict = useCallback(async () => { @@ -62,7 +62,7 @@ export default function SetList() { if (best.name === '') setCount(0); else setCount(_count); setSet({...best, image}); - }, []); + }, [settings]); const refresh = useCallback(async () => { predict(); @@ -80,7 +80,6 @@ export default function SetList() { navigation.getParent()?.setOptions({ headerRight: () => , }); - setImages(!!settings.images); }, [refresh, navigation]), ); @@ -93,14 +92,12 @@ export default function SetList() { ), - [refresh, dates, setDates, images, setImages], + [refresh, dates, setDates], ); const next = useCallback(async () => { diff --git a/SettingsPage.tsx b/SettingsPage.tsx index 143fb6f..bdd56d8 100644 --- a/SettingsPage.tsx +++ b/SettingsPage.tsx @@ -11,13 +11,15 @@ import {MARGIN} from './constants'; import Input from './input'; import {SnackbarContext} from './MassiveSnack'; import Page from './Page'; -import {getSettings, settings, updateSettings} from './settings.service'; +import {getSettings, updateSettings} from './settings.service'; import Switch from './Switch'; +import {useSettings} from './use-settings'; export default function SettingsPage() { const [battery, setBattery] = useState(false); const [ignoring, setIgnoring] = useState(false); const [search, setSearch] = useState(''); + const {settings, setSettings} = useSettings(); const [vibrate, setVibrate] = useState(!!settings.vibrate); const [alarm, setAlarm] = useState(!!settings.alarm); const [newSet, setNewSet] = useState(settings.newSet); @@ -49,7 +51,7 @@ export default function SettingsPage() { workouts: +workouts, steps: +steps, }); - getSettings(); + getSettings().then(setSettings); }, [ vibrate, alarm, @@ -61,6 +63,7 @@ export default function SettingsPage() { color, workouts, steps, + setSettings, ]); const changeAlarmEnabled = useCallback( diff --git a/WorkoutItem.tsx b/WorkoutItem.tsx index 736d995..466ce50 100644 --- a/WorkoutItem.tsx +++ b/WorkoutItem.tsx @@ -5,6 +5,7 @@ import {List, Menu, Text} from 'react-native-paper'; import ConfirmDialog from './ConfirmDialog'; import Set from './set'; import {deleteSetsBy} from './set.service'; +import {useSettings} from './use-settings'; import {WorkoutsPageParams} from './WorkoutsPage'; export default function WorkoutItem({ @@ -17,6 +18,7 @@ export default function WorkoutItem({ const [showMenu, setShowMenu] = useState(false); const [anchor, setAnchor] = useState({x: 0, y: 0}); const [showRemove, setShowRemove] = useState(''); + const {settings} = useSettings(); const navigation = useNavigation>(); const remove = useCallback(async () => { @@ -44,6 +46,7 @@ export default function WorkoutItem({ description={`${item.sets} sets ${minutes}:${seconds} rest`} onLongPress={longPress} left={() => + !!settings.images && item.image && ( ) diff --git a/settings.service.ts b/settings.service.ts index 6e94451..7aafb18 100644 --- a/settings.service.ts +++ b/settings.service.ts @@ -1,12 +1,9 @@ import {db} from './db'; import Settings from './settings'; -export let settings: Settings; - -export const getSettings = async () => { +export const getSettings = async (): Promise => { const [result] = await db.executeSql(`SELECT * FROM settings LIMIT 1`); - settings = result.rows.item(0); - return settings; + return result.rows.item(0); }; export const updateSettings = async (value: Settings) => { diff --git a/settings.ts b/settings.ts index 55a51f0..8bf8d6e 100644 --- a/settings.ts +++ b/settings.ts @@ -8,6 +8,6 @@ export default interface Settings { showUnit?: number; color?: string; workouts: number; - steps: number; nextAlarm?: string; + steps?: number; } diff --git a/use-settings.ts b/use-settings.ts new file mode 100644 index 0000000..9d1fb6a --- /dev/null +++ b/use-settings.ts @@ -0,0 +1,18 @@ +import React, {useContext} from 'react'; +import Settings from './settings'; + +export const SettingsContext = React.createContext<{ + settings: Settings; + setSettings: (value: Settings) => void; +}>({ + settings: { + alarm: 0, + vibrate: 1, + workouts: 0, + }, + setSettings: () => null, +}); + +export function useSettings() { + return useContext(SettingsContext); +}