diff --git a/src/commands/ownedtanks.ts b/src/commands/ownedtanks.tsx similarity index 54% rename from src/commands/ownedtanks.ts rename to src/commands/ownedtanks.tsx index 214b37e81..55f7a434d 100644 --- a/src/commands/ownedtanks.ts +++ b/src/commands/ownedtanks.tsx @@ -1,17 +1,21 @@ import { SlashCommandBuilder } from 'discord.js'; -import markdownEscape from 'markdown-escape'; +import PoweredByWargaming from '../components/PoweredByWargaming.js'; +import * as Tanks from '../components/Tanks/index.js'; +import TitleBar from '../components/TitleBar.js'; +import Wrapper from '../components/Wrapper.js'; +import { BLITZ_SERVERS } from '../constants/servers.js'; import usernameAutocomplete from '../core/autocomplete/username.js'; import getBlitzAccount from '../core/blitz/getBlitzAccount.js'; import getTankStats from '../core/blitz/getTankStats.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; -import resolveTankName from '../core/blitz/resolveTankName.js'; -import { TANK_TYPE_EMOJIS, tankopedia } from '../core/blitz/tankopedia.js'; +import { TIER_ROMAN_NUMERALS, tankopedia } from '../core/blitz/tankopedia.js'; import cmdName from '../core/interaction/cmdName.js'; -import infoEmbed from '../core/interaction/infoEmbed.js'; import addUsernameOption from '../core/options/addUsernameOption.js'; import { args } from '../core/process/args.js'; +import render from '../core/ui/render.js'; import { CommandRegistry } from '../events/interactionCreate.js'; import { AccountInfo } from '../types/accountInfo.js'; +import { PlayerClanData } from '../types/playerClanData.js'; const COMP_TANKS = [ // light tanks @@ -36,7 +40,7 @@ const COMP_TANKS = [ export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() @@ -63,36 +67,44 @@ export default { const tanks = tankStats .map((tankData) => tankopedia[tankData.tank_id]) .filter((tank) => tank?.tier === tier); + const clanData = await getWargamingResponse( + `https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${args['wargaming-application-id']}&account_id=${id}&extra=clan`, + ); - await interaction.editReply({ - embeds: [ - infoEmbed( - `${markdownEscape(accountInfo[id].nickname)}'s owned ${ - tier === null ? '' : `tier ${tier} ` - }tanks`, - `${ - tanks.length === 0 - ? `No tanks found in tier ${tier}` - : tanks - .map( - (tank) => - `${TANK_TYPE_EMOJIS[tank.type]} ${markdownEscape( - resolveTankName(tank.tank_id), - )} ${tank.is_premium ? '⭐' : ''}${ - COMP_TANKS.includes(tank.tank_id) ? 'šŸ†' : '' - }`, - ) - .join('\n') - }\n\n**Legend**\n⭐ = Premium/Collector\n${ - tier === 10 ? 'šŸ† = Comp Tank\n' : '' - }${TANK_TYPE_EMOJIS.heavyTank} = Heavy\n${ - TANK_TYPE_EMOJIS.mediumTank - } = Medium\n${TANK_TYPE_EMOJIS.lightTank} = Light\n${ - TANK_TYPE_EMOJIS['AT-SPG'] - } = Tank Destroyer`, - ), - ], - }); + console.time('ownedtanks'); + const image = await render( + + {/* TODO: integrate some of these into title bar */} + + + + {tanks.map((tank) => ( + + ))} + + + + , + ); + + await interaction.editReply({ files: [image] }); + console.timeEnd('ownedtanks'); }, autocomplete: usernameAutocomplete, diff --git a/src/commands/stats.tsx b/src/commands/stats.tsx index 06235a9a9..f9354e72e 100644 --- a/src/commands/stats.tsx +++ b/src/commands/stats.tsx @@ -172,7 +172,6 @@ export default { files: [image], components: [actionRow], }); - }, autocomplete: usernameAutocomplete, diff --git a/src/components/PoweredByWargaming.tsx b/src/components/PoweredByWargaming.tsx new file mode 100644 index 000000000..e18ad7e7f --- /dev/null +++ b/src/components/PoweredByWargaming.tsx @@ -0,0 +1,15 @@ +import { theme } from '../stitches.config.js'; + +export default function PoweredByWargaming() { + return ( +
+ + + Powered by Wargaming + +
+ ); +} diff --git a/src/components/Tanks/components/Item.tsx b/src/components/Tanks/components/Item.tsx new file mode 100644 index 000000000..91f7061e4 --- /dev/null +++ b/src/components/Tanks/components/Item.tsx @@ -0,0 +1,35 @@ +import { TANK_ICONS, TankType } from '../../../core/blitz/tankopedia.js'; + +export interface ItemProps { + icon?: string; + type: TankType; + name: string; +} + +export function Item({ icon, type, name }: ItemProps) { + return ( +
+ {icon && } + +
+ + + {name} + +
+
+ ); +} diff --git a/src/components/Tanks/components/Root.tsx b/src/components/Tanks/components/Root.tsx new file mode 100644 index 000000000..1a23e18ea --- /dev/null +++ b/src/components/Tanks/components/Root.tsx @@ -0,0 +1,21 @@ +import { ReactNode } from 'react'; + +export interface RootProps { + children: ReactNode; +} + +export function Root({ children }: RootProps) { + return ( +
+ {children} +
+ ); +} diff --git a/src/components/Tanks/index.ts b/src/components/Tanks/index.ts new file mode 100644 index 000000000..9ac57386e --- /dev/null +++ b/src/components/Tanks/index.ts @@ -0,0 +1,2 @@ +export * from './components/Item.js'; +export * from './components/Root.js'; diff --git a/src/core/blitz/tankopedia.ts b/src/core/blitz/tankopedia.ts index 526772e74..def1090eb 100644 --- a/src/core/blitz/tankopedia.ts +++ b/src/core/blitz/tankopedia.ts @@ -1,6 +1,8 @@ import { StaticPool } from 'node-worker-threads-pool'; import { WargamingResponse } from '../../types/wargamingResponse.js'; +export type TankType = 'AT-SPG' | 'lightTank' | 'mediumTank' | 'heavyTank'; + export interface TankopediaEntry { name: string; nation: string; @@ -9,7 +11,7 @@ export interface TankopediaEntry { cost: { price_credit: number; price_gold: number }; images: { preview: string; normal: string }; tank_id: number; - type: string; + type: TankType; description: string; } @@ -25,14 +27,24 @@ export const tankopedia = ( ).data; console.log('Cached tankopedia'); -/** - * @deprecated - */ -export const TANK_TYPE_EMOJIS: Record = { - 'AT-SPG': 'šŸ”½', - heavyTank: 'šŸ‡­', - mediumTank: 'šŸ‡²', - lightTank: 'šŸ‡±', +export const TANK_ICONS: Record = { + 'AT-SPG': 'https://i.imgur.com/BIHSEH0.png', + lightTank: 'https://i.imgur.com/CSNha5V.png', + mediumTank: 'https://i.imgur.com/wvf3ltm.png', + heavyTank: 'https://i.imgur.com/ECeqlZa.png', +}; + +export const TIER_ROMAN_NUMERALS: Record = { + 1: 'I', + 2: 'II', + 3: 'III', + 4: 'IV', + 5: 'V', + 6: 'VI', + 7: 'VII', + 8: 'VIII', + 9: 'IX', + 10: 'X', }; export const TANK_IDS = Object.keys(tankopedia).map((id) => Number(id));