From 3ea77f5899ad84461e2d3399d15240a7e0ea78a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 1 Nov 2023 11:45:19 -0500 Subject: [PATCH] feat: autocomplete size limits --- src/core/blitz/searchClansAcrossRegions.ts | 36 +++++++++++--------- src/core/blitz/searchPlayersAcrossRegions.ts | 4 +-- src/core/discord/autocompleteClan.ts | 33 ++++++++++++------ src/core/discord/autocompleteTanks.ts | 28 +++++++++++---- src/core/discord/autocompleteUsername.ts | 32 ++++++++++++----- 5 files changed, 88 insertions(+), 45 deletions(-) diff --git a/src/core/blitz/searchClansAcrossRegions.ts b/src/core/blitz/searchClansAcrossRegions.ts index 98b4cfabb..45539244b 100644 --- a/src/core/blitz/searchClansAcrossRegions.ts +++ b/src/core/blitz/searchClansAcrossRegions.ts @@ -9,43 +9,45 @@ export type ClanListWithRegion = (Clan & { export default async function searchClansAcrossRegions( search: string, - limit = 9, + limit = 25, ) { const trimmed = search.trim(); if (trimmed.length < 3 && trimmed.length > 100) return []; - const normalizedLimit = Math.round(limit / 3); + const normalizedLimit = Math.floor(limit / 3); + + // TODO: remove splice once wargaming fixes the functionality of the limit felid return ( await Promise.all([ fetchBlitz( `https://api.wotblitz.com/wotb/clans/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${search}&limit=${normalizedLimit}`, - ).then( - (value) => - value && - value.map((account) => ({ + ).then((value) => + value + .map((account) => ({ ...account, region: 'com' as Region, - })), + })) + .splice(0, normalizedLimit), ), fetchBlitz( `https://api.wotblitz.eu/wotb/clans/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${search}&limit=${normalizedLimit}`, - ).then( - (value) => - value && - value.map((account) => ({ + ).then((value) => + value + .map((account) => ({ ...account, region: 'eu' as Region, - })), + })) + .splice(0, normalizedLimit), ), fetchBlitz( `https://api.wotblitz.asia/wotb/clans/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${search}&limit=${normalizedLimit}`, - ).then( - (value) => - value && - value.map((account) => ({ + ).then((value) => + value + .map((account) => ({ ...account, region: 'asia' as Region, - })), + })) + .splice(0, normalizedLimit), ), ]) ) diff --git a/src/core/blitz/searchPlayersAcrossRegions.ts b/src/core/blitz/searchPlayersAcrossRegions.ts index e8a12a17a..cfc61bb89 100644 --- a/src/core/blitz/searchPlayersAcrossRegions.ts +++ b/src/core/blitz/searchPlayersAcrossRegions.ts @@ -16,10 +16,10 @@ export const usernamePatternWithoutPosition = /[a-zA-Z0-9_]{3,24}/; export default async function searchPlayersAcrossRegions( search: string, - limit = 9, + limit = 25, ) { const trimmedSearch = search.trim(); - const normalizedLimit = Math.round(limit / 3); + const normalizedLimit = Math.floor(limit / 3); const encodedSearch = encodeURIComponent(trimmedSearch); if (usernamePattern.test(trimmedSearch)) { diff --git a/src/core/discord/autocompleteClan.ts b/src/core/discord/autocompleteClan.ts index 83b4bdc0e..bbbd9a2de 100644 --- a/src/core/discord/autocompleteClan.ts +++ b/src/core/discord/autocompleteClan.ts @@ -3,26 +3,39 @@ import { AutocompleteInteraction, CacheType, } from 'discord.js'; -import { REGION_NAMES } from '../../constants/regions'; +import { REGION_NAMES_SHORT } from '../../constants/regions'; import searchClansAcrossRegions from '../blitz/searchClansAcrossRegions'; +export const DISCORD_CHOICES_MAX_NAME_SIZE = 25; +export const OVERFLOW_SUFFIX = '…'; + export default async function autocompleteClan( interaction: AutocompleteInteraction, ) { const focusedOption = interaction.options.getFocused(true); if (focusedOption.name !== 'clan') return; if (focusedOption.value.length < 2) return interaction.respond([]); - const players = await searchClansAcrossRegions(focusedOption.value); + const clans = await searchClansAcrossRegions(focusedOption.value); await interaction.respond( - players - ? players.map( - (player) => - ({ - name: `${player.name} (${REGION_NAMES[player.region]})`, - value: `${player.region}/${player.clan_id}`, - }) satisfies ApplicationCommandOptionChoiceData, - ) + clans + ? clans.map((clan) => { + let name = `${clan.name} (${REGION_NAMES_SHORT[clan.region]})`; + + if (name.length > DISCORD_CHOICES_MAX_NAME_SIZE) { + const overSize = name.length - DISCORD_CHOICES_MAX_NAME_SIZE; + + name = `${clan.name.slice( + 0, + clan.name.length - overSize - OVERFLOW_SUFFIX.length, + )}${OVERFLOW_SUFFIX} (${REGION_NAMES_SHORT[clan.region]})`; + } + + return { + name, + value: `${clan.region}/${clan.clan_id}`, + } satisfies ApplicationCommandOptionChoiceData; + }) : [], ); } diff --git a/src/core/discord/autocompleteTanks.ts b/src/core/discord/autocompleteTanks.ts index adfc8477b..de74a907f 100644 --- a/src/core/discord/autocompleteTanks.ts +++ b/src/core/discord/autocompleteTanks.ts @@ -5,6 +5,10 @@ import { } from 'discord.js'; import { go } from 'fuzzysort'; import { TANK_NAMES_DIACRITICS } from '../blitzstars/tankopedia'; +import { + DISCORD_CHOICES_MAX_NAME_SIZE, + OVERFLOW_SUFFIX, +} from './autocompleteClan'; export default async function autocompleteTanks( interaction: AutocompleteInteraction, @@ -18,13 +22,23 @@ export default async function autocompleteTanks( go(focusedOption.value, await TANK_NAMES_DIACRITICS, { keys: ['combined'], limit: 10, - }).map( - async (item) => - ({ - name: item.obj.original, - value: `${item.obj.id}`, - }) satisfies ApplicationCommandOptionChoiceData, - ), + }).map(async (item) => { + let name = item.obj.original; + + if (name.length > DISCORD_CHOICES_MAX_NAME_SIZE) { + const overSize = name.length - DISCORD_CHOICES_MAX_NAME_SIZE; + + name = `${item.obj.original.slice( + 0, + item.obj.original.length - overSize - OVERFLOW_SUFFIX.length, + )}${OVERFLOW_SUFFIX}`; + } + + return { + name, + value: `${item.obj.id}`, + } satisfies ApplicationCommandOptionChoiceData; + }), ) : [], ); diff --git a/src/core/discord/autocompleteUsername.ts b/src/core/discord/autocompleteUsername.ts index 5160a2024..333b51624 100644 --- a/src/core/discord/autocompleteUsername.ts +++ b/src/core/discord/autocompleteUsername.ts @@ -5,6 +5,10 @@ import { } from 'discord.js'; import { REGION_NAMES_SHORT } from '../../constants/regions'; import searchPlayersAcrossRegions from '../blitz/searchPlayersAcrossRegions'; +import { + DISCORD_CHOICES_MAX_NAME_SIZE, + OVERFLOW_SUFFIX, +} from './autocompleteClan'; export default async function autocompleteUsername( interaction: AutocompleteInteraction, @@ -16,15 +20,25 @@ export default async function autocompleteUsername( try { await interaction.respond( players - ? players.map( - (player) => - ({ - name: `${player.nickname} (${ - REGION_NAMES_SHORT[player.region] - })`, - value: `${player.region}/${player.account_id}`, - }) satisfies ApplicationCommandOptionChoiceData, - ) + ? players.map((player) => { + let name = `${player.nickname} (${ + REGION_NAMES_SHORT[player.region] + })`; + + if (name.length > DISCORD_CHOICES_MAX_NAME_SIZE) { + const overSize = name.length - DISCORD_CHOICES_MAX_NAME_SIZE; + + name = `${player.nickname.slice( + 0, + player.nickname.length - overSize - OVERFLOW_SUFFIX.length, + )}${OVERFLOW_SUFFIX} (${REGION_NAMES_SHORT[player.region]})`; + } + + return { + name, + value: `${player.region}/${player.account_id}`, + } satisfies ApplicationCommandOptionChoiceData; + }) : [], ); } catch (error) {}