Allow editing of multiple workouts
This commit is contained in:
parent
9fbae74a01
commit
8e42e9c3e4
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
NavigationProp,
|
||||||
RouteProp,
|
RouteProp,
|
||||||
useFocusEffect,
|
useFocusEffect,
|
||||||
useNavigation,
|
useNavigation,
|
||||||
|
@ -12,9 +13,8 @@ import { In } from "typeorm";
|
||||||
import AppInput from "./AppInput";
|
import AppInput from "./AppInput";
|
||||||
import ConfirmDialog from "./ConfirmDialog";
|
import ConfirmDialog from "./ConfirmDialog";
|
||||||
import { MARGIN, PADDING } from "./constants";
|
import { MARGIN, PADDING } from "./constants";
|
||||||
import { getNow, planRepo, setRepo, settingsRepo } from "./db";
|
import { planRepo, setRepo, settingsRepo } from "./db";
|
||||||
import { fixNumeric } from "./fix-numeric";
|
import { fixNumeric } from "./fix-numeric";
|
||||||
import { defaultSet } from "./gym-set";
|
|
||||||
import Settings from "./settings";
|
import Settings from "./settings";
|
||||||
import StackHeader from "./StackHeader";
|
import StackHeader from "./StackHeader";
|
||||||
import { toast } from "./toast";
|
import { toast } from "./toast";
|
||||||
|
@ -29,14 +29,13 @@ export default function EditWorkouts() {
|
||||||
const [steps, setSteps] = useState("");
|
const [steps, setSteps] = useState("");
|
||||||
const [oldSteps, setOldSteps] = useState("");
|
const [oldSteps, setOldSteps] = useState("");
|
||||||
const [uri, setUri] = useState("");
|
const [uri, setUri] = useState("");
|
||||||
const [oldUri, setOldUri] = useState("");
|
|
||||||
const [minutes, setMinutes] = useState("");
|
const [minutes, setMinutes] = useState("");
|
||||||
const [oldMinutes, setOldMinutes] = useState("");
|
const [oldMinutes, setOldMinutes] = useState("");
|
||||||
const [seconds, setSeconds] = useState("");
|
const [seconds, setSeconds] = useState("");
|
||||||
const [oldSeconds, setOldSeconds] = useState("");
|
const [oldSeconds, setOldSeconds] = useState("");
|
||||||
const [sets, setSets] = useState("");
|
const [sets, setSets] = useState("");
|
||||||
const [oldSets, setOldSets] = useState("");
|
const [oldSets, setOldSets] = useState("");
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation<NavigationProp<WorkoutsPageParams>>();
|
||||||
const setsRef = useRef<TextInput>(null);
|
const setsRef = useRef<TextInput>(null);
|
||||||
const stepsRef = useRef<TextInput>(null);
|
const stepsRef = useRef<TextInput>(null);
|
||||||
const minutesRef = useRef<TextInput>(null);
|
const minutesRef = useRef<TextInput>(null);
|
||||||
|
@ -56,7 +55,9 @@ export default function EditWorkouts() {
|
||||||
console.log({ gymSets });
|
console.log({ gymSets });
|
||||||
setOldNames(gymSets.map((set) => set.name).join(", "));
|
setOldNames(gymSets.map((set) => set.name).join(", "));
|
||||||
setOldSteps(gymSets.map((set) => set.steps).join(", "));
|
setOldSteps(gymSets.map((set) => set.steps).join(", "));
|
||||||
setOldUri(gymSets.map((set) => set.steps).join(", "));
|
setOldMinutes(gymSets.map((set) => set.minutes).join(", "));
|
||||||
|
setOldSeconds(gymSets.map((set) => set.seconds).join(", "));
|
||||||
|
setOldSets(gymSets.map((set) => set.sets).join(", "));
|
||||||
});
|
});
|
||||||
}, [params.names])
|
}, [params.names])
|
||||||
);
|
);
|
||||||
|
@ -73,36 +74,17 @@ export default function EditWorkouts() {
|
||||||
image: removeImage ? "" : uri,
|
image: removeImage ? "" : uri,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
await planRepo
|
for (const oldName of params.names) {
|
||||||
.createQueryBuilder()
|
await planRepo
|
||||||
.update()
|
.createQueryBuilder()
|
||||||
.set({
|
.update()
|
||||||
workouts: () => `REPLACE(workouts, '${params.gymSet.name}', '${name}')`,
|
.set({
|
||||||
})
|
workouts: () => `REPLACE(workouts, '${oldName}', '${name}')`,
|
||||||
.where("workouts LIKE :name", { name: `%${params.gymSet.name}%` })
|
})
|
||||||
.execute();
|
.where("workouts LIKE :name", { name: `%${oldName}%` })
|
||||||
navigation.goBack();
|
.execute();
|
||||||
};
|
}
|
||||||
|
navigation.navigate("WorkoutList", { clearNames: true });
|
||||||
const add = async () => {
|
|
||||||
const now = await getNow();
|
|
||||||
await setRepo.save({
|
|
||||||
...defaultSet,
|
|
||||||
name,
|
|
||||||
hidden: true,
|
|
||||||
image: uri,
|
|
||||||
minutes: minutes ? +minutes : 3,
|
|
||||||
seconds: seconds ? +seconds : 30,
|
|
||||||
sets: sets ? +sets : 3,
|
|
||||||
steps,
|
|
||||||
created: now,
|
|
||||||
});
|
|
||||||
navigation.goBack();
|
|
||||||
};
|
|
||||||
|
|
||||||
const save = async () => {
|
|
||||||
if (params.gymSet.name) return update();
|
|
||||||
return add();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeImage = useCallback(async () => {
|
const changeImage = useCallback(async () => {
|
||||||
|
@ -126,14 +108,12 @@ export default function EditWorkouts() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<StackHeader
|
<StackHeader title={`Edit ${params.names.length} workouts`} />
|
||||||
title={params.gymSet.name ? "Edit workout" : "Add workout"}
|
|
||||||
/>
|
|
||||||
<View style={{ padding: PADDING, flex: 1 }}>
|
<View style={{ padding: PADDING, flex: 1 }}>
|
||||||
<ScrollView style={{ flex: 1 }}>
|
<ScrollView style={{ flex: 1 }}>
|
||||||
<AppInput
|
<AppInput
|
||||||
autoFocus
|
autoFocus
|
||||||
label="Name"
|
label={`Names: ${oldNames}`}
|
||||||
value={name}
|
value={name}
|
||||||
onChangeText={setName}
|
onChangeText={setName}
|
||||||
onSubmitEditing={submitName}
|
onSubmitEditing={submitName}
|
||||||
|
@ -144,7 +124,7 @@ export default function EditWorkouts() {
|
||||||
selectTextOnFocus={false}
|
selectTextOnFocus={false}
|
||||||
value={steps}
|
value={steps}
|
||||||
onChangeText={setSteps}
|
onChangeText={setSteps}
|
||||||
label="Steps"
|
label={`Steps: ${oldSteps}`}
|
||||||
multiline
|
multiline
|
||||||
onSubmitEditing={() => setsRef.current?.focus()}
|
onSubmitEditing={() => setsRef.current?.focus()}
|
||||||
/>
|
/>
|
||||||
|
@ -158,7 +138,7 @@ export default function EditWorkouts() {
|
||||||
if (fixed.length !== newSets.length)
|
if (fixed.length !== newSets.length)
|
||||||
toast("Sets must be a number");
|
toast("Sets must be a number");
|
||||||
}}
|
}}
|
||||||
label="Sets per workout"
|
label={`Sets: ${oldSets}`}
|
||||||
keyboardType="numeric"
|
keyboardType="numeric"
|
||||||
onSubmitEditing={() => minutesRef.current?.focus()}
|
onSubmitEditing={() => minutesRef.current?.focus()}
|
||||||
/>
|
/>
|
||||||
|
@ -174,14 +154,14 @@ export default function EditWorkouts() {
|
||||||
if (fixed.length !== newMinutes.length)
|
if (fixed.length !== newMinutes.length)
|
||||||
toast("Reps must be a number");
|
toast("Reps must be a number");
|
||||||
}}
|
}}
|
||||||
label="Rest minutes"
|
label={`Rest minutes: ${oldMinutes}`}
|
||||||
keyboardType="numeric"
|
keyboardType="numeric"
|
||||||
/>
|
/>
|
||||||
<AppInput
|
<AppInput
|
||||||
innerRef={secondsRef}
|
innerRef={secondsRef}
|
||||||
value={seconds}
|
value={seconds}
|
||||||
onChangeText={setSeconds}
|
onChangeText={setSeconds}
|
||||||
label="Rest seconds"
|
label={`Rest seconds: ${oldSeconds}`}
|
||||||
keyboardType="numeric"
|
keyboardType="numeric"
|
||||||
blurOnSubmit
|
blurOnSubmit
|
||||||
/>
|
/>
|
||||||
|
@ -206,7 +186,7 @@ export default function EditWorkouts() {
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<Button disabled={!name} mode="outlined" icon="save" onPress={save}>
|
<Button disabled={!name} mode="outlined" icon="save" onPress={update}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
|
|
|
@ -25,7 +25,7 @@ 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");
|
||||||
return `${item.sets} x ${item.minutes || 0}:${seconds}`;
|
return `${item.sets} x ${item.minutes || 0}:${seconds}`;
|
||||||
}, [item]);
|
}, [item.sets, item.minutes, item.seconds]);
|
||||||
|
|
||||||
const left = useCallback(() => {
|
const left = useCallback(() => {
|
||||||
if (!images || !item.image) return null;
|
if (!images || !item.image) return null;
|
||||||
|
@ -34,10 +34,10 @@ export default function WorkoutItem({
|
||||||
);
|
);
|
||||||
}, [item.image, images]);
|
}, [item.image, images]);
|
||||||
|
|
||||||
const long = useCallback(() => {
|
const long = () => {
|
||||||
if (names.length > 0) return;
|
if (names.length > 0) return;
|
||||||
setNames([item.name]);
|
setNames([item.name]);
|
||||||
}, [names.length, item.name, setNames]);
|
};
|
||||||
|
|
||||||
const backgroundColor = useMemo(() => {
|
const backgroundColor = useMemo(() => {
|
||||||
if (!names.includes(item.name)) return;
|
if (!names.includes(item.name)) return;
|
||||||
|
@ -45,13 +45,14 @@ export default function WorkoutItem({
|
||||||
return LIGHT_RIPPLE;
|
return LIGHT_RIPPLE;
|
||||||
}, [dark, names, item.name]);
|
}, [dark, names, item.name]);
|
||||||
|
|
||||||
const press = useCallback(() => {
|
const press = () => {
|
||||||
|
console.log({ names });
|
||||||
if (names.length === 0)
|
if (names.length === 0)
|
||||||
return navigation.navigate("EditWorkout", { gymSet: item });
|
return navigation.navigate("EditWorkout", { gymSet: item });
|
||||||
const removing = names.find((name) => name === item.name);
|
const removing = names.find((name) => name === item.name);
|
||||||
if (removing) setNames(names.filter((name) => name !== item.name));
|
if (removing) setNames(names.filter((name) => name !== item.name));
|
||||||
else setNames([...names, item.name]);
|
else setNames([...names, item.name]);
|
||||||
}, [names, item, navigation, setNames]);
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<List.Item
|
<List.Item
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
import {
|
import {
|
||||||
NavigationProp,
|
NavigationProp,
|
||||||
|
RouteProp,
|
||||||
useFocusEffect,
|
useFocusEffect,
|
||||||
useNavigation,
|
useNavigation,
|
||||||
|
useRoute,
|
||||||
} from "@react-navigation/native";
|
} from "@react-navigation/native";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, 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 { In } from "typeorm";
|
||||||
import { LIMIT } from "./constants";
|
import { LIMIT } from "./constants";
|
||||||
import { setRepo, settingsRepo } from "./db";
|
import { setRepo, settingsRepo } from "./db";
|
||||||
import DrawerHeader from "./DrawerHeader";
|
import DrawerHeader from "./DrawerHeader";
|
||||||
|
@ -25,6 +28,7 @@ export default function WorkoutList() {
|
||||||
const [settings, setSettings] = useState<Settings>();
|
const [settings, setSettings] = useState<Settings>();
|
||||||
const [names, setNames] = useState<string[]>([]);
|
const [names, setNames] = useState<string[]>([]);
|
||||||
const navigation = useNavigation<NavigationProp<WorkoutsPageParams>>();
|
const navigation = useNavigation<NavigationProp<WorkoutsPageParams>>();
|
||||||
|
const { params } = useRoute<RouteProp<WorkoutsPageParams, "WorkoutList">>();
|
||||||
|
|
||||||
const refresh = useCallback(async (value: string) => {
|
const refresh = useCallback(async (value: string) => {
|
||||||
const newWorkouts = await setRepo
|
const newWorkouts = await setRepo
|
||||||
|
@ -45,7 +49,8 @@ export default function WorkoutList() {
|
||||||
useCallback(() => {
|
useCallback(() => {
|
||||||
refresh(term);
|
refresh(term);
|
||||||
settingsRepo.findOne({ where: {} }).then(setSettings);
|
settingsRepo.findOne({ where: {} }).then(setSettings);
|
||||||
}, [refresh, term])
|
if (params?.clearNames) setNames([]);
|
||||||
|
}, [refresh, term, params])
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderItem = useCallback(
|
const renderItem = useCallback(
|
||||||
|
@ -106,7 +111,7 @@ export default function WorkoutList() {
|
||||||
|
|
||||||
const remove = async () => {
|
const remove = async () => {
|
||||||
setNames([]);
|
setNames([]);
|
||||||
await setRepo.delete(names.length > 0 ? names : {});
|
if (names.length > 0) await setRepo.delete({ name: In(names) });
|
||||||
await refresh(term);
|
await refresh(term);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,11 +119,15 @@ export default function WorkoutList() {
|
||||||
setNames(workouts.map((workout) => workout.name));
|
setNames(workouts.map((workout) => workout.name));
|
||||||
};
|
};
|
||||||
|
|
||||||
const edit = useCallback(() => {}, []);
|
const edit = () => {
|
||||||
|
navigation.navigate("EditWorkouts", { names });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DrawerHeader name="Workouts">
|
<DrawerHeader
|
||||||
|
name={names.length > 0 ? `${names.length} selected` : "Workouts"}
|
||||||
|
>
|
||||||
<ListMenu
|
<ListMenu
|
||||||
onClear={clear}
|
onClear={clear}
|
||||||
onDelete={remove}
|
onDelete={remove}
|
||||||
|
@ -131,7 +140,7 @@ export default function WorkoutList() {
|
||||||
{workouts?.length === 0 ? (
|
{workouts?.length === 0 ? (
|
||||||
<List.Item
|
<List.Item
|
||||||
title="No workouts yet."
|
title="No workouts yet."
|
||||||
description="A workout is something you do at the gym. For example Deadlifts are a workout."
|
description="A workout is something you do at the gym. E.g. Deadlifts"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<FlatList
|
<FlatList
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import { createStackNavigator } from "@react-navigation/stack";
|
import { createStackNavigator } from "@react-navigation/stack";
|
||||||
import EditWorkout from "./EditWorkout";
|
import EditWorkout from "./EditWorkout";
|
||||||
|
import EditWorkouts from "./EditWorkouts";
|
||||||
import GymSet from "./gym-set";
|
import GymSet from "./gym-set";
|
||||||
import WorkoutList from "./WorkoutList";
|
import WorkoutList from "./WorkoutList";
|
||||||
|
|
||||||
export type WorkoutsPageParams = {
|
export type WorkoutsPageParams = {
|
||||||
WorkoutList: {};
|
WorkoutList: {
|
||||||
|
clearNames?: boolean;
|
||||||
|
};
|
||||||
EditWorkout: {
|
EditWorkout: {
|
||||||
gymSet: GymSet;
|
gymSet: GymSet;
|
||||||
};
|
};
|
||||||
|
@ -22,6 +25,7 @@ export default function WorkoutsPage() {
|
||||||
>
|
>
|
||||||
<Stack.Screen name="WorkoutList" component={WorkoutList} />
|
<Stack.Screen name="WorkoutList" component={WorkoutList} />
|
||||||
<Stack.Screen name="EditWorkout" component={EditWorkout} />
|
<Stack.Screen name="EditWorkout" component={EditWorkout} />
|
||||||
|
<Stack.Screen name="EditWorkouts" component={EditWorkouts} />
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user