mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: added basic rendering
This commit is contained in:
1 parent
aa6011b18d
commit
9a2e11a2a4
7 files changed
+233
-13
No files matched your search
Vendored
+1
@@ -28,6 +28,7 @@
|
|||||||
"statsfull",
|
"statsfull",
|
||||||
"Stringifying",
|
"Stringifying",
|
||||||
"strvk",
|
"strvk",
|
||||||
|
"subnation",
|
||||||
"tankaverages",
|
"tankaverages",
|
||||||
"tankopedia",
|
"tankopedia",
|
||||||
"tankstats",
|
"tankstats",
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
import { SlashCommandBuilder, SlashCommandSubcommandBuilder } from 'discord.js';
|
import { SlashCommandBuilder, SlashCommandSubcommandBuilder } from 'discord.js';
|
||||||
|
import * as Leaderboard from '../components/Leaderboard';
|
||||||
|
import TitleBar from '../components/TitleBar';
|
||||||
|
import Wrapper from '../components/Wrapper';
|
||||||
|
import { REGION_NAMES } from '../constants/regions';
|
||||||
|
import getWargamingResponse from '../core/blitz/getWargamingResponse';
|
||||||
import regionToRegionSubdomain from '../core/blitz/regionToRegionSubdomain';
|
import regionToRegionSubdomain from '../core/blitz/regionToRegionSubdomain';
|
||||||
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
||||||
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
||||||
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
||||||
|
import { WARGAMING_APPLICATION_ID } from '../core/node/arguments';
|
||||||
import { CommandRegistry } from '../events/interactionCreate';
|
import { CommandRegistry } from '../events/interactionCreate';
|
||||||
|
import { AccountInfo } from '../types/accountInfo';
|
||||||
|
|
||||||
export interface LeaguePlayer {
|
export interface LeaguePlayer {
|
||||||
spa_id: number;
|
spa_id: number;
|
||||||
@@ -23,7 +30,76 @@ export interface LeagueTop {
|
|||||||
result: LeaguePlayer[];
|
result: LeaguePlayer[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const LEAGUE_INDEXES = ['diamond', 'platinum', 'gold', 'silver', 'bronze'];
|
export type RatingsReward = {
|
||||||
|
from_position: number;
|
||||||
|
to_position: number;
|
||||||
|
count: number;
|
||||||
|
} & (
|
||||||
|
| {
|
||||||
|
type: 'vehicle';
|
||||||
|
|
||||||
|
vehicle: {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
nation: string;
|
||||||
|
subnation: string;
|
||||||
|
use_subnation_flag: boolean;
|
||||||
|
type_slug: string;
|
||||||
|
level: number;
|
||||||
|
roman_level: string;
|
||||||
|
user_string: string;
|
||||||
|
image_url: string;
|
||||||
|
preview_url: string;
|
||||||
|
is_premium: boolean;
|
||||||
|
is_collectible: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'stuff';
|
||||||
|
|
||||||
|
stuff: {
|
||||||
|
name: string;
|
||||||
|
count: number;
|
||||||
|
title: string;
|
||||||
|
image_url: string;
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
sizes: {};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export interface RatingsLeague {
|
||||||
|
title: string;
|
||||||
|
small_icon: string;
|
||||||
|
big_icon: string;
|
||||||
|
background: string;
|
||||||
|
index: number;
|
||||||
|
percentile: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RatingsInfo {
|
||||||
|
title: string;
|
||||||
|
icon: string | null;
|
||||||
|
start_at: string;
|
||||||
|
finish_at: string;
|
||||||
|
current_season: number;
|
||||||
|
updated_at: string;
|
||||||
|
count: number;
|
||||||
|
|
||||||
|
rewards: RatingsReward[];
|
||||||
|
leagues: RatingsLeague[];
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Caching ratings info...');
|
||||||
|
const ratingsLeagueInfo = fetch(
|
||||||
|
'https://na.wotblitz.com/en/api/rating-leaderboards/season/',
|
||||||
|
)
|
||||||
|
.then((response) => response.json() as Promise<RatingsInfo>)
|
||||||
|
.then((info) => {
|
||||||
|
console.log('Cached ratings info');
|
||||||
|
return info;
|
||||||
|
});
|
||||||
|
|
||||||
function optionalParameters(option: SlashCommandSubcommandBuilder) {
|
function optionalParameters(option: SlashCommandSubcommandBuilder) {
|
||||||
return option
|
return option
|
||||||
@@ -31,13 +107,15 @@ function optionalParameters(option: SlashCommandSubcommandBuilder) {
|
|||||||
option
|
option
|
||||||
.setName('limit')
|
.setName('limit')
|
||||||
.setDescription('How many rows to display (default: 16)')
|
.setDescription('How many rows to display (default: 16)')
|
||||||
.setRequired(true)
|
.setRequired(false)
|
||||||
.setMinValue(5)
|
.setMinValue(5)
|
||||||
.setMaxValue(30),
|
.setMaxValue(30),
|
||||||
)
|
)
|
||||||
.addStringOption(addUsernameChoices);
|
.addStringOption(addUsernameChoices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LEAGUE_INDEXES = ['diamond', 'platinum', 'gold', 'silver', 'bronze'];
|
||||||
|
|
||||||
export const ratingsCommand: CommandRegistry = {
|
export const ratingsCommand: CommandRegistry = {
|
||||||
inProduction: true,
|
inProduction: true,
|
||||||
inDevelopment: true,
|
inDevelopment: true,
|
||||||
@@ -98,14 +176,38 @@ export const ratingsCommand: CommandRegistry = {
|
|||||||
const { result } = await fetch(
|
const { result } = await fetch(
|
||||||
`https://${regionSubdomain}.wotblitz.com/en/api/rating-leaderboards/league/${leagueIndex}/top/`,
|
`https://${regionSubdomain}.wotblitz.com/en/api/rating-leaderboards/league/${leagueIndex}/top/`,
|
||||||
).then((response) => response.json() as Promise<LeagueTop>);
|
).then((response) => response.json() as Promise<LeagueTop>);
|
||||||
|
const { nickname } = await getWargamingResponse<AccountInfo>(
|
||||||
return `\`\`\`${result
|
`https://api.wotblitz.${player.region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${player.id}`,
|
||||||
|
).then((accounts) => accounts[player.id]);
|
||||||
|
const leagueInfo = (await ratingsLeagueInfo).leagues[leagueIndex];
|
||||||
|
const items = result
|
||||||
.slice(0, limit)
|
.slice(0, limit)
|
||||||
.map(
|
.map((player) => (
|
||||||
(player) =>
|
<Leaderboard.Item
|
||||||
`${player.number}: ${player.nickname} [${player.clan_tag}]`,
|
nickname={player.nickname}
|
||||||
)
|
points={player.score}
|
||||||
.join('\n')}\`\`\``;
|
position={player.number}
|
||||||
|
clan={player.clan_tag}
|
||||||
|
reward=""
|
||||||
|
deltaPoints={Math.round(Math.random() * 10 - 5)}
|
||||||
|
deltaPosition={Math.round(Math.random() * 10 - 5)}
|
||||||
|
key={player.spa_id}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<TitleBar
|
||||||
|
name={leagueInfo.title}
|
||||||
|
image={`https:${leagueInfo.small_icon}`}
|
||||||
|
description={`Top ${limit} players • ${new Date().toDateString()} • ${
|
||||||
|
REGION_NAMES[player.region]
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Leaderboard.Root>{items}</Leaderboard.Root>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
Whitespace-only changes.
@@ -0,0 +1,104 @@
|
|||||||
|
import { RatingsReward } from '../../../commands/ratings';
|
||||||
|
import { theme } from '../../../stitches.config';
|
||||||
|
|
||||||
|
export interface ItemProps {
|
||||||
|
position: number;
|
||||||
|
deltaPosition?: number;
|
||||||
|
points: number;
|
||||||
|
deltaPoints?: number;
|
||||||
|
reward: RatingsReward;
|
||||||
|
nickname: string;
|
||||||
|
clan?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Item({
|
||||||
|
position,
|
||||||
|
deltaPosition,
|
||||||
|
points,
|
||||||
|
deltaPoints,
|
||||||
|
reward,
|
||||||
|
nickname,
|
||||||
|
clan,
|
||||||
|
}: ItemProps) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
padding: 8,
|
||||||
|
backgroundColor: theme.colors.componentInteractive,
|
||||||
|
borderRadius: 4,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: 8,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
color: theme.colors.textLowContrast,
|
||||||
|
fontSize: 16,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{position}.
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: 4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
color: theme.colors.textHighContrast,
|
||||||
|
fontSize: 16,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{nickname}
|
||||||
|
</span>
|
||||||
|
{clan && (
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
color: theme.colors.textLowContrast,
|
||||||
|
fontSize: 16,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
[{clan}]
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{deltaPosition !== undefined && deltaPosition !== 0 && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: 4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
style={{
|
||||||
|
width: 8,
|
||||||
|
height: 8,
|
||||||
|
}}
|
||||||
|
src={
|
||||||
|
deltaPosition > 0
|
||||||
|
? 'https://i.imgur.com/qbjiXa1.png'
|
||||||
|
: 'https://i.imgur.com/3uyNhun.png'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
color: theme.colors.textLowContrast,
|
||||||
|
fontSize: 16,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{deltaPosition}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
|
export interface RootProps {
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Root({ children }: RootProps) {
|
||||||
|
return (
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export * from './components/Gap';
|
||||||
|
export * from './components/Item';
|
||||||
|
export * from './components/Root';
|
||||||
+1
-4
@@ -11,8 +11,5 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"jsx": "react-jsx"
|
"jsx": "react-jsx"
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["src/**/*.ts"]
|
||||||
"src/**/*.ts",
|
|
||||||
"src/components/AllStatsOverview/components/WN8SurroundingStat.tsx"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user