Skip to content

Commit 5b0a3dc

Browse files
committed
Fix result ordering
1 parent 00482b0 commit 5b0a3dc

5 files changed

Lines changed: 347 additions & 43 deletions

File tree

contracts/api-registry.json

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,14 @@
368368
"minimum": 1,
369369
"maximum": 50
370370
}
371+
},
372+
{
373+
"name": "cursor",
374+
"in": "query",
375+
"schema": {
376+
"type": "string",
377+
"format": "date-time"
378+
}
371379
}
372380
],
373381
"auth": {
@@ -509,17 +517,45 @@
509517
"summary": "Return jam results",
510518
"parameters": [
511519
{
512-
"name": "jamSlug",
520+
"name": "jam",
513521
"in": "query",
514522
"schema": {
515523
"type": "string"
516524
}
517525
},
518526
{
519-
"name": "jamId",
527+
"name": "category",
520528
"in": "query",
521529
"schema": {
522-
"type": "integer"
530+
"type": "string"
531+
}
532+
},
533+
{
534+
"name": "contentType",
535+
"in": "query",
536+
"schema": {
537+
"type": "string"
538+
}
539+
},
540+
{
541+
"name": "sort",
542+
"in": "query",
543+
"schema": {
544+
"type": "string"
545+
}
546+
},
547+
{
548+
"name": "preview",
549+
"in": "query",
550+
"schema": {
551+
"type": "string"
552+
}
553+
},
554+
{
555+
"name": "recap",
556+
"in": "query",
557+
"schema": {
558+
"type": "string"
523559
}
524560
}
525561
],
@@ -2161,6 +2197,20 @@
21612197
"path": "/radio",
21622198
"tag": "Music",
21632199
"summary": "Return synchronized music radio state",
2200+
"parameters": [
2201+
{
2202+
"name": "station",
2203+
"in": "query",
2204+
"schema": {
2205+
"type": "string",
2206+
"enum": [
2207+
"all",
2208+
"safe"
2209+
],
2210+
"default": "all"
2211+
}
2212+
}
2213+
],
21642214
"auth": {
21652215
"required": false,
21662216
"optional": true,
@@ -2180,6 +2230,10 @@
21802230
"tag": "Music",
21812231
"summary": "Vote for the next music radio track",
21822232
"requestBody": true,
2233+
"requestExample": {
2234+
"trackId": 123,
2235+
"station": "all"
2236+
},
21832237
"auth": {
21842238
"required": true,
21852239
"optional": false,
@@ -2196,13 +2250,43 @@
21962250
"header": "Idempotency-Key"
21972251
}
21982252
},
2253+
{
2254+
"sdkName": "reportRadioTrackDuration",
2255+
"method": "POST",
2256+
"path": "/radio/duration",
2257+
"tag": "Music",
2258+
"summary": "Report the actual audio duration for the current radio track",
2259+
"requestBody": true,
2260+
"requestExample": {
2261+
"trackId": 123,
2262+
"durationSeconds": 142.5,
2263+
"station": "all"
2264+
},
2265+
"auth": {
2266+
"required": false,
2267+
"optional": false,
2268+
"kind": "none",
2269+
"label": "Public"
2270+
},
2271+
"visibility": "public",
2272+
"rateLimit": {
2273+
"documented": true,
2274+
"headers": true
2275+
}
2276+
},
21992277
{
22002278
"sdkName": "sendRadioEmote",
22012279
"method": "POST",
22022280
"path": "/radio/emote",
22032281
"tag": "Music",
22042282
"summary": "Send an ephemeral music radio emote",
22052283
"requestBody": true,
2284+
"requestExample": {
2285+
"emote": "jam",
2286+
"station": "all",
2287+
"x": 0.8,
2288+
"y": 0.9
2289+
},
22062290
"auth": {
22072291
"required": true,
22082292
"optional": false,
@@ -2225,6 +2309,20 @@
22252309
"path": "/radio/events",
22262310
"tag": "Music",
22272311
"summary": "Subscribe to music radio server-sent events",
2312+
"parameters": [
2313+
{
2314+
"name": "station",
2315+
"in": "query",
2316+
"schema": {
2317+
"type": "string",
2318+
"enum": [
2319+
"all",
2320+
"safe"
2321+
],
2322+
"default": "all"
2323+
}
2324+
}
2325+
],
22282326
"auth": {
22292327
"required": false,
22302328
"optional": true,

features/games/scoring.service.ts

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,56 @@ function ratingBelongsToScoreVersion(rating: RatingCategoryRef, version: PageVer
4040
return ratingVersion === version;
4141
}
4242

43+
function categoryScore(
44+
game: { id: number; categoryAverages: CategoryAverage[] },
45+
categoryId: number,
46+
categoryName?: string,
47+
) {
48+
const categoryAverage = game.categoryAverages.find((avg) =>
49+
categoryId >= 0
50+
? avg.categoryId === categoryId
51+
: avg.categoryName === categoryName,
52+
);
53+
return categoryAverage?.averageScore ?? 0;
54+
}
55+
56+
function categoryRatingCount(
57+
game: { id: number; categoryAverages: CategoryAverage[] },
58+
categoryId: number,
59+
categoryName?: string,
60+
) {
61+
const categoryAverage = game.categoryAverages.find((avg) =>
62+
categoryId >= 0
63+
? avg.categoryId === categoryId
64+
: avg.categoryName === categoryName,
65+
);
66+
return categoryAverage?.ratingCount ?? 0;
67+
}
68+
69+
function compareGamesByRawCategoryScore(
70+
a: { id: number; categoryAverages: CategoryAverage[] },
71+
b: { id: number; categoryAverages: CategoryAverage[] },
72+
categoryId: number,
73+
categoryName?: string,
74+
) {
75+
const scoreDiff =
76+
categoryScore(b, categoryId, categoryName) -
77+
categoryScore(a, categoryId, categoryName);
78+
if (scoreDiff !== 0) return scoreDiff;
79+
80+
const countDiff =
81+
categoryRatingCount(b, categoryId, categoryName) -
82+
categoryRatingCount(a, categoryId, categoryName);
83+
if (countDiff !== 0) return countDiff;
84+
85+
const overallDiff =
86+
categoryScore(b, -1, OVERALL_RATING_CATEGORY_NAME) -
87+
categoryScore(a, -1, OVERALL_RATING_CATEGORY_NAME);
88+
if (overallDiff !== 0) return overallDiff;
89+
90+
return a.id - b.id;
91+
}
92+
4393
export async function buildVersionScores({
4494
game,
4595
version,
@@ -276,19 +326,18 @@ export async function buildVersionScores({
276326
rankedGames.forEach((entry) => {
277327
entry.categoryAverages.forEach((category: CategoryAverage) => {
278328
const rankedGamesInCategory = rankedGames
279-
.map((candidate) => {
280-
const categoryAvg = candidate.categoryAverages.find(
281-
(cat: CategoryAverage) => cat.categoryId === category.categoryId,
282-
);
283-
return {
284-
gameId: candidate.id,
285-
score: categoryAvg ? categoryAvg.averageScore : 0,
286-
};
287-
})
288-
.sort((a, b) => b.score - a.score);
329+
.slice()
330+
.sort((a, b) =>
331+
compareGamesByRawCategoryScore(
332+
a,
333+
b,
334+
category.categoryId,
335+
category.categoryName,
336+
),
337+
);
289338

290339
const gamePlacement = rankedGamesInCategory.findIndex(
291-
(rankedGame) => rankedGame.gameId === entry.id,
340+
(rankedGame) => rankedGame.id === entry.id,
292341
);
293342

294343
category.placement = gamePlacement + 1;

0 commit comments

Comments
 (0)