-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
238 additions
and
5 deletions.
There are no files selected for viewing
79 changes: 79 additions & 0 deletions
79
packages/api/src/services/players/playerHighestPpCharts.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { Transaction, db } from 'db'; | ||
import { sql } from 'kysely'; | ||
|
||
export const getPlayerHighestPpCharts = async ( | ||
params: { playerId?: number; limit: number; offset: number }, | ||
trx?: Transaction | ||
): Promise< | ||
Array<{ | ||
pp: number; | ||
weight: number; | ||
date: Date; // seems like api actually returns string :( | ||
shared_chart: number; | ||
full_name: string; | ||
label: string; | ||
grade: string | null; | ||
score: number | null; | ||
is_pass: boolean; | ||
}> | ||
> => { | ||
if (!params.playerId) { | ||
throw new Error('playerId is required'); | ||
} | ||
|
||
const query = (trx ?? db) | ||
.selectFrom('results as r') | ||
.innerJoin('shared_charts as sc', 'r.shared_chart', 'sc.id') | ||
.innerJoin('chart_instances as ci', (join) => | ||
join.on('ci.id', '=', (eb) => | ||
eb | ||
.selectFrom('chart_instances') | ||
.select('id') | ||
.where('shared_chart', '=', sql.ref('r.shared_chart')) | ||
.orderBy('mix', 'desc') | ||
.limit(1) | ||
) | ||
) | ||
.innerJoin('tracks as t', 't.id', 'sc.track') | ||
.innerJoin( | ||
(eb) => | ||
eb | ||
.selectFrom('results') | ||
.select(({ fn }) => ['player_id', 'shared_chart', fn.max('pp').as('best_pp')]) | ||
.groupBy(['shared_chart', 'player_id']) | ||
.where('pp', 'is not', null) | ||
.as('max_pp_results'), | ||
(join) => | ||
join | ||
.onRef('max_pp_results.player_id', '=', 'r.player_id') | ||
.onRef('max_pp_results.shared_chart', '=', 'r.shared_chart') | ||
.onRef('max_pp_results.best_pp', '=', `r.pp`) | ||
) | ||
.select([ | ||
'pp', | ||
'r.gained as date', | ||
'r.grade', | ||
'r.score_phoenix as score', | ||
'r.is_pass', | ||
't.full_name', | ||
'ci.label', | ||
'r.shared_chart', | ||
]) | ||
.where('r.player_id', '=', params.playerId) | ||
.orderBy('pp', 'desc') | ||
.limit(params.limit) | ||
.offset(params.offset) | ||
.$narrowType<{ pp: number }>(); | ||
|
||
const timeStart = performance.now(); | ||
const result = await query.execute(); | ||
const timeEnd = performance.now(); | ||
console.log('query time:', timeEnd - timeStart, 'ms'); | ||
|
||
return result.map((row, index) => ({ | ||
...row, | ||
date: new Date(row.date), | ||
weight: 0.95 ** (index + params.offset), | ||
is_pass: row.is_pass === 1, | ||
})); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { getPlayerHighestPpCharts } from 'services/players/playerHighestPpCharts'; | ||
import { publicProcedure } from 'trpc/trpc'; | ||
import z from 'zod'; | ||
|
||
export const highestPpCharts = publicProcedure | ||
.input( | ||
z.object({ | ||
playerId: z.number().optional(), | ||
cursor: z.number(), | ||
pageSize: z.number(), | ||
}) | ||
) | ||
.query(async ({ ctx, input }) => { | ||
const { cursor, pageSize = 20, playerId } = input; | ||
const offset = cursor ?? 0; | ||
return { | ||
items: await getPlayerHighestPpCharts({ | ||
playerId: playerId ?? ctx.user?.id, | ||
limit: pageSize, | ||
offset, | ||
}), | ||
nextCursor: offset + pageSize, | ||
}; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
packages/web/src/features/profile/components/HighestPpCharts/HighestPpCharts.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { Button, Flex, SimpleGrid, Stack, Text } from '@mantine/core'; | ||
import { MdExpandMore } from 'react-icons/md'; | ||
import { useParams } from 'react-router'; | ||
import { NavLink } from 'react-router-dom'; | ||
|
||
import { Card } from 'components/Card/Card'; | ||
import { ChartLabel } from 'components/ChartLabel/ChartLabel'; | ||
import { Grade } from 'components/Grade/Grade'; | ||
import Loader from 'components/Loader/Loader'; | ||
|
||
import { routes } from 'constants/routes'; | ||
|
||
import { useLanguage } from 'utils/context/translation'; | ||
import { labelToTypeLevel } from 'utils/leaderboards'; | ||
import { getLongTimeAgo } from 'utils/timeAgo'; | ||
import { api } from 'utils/trpc'; | ||
|
||
import css from './highest-pp-charts.module.css'; | ||
|
||
const pageSize = 20; | ||
|
||
export const HighestPpCharts = (): JSX.Element => { | ||
const params = useParams(); | ||
const charts = api.players.highestPpCharts.useInfiniteQuery( | ||
{ playerId: params.id ? Number(params.id) : undefined, pageSize }, | ||
{ getNextPageParam: (lastPage) => lastPage.nextCursor, initialCursor: 0 } | ||
); | ||
const lang = useLanguage(); | ||
|
||
return ( | ||
<Card p="xs" title={lang.BEST_SCORES}> | ||
<SimpleGrid spacing="xs" className={css.grid}> | ||
{charts.data?.pages.flatMap((page) => | ||
page.items.map((item) => { | ||
const date = new Date(item.date); | ||
const daysAgo = Math.floor((Date.now() - date.getTime()) / (1000 * 60 * 60 * 24)); | ||
console.log({ | ||
date, | ||
daysAgo, | ||
}); | ||
const dateColor = | ||
daysAgo < 30 | ||
? 'green' | ||
: `rgba(255, 255, 255, ${Math.min(1, Math.max(0.2, 1 - (daysAgo - 30) / 360))})`; | ||
const [chartType, chartLevel] = labelToTypeLevel(item.label); | ||
return ( | ||
<Card key={item.shared_chart} fz="md" p="0.5em" level={2} className={css.row}> | ||
{chartType && chartLevel ? ( | ||
<Flex> | ||
<ChartLabel type={chartType} level={chartLevel} /> | ||
</Flex> | ||
) : ( | ||
<span>{item.label}</span> | ||
)} | ||
<NavLink | ||
to={routes.leaderboard.sharedChart.getPath({ | ||
sharedChartId: item.shared_chart, | ||
})} | ||
> | ||
{item.full_name} | ||
</NavLink> | ||
<Text lh="1" c={dateColor} fz="xs"> | ||
{getLongTimeAgo(lang, date)} | ||
</Text> | ||
<Stack c="dark.2" gap="0.1em" ta="right"> | ||
<Text c="dark.1" lh="1em" size="xs"> | ||
{(item.pp * item.weight).toFixed(2)}pp | ||
</Text> | ||
<Text lh="1em" size="xs"> | ||
weighted {Math.round(item.weight * 100)}% | ||
</Text> | ||
</Stack> | ||
<Grade | ||
pl="0.5em" | ||
h="1em" | ||
score={item.score ?? 0} | ||
isPass={item.is_pass ?? false} | ||
scoring="phoenix" | ||
/> | ||
<Text pl="0.5em" fw="bold" ta="right"> | ||
{item.pp?.toFixed(2)} | ||
<Text span c="dark.2" ta="right"> | ||
{' '} | ||
pp | ||
</Text> | ||
</Text> | ||
</Card> | ||
); | ||
}) | ||
)} | ||
</SimpleGrid> | ||
{charts.isFetchingNextPage ? ( | ||
<Loader /> | ||
) : ( | ||
<Button | ||
leftSection={<MdExpandMore />} | ||
mt="xs" | ||
color="dark.4" | ||
onClick={() => charts.fetchNextPage()} | ||
> | ||
{lang.SHOW_MORE} | ||
</Button> | ||
)} | ||
</Card> | ||
); | ||
}; |
17 changes: 17 additions & 0 deletions
17
packages/web/src/features/profile/components/HighestPpCharts/highest-pp-charts.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
.grid { | ||
grid-template-columns: auto 1fr auto auto auto auto; | ||
} | ||
|
||
.row { | ||
display: grid; | ||
grid-template-columns: subgrid; | ||
grid-column: 1 / -1; | ||
align-items: center; | ||
justify-content: start; | ||
line-height: 1; | ||
} | ||
|
||
.playIcon { | ||
font-size: 0.7rem; | ||
margin-right: 0.5em; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters