From 85dd2b6d17de2081dda7f4ea82e5cbdae914a9b4 Mon Sep 17 00:00:00 2001 From: Brandon Presley Date: Wed, 21 Sep 2022 11:50:20 +1200 Subject: [PATCH] Move rest timer and sets per session settings to Workouts Closes #32 --- EditPlan.tsx | 3 +- EditSet.tsx | 15 +-- EditWorkout.tsx | 93 +++++++++++++----- PlanItem.tsx | 2 +- PlanList.tsx | 2 +- SetForm.tsx | 61 ++++++++---- SetItem.tsx | 4 +- SetList.tsx | 15 +-- SettingsPage.tsx | 35 +------ WorkoutItem.tsx | 4 + WorkoutList.tsx | 2 +- best.service.ts | 2 +- db.ts | 30 ++++++ .../en-US/images/phoneScreenshots/edit.png | Bin 115697 -> 85944 bytes .../images/phoneScreenshots/settings.png | Bin 100558 -> 89184 bytes .../en-US/images/phoneScreenshots/workout.png | Bin 0 -> 79083 bytes plan.service.ts | 2 +- set.service.ts | 34 +++++-- set.ts | 5 +- settings.ts | 3 - workout.service.ts | 11 ++- workout.ts | 2 + 22 files changed, 214 insertions(+), 111 deletions(-) create mode 100644 metadata/en-US/images/phoneScreenshots/workout.png diff --git a/EditPlan.tsx b/EditPlan.tsx index 91436ca..5abc071 100644 --- a/EditPlan.tsx +++ b/EditPlan.tsx @@ -53,7 +53,8 @@ export default function EditPlan() { if (!days || !workouts) return; const newWorkouts = workouts.filter(workout => workout).join(','); const newDays = days.filter(day => day).join(','); - if (!plan.id) await addPlan({days: newDays, workouts: newWorkouts}); + if (typeof plan.id === 'undefined') + await addPlan({days: newDays, workouts: newWorkouts}); else await updatePlan({ days: newDays, diff --git a/EditSet.tsx b/EditSet.tsx index 23e182f..d113e97 100644 --- a/EditSet.tsx +++ b/EditSet.tsx @@ -22,20 +22,22 @@ export default function EditSet() { useFocusEffect( useCallback(() => { + console.log(`${EditSet.name}.focus:`, params); navigation.getParent()?.setOptions({ headerLeft: () => ( navigation.goBack()} /> ), headerRight: null, - title: params.set.id ? 'Edit set' : 'Create set', + title: typeof params.set.id === 'number' ? 'Edit set' : 'Create set', }); - }, [navigation, params.set.id]), + }, [navigation, params]), ); - const startTimer = useCallback(async () => { + const startTimer = useCallback(async (set: Set) => { const settings = await getSettings(); if (!settings.alarm) return; - const milliseconds = settings.minutes * 60 * 1000 + settings.seconds * 1000; + const milliseconds = + Number(set.minutes) * 60 * 1000 + Number(set.seconds) * 1000; NativeModules.AlarmModule.timer( milliseconds, !!settings.vibrate, @@ -54,7 +56,8 @@ export default function EditSet() { const add = useCallback( async (set: Set) => { - startTimer(); + console.log(`${EditSet.name}.add`, {set}); + startTimer(set); await addSet(set); const settings = await getSettings(); if (settings.notify === 0) return navigation.goBack(); @@ -70,7 +73,7 @@ export default function EditSet() { const save = useCallback( async (set: Set) => { - if (params.set.id) return update(set); + if (typeof params.set.id === 'number') return update(set); return add(set); }, [update, add, params.set.id], diff --git a/EditWorkout.tsx b/EditWorkout.tsx index f06421a..760f1ab 100644 --- a/EditWorkout.tsx +++ b/EditWorkout.tsx @@ -11,20 +11,28 @@ import {Button, Card, IconButton, TouchableRipple} from 'react-native-paper'; import ConfirmDialog from './ConfirmDialog'; import {MARGIN, PADDING} from './constants'; import MassiveInput from './MassiveInput'; -import {updateWorkouts} from './plan.service'; +import {updatePlanWorkouts} from './plan.service'; import Set from './set'; -import {addSet, getSets, updateSetImage, updateSetName} from './set.service'; +import {addSet, getSets, updateManySet, updateSetImage} from './set.service'; import Workout from './workout'; -import {addWorkout, getWorkout, updateSteps} from './workout.service'; +import { + addWorkout, + getWorkout, + updateName, + updateSteps, +} from './workout.service'; import {WorkoutsPageParams} from './WorkoutsPage'; export default function EditWorkout() { - const [name, setName] = useState(''); + const {params} = useRoute>(); + const [name, setName] = useState(params.value.name); const [removeImage, setRemoveImage] = useState(false); const [showRemove, setShowRemove] = useState(false); const [steps, setSteps] = useState(''); const [uri, setUri] = useState(); - const {params} = useRoute>(); + const [minutes, setMinutes] = useState(''); + const [seconds, setSeconds] = useState(''); + const [sets, setSets] = useState(''); const navigation = useNavigation(); useFocusEffect( @@ -37,39 +45,60 @@ export default function EditWorkout() { title: params.value.name ? params.value.name : 'New workout', }); if (!params.value.name) return; - getSets({search: params.value.name, limit: 1, offset: 0}).then(sets => - setUri(sets[0]?.image), + getSets({search: params.value.name, limit: 1, offset: 0}).then( + ([set]) => { + if (!set) return; + setUri(set.image); + setMinutes(set.minutes?.toString() ?? '3'); + setSeconds(set.seconds?.toString() ?? '30'); + setSets(set.sets?.toString() ?? '3'); + }, ); + console.log(`${EditWorkout.name}.focus`, {params}); getWorkout(params.value.name).then(workout => setSteps(workout.steps)); - }, [navigation, params.value.name]), + }, [navigation, params]), ); - const update = useCallback(async () => { + const update = async () => { console.log(`${EditWorkout.name}.update`, { params: params.value.name, name, uri, steps, }); - if (name) { - await updateSetName(params.value.name, name); - await updateWorkouts(params.value.name, name); - } + await updateManySet({ + oldName: params.value.name, + newName: name || params.value.name, + sets, + seconds, + minutes, + }); + await updatePlanWorkouts(params.value.name, name || params.value.name); + await updateName(params.value.name, name); if (uri || removeImage) await updateSetImage(params.value.name, uri || ''); if (steps) await updateSteps(params.value.name, steps); navigation.goBack(); - }, [navigation, params.value.name, name, uri, steps, removeImage]); + }; - const add = useCallback(async () => { - await addSet({name, reps: 0, weight: 0, hidden: true, image: uri} as Set); - await addWorkout({name, steps} as Workout); + const add = async () => { + await addSet({ + name, + reps: 0, + weight: 0, + hidden: true, + image: uri, + minutes: +minutes, + seconds: +seconds, + sets: +sets, + } as Set); + addWorkout({name, steps} as Workout); navigation.goBack(); - }, [navigation, name, steps, uri]); + }; - const save = useCallback(async () => { + const save = async () => { if (params.value.name) return update(); return add(); - }, [update, add, params.value.name]); + }; const changeImage = useCallback(async () => { const {fileCopyUri} = await DocumentPicker.pickSingle({ @@ -88,11 +117,7 @@ export default function EditWorkout() { return ( - + + + + {uri ? ( >(); const remove = useCallback(async () => { - if (item.id) await deletePlan(item.id); + if (typeof item.id === 'number') await deletePlan(item.id); setShow(false); onRemove(); }, [setShow, item.id, onRemove]); diff --git a/PlanList.tsx b/PlanList.tsx index 1483ed9..700479c 100644 --- a/PlanList.tsx +++ b/PlanList.tsx @@ -43,7 +43,7 @@ export default function PlanList() { ); const onAdd = () => - navigation.navigate('EditPlan', {plan: {days: '', workouts: '', id: 0}}); + navigation.navigate('EditPlan', {plan: {days: '', workouts: ''}}); return ( diff --git a/SetForm.tsx b/SetForm.tsx index a58071c..be3fa8d 100644 --- a/SetForm.tsx +++ b/SetForm.tsx @@ -1,6 +1,6 @@ import React, {useEffect, useRef, useState} from 'react'; -import {ScrollView} from 'react-native'; -import {Button, Text} from 'react-native-paper'; +import {ScrollView, View} from 'react-native'; +import {Button} from 'react-native-paper'; import {MARGIN} from './constants'; import MassiveInput from './MassiveInput'; import Set from './set'; @@ -20,18 +20,23 @@ export default function SetForm({ const [weight, setWeight] = useState(set.weight.toString()); const [unit, setUnit] = useState(set.unit); const [uri, setUri] = useState(set.image); + const [minutes, setMinutes] = useState(set.minutes?.toString()); + const [seconds, setSeconds] = useState(set.seconds?.toString()); const [selection, setSelection] = useState({ start: 0, end: set.reps.toString().length, }); const weightRef = useRef(null); const repsRef = useRef(null); + const unitRef = useRef(null); + const minutesRef = useRef(null); + const secondsRef = useRef(null); useEffect(() => { console.log('SetForm.useEffect:', {uri, name: set.name}); if (!uri) - getSets({search: set.name, limit: 1, offset: 0}).then(sets => - setUri(sets[0]?.image), + getSets({search: set.name, limit: 1, offset: 0}).then(([s]) => + setUri(s?.image), ); }, [uri, set.name]); @@ -44,6 +49,9 @@ export default function SetForm({ id: set.id, unit, image: uri, + minutes: Number(minutes ?? 3), + seconds: Number(seconds ?? 30), + sets: set.sets ?? 3, }); }; @@ -75,7 +83,7 @@ export default function SetForm({ keyboardType="numeric" value={weight} onChangeText={setWeight} - onSubmitEditing={handleSubmit} + onSubmitEditing={() => unitRef.current?.focus()} innerRef={weightRef} /> minutesRef.current?.focus()} + innerRef={unitRef} /> - - {workouts?.map((workout, index) => ( - - - {workout} - - {index === workouts.length - 1 ? '.' : ', '} - - ))} - + {workouts && ( + + )} + {!set.id && ( + + secondsRef.current?.focus()} + /> + + + )}