Add setting to show/hide unit field

Closes #34
This commit is contained in:
Brandon Presley 2022-09-21 13:48:45 +12:00
parent 719560b664
commit 0bc644a1ba
8 changed files with 57 additions and 39 deletions

View File

@ -10,17 +10,14 @@ import {getBestReps, getBestWeights} from './best.service';
import {BestPageParams} from './BestPage'; import {BestPageParams} from './BestPage';
import Page from './Page'; import Page from './Page';
import Set from './set'; import Set from './set';
import Settings from './settings'; import {settings} from './settings.service';
import {getSettings} from './settings.service';
export default function BestList() { export default function BestList() {
const [bests, setBests] = useState<Set[]>([]); const [bests, setBests] = useState<Set[]>([]);
const [search, setSearch] = useState(''); const [search, setSearch] = useState('');
const [settings, setSettings] = useState<Settings>();
const navigation = useNavigation<NavigationProp<BestPageParams>>(); const navigation = useNavigation<NavigationProp<BestPageParams>>();
const refresh = useCallback(async () => { const refresh = useCallback(async () => {
getSettings().then(setSettings);
const weights = await getBestWeights(search); const weights = await getBestWeights(search);
console.log(`${BestList.name}.refresh:`, {length: weights.length}); console.log(`${BestList.name}.refresh:`, {length: weights.length});
let newBest: Set[] = []; let newBest: Set[] = [];
@ -51,7 +48,7 @@ export default function BestList() {
description={`${item.reps} x ${item.weight}${item.unit || 'kg'}`} description={`${item.reps} x ${item.weight}${item.unit || 'kg'}`}
onPress={() => navigation.navigate('ViewBest', {best: item})} onPress={() => navigation.navigate('ViewBest', {best: item})}
left={() => left={() =>
(settings?.images && item.image && ( (settings.images && item.image && (
<Image source={{uri: item.image}} style={{height: 75, width: 75}} /> <Image source={{uri: item.image}} style={{height: 75, width: 75}} />
)) || )) ||
null null

View File

@ -13,7 +13,7 @@ import {SnackbarContext} from './MassiveSnack';
import Set from './set'; import Set from './set';
import {addSet, updateSet} from './set.service'; import {addSet, updateSet} from './set.service';
import SetForm from './SetForm'; import SetForm from './SetForm';
import {getSettings} from './settings.service'; import {settings} from './settings.service';
export default function EditSet() { export default function EditSet() {
const {params} = useRoute<RouteProp<HomePageParams, 'EditSet'>>(); const {params} = useRoute<RouteProp<HomePageParams, 'EditSet'>>();
@ -34,7 +34,6 @@ export default function EditSet() {
); );
const startTimer = useCallback(async (set: Set) => { const startTimer = useCallback(async (set: Set) => {
const settings = await getSettings();
if (!settings.alarm) return; if (!settings.alarm) return;
const milliseconds = const milliseconds =
Number(set.minutes) * 60 * 1000 + Number(set.seconds) * 1000; Number(set.minutes) * 60 * 1000 + Number(set.seconds) * 1000;
@ -59,8 +58,7 @@ export default function EditSet() {
console.log(`${EditSet.name}.add`, {set}); console.log(`${EditSet.name}.add`, {set});
startTimer(set); startTimer(set);
await addSet(set); await addSet(set);
const settings = await getSettings(); if (!settings.notify) return navigation.goBack();
if (settings.notify === 0) return navigation.goBack();
if ( if (
set.weight > params.set.weight || set.weight > params.set.weight ||
(set.reps > params.set.reps && set.weight === params.set.weight) (set.reps > params.set.reps && set.weight === params.set.weight)

View File

@ -4,6 +4,7 @@ import {Button} from 'react-native-paper';
import MassiveInput from './MassiveInput'; import MassiveInput from './MassiveInput';
import Set from './set'; import Set from './set';
import {getSets} from './set.service'; import {getSets} from './set.service';
import {settings} from './settings.service';
export default function SetForm({ export default function SetForm({
save, save,
@ -81,13 +82,15 @@ export default function SetForm({
onSubmitEditing={() => unitRef.current?.focus()} onSubmitEditing={() => unitRef.current?.focus()}
innerRef={weightRef} innerRef={weightRef}
/> />
<MassiveInput {!!settings.showUnit && (
autoCapitalize="none" <MassiveInput
label="Unit" autoCapitalize="none"
value={unit} label="Unit"
onChangeText={setUnit} value={unit}
innerRef={unitRef} onChangeText={setUnit}
/> innerRef={unitRef}
/>
)}
{workouts && ( {workouts && (
<MassiveInput <MassiveInput
label="Todays workout" label="Todays workout"

View File

@ -14,7 +14,7 @@ import {getTodaysPlan} from './plan.service';
import Set from './set'; import Set from './set';
import {defaultSet, getSets, getTodaysSets} from './set.service'; import {defaultSet, getSets, getTodaysSets} from './set.service';
import SetItem from './SetItem'; import SetItem from './SetItem';
import {getSettings} from './settings.service'; import {settings} from './settings.service';
const limit = 15; const limit = 15;
@ -43,8 +43,8 @@ export default function SetList() {
}, [search, refresh]); }, [search, refresh]);
const predict = useCallback(async () => { const predict = useCallback(async () => {
const settings = await getSettings(); console.log(`${SetList.name}.predict:`, {settings});
if (!settings.predict) return; if (!settings.predict) return setSet({...defaultSet});
const todaysPlan = await getTodaysPlan(); const todaysPlan = await getTodaysPlan();
console.log(`${SetList.name}.predict:`, {todaysPlan}); console.log(`${SetList.name}.predict:`, {todaysPlan});
if (todaysPlan.length === 0) return; if (todaysPlan.length === 0) return;
@ -78,7 +78,7 @@ export default function SetList() {
navigation.getParent()?.setOptions({ navigation.getParent()?.setOptions({
headerRight: () => <DrawerMenu name="Home" />, headerRight: () => <DrawerMenu name="Home" />,
}); });
getSettings().then(settings => setImages(!!settings.images)); setImages(!!settings.images);
}, [refresh, predict, navigation]), }, [refresh, predict, navigation]),
); );

View File

@ -1,3 +1,4 @@
import {useFocusEffect} from '@react-navigation/native';
import React, {useCallback, useContext, useEffect, useState} from 'react'; import React, {useCallback, useContext, useEffect, 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';
@ -7,7 +8,7 @@ import {MARGIN} from './constants';
import {SnackbarContext} from './MassiveSnack'; import {SnackbarContext} from './MassiveSnack';
import MassiveSwitch from './MassiveSwitch'; import MassiveSwitch from './MassiveSwitch';
import Page from './Page'; import Page from './Page';
import {getSettings, updateSettings} from './settings.service'; import {getSettings, settings, updateSettings} from './settings.service';
interface Input<T> { interface Input<T> {
name: string; name: string;
@ -25,23 +26,21 @@ 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 [search, setSearch] = useState(''); const [search, setSearch] = useState('');
const [showUnit, setShowUnit] = useState(true);
const {toast} = useContext(SnackbarContext); const {toast} = useContext(SnackbarContext);
const refresh = useCallback(async () => { useFocusEffect(
const settings = await getSettings(); useCallback(() => {
console.log('SettingsPage.refresh:', {settings}); console.log('SettingsPage.refresh:', {settings});
setAlarm(!!settings.alarm); setAlarm(!!settings.alarm);
setPredict(!!settings.predict); setPredict(!!settings.predict);
setVibrate(!!settings.vibrate); setVibrate(!!settings.vibrate);
setSound(settings.sound); setSound(settings.sound);
setNotify(!!settings.notify); setNotify(!!settings.notify);
setImages(!!settings.images); setImages(!!settings.images);
NativeModules.AlarmModule.ignoringBattery(setIgnoring); NativeModules.AlarmModule.ignoringBattery(setIgnoring);
}, []); }, []),
);
useEffect(() => {
refresh();
}, [refresh]);
useEffect(() => { useEffect(() => {
updateSettings({ updateSettings({
@ -51,8 +50,10 @@ export default function SettingsPage() {
sound, sound,
notify: +notify, notify: +notify,
images: +images, images: +images,
showUnit: +showUnit,
}); });
}, [vibrate, alarm, predict, sound, notify, images]); getSettings();
}, [vibrate, alarm, predict, sound, notify, images, showUnit]);
const changeAlarmEnabled = useCallback( const changeAlarmEnabled = useCallback(
(enabled: boolean) => { (enabled: boolean) => {
@ -110,12 +111,22 @@ export default function SettingsPage() {
[toast], [toast],
); );
const changeUnit = useCallback(
(enabled: boolean) => {
setShowUnit(enabled);
if (enabled) toast('Show option to select unit for sets.', 4000);
else toast('Hid the unit option when adding/editing sets.', 4000);
},
[toast],
);
const switches: Input<boolean>[] = [ const switches: Input<boolean>[] = [
{name: 'Rest timers', value: alarm, onChange: changeAlarmEnabled}, {name: 'Rest timers', value: alarm, onChange: changeAlarmEnabled},
{name: 'Vibrate', value: vibrate, onChange: changeVibrate}, {name: 'Vibrate', value: vibrate, onChange: changeVibrate},
{name: 'Predict sets', value: predict, onChange: changePredict}, {name: 'Predict sets', value: predict, onChange: changePredict},
{name: 'Record notifications', value: notify, onChange: changeNotify}, {name: 'Record notifications', value: notify, onChange: changeNotify},
{name: 'Show images', value: images, onChange: changeImages}, {name: 'Show images', value: images, onChange: changeImages},
{name: 'Show unit', value: showUnit, onChange: changeUnit},
]; ];
return ( return (

7
db.ts
View File

@ -3,6 +3,7 @@ import {
openDatabase, openDatabase,
SQLiteDatabase, SQLiteDatabase,
} from 'react-native-sqlite-storage'; } from 'react-native-sqlite-storage';
import {getSettings} from './settings.service';
enablePromise(true); enablePromise(true);
@ -103,6 +104,10 @@ const addSeconds = `
ALTER TABLE sets ADD COLUMN seconds INTEGER NOT NULL DEFAULT 30 ALTER TABLE sets ADD COLUMN seconds INTEGER NOT NULL DEFAULT 30
`; `;
const addShowUnit = `
ALTER TABLE settings ADD COLUMN showUnit BOOLEAN DEFAULT true;
`;
export let db: SQLiteDatabase; export let db: SQLiteDatabase;
export const migrations = async () => { export const migrations = async () => {
@ -124,8 +129,10 @@ export const migrations = async () => {
await db.executeSql(addSets).catch(() => null); await db.executeSql(addSets).catch(() => null);
await db.executeSql(addMinutes).catch(() => null); await db.executeSql(addMinutes).catch(() => null);
await db.executeSql(addSeconds).catch(() => null); await db.executeSql(addSeconds).catch(() => null);
await db.executeSql(addShowUnit).catch(() => null);
const [result] = await db.executeSql(selectSettings); const [result] = await db.executeSql(selectSettings);
if (result.rows.length === 0) await db.executeSql(insertSettings); if (result.rows.length === 0) await db.executeSql(insertSettings);
await getSettings();
}; };
export interface PageParams { export interface PageParams {

View File

@ -1,10 +1,11 @@
import {db} from './db'; import {db} from './db';
import Settings from './settings'; import Settings from './settings';
export let settings: Settings;
export const getSettings = async () => { export const getSettings = async () => {
const [result] = await db.executeSql(`SELECT * FROM settings LIMIT 1`); const [result] = await db.executeSql(`SELECT * FROM settings LIMIT 1`);
const settings: Settings = result.rows.item(0); settings = result.rows.item(0);
return settings;
}; };
export const updateSettings = async (value: Settings) => { export const updateSettings = async (value: Settings) => {

View File

@ -5,4 +5,5 @@ export default interface Settings {
sound: string; sound: string;
notify: number; notify: number;
images: number; images: number;
showUnit: number;
} }