Skip to content

Commit 402dbf4

Browse files
committed
update switch track timing logic
1 parent 86b74d8 commit 402dbf4

File tree

6 files changed

+73
-21
lines changed

6 files changed

+73
-21
lines changed

client/src/components/SwitchRace/SwitchTrackScreen.jsx

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useState, useContext, useEffect } from "react";
22

33
// components
4-
import { BackButton, Footer } from "@components";
4+
import { BackButton, ConfirmationModal, Footer } from "@components";
55

66
// context
77
import { GlobalDispatchContext, GlobalStateContext } from "@context/GlobalContext";
@@ -12,38 +12,51 @@ import { backendAPI, getErrorMessage } from "@utils";
1212

1313
export const SwitchTrackScreen = () => {
1414
const dispatch = useContext(GlobalDispatchContext);
15-
const { tracks, trackLastSwitchedDate } = useContext(GlobalStateContext);
15+
const { tracks, lastRaceStartedDate, isAdmin } = useContext(GlobalStateContext);
1616

1717
const [selectedTrack, setSelectedTrack] = useState(null);
18-
const [areAllButtonsDisabled, setAreAllButtonsDisabled] = useState(true);
18+
const [areAllButtonsDisabled, setAreAllButtonsDisabled] = useState(false);
19+
const [showRaceWarning, setShowRaceWarning] = useState(false);
20+
const [showConfirmationModal, setShowConfirmationModal] = useState(false);
1921

2022
useEffect(() => {
21-
if (trackLastSwitchedDate) {
22-
const lastSwitch = trackLastSwitchedDate;
23-
const now = new Date().getTime();
24-
const diffMs = now - lastSwitch;
25-
const diffMinutes = diffMs / (100 * 60);
26-
setAreAllButtonsDisabled(diffMinutes < 30);
23+
if (lastRaceStartedDate) {
24+
const now = Date.now();
25+
const diffMinutes = (now - lastRaceStartedDate) / (1000 * 60);
26+
const isRecentRace = diffMinutes < 5;
27+
28+
if (isRecentRace) {
29+
if (isAdmin) {
30+
setAreAllButtonsDisabled(false);
31+
setShowRaceWarning(true);
32+
} else {
33+
setAreAllButtonsDisabled(true);
34+
setShowRaceWarning(false);
35+
}
36+
} else {
37+
setAreAllButtonsDisabled(false);
38+
setShowRaceWarning(false);
39+
}
2740
} else {
2841
setAreAllButtonsDisabled(false);
42+
setShowRaceWarning(false);
2943
}
30-
}, [trackLastSwitchedDate]);
44+
}, [lastRaceStartedDate, isAdmin]);
3145

3246
const updateTrack = async () => {
3347
setAreAllButtonsDisabled(true);
3448

3549
await backendAPI
3650
.post("/race/switch-track", { selectedTrack })
3751
.then((response) => {
38-
const { leaderboard, numberOfCheckpoints, trackLastSwitchedDate } = response.data.sceneData;
52+
const { leaderboard, numberOfCheckpoints } = response.data.sceneData;
3953

4054
dispatch({
4155
type: SET_SCENE_DATA,
4256
payload: {
4357
leaderboard,
4458
numberOfCheckpoints,
4559
tracks,
46-
trackLastSwitchedDate,
4760
},
4861
});
4962
})
@@ -56,6 +69,14 @@ export const SwitchTrackScreen = () => {
5669
});
5770
};
5871

72+
const handleUpdateTrackClick = () => {
73+
if (showRaceWarning) {
74+
setShowConfirmationModal(true);
75+
} else {
76+
updateTrack();
77+
}
78+
};
79+
5980
return (
6081
<>
6182
<BackButton onClick={() => dispatch({ type: SCREEN_MANAGER.SHOW_HOME_SCREEN })} />
@@ -83,10 +104,36 @@ export const SwitchTrackScreen = () => {
83104
</div>
84105

85106
<Footer>
86-
<button className="btn-primary" disabled={areAllButtonsDisabled || !selectedTrack} onClick={updateTrack}>
87-
Update Track
88-
</button>
107+
{areAllButtonsDisabled && !isAdmin ? (
108+
<div className="tooltip">
109+
<span className="tooltip-content">A race was recently started. Please try again in a few minutes.</span>
110+
<button
111+
className="btn-primary"
112+
disabled={areAllButtonsDisabled || !selectedTrack}
113+
onClick={handleUpdateTrackClick}
114+
>
115+
Update Track
116+
</button>
117+
</div>
118+
) : (
119+
<button
120+
className="btn-primary"
121+
disabled={areAllButtonsDisabled || !selectedTrack}
122+
onClick={handleUpdateTrackClick}
123+
>
124+
Update Track
125+
</button>
126+
)}
89127
</Footer>
128+
129+
{showConfirmationModal && (
130+
<ConfirmationModal
131+
title="Switch Track"
132+
message="A race may currently be in progress. Are you sure you want to switch tracks?"
133+
handleOnConfirm={updateTrack}
134+
handleToggleShowConfirmationModal={() => setShowConfirmationModal(false)}
135+
/>
136+
)}
90137
</>
91138
);
92139
};

client/src/context/reducer.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ const globalReducer = (state, action) => {
100100
tracks: payload.tracks,
101101
visitorInventory: payload.visitorInventory,
102102
badges: payload.badges,
103-
trackLastSwitchedDate: payload.trackLastSwitchedDate,
103+
lastRaceStartedDate: payload.lastRaceStartedDate,
104104
error: "",
105105
};
106106
case SET_VISITOR_INVENTORY:
@@ -114,7 +114,6 @@ const globalReducer = (state, action) => {
114114
...state,
115115
leaderboard: payload.leaderboard,
116116
numberOfCheckpoints: payload.numberOfCheckpoints,
117-
trackLastSwitchedDate: payload.trackLastSwitchedDate,
118117
error: "",
119118
};
120119
case SET_LEADERBOARD:

client/src/utils/loadGameState.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const loadGameState = async (dispatch) => {
1717
tracks,
1818
visitorInventory,
1919
badges,
20-
trackLastSwitchedDate,
20+
lastRaceStartedDate,
2121
} = result.data;
2222

2323
await dispatch({
@@ -33,7 +33,7 @@ export const loadGameState = async (dispatch) => {
3333
tracks,
3434
visitorInventory,
3535
badges,
36-
trackLastSwitchedDate,
36+
lastRaceStartedDate,
3737
},
3838
});
3939

server/controllers/handleLoadGameState.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export const handleLoadGameState = async (req, res) => {
8484
tracks: parseEnvJson(process.env.TRACKS) || TRACKS,
8585
visitorInventory,
8686
badges,
87-
trackLastSwitchedDate: sceneData.trackLastSwitchedDate || null,
87+
lastRaceStartedDate: sceneData.lastRaceStartedDate || null,
8888
});
8989
} catch (error) {
9090
return errorHandler({

server/controllers/handleRaceStart.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ export const handleRaceStart = async (req, res) => {
6363
});
6464
if (updateVisitorResult instanceof Error) throw updateVisitorResult;
6565

66+
// Update world data object with last race started timestamp
67+
await world.updateDataObject(
68+
{
69+
[`${sceneDropId}.lastRaceStartedDate`]: startTimestamp,
70+
},
71+
);
72+
6673
addNewRowToGoogleSheets({
6774
identityId,
6875
displayName,

server/controllers/handleSwitchTrack.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ export const handleSwitchTrack = async (req, res) => {
7070
numberOfCheckpoints: numberOfCheckpoints?.length,
7171
leaderboard: {},
7272
position,
73-
trackLastSwitchedDate: new Date().getTime(),
7473
};
7574

7675
await world.updateDataObject(

0 commit comments

Comments
 (0)