feat: user error strings

This commit is contained in:
TrèsAbhi committed 2024-03-09 11:48:35 -06:00
1 parent 265eff98bf
commit 889ae39e3b
14 files changed
+71 -374

No files matched your search

+2 -2
View File
@@ -51,11 +51,11 @@ export async function renderBreakdown(
const { t, translate } = translator(locale);
const awaitedTankDefinitions = await tankDefinitions;
const awaitedTankAverages = await tankAverages;
const statsInPeriod = await getStatsInPeriod(region, id, start, end);
const statsInPeriod = await getStatsInPeriod(region, id, start, end, locale);
const { filteredOrder } = await filterStats(statsInPeriod, filters);
const accountInfo = await getAccountInfo(region, id);
const clanData = await getClanAccountInfo(region, id, ['clan']);
const tankStats = await getTankStats(region, id);
const tankStats = await getTankStats(region, id, locale);
const filterDescriptions = await filtersToDescription(filters, locale);
const orderedCurrentStats: AllStats[] = [];
const orderedCareerStats: AllStats[] = [];
+4 -2
View File
@@ -48,7 +48,7 @@ async function render(
includeLatestHistories: true,
includePreviousHistories: true,
})
: getTankHistories(region, id, {
: getTankHistories(region, id, locale, {
tankId: tankId!,
start,
end,
@@ -140,7 +140,9 @@ export const evolutionCommand = new Promise<CommandRegistry>(
const period = resolvePeriodFromCommand(player.region, interaction);
const tankIdRaw = interaction.options.getString('tank')!;
const tankId =
commandGroup === 'tank' ? await resolveTankId(tankIdRaw) : null;
commandGroup === 'tank'
? await resolveTankId(tankIdRaw, interaction.locale)
: null;
const path = commandToURL(interaction, {
...player,
...getCustomPeriodParams(interaction),
+7 -1
View File
@@ -41,7 +41,13 @@ async function render(
const { nickname } = await getAccountInfo(region, id);
const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan;
const clanImage = clan ? emblemIdToURL(clan.emblem_set_id) : undefined;
const diffedTankStats = await getStatsInPeriod(region, id, start, end);
const diffedTankStats = await getStatsInPeriod(
region,
id,
start,
end,
locale,
);
const { stats, supplementary, filteredOrder } = await filterStats(
diffedTankStats,
filters,
+1 -1
View File
@@ -37,7 +37,7 @@ export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
const account = await resolvePlayerFromCommand(interaction);
const { id, region: server } = account;
const accountInfo = await getAccountInfo(server, id);
const tankStats = await getTankStats(server, id);
const tankStats = await getTankStats(server, id, interaction.locale);
const filteredTanks = (
await Promise.all(
tankStats.map(async (tankData) => ({
+7 -1
View File
@@ -39,7 +39,13 @@ async function render(
const { nickname } = await getAccountInfo(region, id);
const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan;
const clanImage = clan ? emblemIdToURL(clan.emblem_set_id) : undefined;
const diffedTankStats = await getStatsInPeriod(region, id, start, end);
const diffedTankStats = await getStatsInPeriod(
region,
id,
start,
end,
locale,
);
const { stats, supplementary } = await filterStats(diffedTankStats, filters);
const filterDescriptions = await filtersToDescription(filters, locale);
+9 -4
View File
@@ -1,18 +1,23 @@
import { Locale } from 'discord.js';
import { Region } from '../../constants/regions';
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
import { UserError } from '../../hooks/userError';
import { TanksStats } from '../../types/tanksStats';
import { translator } from '../localization/translator';
import fetchBlitz from './fetchBlitz';
export default async function getTankStats(region: Region, id: number) {
export default async function getTankStats(
region: Region,
id: number,
locale: Locale,
) {
const { t } = translator(locale);
const tankStats = await fetchBlitz<TanksStats>(
`https://api.wotblitz.${region}/wotb/tanks/stats/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
);
if (tankStats[id] === null) {
throw new UserError(
"# No tank stats available\nThis player doesn't have any stats available. This may not be the player you are looking for.",
);
throw new UserError(t`bot.common.errors.no_tank_stats`);
}
return tankStats[id];
+12 -4
View File
@@ -1,12 +1,18 @@
import { Locale } from 'discord.js';
import { go } from 'fuzzysort';
import { UserError } from '../../hooks/userError';
import markdownEscape from 'markdown-escape';
import { UserError } from '../../hooks/userError';
import {
tankDefinitions,
tanksDefinitionsArray,
} from '../blitzkrieg/tankDefinitions';
import { translator } from '../localization/translator';
export default async function resolveTankId(tank: string | number) {
export default async function resolveTankId(
tank: string | number,
locale: Locale,
) {
const { translate } = translator(locale);
const number = typeof tank === 'string' ? parseInt(tank) : tank;
if (Number.isNaN(number)) {
@@ -17,7 +23,9 @@ export default async function resolveTankId(tank: string | number) {
if (searchResult.length === 0) {
throw new UserError(
`# Tank not found\nCould not find tank by the name "${markdownEscape(`${tank}`)}".`,
translate('bot.common.errors.tank_name_not_found', [
markdownEscape(`${tank}`),
]),
);
} else {
return searchResult[0].obj.id;
@@ -27,7 +35,7 @@ export default async function resolveTankId(tank: string | number) {
return number;
} else {
throw new UserError(
`# Tank not found\nCould not find tank by the ID "${number}". Try typing the name of the tank instead of a number.`,
translate('bot.common.errors.tank_id_not_found', [`${number}`]),
);
}
}
+3 -1
View File
@@ -1,3 +1,4 @@
import { Locale } from 'discord.js';
import { Region } from '../../constants/regions';
import {
GetHistoriesOptions,
@@ -34,6 +35,7 @@ export const getTankHistoriesDefaultOptions: GetTankHistoriesOptions = {
export default async function getTankHistories(
server: Region,
id: number,
locale: Locale,
options?: Partial<GetTankHistoriesOptions>,
) {
const mergedOptions = { ...getTankHistoriesDefaultOptions, ...options };
@@ -76,7 +78,7 @@ export default async function getTankHistories(
const latestNodes: TankHistories = [];
if (mergedOptions.includeLatestHistories) {
(await getTankStats(server, id)).forEach((tankHistory) => {
(await getTankStats(server, id, locale)).forEach((tankHistory) => {
if (
tankHistory.all.battles > (lastBattles[tankHistory.tank_id] ?? 0) &&
(mergedOptions.tankId === undefined ||
+3 -1
View File
@@ -1,3 +1,4 @@
import { Locale } from 'discord.js';
import { Region } from '../../constants/regions';
import { AllStats } from '../blitz/getAccountInfo';
import getTankHistories, {
@@ -45,8 +46,9 @@ export default async function getStatsInPeriod(
id: number,
start: number,
end: number,
locale: Locale,
) {
const history = await getTankHistories(server, id, {
const history = await getTankHistories(server, id, locale, {
includeLatestHistories: true,
});
+4 -1
View File
@@ -15,6 +15,9 @@ export async function getFiltersFromCommand(
treeType:
(interaction.options.getString('tree-type') as TreeType | undefined) ??
undefined,
tank: tankRaw === null ? undefined : await resolveTankId(tankRaw),
tank:
tankRaw === null
? undefined
: await resolveTankId(tankRaw, interaction.locale),
} satisfies StatFilters;
}
+3 -1
View File
@@ -3,11 +3,13 @@ import markdownEscape from 'markdown-escape';
import { Region } from '../../constants/regions';
import { UserError } from '../../hooks/userError';
import searchClansAcrossRegions from '../blitz/searchClansAcrossRegions';
import { translator } from '../localization/translator';
import { serverAndIdPattern } from './resolvePlayerFromCommand';
export default async function resolveClanFromCommand(
interaction: ChatInputCommandInteraction,
) {
const { translate } = translator(interaction.locale);
const clan = interaction.options.getString('clan', true);
if (serverAndIdPattern.test(clan)) {
@@ -20,7 +22,7 @@ export default async function resolveClanFromCommand(
return { region: accounts[0].region, id: accounts[0].clan_id };
} else {
throw new UserError(
`# Could not find clan\nCouldn't find "${markdownEscape(clan)}". Try selecting a clan from the search result.`,
translate('bot.common.errors.clan_not_found', [markdownEscape(clan)]),
);
}
}
+6 -6
View File
@@ -4,6 +4,7 @@ import { Region } from '../../constants/regions';
import { UserError } from '../../hooks/userError';
import searchPlayersAcrossRegions from '../blitz/searchPlayersAcrossRegions';
import { getBlitzFromDiscord } from '../blitzkrieg/discordBlitz';
import { translator } from '../localization/translator';
export const serverAndIdPattern = /(com|eu|asia)\/[0-9]+/;
@@ -15,6 +16,7 @@ export interface ResolvedPlayer {
export default async function resolvePlayerFromCommand(
interaction: ChatInputCommandInteraction<CacheType>,
) {
const { t, translate } = translator(interaction.locale);
const commandUsername = interaction.options.getString('username');
if (commandUsername) {
@@ -35,9 +37,9 @@ export default async function resolvePlayerFromCommand(
} satisfies ResolvedPlayer;
} else {
throw new UserError(
`# Could not find user\nI couldn't find user "${markdownEscape(
commandUsername,
)}". Try picking an user from the search result, typing in a valid username, or using the \`/link\` command.`,
translate('bot.common.errors.player_not_found', [
markdownEscape(commandUsername),
]),
);
}
}
@@ -47,9 +49,7 @@ export default async function resolvePlayerFromCommand(
if (account) {
return { region: account.region, id: account.blitz };
} else {
throw new UserError(
"# I don't know who you are\nUse the `/link` command to get started.",
);
throw new UserError(t`bot.common.errors.player_not_linked`);
}
}
}
+10 -1
View File
@@ -176,6 +176,15 @@
"battles_in_period": "No battles played in this period",
"players_in_period": "No players in this period",
"tanks_found": "No tanks found"
},
"errors": {
"clan_not_found": "# Could not find clan\nCouldn't find \"%s\". Try selecting a clan from the search result.",
"player_not_found": "# Could not find user\nI couldn't find user \"%s\". Try picking an user from the search result, typing in a valid username, or using the `/link` command.",
"player_not_linked": "# I don't know who you are\nUse the `/link` command to get started.",
"tank_name_not_found": "# Tank not found\nCould not find tank by the name \"%s\".",
"tank_id_not_found": "# Tank not found\nCould not find tank by the ID \"%s\". Try typing the name of the tank instead of a number.",
"no_tank_stats": "# No tank stats available\nThis player doesn't have any stats available. This may not be the player you are looking for."
}
},
@@ -478,7 +487,7 @@
"description": "Basic information about a player",
"body": {
"title": "%'s information",
"title": "%s's information",
"nickname": "Nickname",
"battles": "Battles",
"winrate": "Winrate",
-348
View File
@@ -1,348 +0,0 @@
{
"common": {
"nations": {
"ussr": "U.S.S.R.",
"germany": "Germany",
"usa": "U.S.A.",
"china": "China",
"uk": "U.K.",
"france": "France",
"japan": "Japan",
"european": "European nation",
"other": "Hybrid nation"
},
"tank_class_short": {
"lightTank": "Light",
"mediumTank": "Medium",
"heavyTank": "Heavy",
"AT-SPG": "TD"
},
"tree_type": {
"researchable": "Tech tree",
"premium": "Premium",
"collector": "Collector"
},
"regions": {
"normal": {
"com": "North America",
"eu": "Europe",
"asia": "Asia-Pacific"
},
"short": {
"com": "NA",
"eu": "EU",
"asia": "APAC"
}
},
"leagues": {
"diamond": "Diamond",
"platinum": "Platinum",
"gold": "Gold",
"silver": "Silver",
"bronze": "Bronze"
}
},
"bot": {
"common": {
"wn8": {
"$": "WN8",
"very_bad": "Very bad",
"bad": "Bad",
"below_average": "Below average",
"average": "Average",
"above_average": "Above average",
"good": "Good",
"very_good": "Very good",
"great": "Great",
"unicum": "Unicum",
"super_unicum": "Super unicum"
},
"subcommands": {
"today": {
"$": "today",
"description": "Today"
},
"30": {
"$": "30",
"description": "30 days"
},
"60": {
"$": "60",
"description": "60 days"
},
"90": {
"$": "90",
"description": "90 days"
},
"career": {
"$": "career",
"description": "Career"
},
"custom": {
"$": "custom",
"description": "Custom range",
"options": {
"start": {
"$": "start",
"description": "Start in number of days ago from today"
},
"end": {
"$": "end",
"description": "End in number of days ago from today"
}
}
}
},
"options": {
"clan": {
"$": "clan",
"description": "The clan name or tag"
},
"tank": {
"$": "tank",
"description": "The tank to get stats for"
},
"username": {
"$": "username",
"description": "The Blitz username of the player"
},
"filters": {
"nation": {
"$": "nation",
"description": "Nation"
},
"tank_class": {
"$": "tank-class",
"description": "Tank class"
},
"tree_type": {
"$": "tree-type",
"description": "Tree type"
}
},
"region": {
"$": "region",
"description": "Region"
}
},
"periods": {
"career": "Career",
"today": "Today",
"days": "%s days",
"custom": "%s - %s days"
},
"filters": {
"none": "No filters",
"tier": "Tier %s"
},
"no_data": {
"battles_in_period": "No battles played in this period",
"players_in_period": "No players in this period",
"tanks_found": "No tanks found"
}
},
"commands": {
"about": {
"$": "about",
"description": "All the info you need about the bot",
"subcommands": {
"commands": {
"$": "commands",
"description": "List of all commands and their descriptions",
"body": "# Commands\n\nBlitzkrieg offers the following commands:\n\n"
},
"embeds": {
"$": "embeds",
"description": "How embeds work"
},
"introduction": {
"$": "introduction",
"description": "About the bot"
},
"invite": {
"$": "invite",
"description": "How to invite the bot"
},
"timezones": {
"$": "timezones",
"description": "How Blitzkrieg infers and uses your timezone"
},
"creators": {
"$": "creators",
"description": "People who have worked on the bot"
}
}
},
"breakdown": {
"$": "breakdown",
"description": "A period's breakdown by tanks played",
"body": {
"total": "Total",
"battles": "Battles",
"wn8": "WN8",
"winrate": "Winrate",
"damage": "Damage",
"unknown_tank": "Unknown tank %s"
}
},
"debug": {
"$": "debug",
"description": "Debug information about the bot",
"body": {
"title": "# Debug\n\n",
"version": "Version",
"shard": {
"$": "Shard",
"default": "default"
},
"uptime": "Uptime"
}
},
"evolution": {
"$": "evolution",
"description": "Evolution of statistics",
"groups": {
"player": {
"$": "player",
"description": "Player statistics"
},
"tank": {
"$": "tank",
"description": "Tank statistics"
}
}
},
"inactive": {
"$": "inactive",
"description": "Lists all inactive players in a clan above a threshold",
"options": {
"threshold": {
"$": "threshold",
"description": "The number of days inactive (default: %s days)"
}
},
"body": {
"subtitle": "Inactive for %s+ days",
"listing": "%s days"
}
},
"full_stats": {
"$": "full-stats",
"description": "Full in-game statistics",
"body": {
"cards": {
"games": {
"$": "Games",
"winrate": "Winrate",
"battles": "Battles",
"wins_losses": "Wins / losses"
},
"efficiency": {
"$": "Efficiency",
"wn8": "WN8",
"survival": "Survival",
"accuracy": "Accuracy"
},
"lethality": {
"$": "Lethality",
"average_damage": "Average damage",
"damage_per_tier": "Damage per tier",
"damage_ratio": "Damage ratio",
"average_kills": "Average kills"
},
"miscellaneous": {
"$": "Miscellaneous",
"average_tier": "Average tier",
"average_spots": "Average spots",
"average_xp": "Average XP",
"kills_to_death_ratio": "Kills to death ratio"
}
}
}
},
"link": {
"$": "link",
"description": "Links your Blitz and Discord account",
"body": {
"accounts_linked": "Accounts linked",
"no_role_permissions": {
"$": "%s failed to verify",
"description": "I don't have the permission to manage roles."
}
},
"embed": {
"title": "Incorrect account?",
"description": "Use the command again and select a username from the search results."
}
},
"search_clans": {
"$": "search-clans",
"description": "Search clans",
"options": {
"limit": {
"$": "limit",
"description": "The max number of clan results (default: %s)"
}
},
"body": {
"title": "Clan search for %s in region %s",
"no_results": "No clans found"
}
},
"search_players": {
"$": "search-players",
"description": "Search players",
"options": {
"limit": {
"$": "limit",
"description": "The max number of player results (default: %s)"
}
},
"body": {
"title": "Player search for %s in region %s",
"no_results": "No players found"
}
},
"ratings": {
"$": "ratings",
"description": "Ratings battles statistics",
"subcommands": {
"neighbors": {
"$": "neighbors",
"description": "Neighboring players on the leaderboard"
},
"league": {
"$": "league",
"description": "Top players of a league"
}
},
"options": {
"limit": {
"$": "limit",
"description": "How many neighbors to display (default: %s)"
},
"season": {
"$": "season",
"description": "Season number (default: current)",
"choices": {
"current": "%s (current)"
}
},
"league": {
"$": "league",
"description": "The league to display"
}
},
"body": {
"top_players": "Top %s players",
"no_participation": "# %s didn't play ratings in season %s\n\nThis player did not participate in this season or did not get past calibration.",
"no_ongoing_season": "# No ongoing season\n\nThere isn't a currently running ratings season.",
"deleted_player": "Deleted %s",
"neighbors": "Ratings neighbors",
"more": "+%s more"
}
}
}
},
"website": {}
}