Skip to content

Commit c617527

Browse files
committed
refactor data objects
1 parent b4942cc commit c617527

23 files changed

+321
-179
lines changed

client/src/context/reducer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const globalReducer = (state, action) => {
7474
...state,
7575
checkpointsCompleted: payload.checkpointsCompleted,
7676
elapsedTimeInSeconds: payload.elapsedTimeInSeconds,
77-
highscore: payload.highscore,
77+
highScore: payload.highScore,
7878
isAdmin: payload.isAdmin,
7979
leaderboard: payload.leaderboard,
8080
numberOfCheckpoints: payload.numberOfCheckpoints,

client/src/pages/Leaderboard.jsx

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { backendAPI, loadGameState } from "@utils";
1616

1717
function Leaderboard() {
1818
const dispatch = useContext(GlobalDispatchContext);
19-
const { leaderboard, highscore, isAdmin } = useContext(GlobalStateContext);
19+
const { leaderboard, highScore, isAdmin } = useContext(GlobalStateContext);
2020
const [loading, setLoading] = useState(true);
2121
const [showSettings, setShowSettings] = useState(false);
2222
const location = useLocation();
@@ -36,23 +36,6 @@ function Leaderboard() {
3636
fetchGameState();
3737
}, [dispatch, backendAPI]);
3838

39-
const sortedLeaderboard = leaderboard
40-
? Object.entries(leaderboard)
41-
.filter(([, playerData]) => playerData && playerData.highscore)
42-
.sort(([, a], [, b]) => {
43-
const aScore = a.highscore.split(":").map(Number);
44-
const bScore = b.highscore.split(":").map(Number);
45-
46-
for (let i = 0; i < 3; i++) {
47-
if (aScore[i] !== bScore[i]) {
48-
return aScore[i] - bScore[i];
49-
}
50-
}
51-
return 0;
52-
})
53-
.slice(0, 20)
54-
: [];
55-
5639
if (loading) return <Loading />;
5740

5841
if (showSettings) return <AdminView setShowSettings={setShowSettings} />;
@@ -63,10 +46,10 @@ function Leaderboard() {
6346
<>
6447
{isAdmin && <AdminGear setShowSettings={setShowSettings} />}
6548
<div className="px-4 my-6">
66-
<div className="highscore-container">
49+
<div className="highScore-container">
6750
<div className="icon">🏅</div>
6851
<h3>Personal Best</h3>
69-
<p>{highscore || "No highscore available"}</p>
52+
<p>{highScore || "No highScore available"}</p>
7053
</div>
7154
<div className="icon pt-4">🏆</div>
7255
<div className="pb-4">
@@ -81,18 +64,20 @@ function Leaderboard() {
8164
</tr>
8265
</thead>
8366
<tbody>
84-
{sortedLeaderboard?.length === 0 ? (
67+
{leaderboard?.length === 0 ? (
8568
<tr>
8669
<td colSpan="3">There are no race finishes yet.</td>
8770
</tr>
8871
) : (
89-
sortedLeaderboard?.map(([userId, entry], index) => (
90-
<tr key={userId}>
91-
<td>{index + 1}</td>
92-
<td>{entry.username}</td>
93-
<td>{entry.highscore}</td>
94-
</tr>
95-
))
72+
leaderboard?.map((item, index) => {
73+
return (
74+
<tr key={index}>
75+
<td>{index + 1}</td>
76+
<td>{item.displayName}</td>
77+
<td>{item.highScore}</td>
78+
</tr>
79+
);
80+
})
9681
)}
9782
</tbody>
9883
</table>

client/src/pages/Leaderboard.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
text-align: center;
1010
}
1111

12-
.highscore-container {
12+
.highScore-container {
1313
text-align: center;
1414
margin-bottom: 20px;
1515
padding: 10px;

client/src/utils/loadGameState.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const loadGameState = async (dispatch) => {
1010
payload: {
1111
checkpointsCompleted: result.data.checkpointsCompleted,
1212
elapsedTimeInSeconds: result.data.elapsedTimeInSeconds,
13-
highscore: result.data.highscore,
13+
highScore: result.data.highScore,
1414
isAdmin: result.data.isAdmin,
1515
leaderboard: result.data.leaderboard,
1616
numberOfCheckpoints: result.data.numberOfCheckpoints,

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "",
55
"dependencies": {
66
"@googleapis/sheets": "^7.0.0",
7-
"@rtsdk/topia": "^0.15.8",
7+
"@rtsdk/topia": "^0.17.4",
88
"axios": "^1.6.7",
99
"body-parser": "^1.20.2",
1010
"concurrently": "^8.2.2",

server/constants.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,10 @@ export const TRACKS = [
4040
sceneId: "oXghmgohNPuaICPA9Ne5",
4141
},
4242
];
43+
44+
export const DEFAULT_PROGRESS = {
45+
checkpoints: { 0: false },
46+
elapsedTime: null,
47+
highScore: null,
48+
startTimestamp: null,
49+
};

server/controllers/handleCancelRace.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
import { errorHandler, getCredentials, World } from "../utils/index.js";
1+
import { errorHandler, getCredentials, getVisitor, updateVisitorProgress } from "../utils/index.js";
22

33
export const handleCancelRace = async (req, res) => {
44
try {
55
const credentials = getCredentials(req.query);
6-
const { urlSlug, profileId, sceneDropId } = credentials;
76

8-
const world = await World.create(urlSlug, { credentials });
7+
const { visitor, visitorProgress } = await getVisitor(credentials);
98

10-
if (profileId) {
11-
world
12-
.updateDataObject({
13-
[`${sceneDropId}.profiles.${profileId}.checkpoints`]: {},
14-
[`${sceneDropId}.profiles.${profileId}.elapsedTime`]: null,
15-
[`${sceneDropId}.profiles.${profileId}.startTimestamp`]: null,
16-
})
17-
.then()
18-
.catch((error) => console.error(JSON.stringify(error)));
19-
}
9+
const updateVisitorResult = await updateVisitorProgress({
10+
credentials,
11+
updatedProgress: {
12+
checkpoints: {},
13+
elapsedTime: null,
14+
startTimestamp: null,
15+
},
16+
visitor,
17+
visitorProgress,
18+
});
19+
if (updateVisitorResult instanceof Error) throw updateVisitorResult;
2020

2121
return res.json({ success: true });
2222
} catch (error) {

server/controllers/handleCheckpointEntered.js

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,34 @@
11
import {
22
getCredentials,
3-
World,
43
errorHandler,
5-
checkpointZeroEntered,
64
finishLineEntered,
75
checkpointEntered,
86
Visitor,
7+
getVisitor,
8+
getElapsedTime,
99
} from "../utils/index.js";
1010
import { CHECKPOINT_NAMES } from "../constants.js";
1111
import redisObj from "../redis/redis.js";
1212

1313
export const handleCheckpointEntered = async (req, res) => {
1414
try {
1515
const credentials = getCredentials(req.body);
16-
const { profileId, sceneDropId, urlSlug, visitorId } = credentials;
16+
const { profileId, urlSlug, visitorId } = credentials;
1717
const { uniqueName } = req.body;
1818
const channel = `${process.env.INTERACTIVE_KEY}_RACE`;
1919

20+
const { visitorProgress } = await getVisitor(credentials);
21+
const { startTimestamp } = visitorProgress;
22+
23+
const currentTimestamp = Date.now();
24+
const currentElapsedTime = getElapsedTime(currentTimestamp, startTimestamp);
2025
const checkpointNumber = uniqueName === CHECKPOINT_NAMES.START ? 0 : parseInt(uniqueName.split("-").pop(), 10);
2126

27+
if (!startTimestamp) return { success: false, message: "Race has not started yet" };
28+
29+
const cachedCheckpoints = JSON.parse(await redisObj.get(profileId)) || {};
30+
2231
if (checkpointNumber !== 0) {
23-
const cachedCheckpoints = JSON.parse(await redisObj.get(profileId)) || {};
2432
if (checkpointNumber > 1 && !cachedCheckpoints[checkpointNumber - 2]) {
2533
redisObj.publish(channel, {
2634
profileId,
@@ -52,25 +60,24 @@ export const handleCheckpointEntered = async (req, res) => {
5260
}
5361
}
5462

55-
const world = World.create(urlSlug, { credentials });
56-
const dataObject = await world.fetchDataObject();
57-
const raceObject = dataObject?.[sceneDropId] || {};
58-
const profileObject = raceObject?.profiles?.[profileId] || {};
59-
60-
const { startTimestamp } = profileObject;
61-
if (!startTimestamp) return { success: false, message: "Race has not started yet" };
62-
const currentTimestamp = Date.now();
63-
6463
if (checkpointNumber === 0) {
65-
const currentElapsedTime = checkpointZeroEntered(currentTimestamp, profileObject);
6664
redisObj.publish(channel, {
6765
profileId,
6866
checkpointNumber,
6967
currentRaceFinishedElapsedTime: currentElapsedTime,
7068
});
71-
await finishLineEntered({ credentials, currentElapsedTime, profileObject, raceObject, world });
69+
const result = await finishLineEntered({ credentials, currentElapsedTime });
70+
console.log("🚀 ~ handleCheckpointEntered.js:70 ~ result:", result);
71+
if (result instanceof Error) throw result;
7272
} else {
73-
await checkpointEntered({ checkpointNumber, currentTimestamp, credentials, profileObject, world });
73+
const result = await checkpointEntered({
74+
checkpoints: cachedCheckpoints,
75+
checkpointNumber,
76+
currentTimestamp,
77+
credentials,
78+
});
79+
console.log("🚀 ~ handleCheckpointEntered.js:79 ~ result:", result);
80+
if (result instanceof Error) throw result;
7481
}
7582

7683
return res.status(200).json({ success: true });

server/controllers/handleCompleteRace.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
import { World, errorHandler, getCredentials } from "../utils/index.js";
1+
import { errorHandler, getCredentials, getVisitor } from "../utils/index.js";
22

33
export const handleCompleteRace = async (req, res) => {
44
try {
55
const credentials = getCredentials(req.query);
6-
const { urlSlug, profileId } = credentials;
76

8-
const world = await World.create(urlSlug, { credentials });
9-
await world.fetchDataObject();
10-
11-
const elapsedTime = world?.dataObject?.sceneDropId?.profiles?.[profileId]?.elapsedTime;
7+
const { visitorProgress } = await getVisitor(credentials);
8+
const elapsedTime = visitorProgress.elapsedTime;
129

1310
return res.json({ success: true, elapsedTime });
1411
} catch (error) {

0 commit comments

Comments
 (0)