Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default {
expo: {
name: IS_DEV ? "Muscle Quest (Dev)" : "Muscle Quest",
slug: "musclequest",
version: "0.21.04", // MM.mm.pp
version: "0.21.05", // MM.mm.pp
orientation: "portrait",
icon: "./assets/images/icon.png",
scheme: "musclequest",
Expand All @@ -14,7 +14,7 @@ export default {
bundleIdentifier: "com.isotronic.musclequest",
},
android: {
versionCode: 2104, // MMmmpp
versionCode: 2105, // MMmmpp
googleServicesFile: "./google-services.json",
adaptiveIcon: {
foregroundImage: "./assets/images/ic_launcher_foreground.png",
Expand Down
66 changes: 54 additions & 12 deletions app/(app)/(create-plan)/exercises.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,19 @@ export default function ExercisesScreen() {
newExerciseId,
setNewExerciseId,
replaceExercise,
createSuperset,
} = useWorkoutStore();
const { index } = useLocalSearchParams();
const { index, supersetForIndex } = useLocalSearchParams<{
index: string;
supersetForIndex?: string;
}>();
const currentWorkoutIndex = Number(index);
const currentWorkout = workouts[currentWorkoutIndex];
const replacing = replaceExerciseIndex !== undefined;
const supersetMode = supersetForIndex !== undefined;
const supersetForExerciseIndex = supersetMode
? Number(supersetForIndex)
: undefined;

const {
data: settings,
Expand All @@ -67,7 +75,7 @@ export default function ExercisesScreen() {
const [selectedExercises, setSelectedExercises] = useState<number[]>([]);

useEffect(() => {
if (currentWorkout?.exercises && !replacing) {
if (currentWorkout?.exercises && !replacing && !supersetMode) {
const existingExerciseIds = currentWorkout.exercises.map(
(exercise) => exercise.exercise_id,
);
Expand All @@ -84,7 +92,13 @@ export default function ExercisesScreen() {
// Clear the newExerciseId after it's used
setNewExerciseId(null);
}
}, [currentWorkout, newExerciseId, replacing, setNewExerciseId]);
}, [
currentWorkout,
newExerciseId,
replacing,
supersetMode,
setNewExerciseId,
]);

const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
Expand All @@ -102,13 +116,38 @@ export default function ExercisesScreen() {

const handleSelectExercise = useCallback(
(exerciseId: number) => {
if (replacing) {
// Check if this exercise already exists in the current workout
const workout = workouts[currentWorkoutIndex];
const exerciseAlreadyExists = workout.exercises.some(
(e) => e.exercise_id === exerciseId,
);
const workout = workouts[currentWorkoutIndex];
const exerciseAlreadyExists = workout?.exercises.some(
(e) => e.exercise_id === exerciseId,
);

if (supersetMode) {
// Single-select: pair as superset partner
if (exerciseAlreadyExists) {
Alert.alert(
"Exercise Already Added",
"This exercise is already in your workout. Please choose a different one.",
[{ text: "OK" }],
);
return;
}
const exercise = allExercises.find(
(ex) => ex.exercise_id === exerciseId,
);
if (exercise && supersetForExerciseIndex !== undefined) {
const newExercise = {
...exercise,
sets:
exercise.tracking_type === "time" ? defaultTimeSets : defaultSets,
};
createSuperset(
currentWorkoutIndex,
supersetForExerciseIndex,
newExercise,
);
router.back();
}
} else if (replacing) {
if (exerciseAlreadyExists) {
Alert.alert(
"Exercise Already Added",
Expand All @@ -134,7 +173,7 @@ export default function ExercisesScreen() {
defaultSets,
defaultTimeSets,
);
router.back(); // Return immediately after replacement
router.back();
}
} else {
// Normal add mode - allow multiple selections
Expand All @@ -146,14 +185,17 @@ export default function ExercisesScreen() {
}
},
[
supersetMode,
supersetForExerciseIndex,
replacing,
allExercises,
replaceExerciseIndex,
defaultTimeSets,
defaultSets,
replaceExercise,
createSuperset,
currentWorkoutIndex,
workouts, // Make sure 'workouts' is included in dependencies
workouts,
],
);

Expand Down Expand Up @@ -280,7 +322,7 @@ export default function ExercisesScreen() {
});
}}
/>
{!replacing && (
{!replacing && !supersetMode && (
<View style={styles.bottomButtons}>
<Button
mode="outlined"
Expand Down
42 changes: 41 additions & 1 deletion app/(app)/(create-plan)/sets-overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,19 @@ export default function SetsOverviewScreen() {
const defaultTime = 60;
const defaultTotalSeconds = totalSeconds;

const exercise = workouts[Number(workoutIndex)]?.exercises.find(
const currentWorkout = workouts[Number(workoutIndex)];
const exercise = currentWorkout?.exercises.find(
(ex) => ex.exercise_id === Number(exerciseId),
);

const supersetPartner = exercise?.supersetGroupId
? currentWorkout?.exercises.find(
(ex) =>
ex.exercise_id !== Number(exerciseId) &&
ex.supersetGroupId === exercise.supersetGroupId,
)
: null;

const sets = exercise?.sets || [];

const [modalVisible, setModalVisible] = useState(false);
Expand Down Expand Up @@ -102,6 +111,14 @@ export default function SetsOverviewScreen() {
title: exercise?.name,
}}
/>
{supersetPartner && (
<View style={styles.supersetBanner}>
<ThemedText style={styles.supersetBannerLabel}>Superset</ThemedText>
<ThemedText style={styles.supersetBannerPartner}>
Paired with {supersetPartner.name}
</ThemedText>
</View>
)}
<FlatList
data={sets}
renderItem={renderSetItem}
Expand Down Expand Up @@ -149,6 +166,29 @@ const styles = StyleSheet.create({
flex: 1,
padding: 16,
},
supersetBanner: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
backgroundColor: Colors.dark.cardBackground,
borderLeftWidth: 3,
borderLeftColor: Colors.dark.tint,
borderRadius: 8,
paddingHorizontal: 14,
paddingVertical: 10,
marginBottom: 12,
},
supersetBannerLabel: {
fontSize: 12,
fontWeight: "700",
color: Colors.dark.tint,
textTransform: "uppercase",
letterSpacing: 1,
},
supersetBannerPartner: {
fontSize: 13,
color: Colors.dark.subText,
},
setItem: {
backgroundColor: Colors.dark.cardBackground,
padding: 16,
Expand Down
Loading
Loading