feat: simpler subcommands

This commit is contained in:
TrèsAbhi committed 2023-10-11 18:26:35 -05:00
1 parent f965452c5d
commit 78e4c82f20
28 files changed
+397 -461

No files matched your search

+1 -1
View File
@@ -58,7 +58,7 @@ export const eligibleCommand: CommandRegistry = {
let body = '';
if (clan === 'SKLLD') {
const { diffed } = await getDiffedTankStats(
const { diff: diffed } = await getDiffedTankStats(
server,
id,
getTimeDaysAgo(server, 30),
+3 -4
View File
@@ -1,9 +1,9 @@
import { SlashCommandBuilder } from 'discord.js';
import { CYCLIC_API } from '../constants/cyclic';
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
import getWargamingResponse from '../core/blitz/getWargamingResponse';
import resolveTankId from '../core/blitz/resolveTankId';
import addStatTypeSubCommandGroups from '../core/discord/addStatTypeSubCommandGroups';
import addUsernameChoices from '../core/discord/addUsernameChoices';
import autocompleteTanks from '../core/discord/autocompleteTanks';
import autocompleteUsername from '../core/discord/autocompleteUsername';
import interactionToURL from '../core/discord/interactionToURL';
@@ -24,7 +24,7 @@ export const evolutionCommand = new Promise<CommandRegistryRaw>(
new SlashCommandBuilder()
.setName('evolution')
.setDescription('Evolution of statistics'),
false,
(option) => option.addStringOption(addUsernameChoices),
);
resolve({
@@ -59,7 +59,6 @@ export const evolutionCommand = new Promise<CommandRegistryRaw>(
return [
await evolution(commandGroup, period, player, tankId),
primaryButton(path, 'Refresh'),
// linkButton(`${CYCLIC_API}/${path}`, 'Embed'),
linkButton(
`https://www.blitzstars.com/player/${player.region}/${nickname}${
commandGroup === 'tank' ? `/tank/${tankId!}` : ''
@@ -75,7 +74,7 @@ export const evolutionCommand = new Promise<CommandRegistryRaw>(
},
async button(interaction) {
const url = new URL(`${CYCLIC_API}/${interaction.customId}`);
const url = new URL(`https://example.com/${interaction.customId}`);
const path = url.pathname.split('/').filter(Boolean);
const commandGroup = path[1] as StatType;
const player = await resolvePlayerFromButton(interaction);
+3 -3
View File
@@ -1,10 +1,10 @@
import { SlashCommandBuilder } from 'discord.js';
import { TreeTypeString } from '../components/Tanks';
import { CYCLIC_API } from '../constants/cyclic';
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
import getWargamingResponse from '../core/blitz/getWargamingResponse';
import resolveTankId from '../core/blitz/resolveTankId';
import addStatTypeSubCommandGroups from '../core/discord/addStatTypeSubCommandGroups';
import addUsernameChoices from '../core/discord/addUsernameChoices';
import autocompleteTanks from '../core/discord/autocompleteTanks';
import autocompleteUsername from '../core/discord/autocompleteUsername';
import interactionToURL from '../core/discord/interactionToURL';
@@ -25,6 +25,7 @@ export const fullStatsCommand = new Promise<CommandRegistryRaw>(
new SlashCommandBuilder()
.setName('full-stats')
.setDescription('Full in-game statistics'),
(option) => option.addStringOption(addUsernameChoices),
);
resolve({
@@ -82,7 +83,6 @@ export const fullStatsCommand = new Promise<CommandRegistryRaw>(
: null,
),
primaryButton(path, 'Refresh'),
// linkButton(`${CYCLIC_API}/${path}`, 'Embed'),
linkButton(
`https://www.blitzstars.com/player/${player.region}/${nickname}`,
'BlitzStars',
@@ -96,7 +96,7 @@ export const fullStatsCommand = new Promise<CommandRegistryRaw>(
},
async button(interaction) {
const url = new URL(`${CYCLIC_API}/${interaction.customId}`);
const url = new URL(`https://example.com/${interaction.customId}`);
const path = url.pathname.split('/').filter(Boolean);
const commandGroup = path[1] as StatType;
const player = await resolvePlayerFromButton(interaction);
+91 -71
View File
@@ -1,28 +1,77 @@
import { SlashCommandBuilder } from 'discord.js';
import AllStatsOverview from '../components/AllStatsOverview';
import NoData, { NoDataType } from '../components/NoData';
import { TreeTypeString } from '../components/Tanks';
import { CYCLIC_API } from '../constants/cyclic';
import TitleBar from '../components/TitleBar';
import Wrapper from '../components/Wrapper';
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
import { StatFilters, filterStats } from '../core/blitz/filterStats';
import getWargamingResponse from '../core/blitz/getWargamingResponse';
import resolveTankId from '../core/blitz/resolveTankId';
import { filtersToDescription } from '../core/blitzkrieg/filtersToDescription';
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
import getDiffedTankStats from '../core/blitzstars/getDiffedTankStats';
import { PeriodType } from '../core/discord/addPeriodSubCommands';
import addStatTypeSubCommandGroups from '../core/discord/addStatTypeSubCommandGroups';
import addUsernameChoices from '../core/discord/addUsernameChoices';
import autocompleteTanks from '../core/discord/autocompleteTanks';
import autocompleteUsername from '../core/discord/autocompleteUsername';
import interactionToURL from '../core/discord/interactionToURL';
import linkButton from '../core/discord/linkButton';
import primaryButton from '../core/discord/primaryButton';
import { refreshButton } from '../core/discord/refreshButton';
import resolvePeriodFromButton from '../core/discord/resolvePeriodFromButton';
import resolvePeriodFromCommand from '../core/discord/resolvePeriodFromCommand';
import resolvePeriodFromCommand, {
ResolvedPeriod,
} from '../core/discord/resolvePeriodFromCommand';
import resolvePlayerFromButton from '../core/discord/resolvePlayerFromButton';
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
import resolvePlayerFromCommand, {
ResolvedPlayer,
} from '../core/discord/resolvePlayerFromCommand';
import { CommandRegistryRaw } from '../events/interactionCreate';
import stats, { MultiTankFilters, StatType } from '../renderers/stats';
import { AccountInfo } from '../types/accountInfo';
import { PlayerClanData } from '../types/playerClanData';
export default async function render(
{ region, id }: ResolvedPlayer,
{ start, end, name: statsName }: ResolvedPeriod,
filters: StatFilters,
) {
const nickname = (
await getWargamingResponse<AccountInfo>(
`https://api.wotblitz.${region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
)
)[id].nickname;
const clan = (
await getWargamingResponse<PlayerClanData>(
`https://api.wotblitz.${region}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
)
)[id]?.clan;
const clanImage = clan
? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clan.emblem_set_id}.png`
: undefined;
const diffedTankStats = await getDiffedTankStats(region, id, start, end);
const { stats, supplementary } = await filterStats(diffedTankStats, filters);
return (
<Wrapper>
<TitleBar
name={nickname}
image={clanImage}
description={`${statsName} • ${await filtersToDescription(filters)}`}
/>
{!stats?.battles && <NoData type={NoDataType.BattlesInPeriod} />}
{stats?.battles > 0 && (
<AllStatsOverview stats={stats} supplementaryStats={supplementary} />
)}
</Wrapper>
);
}
export const statsCommand = new Promise<CommandRegistryRaw>(async (resolve) => {
const command = await addStatTypeSubCommandGroups(
new SlashCommandBuilder()
.setName('stats')
.setDescription('Regular battles statistics'),
(option) => option.addStringOption(addUsernameChoices),
);
resolve({
@@ -32,59 +81,38 @@ export const statsCommand = new Promise<CommandRegistryRaw>(async (resolve) => {
command,
async handler(interaction) {
const commandGroup = interaction.options.getSubcommandGroup(
true,
) as StatType;
const player = await resolvePlayerFromCommand(interaction);
const resolvedPlayer = await resolvePlayerFromCommand(interaction);
const resolvedPeriod = resolvePeriodFromCommand(
player.region,
resolvedPlayer.region,
interaction,
);
const period = interaction.options.getString('period');
const tankIdRaw = interaction.options.getString('tank')!;
const tankId =
commandGroup === 'tank' ? await resolveTankId(tankIdRaw) : null;
const start = interaction.options.getInteger('start');
const end = interaction.options.getInteger('end');
const filters = {
nation: interaction.options.getString('nation') ?? undefined,
tier:
parseInt(interaction.options.getString('tier') ?? '0') || undefined,
tankType: interaction.options.getString('tank-type') ?? undefined,
treeType:
(interaction.options.getString('tree-type') as
| TreeTypeString
| undefined) ?? undefined,
tank:
parseInt(interaction.options.getString('tank') ?? '0') || undefined,
} satisfies StatFilters;
const path = interactionToURL(interaction, {
...player,
tankId,
start,
end,
period,
...resolvedPlayer,
...((interaction.options.getSubcommand() as PeriodType) === 'custom'
? {
start: interaction.options.getInteger('start', true),
end: interaction.options.getInteger('end', true),
}
: undefined),
...filters,
});
const { nickname } = (
await getWargamingResponse<AccountInfo>(
`https://api.wotblitz.${player.region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${player.id}`,
)
)[player.id];
const tierOption = interaction.options.getString('tier');
return [
await stats(
commandGroup,
resolvedPeriod,
player,
commandGroup === 'tank'
? tankId
: commandGroup === 'multi-tank'
? ({
'tank-type':
interaction.options.getString('tank-type') ?? undefined,
nation: interaction.options.getString('nation') ?? undefined,
tier: tierOption ? parseInt(tierOption) : undefined,
'tree-type': (interaction.options.getString('tree-type') ??
undefined) as TreeTypeString | undefined,
} satisfies Partial<MultiTankFilters>)
: null,
),
primaryButton(path, 'Refresh'),
// linkButton(`${CYCLIC_API}/${path}`, 'Embed'),
linkButton(
`https://www.blitzstars.com/player/${player.region}/${nickname}`,
'BlitzStars',
),
await render(resolvedPlayer, resolvedPeriod, filters),
refreshButton(interaction, path),
await getBlitzStarsLinkButton(resolvedPlayer.region, resolvedPlayer.id),
];
},
@@ -94,27 +122,19 @@ export const statsCommand = new Promise<CommandRegistryRaw>(async (resolve) => {
},
async button(interaction) {
const url = new URL(`${CYCLIC_API}/${interaction.customId}`);
const path = url.pathname.split('/').filter(Boolean);
const commandGroup = path[1] as StatType;
const url = new URL(`https://example.com${interaction.customId}`);
const player = await resolvePlayerFromButton(interaction);
const period = resolvePeriodFromButton(player.region, interaction);
return await stats(
commandGroup,
period,
player,
commandGroup === 'tank'
? parseInt(url.searchParams.get('tankId')!)
: commandGroup === 'multi-tank'
? ({
'tank-type': url.searchParams.get('tank-type')!,
nation: url.searchParams.get('nation')!,
tier: parseInt(url.searchParams.get('tier')!),
'tree-type': url.searchParams.get('tree-type') as TreeTypeString,
} satisfies MultiTankFilters)
: null,
);
return await render(player, period, {
nation: url.searchParams.get('nation') ?? undefined,
tank: parseInt(url.searchParams.get('tank') ?? '0') || undefined,
tankType: url.searchParams.get('tank-type') ?? undefined,
treeType:
(url.searchParams.get('tree-type') as TreeTypeString | undefined) ??
undefined,
tier: parseInt(url.searchParams.get('tier') ?? '0') || undefined,
});
},
});
});
+1 -1
View File
@@ -65,7 +65,7 @@ export const todayCommand: CommandRegistry = {
return [
await today(player, cutoff, maximized, showTotal, false),
primaryButton(path, 'Refresh'),
// linkButton(`${CYCLIC_API}/${path}`, 'Embed'),
// linkButton(`https://example.com/${path}`, 'Embed'),
linkButton(
`https://www.blitzstars.com/player/${player.region}/${nickname}`,
'BlitzStars',