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
77 changes: 62 additions & 15 deletions client/src/components/SwitchRace/SwitchTrackScreen.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState, useContext, useEffect } from "react";

// components
import { BackButton, Footer } from "@components";
import { BackButton, ConfirmationModal, Footer } from "@components";

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

export const SwitchTrackScreen = () => {
const dispatch = useContext(GlobalDispatchContext);
const { tracks, trackLastSwitchedDate } = useContext(GlobalStateContext);
const { tracks, lastRaceStartedDate, isAdmin } = useContext(GlobalStateContext);

const [selectedTrack, setSelectedTrack] = useState(null);
const [areAllButtonsDisabled, setAreAllButtonsDisabled] = useState(true);
const [areAllButtonsDisabled, setAreAllButtonsDisabled] = useState(false);
const [showRaceWarning, setShowRaceWarning] = useState(false);
const [showConfirmationModal, setShowConfirmationModal] = useState(false);

useEffect(() => {
if (trackLastSwitchedDate) {
const lastSwitch = trackLastSwitchedDate;
const now = new Date().getTime();
const diffMs = now - lastSwitch;
const diffMinutes = diffMs / (100 * 60);
setAreAllButtonsDisabled(diffMinutes < 30);
if (lastRaceStartedDate) {
const now = Date.now();
const diffMinutes = (now - lastRaceStartedDate) / (1000 * 60);
const isRecentRace = diffMinutes < 5;

if (isRecentRace) {
if (isAdmin) {
setAreAllButtonsDisabled(false);
setShowRaceWarning(true);
} else {
setAreAllButtonsDisabled(true);
setShowRaceWarning(false);
}
} else {
setAreAllButtonsDisabled(false);
setShowRaceWarning(false);
}
} else {
setAreAllButtonsDisabled(false);
setShowRaceWarning(false);
}
}, [trackLastSwitchedDate]);
}, [lastRaceStartedDate, isAdmin]);

const updateTrack = async () => {
setAreAllButtonsDisabled(true);

await backendAPI
.post("/race/switch-track", { selectedTrack })
.then((response) => {
const { leaderboard, numberOfCheckpoints, trackLastSwitchedDate } = response.data.sceneData;
const { leaderboard, numberOfCheckpoints } = response.data.sceneData;

dispatch({
type: SET_SCENE_DATA,
payload: {
leaderboard,
numberOfCheckpoints,
tracks,
trackLastSwitchedDate,
},
});
})
Expand All @@ -56,6 +69,14 @@ export const SwitchTrackScreen = () => {
});
};

const handleUpdateTrackClick = () => {
if (showRaceWarning) {
setShowConfirmationModal(true);
} else {
updateTrack();
}
};

return (
<>
<BackButton onClick={() => dispatch({ type: SCREEN_MANAGER.SHOW_HOME_SCREEN })} />
Expand Down Expand Up @@ -83,10 +104,36 @@ export const SwitchTrackScreen = () => {
</div>

<Footer>
<button className="btn-primary" disabled={areAllButtonsDisabled || !selectedTrack} onClick={updateTrack}>
Update Track
</button>
{areAllButtonsDisabled && !isAdmin ? (
<div className="tooltip">
<span className="tooltip-content">A race was recently started. Please try again in a few minutes.</span>
<button
className="btn-primary"
disabled={areAllButtonsDisabled || !selectedTrack}
onClick={handleUpdateTrackClick}
>
Update Track
</button>
</div>
) : (
<button
className="btn-primary"
disabled={areAllButtonsDisabled || !selectedTrack}
onClick={handleUpdateTrackClick}
>
Update Track
</button>
)}
</Footer>

{showConfirmationModal && (
<ConfirmationModal
title="Switch Track"
message="A race may currently be in progress. Are you sure you want to switch tracks?"
handleOnConfirm={updateTrack}
handleToggleShowConfirmationModal={() => setShowConfirmationModal(false)}
/>
)}
</>
);
};
Expand Down
3 changes: 1 addition & 2 deletions client/src/context/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const globalReducer = (state, action) => {
tracks: payload.tracks,
visitorInventory: payload.visitorInventory,
badges: payload.badges,
trackLastSwitchedDate: payload.trackLastSwitchedDate,
lastRaceStartedDate: payload.lastRaceStartedDate,
error: "",
};
case SET_VISITOR_INVENTORY:
Expand All @@ -114,7 +114,6 @@ const globalReducer = (state, action) => {
...state,
leaderboard: payload.leaderboard,
numberOfCheckpoints: payload.numberOfCheckpoints,
trackLastSwitchedDate: payload.trackLastSwitchedDate,
error: "",
};
case SET_LEADERBOARD:
Expand Down
4 changes: 2 additions & 2 deletions client/src/utils/loadGameState.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const loadGameState = async (dispatch) => {
tracks,
visitorInventory,
badges,
trackLastSwitchedDate,
lastRaceStartedDate,
} = result.data;

await dispatch({
Expand All @@ -33,7 +33,7 @@ export const loadGameState = async (dispatch) => {
tracks,
visitorInventory,
badges,
trackLastSwitchedDate,
lastRaceStartedDate,
},
});

Expand Down
2 changes: 1 addition & 1 deletion server/controllers/handleLoadGameState.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const handleLoadGameState = async (req, res) => {
tracks: parseEnvJson(process.env.TRACKS) || TRACKS,
visitorInventory,
badges,
trackLastSwitchedDate: sceneData.trackLastSwitchedDate || null,
lastRaceStartedDate: sceneData.lastRaceStartedDate || null,
});
} catch (error) {
return errorHandler({
Expand Down
7 changes: 7 additions & 0 deletions server/controllers/handleRaceStart.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ export const handleRaceStart = async (req, res) => {
});
if (updateVisitorResult instanceof Error) throw updateVisitorResult;

// Update world data object with last race started timestamp
await world.updateDataObject(
{
[`${sceneDropId}.lastRaceStartedDate`]: startTimestamp,
},
);

addNewRowToGoogleSheets({
identityId,
displayName,
Expand Down
1 change: 0 additions & 1 deletion server/controllers/handleSwitchTrack.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ export const handleSwitchTrack = async (req, res) => {
numberOfCheckpoints: numberOfCheckpoints?.length,
leaderboard: {},
position,
trackLastSwitchedDate: new Date().getTime(),
};

await world.updateDataObject(
Expand Down