Skip to content

Commit fc3fae4

Browse files
committed
(fix) state-staleness patch focused on Tab restarts
1 parent 5885fca commit fc3fae4

File tree

3 files changed

+52
-26
lines changed

3 files changed

+52
-26
lines changed

client/src/components/Typing.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,8 @@ function Typing({
510510
startTime: null,
511511
inProgress: false,
512512
completed: false,
513-
manuallyStarted: false
513+
manuallyStarted: false,
514+
results: []
514515
}));
515516

516517
}

client/src/context/RaceContext.jsx

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -335,18 +335,29 @@ export const RaceProvider = ({ children }) => {
335335
});
336336
};
337337

338-
const handleRaceStart = (data) => {
339-
// Only process the race:start event if:
340-
// 1. It's not practice mode, OR
341-
// 2. It's practice mode but we haven't manually started it yet
342-
if (raceState.type !== 'practice' || !raceState.manuallyStarted) {
343-
setRaceState(prev => ({
338+
const handleRaceStart = (data = {}) => {
339+
let shouldResetTyping = false;
340+
setRaceState(prev => {
341+
if (data.code && prev.code && data.code !== prev.code) {
342+
return prev;
343+
}
344+
// Only process the race:start event if:
345+
// 1. It's not practice mode, OR
346+
// 2. It's practice mode but we haven't manually started it yet
347+
if (prev.type === 'practice' && prev.manuallyStarted) {
348+
return prev;
349+
}
350+
shouldResetTyping = true;
351+
return {
344352
...prev,
345353
startTime: data.startTime,
346354
inProgress: true,
347-
countdown: null
348-
}));
349-
355+
countdown: null,
356+
results: []
357+
};
358+
});
359+
360+
if (shouldResetTyping) {
350361
// Reset typing state
351362
setTypingState({
352363
input: '',
@@ -384,20 +395,33 @@ export const RaceProvider = ({ children }) => {
384395
});
385396
};
386397

387-
const handleResultsUpdate = (data) => {
388-
setRaceState(prev => ({
389-
...prev,
390-
// Sort results by completion time (ascending)
391-
results: data.results.sort((a, b) => a.completion_time - b.completion_time)
392-
}));
398+
const handleResultsUpdate = (data = {}) => {
399+
setRaceState(prev => {
400+
if (data.code && prev.code && data.code !== prev.code) {
401+
return prev;
402+
}
403+
const sortedResults = Array.isArray(data.results)
404+
? [...data.results].sort((a, b) => a.completion_time - b.completion_time)
405+
: [];
406+
return {
407+
...prev,
408+
// Sort results by completion time (ascending)
409+
results: sortedResults
410+
};
411+
});
393412
};
394413

395-
const handleRaceEnd = () => {
396-
setRaceState(prev => ({
397-
...prev,
398-
inProgress: false,
399-
completed: true
400-
}));
414+
const handleRaceEnd = (data = {}) => {
415+
setRaceState(prev => {
416+
if (data.code && prev.code && data.code !== prev.code) {
417+
return prev;
418+
}
419+
return {
420+
...prev,
421+
inProgress: false,
422+
completed: true
423+
};
424+
});
401425
};
402426

403427
// Inactivity event handlers
@@ -669,7 +693,8 @@ export const RaceProvider = ({ children }) => {
669693
startTime: null,
670694
inProgress: false,
671695
completed: false,
672-
manuallyStarted: false
696+
manuallyStarted: false,
697+
results: []
673698
};
674699

675700
// Build options with current snippet filters

server/controllers/socket-handlers.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,7 +2091,7 @@ const startRace = async (io, code) => {
20912091
}
20922092

20932093
// Broadcast race start
2094-
io.to(code).emit('race:start', { startTime: race.startTime });
2094+
io.to(code).emit('race:start', { code, startTime: race.startTime });
20952095
} catch (err) {
20962096
console.error('Error starting race:', err);
20972097
}
@@ -2154,7 +2154,7 @@ const handlePlayerFinish = async (io, code, playerId, resultData) => {
21542154
.sort((a, b) => a.completion_time - b.completion_time); // Sort by time initially
21552155

21562156
// Broadcast updated results list
2157-
io.to(code).emit('race:resultsUpdate', { results: allResults });
2157+
io.to(code).emit('race:resultsUpdate', { code, results: allResults });
21582158

21592159
// Check if all players have finished
21602160
if (players.every(p => p.completed)) {
@@ -2197,7 +2197,7 @@ const endRace = async (io, code) => {
21972197
}
21982198

21992199
// Broadcast race end signal (without results payload)
2200-
io.to(code).emit('race:end');
2200+
io.to(code).emit('race:end', { code });
22012201
console.log(`Broadcasted race end signal for ${code}`);
22022202

22032203
} catch (err) {

0 commit comments

Comments
 (0)