Timer implemented. No working tests.
This commit is contained in:
@@ -7,6 +7,9 @@ import ExerciseModal from '../ExerciseModal';
|
||||
import { useTracker } from './useTracker';
|
||||
import SetLogger from './SetLogger';
|
||||
import { formatSetMetrics } from '../../utils/setFormatting';
|
||||
import { useAuth } from '../../context/AuthContext';
|
||||
import { api } from '../../services/api';
|
||||
import RestTimerFAB from '../ui/RestTimerFAB';
|
||||
|
||||
interface ActiveSessionViewProps {
|
||||
tracker: ReturnType<typeof useTracker>;
|
||||
@@ -71,6 +74,61 @@ const ActiveSessionView: React.FC<ActiveSessionViewProps> = ({ tracker, activeSe
|
||||
exercises
|
||||
} = tracker;
|
||||
|
||||
const { currentUser, updateUser } = useAuth();
|
||||
|
||||
// Timer Logic is now managed in useTracker to persist across re-renders/step changes
|
||||
const { timer } = tracker;
|
||||
|
||||
const handleLogSet = async () => {
|
||||
await handleAddSet();
|
||||
|
||||
// Determine next rest time
|
||||
let nextTime = currentUser?.profile?.restTimerDefault || 120;
|
||||
|
||||
if (activePlan) {
|
||||
// Logic: activePlan set just added. We are moving to next step?
|
||||
// Tracker's handleAddSet calls addSet -> which calls ActiveWorkoutContext's addSet -> which increments currentStepIndex (logic inside context)
|
||||
// But state update might be async or we might need to look at current index before update?
|
||||
// Usually we want the rest time AFTER the set we just did.
|
||||
// The user just configured the set for the *current* step index.
|
||||
// So we look at activePlan.steps[currentStepIndex].restTime.
|
||||
// BUT, if the user just finished step 0, and step 0 says "Rest 60s", then we rest 60s.
|
||||
// If fallback, use default.
|
||||
|
||||
// Note: currentStepIndex might update immediately or after render.
|
||||
// In a real app, we might get the next set's target time? No, rest is usually associated with the fatigue of the set just done.
|
||||
// Requirement: "rest time after this set".
|
||||
// So we use currentStepIndex (which likely points to the set we just logged, assuming UI hasn't advanced yet?
|
||||
// Actually, handleAddSet likely appends set. Context might auto-advance.
|
||||
// Let's assume we use the restTime of the step that matches the set just logged.
|
||||
|
||||
const currentStep = activePlan.steps[currentStepIndex];
|
||||
if (currentStep && currentStep.restTimeSeconds) {
|
||||
nextTime = currentStep.restTimeSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
if (timer.status !== 'RUNNING') {
|
||||
timer.reset(nextTime);
|
||||
timer.start();
|
||||
}
|
||||
};
|
||||
|
||||
const handleDurationChange = async (newVal: number) => {
|
||||
// Update user profile
|
||||
try {
|
||||
await api.patch('/auth/profile', { restTimerDefault: newVal });
|
||||
if (currentUser) {
|
||||
updateUser({
|
||||
...currentUser,
|
||||
profile: { ...currentUser.profile, restTimerDefault: newVal }
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to update default timer", e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
const isPlanFinished = activePlan && currentStepIndex >= activePlan.steps.length;
|
||||
@@ -177,7 +235,7 @@ const ActiveSessionView: React.FC<ActiveSessionViewProps> = ({ tracker, activeSe
|
||||
<SetLogger
|
||||
tracker={tracker}
|
||||
lang={lang}
|
||||
onLogSet={handleAddSet}
|
||||
onLogSet={handleLogSet}
|
||||
/>
|
||||
|
||||
{activeSession.sets.length > 0 && (
|
||||
@@ -397,6 +455,8 @@ const ActiveSessionView: React.FC<ActiveSessionViewProps> = ({ tracker, activeSe
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<RestTimerFAB timer={timer} onDurationChange={handleDurationChange} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,10 @@ import ExerciseModal from '../ExerciseModal';
|
||||
import { useTracker } from './useTracker';
|
||||
import SetLogger from './SetLogger';
|
||||
import { formatSetMetrics } from '../../utils/setFormatting';
|
||||
import { useAuth } from '../../context/AuthContext';
|
||||
import { api } from '../../services/api';
|
||||
// import { useRestTimer } from '../../hooks/useRestTimer'; // Not needed if using tracker.timer
|
||||
import RestTimerFAB from '../ui/RestTimerFAB';
|
||||
|
||||
interface SporadicViewProps {
|
||||
tracker: ReturnType<typeof useTracker>;
|
||||
@@ -26,6 +30,31 @@ const SporadicView: React.FC<SporadicViewProps> = ({ tracker, lang }) => {
|
||||
loadQuickLogSession
|
||||
} = tracker;
|
||||
|
||||
const { currentUser, updateUser } = useAuth();
|
||||
|
||||
// Timer Logic is now managed in useTracker
|
||||
const { timer } = tracker;
|
||||
|
||||
const handleLogSet = async () => {
|
||||
await handleLogSporadicSet();
|
||||
// Always usage default/current setting for sporadic
|
||||
timer.start();
|
||||
};
|
||||
|
||||
const handleDurationChange = async (newVal: number) => {
|
||||
try {
|
||||
await api.patch('/auth/profile', { restTimerDefault: newVal });
|
||||
if (currentUser) {
|
||||
updateUser({
|
||||
...currentUser,
|
||||
profile: { ...currentUser.profile, restTimerDefault: newVal }
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to update default timer", e);
|
||||
}
|
||||
};
|
||||
|
||||
const [todaysSets, setTodaysSets] = useState<WorkoutSet[]>([]);
|
||||
const [editingSetId, setEditingSetId] = useState<string | null>(null);
|
||||
const [editingSet, setEditingSet] = useState<WorkoutSet | null>(null);
|
||||
@@ -72,7 +101,7 @@ const SporadicView: React.FC<SporadicViewProps> = ({ tracker, lang }) => {
|
||||
<SetLogger
|
||||
tracker={tracker}
|
||||
lang={lang}
|
||||
onLogSet={handleLogSporadicSet}
|
||||
onLogSet={handleLogSet}
|
||||
isSporadic={true}
|
||||
/>
|
||||
|
||||
@@ -301,6 +330,8 @@ const SporadicView: React.FC<SporadicViewProps> = ({ tracker, lang }) => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<RestTimerFAB timer={tracker.timer} onDurationChange={handleDurationChange} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ import { usePlanExecution } from '../../hooks/usePlanExecution';
|
||||
import { useAuth } from '../../context/AuthContext';
|
||||
import { useActiveWorkout } from '../../context/ActiveWorkoutContext';
|
||||
import { useSession } from '../../context/SessionContext';
|
||||
import { useRestTimer } from '../../hooks/useRestTimer';
|
||||
|
||||
export const useTracker = (props: any) => { // Props ignored/removed
|
||||
const { currentUser } = useAuth();
|
||||
@@ -61,6 +62,21 @@ export const useTracker = (props: any) => { // Props ignored/removed
|
||||
const form = useWorkoutForm({ userId, onUpdateSet: handleUpdateSetWrapper });
|
||||
const planExec = usePlanExecution({ activeSession, activePlan, exercises });
|
||||
|
||||
// Rest Timer Logic (Moved from ActiveSessionView to persist state)
|
||||
const getTargetRestTime = () => {
|
||||
if (activePlan) {
|
||||
const currentStep = activePlan.steps[planExec.currentStepIndex];
|
||||
if (currentStep && currentStep.restTimeSeconds) {
|
||||
return currentStep.restTimeSeconds;
|
||||
}
|
||||
}
|
||||
return currentUser?.profile?.restTimerDefault || 120;
|
||||
};
|
||||
const targetRestTime = getTargetRestTime();
|
||||
const timer = useRestTimer({
|
||||
defaultTime: targetRestTime
|
||||
});
|
||||
|
||||
// Initial Data Load
|
||||
useEffect(() => {
|
||||
if (!userId) return;
|
||||
@@ -247,7 +263,8 @@ export const useTracker = (props: any) => { // Props ignored/removed
|
||||
onSessionEnd: endSession,
|
||||
onSessionQuit: quitSession,
|
||||
onRemoveSet: removeSet,
|
||||
activeSession // Need this in view
|
||||
activeSession, // Need this in view
|
||||
timer // Expose timer to views
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user