diff --git a/src/commands/ratings.tsx b/src/commands/ratings.tsx index ae9a64238..c3aa6d6be 100644 --- a/src/commands/ratings.tsx +++ b/src/commands/ratings.tsx @@ -1,4 +1,4 @@ -import { SlashCommandBuilder, SlashCommandSubcommandBuilder } from 'discord.js'; +import { SlashCommandBuilder } from 'discord.js'; import { BlitzkriegRatingsLeaderboard } from '../../scripts/buildRatingsLeaderboard'; import { octokit } from '../bot'; import * as Leaderboard from '../components/Leaderboard'; @@ -7,7 +7,7 @@ import Wrapper from '../components/Wrapper'; import { Region } from '../constants/regions'; import regionToRegionSubdomain from '../core/blitz/regionToRegionSubdomain'; import addRegionChoices from '../core/discord/addRegionChoices'; -import { CommandRegistry } from '../events/interactionCreate'; +import { CommandRegistryRaw } from '../events/interactionCreate'; export interface RatingsPlayer { spa_id: number; @@ -102,157 +102,145 @@ const ratingsInfo = fetch( return info; }); -function optionalParameters(option: SlashCommandSubcommandBuilder) { - return option - .addStringOption(addRegionChoices) - .addIntegerOption((option) => - option - .setName('limit') - .setDescription('How many rows to display (default: 10)') - .setRequired(false) - .setMinValue(5) - .setMaxValue(30), - ); -} - -const LEAGUE_INDEXES = ['diamond', 'platinum', 'gold', 'silver', 'bronze']; - export const DATABASE_REPO = { owner: 'tresabhi', repo: 'blitzkrieg-db' }; -export const ratingsCommand: CommandRegistry = { - inProduction: true, - inDevelopment: true, - inPublic: true, +const LEAGUE_SUBCOMMAND_TO_INDEX: Record = {}; - command: new SlashCommandBuilder() - .setName('ratings') - .setDescription('Ratings battles statistics') - .addSubcommandGroup((option) => - option - .setName('league') - .setDescription('Top league players') - .addSubcommand((option) => - optionalParameters( - option - .setName('diamond') - .setDescription('Top Diamond League players'), - ), - ) - .addSubcommand((option) => - optionalParameters( - option - .setName('platinum') - .setDescription('Top Platinum League players'), - ), - ) - .addSubcommand((option) => - optionalParameters( - option.setName('gold').setDescription('Top Gold League players'), - ), - ) - .addSubcommand((option) => - optionalParameters( - option - .setName('silver') - .setDescription('Top Silver League players'), - ), - ) - .addSubcommand((option) => - optionalParameters( - option - .setName('bronze') - .setDescription('Top Bronze League players'), - ), - ), - ), - async handler(interaction) { - const subcommandGroup = interaction.options.getSubcommandGroup(true); +export const ratingsCommand = new Promise( + async (resolve) => { + const awaitedRatingsInfo = await ratingsInfo; - if (subcommandGroup === 'league') { - const limit = interaction.options.getInteger('limit') ?? 10; - const subcommand = interaction.options.getSubcommand(true); - const leagueIndex = LEAGUE_INDEXES.indexOf(subcommand); - const region = interaction.options.getString('region') as Region; - const regionSubdomain = regionToRegionSubdomain(region); - const result = await fetch( - `https://${regionSubdomain}.wotblitz.com/en/api/rating-leaderboards/league/${leagueIndex}/top/`, - ) - .then((response) => response.json() as Promise) - .then(({ result }) => result.slice(0, limit)); - const awaitedInfo = await ratingsInfo; - const leagueInfo = awaitedInfo.leagues[leagueIndex]; - const midnightLeaderboard = await octokit.repos - .getContent({ - ...DATABASE_REPO, - path: `${region}/ratings/${awaitedInfo.current_season}/midnight.json`, - }) - .then(({ data }) => { - if (!Array.isArray(data) && data.type === 'file') { - const content = Buffer.from(data.content, 'base64').toString(); - const jsonContent = JSON.parse( - content, - ) as BlitzkriegRatingsLeaderboard; + const command = new SlashCommandBuilder() + .setName('ratings') + .setDescription('Ratings battles statistics') + .addSubcommandGroup((option) => { + const subcommandGroup = option + .setName('league') + .setDescription('Top league players'); - return jsonContent; - } - }) - .catch(() => console.warn('No midnight leaderboard found')); - const items = await Promise.all( - result.map(async (player) => { - const reward = awaitedInfo.rewards.find( - (reward) => - player.number >= reward.from_position && - player.number <= reward.to_position, + awaitedRatingsInfo.leagues.forEach((league) => { + subcommandGroup.addSubcommand((option) => { + const subcommandName = league.title.split(' ')[0].toLowerCase(); + LEAGUE_SUBCOMMAND_TO_INDEX[subcommandName] = league.index; + + return option + .setName(subcommandName) + .setDescription(`Top ${league.title} players`) + .addStringOption(addRegionChoices) + .addIntegerOption((option) => + option + .setName('limit') + .setDescription('How many rows to display (default: 10)') + .setRequired(false) + .setMinValue(5) + .setMaxValue(30), + ); + }); + }); + + return subcommandGroup; + }); + + resolve({ + inProduction: true, + inDevelopment: true, + inPublic: true, + + command, + + async handler(interaction) { + const subcommandGroup = interaction.options.getSubcommandGroup(true); + + if (subcommandGroup === 'league') { + const limit = interaction.options.getInteger('limit') ?? 10; + const subcommand = interaction.options.getSubcommand(true); + const leagueIndex = LEAGUE_SUBCOMMAND_TO_INDEX[subcommand]; + const region = interaction.options.getString('region') as Region; + const regionSubdomain = regionToRegionSubdomain(region); + const result = await fetch( + `https://${regionSubdomain}.wotblitz.com/en/api/rating-leaderboards/league/${leagueIndex}/top/`, + ) + .then((response) => response.json() as Promise) + .then(({ result }) => result.slice(0, limit)); + const awaitedInfo = await ratingsInfo; + const leagueInfo = awaitedInfo.leagues[leagueIndex]; + const midnightLeaderboard = await octokit.repos + .getContent({ + ...DATABASE_REPO, + path: `${region}/ratings/${awaitedInfo.current_season}/midnight.json`, + }) + .then(({ data }) => { + if (!Array.isArray(data) && data.type === 'file') { + const content = Buffer.from(data.content, 'base64').toString(); + const jsonContent = JSON.parse( + content, + ) as BlitzkriegRatingsLeaderboard; + + return jsonContent; + } + }) + .catch(() => console.warn('No midnight leaderboard found')); + const items = await Promise.all( + result.map(async (player) => { + const reward = awaitedInfo.rewards.find( + (reward) => + player.number >= reward.from_position && + player.number <= reward.to_position, + ); + const midnightIndex = midnightLeaderboard?.findIndex( + (item) => item.id === player.spa_id, + ); + const midnightScore = + midnightIndex === undefined + ? player.score + : midnightLeaderboard![midnightIndex].score; + const midnightPosition = + midnightIndex === undefined ? player.number : midnightIndex + 1; + + return ( + + ); + }), ); - const midnightIndex = midnightLeaderboard?.findIndex( - (item) => item.id === player.spa_id, - ); - const midnightScore = - midnightIndex === undefined - ? player.score - : midnightLeaderboard![midnightIndex].score; - const midnightPosition = - midnightIndex === undefined ? player.number : midnightIndex + 1; + + const playersBefore = result[0].number - 1; + const playersAfter = + awaitedInfo.count - result[result.length - 1].number; return ( - + + + + + {playersBefore > 0 && ( + + )} + {items} + {playersAfter > 0 && } + + ); - }), - ); + } - const playersBefore = result[0].number - 1; - const playersAfter = awaitedInfo.count - result[result.length - 1].number; - - return ( - - - - - {playersBefore > 0 && } - {items} - {playersAfter > 0 && } - - - ); - } - - return []; + return []; + }, + }); }, -}; +);