Skip to content

Commit

Permalink
fix: restart timer when pow is submitted
Browse files Browse the repository at this point in the history
  • Loading branch information
Ekep-Obasi committed Feb 12, 2025
1 parent 684e218 commit 9945c1c
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 31 deletions.
61 changes: 37 additions & 24 deletions src/components/common/ElapsedTimer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,18 @@ const ElapsedTimerBase: React.FC<ElapsedTimerProps> = ({ bountyId }: ElapsedTime
const [elapsedTime, setElapsedTime] = useState<string>('00h 00m 00s');
const [firstAssignedAt, setFirstAssignedAt] = useState<string | null>(null);
const [lastPowAt, setLastPowAt] = useState<string | null>(null);
const [accumulatedPauseSeconds, setAccumulatedPauseSeconds] = useState<number>(0);
const [isPaused, setIsPaused] = useState<boolean>(false);
const [closedAt, setClosedAt] = useState<string | null>(null);
const [error, setError] = useState<boolean>(false);
const timerRef = useRef<ReturnType<typeof setInterval>>();
const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);

const clearIntervalIfNeeded = () => {
if (timerRef.current) {
clearInterval(timerRef.current);
timerRef.current = null;
}
};

useEffect(() => {
const fetchTiming = async () => {
Expand All @@ -49,55 +58,59 @@ const ElapsedTimerBase: React.FC<ElapsedTimerProps> = ({ bountyId }: ElapsedTime
try {
const timing = await bountyReviewStore.getBountyTiming(bountyId);

if (timing?.first_assigned_at) {
if (timing) {
setFirstAssignedAt(timing.first_assigned_at);
setLastPowAt(timing.last_pow_at || null);
setIsPaused(timing.is_paused || false);
setClosedAt(timing.closed_at || null);
setAccumulatedPauseSeconds(timing.accumulated_pause_seconds || 0);

setElapsedTime(
formatElapsedTime(timing.first_assigned_at, timing.last_pow_at, timing.is_paused)
formatElapsedTime(
timing.first_assigned_at,
timing.last_pow_at,
timing.is_paused,
timing.closed_at,
timing.accumulated_pause_seconds
)
);
setError(false);
} else {
setFirstAssignedAt(null);
setLastPowAt(null);
setIsPaused(false);
setElapsedTime('00h 00m 00s');

setError(false);
}
} catch (error) {
console.error('Error fetching timing:', error);
setError(true);
setFirstAssignedAt(null);
setLastPowAt(null);
setIsPaused(false);
setElapsedTime('00h 00m 00s');
}
};

fetchTiming();
}, [bountyId]);

useEffect(() => {
if (!firstAssignedAt || lastPowAt || isPaused) {
if (timerRef.current) {
clearInterval(timerRef.current);
}
const stopTimer = (!!closedAt && !!lastPowAt) || isPaused;

if (stopTimer) {
clearIntervalIfNeeded();
return;
}

const updateTimer = () => {
setElapsedTime(formatElapsedTime(firstAssignedAt, lastPowAt, isPaused));
setElapsedTime(
formatElapsedTime(
firstAssignedAt || '',
lastPowAt,
isPaused,
closedAt,
accumulatedPauseSeconds
)
);
};

updateTimer();
timerRef.current = setInterval(updateTimer, 1000);

return () => {
if (timerRef.current) {
clearInterval(timerRef.current);
}
};
}, [firstAssignedAt, lastPowAt, isPaused]);
return () => clearIntervalIfNeeded();
}, [firstAssignedAt, lastPowAt, isPaused, closedAt, accumulatedPauseSeconds]);

if (error) {
return null;
Expand Down
37 changes: 30 additions & 7 deletions src/helpers/timeFormatting.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,45 @@
export const formatElapsedTime = (
firstAssignedAt: string,
lastPowAt: string | null,
isPaused: boolean
isPaused: boolean,
closedAt: string | null,
accumulatedPauseSeconds: number
): string => {
try {
const startTime = new Date(firstAssignedAt);
let startTime = new Date(firstAssignedAt);
const currentTime = new Date();

if (isNaN(startTime.getTime())) {
return '00h 00m 00s';
}

const stopTime = lastPowAt || isPaused ? new Date(lastPowAt || currentTime) : currentTime;
if (!isPaused && lastPowAt) {
startTime = new Date(lastPowAt); // Restart timer from lastPowAt
}

const isBountyComplete = !!closedAt && !!lastPowAt && isPaused;

let stopTime: Date;

if (isBountyComplete) {
stopTime = new Date(closedAt as string);
} else if (isPaused && lastPowAt) {
stopTime = new Date(lastPowAt);
} else {
stopTime = currentTime;
}

const elapsedMilliseconds = Math.max(0, stopTime.getTime() - startTime.getTime());

const effectiveElapsedSeconds = Math.max(
0,
Math.floor(elapsedMilliseconds / 1000) -
(isPaused || !lastPowAt ? accumulatedPauseSeconds : 0)
);

const elapsed = Math.max(0, stopTime.getTime() - startTime.getTime());
const hours = Math.floor(elapsed / (1000 * 60 * 60));
const minutes = Math.floor((elapsed % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((elapsed % (1000 * 60)) / 1000);
const hours = Math.floor(effectiveElapsedSeconds / 3600);
const minutes = Math.floor((effectiveElapsedSeconds % 3600) / 60);
const seconds = effectiveElapsedSeconds % 60;

return `${hours.toString().padStart(2, '0')}h ${minutes.toString().padStart(2, '0')}m ${seconds
.toString()
Expand Down
1 change: 1 addition & 0 deletions src/store/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ export interface BountyTiming {
is_paused: boolean;
is_paused_at: string | null;
closed_at: string | null;
accumulated_pause_seconds: number;
}

export interface CreateBountyResponse {
Expand Down

0 comments on commit 9945c1c

Please sign in to comment.