mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 03:59:50 +02:00
feat: some more type prefixes
This commit is contained in:
1 parent
0d8cb5c1ae
commit
26304fc281
71 files changed
+411
-409
No files matched your search
Vendored
+2
@@ -40,6 +40,7 @@
|
|||||||
"Carro",
|
"Carro",
|
||||||
"CCPAOPTOUT",
|
"CCPAOPTOUT",
|
||||||
"CDON",
|
"CDON",
|
||||||
|
"clanid",
|
||||||
"classname",
|
"classname",
|
||||||
"cleandist",
|
"cleandist",
|
||||||
"closedkrieg",
|
"closedkrieg",
|
||||||
@@ -128,6 +129,7 @@
|
|||||||
"NEGATIVEX",
|
"NEGATIVEX",
|
||||||
"NEGATIVEY",
|
"NEGATIVEY",
|
||||||
"NEGATIVEZ",
|
"NEGATIVEZ",
|
||||||
|
"networkidle",
|
||||||
"NITROPAY",
|
"NITROPAY",
|
||||||
"nivo",
|
"nivo",
|
||||||
"nmatname",
|
"nmatname",
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
import { emblemURL, getAccountInfo, getClanAccountInfo } from '@blitzkit/core';
|
import { emblemURL, getAccountInfo, getClanAccountInfo } from "@blitzkit/core";
|
||||||
import { Locale, SlashCommandSubcommandGroupBuilder } from 'discord.js';
|
import { Locale, SlashCommandSubcommandGroupBuilder } from "discord.js";
|
||||||
import { CommandWrapper } from '../components/CommandWrapper';
|
import { CommandWrapper } from "../components/CommandWrapper";
|
||||||
import * as Graph from '../components/Graph';
|
import * as Graph from "../components/Graph";
|
||||||
import { LineColor } from '../components/Graph/components/Line/constants';
|
import { LineColor } from "../components/Graph/components/Line/constants";
|
||||||
import { NoData } from '../components/NoData';
|
import { NoData } from "../components/NoData";
|
||||||
import { TitleBar } from '../components/TitleBar';
|
import { TitleBar } from "../components/TitleBar";
|
||||||
import { resolveTankId } from '../core/blitz/resolveTankId';
|
import { resolveTankId } from "../core/blitz/resolveTankId";
|
||||||
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
|
import { getBlitzStarsLinkButton } from "../core/blitzstars/getBlitzStarsLinkButton";
|
||||||
import { getPlayerHistories } from '../core/blitzstars/getPlayerHistories';
|
import { getPlayerHistories } from "../core/blitzstars/getPlayerHistories";
|
||||||
import { getTankHistories } from '../core/blitzstars/getTankHistories';
|
import { getTankHistories } from "../core/blitzstars/getTankHistories";
|
||||||
import { addPeriodSubCommands } from '../core/discord/addPeriodSubCommands';
|
import { addPeriodSubCommands } from "../core/discord/addPeriodSubCommands";
|
||||||
import { addTankChoices } from '../core/discord/addTankChoices';
|
import { addTankChoices } from "../core/discord/addTankChoices";
|
||||||
import { addUsernameChoices } from '../core/discord/addUsernameChoices';
|
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
|
||||||
import { autocompleteTanks } from '../core/discord/autocompleteTanks';
|
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
|
||||||
import { autocompleteUsername } from '../core/discord/autocompleteUsername';
|
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
|
||||||
import { buttonRefresh } from '../core/discord/buttonRefresh';
|
import { buttonRefresh } from "../core/discord/buttonRefresh";
|
||||||
import { commandToURL } from '../core/discord/commandToURL';
|
import { commandToURL } from "../core/discord/commandToURL";
|
||||||
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
|
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
||||||
import { getCustomPeriodParams } from '../core/discord/getCustomPeriodParams';
|
import { getCustomPeriodParams } from "../core/discord/getCustomPeriodParams";
|
||||||
import { resolvePeriodFromButton } from '../core/discord/resolvePeriodFromButton';
|
import { resolvePeriodFromButton } from "../core/discord/resolvePeriodFromButton";
|
||||||
import {
|
import {
|
||||||
ResolvedPeriod,
|
type ResolvedPeriod,
|
||||||
resolvePeriodFromCommand,
|
resolvePeriodFromCommand,
|
||||||
} from '../core/discord/resolvePeriodFromCommand';
|
} from "../core/discord/resolvePeriodFromCommand";
|
||||||
import { resolvePlayerFromButton } from '../core/discord/resolvePlayerFromButton';
|
import { resolvePlayerFromButton } from "../core/discord/resolvePlayerFromButton";
|
||||||
import {
|
import {
|
||||||
ResolvedPlayer,
|
type ResolvedPlayer,
|
||||||
resolvePlayerFromCommand,
|
resolvePlayerFromCommand,
|
||||||
} from '../core/discord/resolvePlayerFromCommand';
|
} from "../core/discord/resolvePlayerFromCommand";
|
||||||
import { CommandRegistry } from '../events/interactionCreate';
|
import type { CommandRegistry } from "../events/interactionCreate";
|
||||||
|
|
||||||
type EvolutionStatType = 'player' | 'tank';
|
type EvolutionStatType = "player" | "tank";
|
||||||
|
|
||||||
async function render(
|
async function render(
|
||||||
{ region, id }: ResolvedPlayer,
|
{ region, id }: ResolvedPlayer,
|
||||||
{ start, end, name }: ResolvedPeriod,
|
{ start, end, name }: ResolvedPeriod,
|
||||||
type: 'player' | 'tank',
|
type: "player" | "tank",
|
||||||
tankId: number | null,
|
tankId: number | null,
|
||||||
locale: Locale,
|
locale: Locale
|
||||||
) {
|
) {
|
||||||
const accountInfo = await getAccountInfo(region, id);
|
const accountInfo = await getAccountInfo(region, id);
|
||||||
const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan;
|
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
|
||||||
const logo = clan ? emblemURL(clan.emblem_set_id) : undefined;
|
const logo = clan ? emblemURL(clan.emblem_set_id) : undefined;
|
||||||
const histories = await (type === 'player'
|
const histories = await (type === "player"
|
||||||
? getPlayerHistories(region, id, {
|
? getPlayerHistories(region, id, {
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
@@ -61,7 +61,7 @@ async function render(
|
|||||||
[
|
[
|
||||||
history.all.battles,
|
history.all.battles,
|
||||||
(history.all.wins / history.all.battles) * 100,
|
(history.all.wins / history.all.battles) * 100,
|
||||||
] as Graph.PlotItem,
|
] as Graph.PlotItem
|
||||||
);
|
);
|
||||||
const times = histories.map((history) => history.last_battle_time);
|
const times = histories.map((history) => history.last_battle_time);
|
||||||
const minTime = Math.min(...times);
|
const minTime = Math.min(...times);
|
||||||
@@ -82,7 +82,7 @@ async function render(
|
|||||||
verticalMargin={{
|
verticalMargin={{
|
||||||
min: minY,
|
min: minY,
|
||||||
max: maxY,
|
max: maxY,
|
||||||
suffix: '%',
|
suffix: "%",
|
||||||
precision: 2,
|
precision: 2,
|
||||||
}}
|
}}
|
||||||
horizontalMargin={{
|
horizontalMargin={{
|
||||||
@@ -110,22 +110,22 @@ async function render(
|
|||||||
export const evolutionCommand = new Promise<CommandRegistry>(
|
export const evolutionCommand = new Promise<CommandRegistry>(
|
||||||
async (resolve) => {
|
async (resolve) => {
|
||||||
resolve({
|
resolve({
|
||||||
command: createLocalizedCommand('evolution', [
|
command: createLocalizedCommand("evolution", [
|
||||||
{
|
{
|
||||||
group: 'player',
|
group: "player",
|
||||||
modify(option: SlashCommandSubcommandGroupBuilder) {
|
modify(option: SlashCommandSubcommandGroupBuilder) {
|
||||||
addPeriodSubCommands(option, (option) =>
|
addPeriodSubCommands(option, (option) =>
|
||||||
option.addStringOption(addUsernameChoices),
|
option.addStringOption(addUsernameChoices)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: 'tank',
|
group: "tank",
|
||||||
modify(option: SlashCommandSubcommandGroupBuilder) {
|
modify(option: SlashCommandSubcommandGroupBuilder) {
|
||||||
addPeriodSubCommands(option, (option) =>
|
addPeriodSubCommands(option, (option) =>
|
||||||
option
|
option
|
||||||
.addStringOption(addTankChoices)
|
.addStringOption(addTankChoices)
|
||||||
.addStringOption(addUsernameChoices),
|
.addStringOption(addUsernameChoices)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -136,9 +136,9 @@ export const evolutionCommand = new Promise<CommandRegistry>(
|
|||||||
interaction.options.getSubcommandGroup() as EvolutionStatType;
|
interaction.options.getSubcommandGroup() as EvolutionStatType;
|
||||||
const player = await resolvePlayerFromCommand(interaction);
|
const player = await resolvePlayerFromCommand(interaction);
|
||||||
const period = resolvePeriodFromCommand(player.region, interaction);
|
const period = resolvePeriodFromCommand(player.region, interaction);
|
||||||
const tankIdRaw = interaction.options.getString('tank')!;
|
const tankIdRaw = interaction.options.getString("tank")!;
|
||||||
const tankId =
|
const tankId =
|
||||||
commandGroup === 'tank'
|
commandGroup === "tank"
|
||||||
? await resolveTankId(tankIdRaw, interaction.locale)
|
? await resolveTankId(tankIdRaw, interaction.locale)
|
||||||
: null;
|
: null;
|
||||||
const path = commandToURL(interaction, {
|
const path = commandToURL(interaction, {
|
||||||
@@ -153,13 +153,13 @@ export const evolutionCommand = new Promise<CommandRegistry>(
|
|||||||
period,
|
period,
|
||||||
commandGroup,
|
commandGroup,
|
||||||
tankId,
|
tankId,
|
||||||
interaction.locale,
|
interaction.locale
|
||||||
),
|
),
|
||||||
buttonRefresh(interaction, path),
|
buttonRefresh(interaction, path),
|
||||||
await getBlitzStarsLinkButton(
|
await getBlitzStarsLinkButton(
|
||||||
player.region,
|
player.region,
|
||||||
player.id,
|
player.id,
|
||||||
tankId ?? undefined,
|
tankId ?? undefined
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
@@ -171,7 +171,7 @@ export const evolutionCommand = new Promise<CommandRegistry>(
|
|||||||
|
|
||||||
async button(interaction) {
|
async button(interaction) {
|
||||||
const url = new URL(`https://example.com/${interaction.customId}`);
|
const url = new URL(`https://example.com/${interaction.customId}`);
|
||||||
const path = url.pathname.split('/');
|
const path = url.pathname.split("/");
|
||||||
const commandGroup = path[2] as EvolutionStatType;
|
const commandGroup = path[2] as EvolutionStatType;
|
||||||
const player = await resolvePlayerFromButton(interaction);
|
const player = await resolvePlayerFromButton(interaction);
|
||||||
const period = resolvePeriodFromButton(player.region, interaction);
|
const period = resolvePeriodFromButton(player.region, interaction);
|
||||||
@@ -180,10 +180,10 @@ export const evolutionCommand = new Promise<CommandRegistry>(
|
|||||||
player,
|
player,
|
||||||
period,
|
period,
|
||||||
commandGroup,
|
commandGroup,
|
||||||
parseInt(url.searchParams.get('tankId') ?? '0') || null,
|
parseInt(url.searchParams.get("tankId") ?? "0") || null,
|
||||||
interaction.locale,
|
interaction.locale
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
@@ -11,7 +11,7 @@ import { NoData } from '../components/NoData';
|
|||||||
import { TierWeights } from '../components/TierWeights';
|
import { TierWeights } from '../components/TierWeights';
|
||||||
import { TitleBar } from '../components/TitleBar';
|
import { TitleBar } from '../components/TitleBar';
|
||||||
import { filtersToDescription } from '../core/blitzkit/filtersToDescription';
|
import { filtersToDescription } from '../core/blitzkit/filtersToDescription';
|
||||||
import { filterStats, StatFilters } from '../core/blitzstars/filterStats';
|
import { filterStats, type StatFilters } from '../core/blitzstars/filterStats';
|
||||||
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
|
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
|
||||||
import { getStatsInPeriod } from '../core/blitzstars/getStatsInPeriod';
|
import { getStatsInPeriod } from '../core/blitzstars/getStatsInPeriod';
|
||||||
import { addPeriodicFilterOptions } from '../core/discord/addPeriodicFilterOptions';
|
import { addPeriodicFilterOptions } from '../core/discord/addPeriodicFilterOptions';
|
||||||
@@ -26,15 +26,15 @@ import { getFiltersFromButton } from '../core/discord/getFiltersFromButton';
|
|||||||
import { getFiltersFromCommand } from '../core/discord/getFiltersFromCommand';
|
import { getFiltersFromCommand } from '../core/discord/getFiltersFromCommand';
|
||||||
import { resolvePeriodFromButton } from '../core/discord/resolvePeriodFromButton';
|
import { resolvePeriodFromButton } from '../core/discord/resolvePeriodFromButton';
|
||||||
import {
|
import {
|
||||||
ResolvedPeriod,
|
type ResolvedPeriod,
|
||||||
resolvePeriodFromCommand,
|
resolvePeriodFromCommand,
|
||||||
} from '../core/discord/resolvePeriodFromCommand';
|
} from '../core/discord/resolvePeriodFromCommand';
|
||||||
import { resolvePlayerFromButton } from '../core/discord/resolvePlayerFromButton';
|
import { resolvePlayerFromButton } from '../core/discord/resolvePlayerFromButton';
|
||||||
import {
|
import {
|
||||||
ResolvedPlayer,
|
type ResolvedPlayer,
|
||||||
resolvePlayerFromCommand,
|
resolvePlayerFromCommand,
|
||||||
} from '../core/discord/resolvePlayerFromCommand';
|
} from '../core/discord/resolvePlayerFromCommand';
|
||||||
import { CommandRegistry } from '../events/interactionCreate';
|
import type { CommandRegistry } from '../events/interactionCreate';
|
||||||
|
|
||||||
async function render(
|
async function render(
|
||||||
{ region, id }: ResolvedPlayer,
|
{ region, id }: ResolvedPlayer,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { chunkLines } from "../core/discord/chunkLines";
|
|||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
||||||
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
|
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
|
||||||
import { translator } from "../core/localization/translator";
|
import { translator } from "../core/localization/translator";
|
||||||
import { CommandRegistry } from "../events/interactionCreate";
|
import { type CommandRegistry } from "../events/interactionCreate";
|
||||||
|
|
||||||
export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
|
export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
|
||||||
resolve({
|
resolve({
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { blitzStarsTankAverages } from '../core/blitzstars/tankAverages';
|
|||||||
import { buttonLink } from '../core/discord/buttonLink';
|
import { buttonLink } from '../core/discord/buttonLink';
|
||||||
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
|
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
|
||||||
import { translator } from '../core/localization/translator';
|
import { translator } from '../core/localization/translator';
|
||||||
import { CommandRegistry } from '../events/interactionCreate';
|
import { type CommandRegistry } from '../events/interactionCreate';
|
||||||
import { theme } from '../stitches.config';
|
import { theme } from '../stitches.config';
|
||||||
|
|
||||||
type WotInspectorReplaySubmission =
|
type WotInspectorReplaySubmission =
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|||||||
import { localizationObject } from "../core/discord/localizationObject";
|
import { localizationObject } from "../core/discord/localizationObject";
|
||||||
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
|
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
|
||||||
import { translator } from "../core/localization/translator";
|
import { translator } from "../core/localization/translator";
|
||||||
import { CommandRegistry } from "../events/interactionCreate";
|
import { type CommandRegistry } from "../events/interactionCreate";
|
||||||
import { theme } from "../stitches.config";
|
import { theme } from "../stitches.config";
|
||||||
|
|
||||||
export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ReactNode } from 'react';
|
import { type ReactNode } from "react";
|
||||||
|
|
||||||
interface RootProps {
|
interface RootProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@@ -8,7 +8,7 @@ export function Root({ children }: RootProps) {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="session-tracker-root"
|
className="session-tracker-root"
|
||||||
style={{ display: 'flex', flexDirection: 'column', gap: 8 }}
|
style={{ display: "flex", flexDirection: "column", gap: 8 }}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import {
|
|||||||
} from '@blitzkit/core';
|
} from '@blitzkit/core';
|
||||||
import { createColors } from 'bepaint';
|
import { createColors } from 'bepaint';
|
||||||
import {
|
import {
|
||||||
AccentColor,
|
type AccentColor,
|
||||||
GrayColor,
|
type GrayColor,
|
||||||
PALETTES,
|
PALETTES,
|
||||||
} from '../../../core/radix/radixColors';
|
} from '../../../core/radix/radixColors';
|
||||||
import { RowStat } from './RowStat';
|
import { RowStat } from './RowStat';
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Percentile } from '@blitzkit/core';
|
import { Percentile } from "@blitzkit/core";
|
||||||
import { createColors } from 'bepaint';
|
import { createColors } from "bepaint";
|
||||||
import {
|
import {
|
||||||
AccentColor,
|
type AccentColor,
|
||||||
GrayColor,
|
type GrayColor,
|
||||||
PALETTES,
|
PALETTES,
|
||||||
} from '../../../core/radix/radixColors';
|
} from "../../../core/radix/radixColors";
|
||||||
import { PercentileIndicator } from '../../PercentileIndicator';
|
import { PercentileIndicator } from "../../PercentileIndicator";
|
||||||
|
|
||||||
interface RowStatProps {
|
interface RowStatProps {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -22,7 +22,7 @@ export function RowStat({
|
|||||||
delta,
|
delta,
|
||||||
percentile,
|
percentile,
|
||||||
minimized = false,
|
minimized = false,
|
||||||
color = 'slate',
|
color = "slate",
|
||||||
}: RowStatProps) {
|
}: RowStatProps) {
|
||||||
const theme = createColors(PALETTES[`${color}Dark`]);
|
const theme = createColors(PALETTES[`${color}Dark`]);
|
||||||
|
|
||||||
@@ -30,29 +30,29 @@ export function RowStat({
|
|||||||
<div
|
<div
|
||||||
className="session-tracker-row-stat"
|
className="session-tracker-row-stat"
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
flexDirection: 'column',
|
flexDirection: "column",
|
||||||
gap: 4,
|
gap: 4,
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
justifyContent: 'center',
|
justifyContent: "center",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
gap: 4,
|
gap: 4,
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
justifyContent: 'center',
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{percentile === undefined && delta !== undefined && delta !== 0 && (
|
{percentile === undefined && delta !== undefined && delta !== 0 && (
|
||||||
<img
|
<img
|
||||||
alt={delta > 0 ? 'Increase' : 'Decrease'}
|
alt={delta > 0 ? "Increase" : "Decrease"}
|
||||||
src={
|
src={
|
||||||
(delta ?? 0) > 0
|
(delta ?? 0) > 0
|
||||||
? 'https://i.imgur.com/qbjiXa1.png'
|
? "https://i.imgur.com/qbjiXa1.png"
|
||||||
: 'https://i.imgur.com/3uyNhun.png'
|
: "https://i.imgur.com/3uyNhun.png"
|
||||||
}
|
}
|
||||||
style={{ width: 12, height: 12 }}
|
style={{ width: 12, height: 12 }}
|
||||||
/>
|
/>
|
||||||
@@ -66,7 +66,7 @@ export function RowStat({
|
|||||||
color: theme.textHighContrast,
|
color: theme.textHighContrast,
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
textAlign: 'center',
|
textAlign: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{value}
|
{value}
|
||||||
@@ -77,7 +77,7 @@ export function RowStat({
|
|||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
color: theme.textLowContrast,
|
color: theme.textLowContrast,
|
||||||
textAlign: 'center',
|
textAlign: "center",
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { GenericStat } from '..';
|
import { type GenericStat } from "..";
|
||||||
import { GenericStatsRow } from './GenericStatsRow';
|
import { GenericStatsRow } from "./GenericStatsRow";
|
||||||
|
|
||||||
interface GenericStatsColumnProps {
|
interface GenericStatsColumnProps {
|
||||||
stats: GenericStat[];
|
stats: GenericStat[];
|
||||||
@@ -7,7 +7,7 @@ interface GenericStatsColumnProps {
|
|||||||
|
|
||||||
export function GenericStatsColumn({ stats }: GenericStatsColumnProps) {
|
export function GenericStatsColumn({ stats }: GenericStatsColumnProps) {
|
||||||
return (
|
return (
|
||||||
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 8 }}>
|
<div style={{ flex: 1, display: "flex", flexDirection: "column", gap: 8 }}>
|
||||||
{stats.map((stat) => (
|
{stats.map((stat) => (
|
||||||
<GenericStatsRow key={stat[0]} stat={stat} />
|
<GenericStatsRow key={stat[0]} stat={stat} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { GenericStat } from '..';
|
import { type GenericStat } from "..";
|
||||||
import { theme } from '../../../stitches.config';
|
import { theme } from "../../../stitches.config";
|
||||||
import { PercentileIndicator } from '../../PercentileIndicator';
|
import { PercentileIndicator } from "../../PercentileIndicator";
|
||||||
|
|
||||||
interface GenericStatsRowProps {
|
interface GenericStatsRowProps {
|
||||||
stat: GenericStat;
|
stat: GenericStat;
|
||||||
@@ -10,18 +10,18 @@ export function GenericStatsRow({ stat }: GenericStatsRowProps) {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
justifyContent: 'space-between',
|
justifyContent: "space-between",
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
color: theme.colors.textLowContrast,
|
color: theme.colors.textLowContrast,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: "nowrap",
|
||||||
maxWidth: 128,
|
maxWidth: 128,
|
||||||
overflow: 'hidden',
|
overflow: "hidden",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{stat[0]}
|
{stat[0]}
|
||||||
@@ -32,9 +32,9 @@ export function GenericStatsRow({ stat }: GenericStatsRowProps) {
|
|||||||
color: theme.colors.textHighContrast,
|
color: theme.colors.textHighContrast,
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
justifyContent: 'center',
|
justifyContent: "center",
|
||||||
gap: 4,
|
gap: 4,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { times } from 'lodash-es';
|
import { times } from "lodash-es";
|
||||||
import { ReactNode } from 'react';
|
import { type ReactNode } from "react";
|
||||||
import { theme } from '../../../../stitches.config';
|
import { theme } from "../../../../stitches.config";
|
||||||
import { Margin } from '../Margin';
|
import { Margin } from "../Margin";
|
||||||
import { MarginOrientation } from '../Margin/constants';
|
import { MarginOrientation } from "../Margin/constants";
|
||||||
import { GRAPH_HEIGHT, GRAPH_WIDTH } from './constants';
|
import { GRAPH_HEIGHT, GRAPH_WIDTH } from "./constants";
|
||||||
|
|
||||||
export interface MarginInputProps {
|
export interface MarginInputProps {
|
||||||
min: number;
|
min: number;
|
||||||
@@ -32,12 +32,12 @@ export function Root({
|
|||||||
xTitle,
|
xTitle,
|
||||||
}: RootProps) {
|
}: RootProps) {
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
<div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
paddingLeft: 64,
|
paddingLeft: 64,
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
justifyContent: 'space-between',
|
justifyContent: "space-between",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span style={{ fontSize: 16, color: theme.colors.textHighContrast }}>
|
<span style={{ fontSize: 16, color: theme.colors.textHighContrast }}>
|
||||||
@@ -48,7 +48,7 @@ export function Root({
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ display: 'flex', gap: 16 }}>
|
<div style={{ display: "flex", gap: 16 }}>
|
||||||
{verticalMargin && (
|
{verticalMargin && (
|
||||||
<Margin {...verticalMargin} verticalSeparations={separations} />
|
<Margin {...verticalMargin} verticalSeparations={separations} />
|
||||||
)}
|
)}
|
||||||
@@ -94,9 +94,9 @@ export function Root({
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
paddingLeft: 64,
|
paddingLeft: 64,
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
justifyContent: 'center',
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
|
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ReactNode } from 'react';
|
import { type ReactNode } from 'react';
|
||||||
|
|
||||||
interface RootProps {
|
interface RootProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { fetchTankDefinitions, TIER_ROMAN_NUMERALS } from "@blitzkit/core";
|
import { fetchTankDefinitions, TIER_ROMAN_NUMERALS } from "@blitzkit/core";
|
||||||
import { literals } from "@blitzkit/i18n";
|
import { literals } from "@blitzkit/i18n";
|
||||||
import { Locale } from "discord.js";
|
import { Locale } from "discord.js";
|
||||||
import { StatFilters } from "../blitzstars/filterStats";
|
import { type StatFilters } from "../blitzstars/filterStats";
|
||||||
import { translator } from "../localization/translator";
|
import { translator } from "../localization/translator";
|
||||||
|
|
||||||
export async function filtersToDescription(
|
export async function filtersToDescription(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { getTimeDaysAgo, Region } from '@blitzkit/core';
|
import { getTimeDaysAgo, type Region } from '@blitzkit/core';
|
||||||
import { PeriodSize } from '../discord/addPeriodSubCommands';
|
import type { PeriodSize } from '../discord/addPeriodSubCommands';
|
||||||
|
|
||||||
export function getPeriodStart(region: Region, period: PeriodSize) {
|
export function getPeriodStart(region: Region, period: PeriodSize) {
|
||||||
if (period === 'career') return 0;
|
if (period === 'career') return 0;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { TankClass, TankType } from '@blitzkit/core';
|
import { TankClass, TankType } from "@blitzkit/core";
|
||||||
import { SupplementaryStats } from '@blitzkit/core/src/blitz/getAccountInfo';
|
import type { SupplementaryStats } from "@blitzkit/core/src/blitz/getAccountInfo";
|
||||||
import { calculateWN8 } from '@blitzkit/core/src/statistics/calculateWN8';
|
import { calculateWN8 } from "@blitzkit/core/src/statistics/calculateWN8";
|
||||||
import { BlitzStats } from '@blitzkit/core/src/statistics/compositeStats';
|
import type { BlitzStats } from "@blitzkit/core/src/statistics/compositeStats";
|
||||||
import { sumAllStats } from '@blitzkit/core/src/statistics/sumAllStats';
|
import { sumAllStats } from "@blitzkit/core/src/statistics/sumAllStats";
|
||||||
import { tankDefinitions } from '../blitzkit/nonBlockingPromises';
|
import { tankDefinitions } from "../blitzkit/nonBlockingPromises";
|
||||||
import { blitzStarsTankAverages } from './tankAverages';
|
import { blitzStarsTankAverages } from "./tankAverages";
|
||||||
|
|
||||||
export interface StatFilters {
|
export interface StatFilters {
|
||||||
nation?: string;
|
nation?: string;
|
||||||
@@ -16,7 +16,7 @@ export interface StatFilters {
|
|||||||
|
|
||||||
export async function filterStats(
|
export async function filterStats(
|
||||||
{ diff, order }: DiffedTankStats,
|
{ diff, order }: DiffedTankStats,
|
||||||
filters: StatFilters,
|
filters: StatFilters
|
||||||
) {
|
) {
|
||||||
// tank, if provided, takes priority over all other filters
|
// tank, if provided, takes priority over all other filters
|
||||||
if (filters.tank) filters = { tank: filters.tank };
|
if (filters.tank) filters = { tank: filters.tank };
|
||||||
@@ -45,14 +45,14 @@ export async function filterStats(
|
|||||||
const battlesOfTanksWithAverages = filteredOrder.reduce<number>(
|
const battlesOfTanksWithAverages = filteredOrder.reduce<number>(
|
||||||
(accumulator, id) =>
|
(accumulator, id) =>
|
||||||
awaitedTankAverages[id] ? accumulator + diff[id].battles : accumulator,
|
awaitedTankAverages[id] ? accumulator + diff[id].battles : accumulator,
|
||||||
0,
|
0
|
||||||
);
|
);
|
||||||
const battlesOfTanksWithTankDefinition = filteredOrder.reduce<number>(
|
const battlesOfTanksWithTankDefinition = filteredOrder.reduce<number>(
|
||||||
(accumulator, id) =>
|
(accumulator, id) =>
|
||||||
awaitedTankDefinitions.tanks[id]
|
awaitedTankDefinitions.tanks[id]
|
||||||
? accumulator + diff[id].battles
|
? accumulator + diff[id].battles
|
||||||
: accumulator,
|
: accumulator,
|
||||||
0,
|
0
|
||||||
);
|
);
|
||||||
const supplementary = {
|
const supplementary = {
|
||||||
WN8:
|
WN8:
|
||||||
@@ -63,7 +63,7 @@ export async function filterStats(
|
|||||||
calculateWN8(awaitedTankAverages[id].all, diff[id]) *
|
calculateWN8(awaitedTankAverages[id].all, diff[id]) *
|
||||||
diff[id].battles
|
diff[id].battles
|
||||||
: accumulator,
|
: accumulator,
|
||||||
0,
|
0
|
||||||
) / battlesOfTanksWithAverages,
|
) / battlesOfTanksWithAverages,
|
||||||
tier:
|
tier:
|
||||||
filteredOrder.reduce<number>(
|
filteredOrder.reduce<number>(
|
||||||
@@ -72,7 +72,7 @@ export async function filterStats(
|
|||||||
? accumulator +
|
? accumulator +
|
||||||
awaitedTankDefinitions.tanks[id]!.tier * diff[id].battles
|
awaitedTankDefinitions.tanks[id]!.tier * diff[id].battles
|
||||||
: accumulator,
|
: accumulator,
|
||||||
0,
|
0
|
||||||
) / battlesOfTanksWithTankDefinition,
|
) / battlesOfTanksWithTankDefinition,
|
||||||
} satisfies SupplementaryStats;
|
} satisfies SupplementaryStats;
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { getAccountInfo, Region } from '@blitzkit/core';
|
import { getAccountInfo, type Region } from "@blitzkit/core";
|
||||||
import { buttonLink } from '../discord/buttonLink';
|
import { buttonLink } from "../discord/buttonLink";
|
||||||
|
|
||||||
export async function getBlitzStarsLinkButton(
|
export async function getBlitzStarsLinkButton(
|
||||||
region: Region,
|
region: Region,
|
||||||
id: number,
|
id: number,
|
||||||
tankId?: number,
|
tankId?: number
|
||||||
) {
|
) {
|
||||||
const { nickname } = await getAccountInfo(region, id);
|
const { nickname } = await getAccountInfo(region, id);
|
||||||
|
|
||||||
return buttonLink(
|
return buttonLink(
|
||||||
`https://www.blitzstars.com/player/${region}/${nickname}${
|
`https://www.blitzstars.com/player/${region}/${nickname}${
|
||||||
tankId ? `/tank/${tankId!}` : ''
|
tankId ? `/tank/${tankId!}` : ""
|
||||||
}`,
|
}`,
|
||||||
'BlitzStars',
|
"BlitzStars"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Region, emptyAllStats, getAccountInfo } from '@blitzkit/core';
|
import { type Region, emptyAllStats, getAccountInfo } from '@blitzkit/core';
|
||||||
import {
|
import {
|
||||||
GetHistoriesOptions,
|
type GetHistoriesOptions,
|
||||||
Histories,
|
type Histories,
|
||||||
History,
|
type History,
|
||||||
getHistoriesDefaultOptions,
|
getHistoriesDefaultOptions,
|
||||||
} from '../../types/histories';
|
} from '../../types/histories';
|
||||||
import { PlayerStats } from './getPlayerStats';
|
import type { PlayerStats } from './getPlayerStats';
|
||||||
|
|
||||||
export async function getPlayerHistories(
|
export async function getPlayerHistories(
|
||||||
server: Region,
|
server: Region,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { BlitzStats, Region } from '@blitzkit/core';
|
import type { BlitzStats, Region } from "@blitzkit/core";
|
||||||
|
|
||||||
interface IndividualPlayerStats {
|
interface IndividualPlayerStats {
|
||||||
clan: { clan_id: number; name: string; tag: string };
|
clan: { clan_id: number; name: string; tag: string };
|
||||||
@@ -25,13 +25,13 @@ export async function getPlayerStats<
|
|||||||
ReturnType = Ids extends number ? PlayerStats : PlayerStats[],
|
ReturnType = Ids extends number ? PlayerStats : PlayerStats[],
|
||||||
>(region: Region, ids: Ids) {
|
>(region: Region, ids: Ids) {
|
||||||
const stats = await Promise.all(
|
const stats = await Promise.all(
|
||||||
((typeof ids === 'number' ? [ids] : ids) as number[]).map((id) =>
|
((typeof ids === "number" ? [ids] : ids) as number[]).map((id) =>
|
||||||
fetch(`https://www.blitzstars.com/api/playerstats/${id}`).then(
|
fetch(`https://www.blitzstars.com/api/playerstats/${id}`).then(
|
||||||
(response) => response.json() as Promise<PlayerStats>,
|
(response) => response.json() as Promise<PlayerStats>
|
||||||
),
|
)
|
||||||
),
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (typeof ids === 'number') return stats[0] as ReturnType;
|
if (typeof ids === "number") return stats[0] as ReturnType;
|
||||||
return stats as ReturnType;
|
return stats as ReturnType;
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { BlitzStats, emptyAllStats, Region } from '@blitzkit/core';
|
import { type BlitzStats, emptyAllStats, type Region } from "@blitzkit/core";
|
||||||
import { Locale } from 'discord.js';
|
import { Locale } from "discord.js";
|
||||||
import { DiffedTankStats } from './filterStats';
|
import type { DiffedTankStats } from "./filterStats";
|
||||||
import {
|
import {
|
||||||
getTankHistories,
|
getTankHistories,
|
||||||
TankHistories,
|
type TankHistories,
|
||||||
TankHistoryRaw,
|
type TankHistoryRaw,
|
||||||
} from './getTankHistories';
|
} from "./getTankHistories";
|
||||||
|
|
||||||
const emptyTankHistoryNode: TankHistoryRaw = {
|
const emptyTankHistoryNode: TankHistoryRaw = {
|
||||||
account_id: 0,
|
account_id: 0,
|
||||||
@@ -22,7 +22,7 @@ export async function getStatsInPeriod(
|
|||||||
id: number,
|
id: number,
|
||||||
start: number,
|
start: number,
|
||||||
end: number,
|
end: number,
|
||||||
locale: Locale,
|
locale: Locale
|
||||||
) {
|
) {
|
||||||
const history = await getTankHistories(server, id, locale, {
|
const history = await getTankHistories(server, id, locale, {
|
||||||
includeLatestHistories: true,
|
includeLatestHistories: true,
|
||||||
@@ -43,8 +43,8 @@ export async function getStatsInPeriod(
|
|||||||
// find the ones played within the range
|
// find the ones played within the range
|
||||||
const inRangeTanks = tanks.filter((tankId) =>
|
const inRangeTanks = tanks.filter((tankId) =>
|
||||||
tankSortedHistory[tankId].some(
|
tankSortedHistory[tankId].some(
|
||||||
(node) => node.last_battle_time > start && node.last_battle_time < end,
|
(node) => node.last_battle_time > start && node.last_battle_time < end
|
||||||
),
|
)
|
||||||
);
|
);
|
||||||
const playedTanks: number[] = [];
|
const playedTanks: number[] = [];
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { Region, emptyAllStats, getTankStats } from '@blitzkit/core';
|
import { type Region, emptyAllStats, getTankStats } from "@blitzkit/core";
|
||||||
import { Locale } from 'discord.js';
|
import { Locale } from "discord.js";
|
||||||
import {
|
import {
|
||||||
GetHistoriesOptions,
|
type GetHistoriesOptions,
|
||||||
Histories,
|
type Histories,
|
||||||
History,
|
type History,
|
||||||
getHistoriesDefaultOptions,
|
getHistoriesDefaultOptions,
|
||||||
} from '../../types/histories';
|
} from "../../types/histories";
|
||||||
import { UserError } from '../blitzkit/userError';
|
import { UserError } from "../blitzkit/userError";
|
||||||
import { translator } from '../localization/translator';
|
import { translator } from "../localization/translator";
|
||||||
|
|
||||||
export interface TankHistory extends History {
|
export interface TankHistory extends History {
|
||||||
tank_id: number;
|
tank_id: number;
|
||||||
@@ -36,12 +36,12 @@ export async function getTankHistories(
|
|||||||
server: Region,
|
server: Region,
|
||||||
id: number,
|
id: number,
|
||||||
locale: Locale,
|
locale: Locale,
|
||||||
options?: Partial<GetTankHistoriesOptions>,
|
options?: Partial<GetTankHistoriesOptions>
|
||||||
) {
|
) {
|
||||||
const { strings } = translator(locale);
|
const { strings } = translator(locale);
|
||||||
const mergedOptions = { ...getTankHistoriesDefaultOptions, ...options };
|
const mergedOptions = { ...getTankHistoriesDefaultOptions, ...options };
|
||||||
const tankHistoriesResponse = await fetch(
|
const tankHistoriesResponse = await fetch(
|
||||||
`https://www.blitzstars.com/api/tankhistories/for/${id}/`,
|
`https://www.blitzstars.com/api/tankhistories/for/${id}/`
|
||||||
);
|
);
|
||||||
const tankHistories = (
|
const tankHistories = (
|
||||||
(await tankHistoriesResponse.json()) as TankHistoriesRaw
|
(await tankHistoriesResponse.json()) as TankHistoriesRaw
|
||||||
@@ -51,7 +51,7 @@ export async function getTankHistories(
|
|||||||
all: history.all,
|
all: history.all,
|
||||||
last_battle_time: history.last_battle_time,
|
last_battle_time: history.last_battle_time,
|
||||||
tank_id: history.tank_id,
|
tank_id: history.tank_id,
|
||||||
}) satisfies TankHistory,
|
}) satisfies TankHistory
|
||||||
);
|
);
|
||||||
const compliantTanks: number[] = [];
|
const compliantTanks: number[] = [];
|
||||||
const lastBattles: Record<number, number> = {};
|
const lastBattles: Record<number, number> = {};
|
||||||
@@ -73,7 +73,7 @@ export async function getTankHistories(
|
|||||||
lastBattles[tank_id] = battles;
|
lastBattles[tank_id] = battles;
|
||||||
|
|
||||||
return complies;
|
return complies;
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const latestNodes: TankHistories = [];
|
const latestNodes: TankHistories = [];
|
||||||
@@ -112,7 +112,7 @@ export async function getTankHistories(
|
|||||||
all: emptyAllStats,
|
all: emptyAllStats,
|
||||||
last_battle_time: -Infinity,
|
last_battle_time: -Infinity,
|
||||||
tank_id: tankId,
|
tank_id: tankId,
|
||||||
} satisfies TankHistory),
|
} satisfies TankHistory)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
TANK_TYPES,
|
TANK_TYPES,
|
||||||
} from '@blitzkit/core';
|
} from '@blitzkit/core';
|
||||||
import {
|
import {
|
||||||
APIApplicationCommandOptionChoice,
|
type APIApplicationCommandOptionChoice,
|
||||||
Locale,
|
Locale,
|
||||||
SlashCommandBuilder,
|
SlashCommandBuilder,
|
||||||
SlashCommandSubcommandBuilder,
|
SlashCommandSubcommandBuilder,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { REGIONS } from '@blitzkit/core';
|
import { REGIONS } from "@blitzkit/core";
|
||||||
import {
|
import {
|
||||||
APIApplicationCommandOptionChoice,
|
type APIApplicationCommandOptionChoice,
|
||||||
Locale,
|
Locale,
|
||||||
SlashCommandStringOption,
|
SlashCommandStringOption,
|
||||||
} from 'discord.js';
|
} from "discord.js";
|
||||||
import { translator } from '../localization/translator';
|
import { translator } from "../localization/translator";
|
||||||
import { localizationObject } from './localizationObject';
|
import { localizationObject } from "./localizationObject";
|
||||||
|
|
||||||
export function addRegionChoices(option: SlashCommandStringOption) {
|
export function addRegionChoices(option: SlashCommandStringOption) {
|
||||||
const { strings } = translator(Locale.EnglishUS);
|
const { strings } = translator(Locale.EnglishUS);
|
||||||
@@ -16,14 +16,14 @@ export function addRegionChoices(option: SlashCommandStringOption) {
|
|||||||
localizationObject(
|
localizationObject(
|
||||||
(strings) => strings.bot.common.options.region.name,
|
(strings) => strings.bot.common.options.region.name,
|
||||||
undefined,
|
undefined,
|
||||||
true,
|
true
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
.setDescription(strings.bot.common.options.region.description)
|
.setDescription(strings.bot.common.options.region.description)
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
localizationObject(
|
localizationObject(
|
||||||
(strings) => strings.bot.common.options.region.description,
|
(strings) => strings.bot.common.options.region.description
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
.addChoices(
|
.addChoices(
|
||||||
...REGIONS.map(
|
...REGIONS.map(
|
||||||
@@ -32,10 +32,10 @@ export function addRegionChoices(option: SlashCommandStringOption) {
|
|||||||
value: region,
|
value: region,
|
||||||
name: strings.common.regions.normal[region],
|
name: strings.common.regions.normal[region],
|
||||||
name_localizations: localizationObject(
|
name_localizations: localizationObject(
|
||||||
(strings) => strings.common.regions.normal[region],
|
(strings) => strings.common.regions.normal[region]
|
||||||
),
|
),
|
||||||
}) satisfies APIApplicationCommandOptionChoice,
|
}) satisfies APIApplicationCommandOptionChoice
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
.setRequired(true);
|
.setRequired(true);
|
||||||
}
|
}
|
||||||
@@ -1,25 +1,25 @@
|
|||||||
import { fetchTankNames, SEARCH_KEYS, TankType } from '@blitzkit/core';
|
import { fetchTankNames, SEARCH_KEYS, TankType } from "@blitzkit/core";
|
||||||
import {
|
import {
|
||||||
ApplicationCommandOptionChoiceData,
|
type ApplicationCommandOptionChoiceData,
|
||||||
AutocompleteInteraction,
|
AutocompleteInteraction,
|
||||||
CacheType,
|
type CacheType,
|
||||||
} from 'discord.js';
|
} from "discord.js";
|
||||||
import { go } from 'fuzzysort';
|
import { go } from "fuzzysort";
|
||||||
import { tankNames } from '../blitzkit/nonBlockingPromises';
|
import { tankNames } from "../blitzkit/nonBlockingPromises";
|
||||||
import { translator } from '../localization/translator';
|
import { translator } from "../localization/translator";
|
||||||
import {
|
import {
|
||||||
DISCORD_CHOICES_MAX_NAME_SIZE,
|
DISCORD_CHOICES_MAX_NAME_SIZE,
|
||||||
OVERFLOW_SUFFIX,
|
OVERFLOW_SUFFIX,
|
||||||
} from './autocompleteClan/constants';
|
} from "./autocompleteClan/constants";
|
||||||
|
|
||||||
export const tankNamesTechTreeOnly = fetchTankNames().then((names) =>
|
export const tankNamesTechTreeOnly = fetchTankNames().then((names) =>
|
||||||
names.filter((tank) => tank.treeType === TankType.RESEARCHABLE),
|
names.filter((tank) => tank.treeType === TankType.RESEARCHABLE)
|
||||||
);
|
);
|
||||||
|
|
||||||
export async function autocompleteTanks(
|
export async function autocompleteTanks(
|
||||||
interaction: AutocompleteInteraction<CacheType>,
|
interaction: AutocompleteInteraction<CacheType>,
|
||||||
techTreeOnly = false,
|
techTreeOnly = false,
|
||||||
fields = ['tank'],
|
fields = ["tank"]
|
||||||
) {
|
) {
|
||||||
const { unwrap } = translator(interaction.locale);
|
const { unwrap } = translator(interaction.locale);
|
||||||
const focusedOption = interaction.options.getFocused(true);
|
const focusedOption = interaction.options.getFocused(true);
|
||||||
@@ -31,7 +31,7 @@ export async function autocompleteTanks(
|
|||||||
go(
|
go(
|
||||||
focusedOption.value,
|
focusedOption.value,
|
||||||
await (techTreeOnly ? tankNamesTechTreeOnly : tankNames),
|
await (techTreeOnly ? tankNamesTechTreeOnly : tankNames),
|
||||||
{ keys: SEARCH_KEYS, limit: 10 },
|
{ keys: SEARCH_KEYS, limit: 10 }
|
||||||
).map(async (item) => {
|
).map(async (item) => {
|
||||||
let name = unwrap(item.obj.searchableName);
|
let name = unwrap(item.obj.searchableName);
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ export async function autocompleteTanks(
|
|||||||
0,
|
0,
|
||||||
unwrap(item.obj.searchableName).length -
|
unwrap(item.obj.searchableName).length -
|
||||||
overSize -
|
overSize -
|
||||||
OVERFLOW_SUFFIX.length,
|
OVERFLOW_SUFFIX.length
|
||||||
)}${OVERFLOW_SUFFIX}`;
|
)}${OVERFLOW_SUFFIX}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,8 +50,8 @@ export async function autocompleteTanks(
|
|||||||
name,
|
name,
|
||||||
value: `${item.obj.id}`,
|
value: `${item.obj.id}`,
|
||||||
} satisfies ApplicationCommandOptionChoiceData<string>;
|
} satisfies ApplicationCommandOptionChoiceData<string>;
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
: [],
|
: []
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
ButtonStyle,
|
ButtonStyle,
|
||||||
ComponentEmojiResolvable,
|
type ComponentEmojiResolvable,
|
||||||
} from 'discord.js';
|
} from "discord.js";
|
||||||
|
|
||||||
export function buttonLink(
|
export function buttonLink(
|
||||||
url: string,
|
url: string,
|
||||||
label: string,
|
label: string,
|
||||||
emoji?: ComponentEmojiResolvable,
|
emoji?: ComponentEmojiResolvable
|
||||||
) {
|
) {
|
||||||
const button = new ButtonBuilder()
|
const button = new ButtonBuilder()
|
||||||
.setStyle(ButtonStyle.Link)
|
.setStyle(ButtonStyle.Link)
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
ButtonStyle,
|
ButtonStyle,
|
||||||
ComponentEmojiResolvable,
|
type ComponentEmojiResolvable,
|
||||||
} from 'discord.js';
|
} from "discord.js";
|
||||||
|
|
||||||
export function buttonPrimary(
|
export function buttonPrimary(
|
||||||
id: string,
|
id: string,
|
||||||
label: string,
|
label: string,
|
||||||
emoji?: ComponentEmojiResolvable,
|
emoji?: ComponentEmojiResolvable
|
||||||
) {
|
) {
|
||||||
const button = new ButtonBuilder()
|
const button = new ButtonBuilder()
|
||||||
.setCustomId(id)
|
.setCustomId(id)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
import { type CacheType, ChatInputCommandInteraction } from "discord.js";
|
||||||
|
|
||||||
export interface Parameters {
|
export interface Parameters {
|
||||||
[key: string]: string | number | boolean | undefined | null;
|
[key: string]: string | number | boolean | undefined | null;
|
||||||
@@ -9,7 +9,7 @@ export interface Parameters {
|
|||||||
|
|
||||||
export function commandToURL(
|
export function commandToURL(
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>,
|
||||||
parameters?: Parameters,
|
parameters?: Parameters
|
||||||
) {
|
) {
|
||||||
const pathname = [
|
const pathname = [
|
||||||
interaction.commandName,
|
interaction.commandName,
|
||||||
@@ -17,11 +17,11 @@ export function commandToURL(
|
|||||||
interaction.options.getSubcommand(false),
|
interaction.options.getSubcommand(false),
|
||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join('/');
|
.join("/");
|
||||||
const params = (parameters ? Object.entries(parameters) : [])
|
const params = (parameters ? Object.entries(parameters) : [])
|
||||||
.filter(([, value]) => value !== undefined && value !== null)
|
.filter(([, value]) => value !== undefined && value !== null)
|
||||||
.map(([key, value]) => `${key}=${value}`)
|
.map(([key, value]) => `${key}=${value}`)
|
||||||
.join('&');
|
.join("&");
|
||||||
|
|
||||||
return `${pathname}${params.length > 0 ? `?${params}` : ''}`;
|
return `${pathname}${params.length > 0 ? `?${params}` : ""}`;
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
import { BlitzKitStrings } from '@blitzkit/i18n';
|
import { type BlitzKitStrings } from "@blitzkit/i18n";
|
||||||
import {
|
import {
|
||||||
Locale,
|
Locale,
|
||||||
SlashCommandBuilder,
|
SlashCommandBuilder,
|
||||||
SlashCommandSubcommandBuilder,
|
SlashCommandSubcommandBuilder,
|
||||||
SlashCommandSubcommandGroupBuilder,
|
SlashCommandSubcommandGroupBuilder,
|
||||||
} from 'discord.js';
|
} from "discord.js";
|
||||||
import { translator } from '../localization/translator';
|
import { translator } from "../localization/translator";
|
||||||
import { localizationObject } from './localizationObject';
|
import { localizationObject } from "./localizationObject";
|
||||||
|
|
||||||
interface CreateLocalizedCommandSubcommand {
|
interface CreateLocalizedCommandSubcommand {
|
||||||
subcommand: string;
|
subcommand: string;
|
||||||
@@ -22,12 +22,12 @@ export function createLocalizedCommand(
|
|||||||
command: string,
|
command: string,
|
||||||
sub?:
|
sub?:
|
||||||
| CreateLocalizedCommandSubcommand[]
|
| CreateLocalizedCommandSubcommand[]
|
||||||
| CreateLocalizedCommandSubcommandGroup[],
|
| CreateLocalizedCommandSubcommandGroup[]
|
||||||
) {
|
) {
|
||||||
const commandPathItem = command.replaceAll(
|
const commandPathItem = command.replaceAll(
|
||||||
'-',
|
"-",
|
||||||
'_',
|
"_"
|
||||||
) as keyof BlitzKitStrings['bot']['commands'];
|
) as keyof BlitzKitStrings["bot"]["commands"];
|
||||||
const { strings } = translator(Locale.EnglishUS);
|
const { strings } = translator(Locale.EnglishUS);
|
||||||
const slashCommand = new SlashCommandBuilder()
|
const slashCommand = new SlashCommandBuilder()
|
||||||
.setName(command)
|
.setName(command)
|
||||||
@@ -35,19 +35,19 @@ export function createLocalizedCommand(
|
|||||||
localizationObject(
|
localizationObject(
|
||||||
(strings) => strings.bot.commands[commandPathItem].name,
|
(strings) => strings.bot.commands[commandPathItem].name,
|
||||||
undefined,
|
undefined,
|
||||||
true,
|
true
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
.setDescription(strings.bot.commands[commandPathItem].description)
|
.setDescription(strings.bot.commands[commandPathItem].description)
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
localizationObject(
|
localizationObject(
|
||||||
(strings) => strings.bot.commands[commandPathItem].description,
|
(strings) => strings.bot.commands[commandPathItem].description
|
||||||
),
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (sub) {
|
if (sub) {
|
||||||
sub.map((subItem) => {
|
sub.map((subItem) => {
|
||||||
if ('subcommand' in subItem) {
|
if ("subcommand" in subItem) {
|
||||||
const subcommandNameLocalizations = localizationObject(
|
const subcommandNameLocalizations = localizationObject(
|
||||||
(strings) =>
|
(strings) =>
|
||||||
(
|
(
|
||||||
@@ -56,7 +56,7 @@ export function createLocalizedCommand(
|
|||||||
}
|
}
|
||||||
).subcommands[subItem.subcommand].name,
|
).subcommands[subItem.subcommand].name,
|
||||||
undefined,
|
undefined,
|
||||||
true,
|
true
|
||||||
);
|
);
|
||||||
const subcommandDescriptionLocalizations = localizationObject(
|
const subcommandDescriptionLocalizations = localizationObject(
|
||||||
(strings) =>
|
(strings) =>
|
||||||
@@ -64,7 +64,7 @@ export function createLocalizedCommand(
|
|||||||
strings.bot.commands[commandPathItem] as unknown as {
|
strings.bot.commands[commandPathItem] as unknown as {
|
||||||
subcommands: Record<string, { description: string }>;
|
subcommands: Record<string, { description: string }>;
|
||||||
}
|
}
|
||||||
).subcommands[subItem.subcommand].description,
|
).subcommands[subItem.subcommand].description
|
||||||
);
|
);
|
||||||
|
|
||||||
slashCommand.addSubcommand((option) => {
|
slashCommand.addSubcommand((option) => {
|
||||||
@@ -78,7 +78,7 @@ export function createLocalizedCommand(
|
|||||||
strings.bot.commands[commandPathItem] as unknown as {
|
strings.bot.commands[commandPathItem] as unknown as {
|
||||||
subcommands: Record<string, { description: string }>;
|
subcommands: Record<string, { description: string }>;
|
||||||
}
|
}
|
||||||
).subcommands[subItem.subcommand].description,
|
).subcommands[subItem.subcommand].description
|
||||||
)
|
)
|
||||||
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
|
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
|
||||||
});
|
});
|
||||||
@@ -91,7 +91,7 @@ export function createLocalizedCommand(
|
|||||||
}
|
}
|
||||||
).groups[subItem.group].name,
|
).groups[subItem.group].name,
|
||||||
undefined,
|
undefined,
|
||||||
true,
|
true
|
||||||
);
|
);
|
||||||
const subcommandDescriptionLocalizations = localizationObject(
|
const subcommandDescriptionLocalizations = localizationObject(
|
||||||
(strings) =>
|
(strings) =>
|
||||||
@@ -99,7 +99,7 @@ export function createLocalizedCommand(
|
|||||||
strings.bot.commands[commandPathItem] as unknown as {
|
strings.bot.commands[commandPathItem] as unknown as {
|
||||||
groups: Record<string, { description: string }>;
|
groups: Record<string, { description: string }>;
|
||||||
}
|
}
|
||||||
).groups[subItem.group].description,
|
).groups[subItem.group].description
|
||||||
);
|
);
|
||||||
|
|
||||||
slashCommand.addSubcommandGroup((option) => {
|
slashCommand.addSubcommandGroup((option) => {
|
||||||
@@ -113,7 +113,7 @@ export function createLocalizedCommand(
|
|||||||
strings.bot.commands[commandPathItem] as unknown as {
|
strings.bot.commands[commandPathItem] as unknown as {
|
||||||
groups: Record<string, { description: string }>;
|
groups: Record<string, { description: string }>;
|
||||||
}
|
}
|
||||||
).groups[subItem.group].description,
|
).groups[subItem.group].description
|
||||||
)
|
)
|
||||||
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
|
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { ChatInputCommandInteraction } from 'discord.js';
|
import { ChatInputCommandInteraction } from "discord.js";
|
||||||
import { PeriodType } from './addPeriodSubCommands';
|
import type { PeriodType } from "./addPeriodSubCommands";
|
||||||
|
|
||||||
export function getCustomPeriodParams(
|
export function getCustomPeriodParams(
|
||||||
interaction: ChatInputCommandInteraction,
|
interaction: ChatInputCommandInteraction,
|
||||||
forcedNonCustomPeriod = false,
|
forcedNonCustomPeriod = false
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
!forcedNonCustomPeriod &&
|
!forcedNonCustomPeriod &&
|
||||||
(interaction.options.getSubcommand() as PeriodType) === 'custom'
|
(interaction.options.getSubcommand() as PeriodType) === "custom"
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
start: interaction.options.getInteger('start', true),
|
start: interaction.options.getInteger("start", true),
|
||||||
end: interaction.options.getInteger('end', true),
|
end: interaction.options.getInteger("end", true),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import { TankClass, TankType } from '@blitzkit/core';
|
import { TankClass, TankType } from "@blitzkit/core";
|
||||||
import { ButtonInteraction } from 'discord.js';
|
import { ButtonInteraction } from "discord.js";
|
||||||
import { StatFilters } from '../blitzstars/filterStats';
|
import type { StatFilters } from "../blitzstars/filterStats";
|
||||||
|
|
||||||
export function getFiltersFromButton(interaction: ButtonInteraction) {
|
export function getFiltersFromButton(interaction: ButtonInteraction) {
|
||||||
const url = new URL(`https://example.com/${interaction.customId}`);
|
const url = new URL(`https://example.com/${interaction.customId}`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
nation: url.searchParams.get('nation') ?? undefined,
|
nation: url.searchParams.get("nation") ?? undefined,
|
||||||
tank: parseInt(url.searchParams.get('tank') ?? '0') || undefined,
|
tank: parseInt(url.searchParams.get("tank") ?? "0") || undefined,
|
||||||
class:
|
class:
|
||||||
(Number(url.searchParams.get('class')) as TankClass | undefined) ??
|
(Number(url.searchParams.get("class")) as TankClass | undefined) ??
|
||||||
undefined,
|
undefined,
|
||||||
type:
|
type:
|
||||||
(Number(url.searchParams.get('type')) as TankType | undefined) ??
|
(Number(url.searchParams.get("type")) as TankType | undefined) ??
|
||||||
undefined,
|
undefined,
|
||||||
tier: parseInt(url.searchParams.get('tier') ?? '0') || undefined,
|
tier: parseInt(url.searchParams.get("tier") ?? "0") || undefined,
|
||||||
} satisfies StatFilters;
|
} satisfies StatFilters;
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ChatInputCommandInteraction } from 'discord.js';
|
import { ChatInputCommandInteraction } from 'discord.js';
|
||||||
import { resolveTankId } from '../blitz/resolveTankId';
|
import { resolveTankId } from '../blitz/resolveTankId';
|
||||||
import { StatFilters } from '../blitzstars/filterStats';
|
import type { StatFilters } from '../blitzstars/filterStats';
|
||||||
|
|
||||||
export async function getFiltersFromCommand(
|
export async function getFiltersFromCommand(
|
||||||
interaction: ChatInputCommandInteraction,
|
interaction: ChatInputCommandInteraction,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { literals } from "@blitzkit/i18n";
|
import { literals } from "@blitzkit/i18n";
|
||||||
import { Locale } from "discord.js";
|
import { Locale } from "discord.js";
|
||||||
import { translator } from "../localization/translator";
|
import { translator } from "../localization/translator";
|
||||||
import { PeriodSize } from "./addPeriodSubCommands";
|
import type { PeriodSize } from "./addPeriodSubCommands";
|
||||||
|
|
||||||
export function getPeriodOptionName(period: PeriodSize, locale: Locale) {
|
export function getPeriodOptionName(period: PeriodSize, locale: Locale) {
|
||||||
const { strings } = translator(locale);
|
const { strings } = translator(locale);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { BlitzKitStrings, literals as literalsFunc } from "@blitzkit/i18n";
|
import { type BlitzKitStrings, literals as literalsFunc } from "@blitzkit/i18n";
|
||||||
import { Locale } from "discord.js";
|
import { Locale } from "discord.js";
|
||||||
import { SUPPORTED_LOCALES_DISCORD } from "../localization/strings/constants";
|
import { SUPPORTED_LOCALES_DISCORD } from "../localization/strings/constants";
|
||||||
import { translator } from "../localization/translator";
|
import { translator } from "../localization/translator";
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import {
|
|||||||
AttachmentBuilder,
|
AttachmentBuilder,
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
EmbedBuilder,
|
EmbedBuilder,
|
||||||
InteractionEditReplyOptions,
|
type InteractionEditReplyOptions,
|
||||||
InteractionReplyOptions,
|
type InteractionReplyOptions,
|
||||||
MessageEditOptions,
|
type MessageEditOptions,
|
||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
import { InteractionReturnable } from "../../events/interactionCreate";
|
import type { InteractionReturnable } from "../../events/interactionCreate";
|
||||||
import { Writeable } from "../../types/writable";
|
import type { Writeable } from "../../types/writable";
|
||||||
import { jsxToPngThreaded } from "../blitzkit/jsxToPngThreaded";
|
import { jsxToPngThreaded } from "../blitzkit/jsxToPngThreaded";
|
||||||
import { RenderConfiguration } from "../blitzkit/renderConfiguration";
|
import { RenderConfiguration } from "../blitzkit/renderConfiguration";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Region } from "@blitzkit/core";
|
import type { Region } from "@blitzkit/core";
|
||||||
import { literals } from "@blitzkit/i18n";
|
import { literals } from "@blitzkit/i18n";
|
||||||
import { ChatInputCommandInteraction } from "discord.js";
|
import { ChatInputCommandInteraction } from "discord.js";
|
||||||
import markdownEscape from "markdown-escape";
|
import markdownEscape from "markdown-escape";
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
import { getTimeDaysAgo, Region } from '@blitzkit/core';
|
import { getTimeDaysAgo, type Region } from "@blitzkit/core";
|
||||||
import { ButtonInteraction } from 'discord.js';
|
import { ButtonInteraction } from "discord.js";
|
||||||
import { getPeriodNow } from '../blitzkit/getPeriodNow';
|
import { getPeriodNow } from "../blitzkit/getPeriodNow";
|
||||||
import { getPeriodStart } from '../blitzkit/getPeriodStart';
|
import { getPeriodStart } from "../blitzkit/getPeriodStart";
|
||||||
import { PeriodType } from './addPeriodSubCommands';
|
import type { PeriodType } from "./addPeriodSubCommands";
|
||||||
import { getPeriodOptionName } from './getPeriodOptionName';
|
import { getPeriodOptionName } from "./getPeriodOptionName";
|
||||||
import { ResolvedPeriod } from './resolvePeriodFromCommand';
|
import type { ResolvedPeriod } from "./resolvePeriodFromCommand";
|
||||||
|
|
||||||
export function resolvePeriodFromButton(
|
export function resolvePeriodFromButton(
|
||||||
region: Region,
|
region: Region,
|
||||||
interaction: ButtonInteraction,
|
interaction: ButtonInteraction
|
||||||
) {
|
) {
|
||||||
let name: string;
|
let name: string;
|
||||||
let start: number;
|
let start: number;
|
||||||
let end: number;
|
let end: number;
|
||||||
const url = new URL(`https://example.com/${interaction.customId}`);
|
const url = new URL(`https://example.com/${interaction.customId}`);
|
||||||
const path = url.pathname.split('/');
|
const path = url.pathname.split("/");
|
||||||
const periodSubcommand = path.at(-1) as PeriodType;
|
const periodSubcommand = path.at(-1) as PeriodType;
|
||||||
|
|
||||||
if (periodSubcommand === 'custom') {
|
if (periodSubcommand === "custom") {
|
||||||
const startRaw = parseInt(url!.searchParams.get('start')!);
|
const startRaw = parseInt(url!.searchParams.get("start")!);
|
||||||
const endRaw = parseInt(url!.searchParams.get('end')!);
|
const endRaw = parseInt(url!.searchParams.get("end")!);
|
||||||
const startDaysAgoMin = Math.min(startRaw, endRaw);
|
const startDaysAgoMin = Math.min(startRaw, endRaw);
|
||||||
const endDaysAgoMax = Math.max(startRaw, endRaw);
|
const endDaysAgoMax = Math.max(startRaw, endRaw);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { getTimeDaysAgo, Region } from "@blitzkit/core";
|
import { getTimeDaysAgo, type Region } from "@blitzkit/core";
|
||||||
import { literals } from "@blitzkit/i18n";
|
import { literals } from "@blitzkit/i18n";
|
||||||
import { CacheType, ChatInputCommandInteraction } from "discord.js";
|
import { type CacheType, ChatInputCommandInteraction } from "discord.js";
|
||||||
import { getPeriodNow } from "../blitzkit/getPeriodNow";
|
import { getPeriodNow } from "../blitzkit/getPeriodNow";
|
||||||
import { getPeriodStart } from "../blitzkit/getPeriodStart";
|
import { getPeriodStart } from "../blitzkit/getPeriodStart";
|
||||||
import { translator } from "../localization/translator";
|
import { translator } from "../localization/translator";
|
||||||
import { PeriodType } from "./addPeriodSubCommands";
|
import type { PeriodType } from "./addPeriodSubCommands";
|
||||||
import { getPeriodOptionName } from "./getPeriodOptionName";
|
import { getPeriodOptionName } from "./getPeriodOptionName";
|
||||||
|
|
||||||
export interface ResolvedPeriod {
|
export interface ResolvedPeriod {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { Region } from '@blitzkit/core';
|
import type { Region } from "@blitzkit/core";
|
||||||
import { ButtonInteraction } from 'discord.js';
|
import { ButtonInteraction } from "discord.js";
|
||||||
import { ResolvedPlayer } from './resolvePlayerFromCommand';
|
import type { ResolvedPlayer } from "./resolvePlayerFromCommand";
|
||||||
|
|
||||||
export async function resolvePlayerFromButton(interaction: ButtonInteraction) {
|
export async function resolvePlayerFromButton(interaction: ButtonInteraction) {
|
||||||
const url = new URL(`https://exmaple.com/${interaction.customId}`);
|
const url = new URL(`https://exmaple.com/${interaction.customId}`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: parseInt(url.searchParams.get('id')!),
|
id: parseInt(url.searchParams.get("id")!),
|
||||||
region: url.searchParams.get('region') as Region,
|
region: url.searchParams.get("region") as Region,
|
||||||
} satisfies ResolvedPlayer;
|
} satisfies ResolvedPlayer;
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { idToRegion, Region } from "@blitzkit/core";
|
import { idToRegion, type Region } from "@blitzkit/core";
|
||||||
import { literals } from "@blitzkit/i18n";
|
import { literals } from "@blitzkit/i18n";
|
||||||
import { CacheType, ChatInputCommandInteraction } from "discord.js";
|
import { type CacheType, ChatInputCommandInteraction } from "discord.js";
|
||||||
import markdownEscape from "markdown-escape";
|
import markdownEscape from "markdown-escape";
|
||||||
import { searchPlayersAcrossRegionsBotWrapper } from "../../blitz/searchPlayersAcrossRegionsBotWrapper";
|
import { searchPlayersAcrossRegionsBotWrapper } from "../../blitz/searchPlayersAcrossRegionsBotWrapper";
|
||||||
import { getBlitzFromDiscord } from "../../blitzkit/getBlitzFromDiscord";
|
import { getBlitzFromDiscord } from "../../blitzkit/getBlitzFromDiscord";
|
||||||
|
|||||||
@@ -1,52 +1,52 @@
|
|||||||
import * as colors from '@radix-ui/colors';
|
import * as colors from "@radix-ui/colors";
|
||||||
import { Theme } from '@radix-ui/themes';
|
import { Theme } from "@radix-ui/themes";
|
||||||
import { ComponentProps } from 'react';
|
import type { ComponentProps } from "react";
|
||||||
|
|
||||||
export type AccentColor = Exclude<
|
export type AccentColor = Exclude<
|
||||||
ComponentProps<typeof Theme>['accentColor'],
|
ComponentProps<typeof Theme>["accentColor"],
|
||||||
'gray' | undefined
|
"gray" | undefined
|
||||||
>;
|
>;
|
||||||
export type AccentColorDark = `${AccentColor}Dark`;
|
export type AccentColorDark = `${AccentColor}Dark`;
|
||||||
export type GrayColor = Exclude<
|
export type GrayColor = Exclude<
|
||||||
ComponentProps<typeof Theme>['grayColor'],
|
ComponentProps<typeof Theme>["grayColor"],
|
||||||
'auto' | undefined
|
"auto" | undefined
|
||||||
>;
|
>;
|
||||||
export type GrayColorDark = `${GrayColor}Dark`;
|
export type GrayColorDark = `${GrayColor}Dark`;
|
||||||
|
|
||||||
export const ACCENT_COLORS: AccentColor[] = [
|
export const ACCENT_COLORS: AccentColor[] = [
|
||||||
'tomato',
|
"tomato",
|
||||||
'red',
|
"red",
|
||||||
'ruby',
|
"ruby",
|
||||||
'crimson',
|
"crimson",
|
||||||
'pink',
|
"pink",
|
||||||
'plum',
|
"plum",
|
||||||
'purple',
|
"purple",
|
||||||
'violet',
|
"violet",
|
||||||
'iris',
|
"iris",
|
||||||
'indigo',
|
"indigo",
|
||||||
'blue',
|
"blue",
|
||||||
'cyan',
|
"cyan",
|
||||||
'teal',
|
"teal",
|
||||||
'jade',
|
"jade",
|
||||||
'green',
|
"green",
|
||||||
'grass',
|
"grass",
|
||||||
'brown',
|
"brown",
|
||||||
'orange',
|
"orange",
|
||||||
'sky',
|
"sky",
|
||||||
'mint',
|
"mint",
|
||||||
'lime',
|
"lime",
|
||||||
'yellow',
|
"yellow",
|
||||||
'amber',
|
"amber",
|
||||||
'gold',
|
"gold",
|
||||||
'bronze',
|
"bronze",
|
||||||
];
|
];
|
||||||
export const GRAY_COLORS: GrayColor[] = [
|
export const GRAY_COLORS: GrayColor[] = [
|
||||||
'gray',
|
"gray",
|
||||||
'mauve',
|
"mauve",
|
||||||
'slate',
|
"slate",
|
||||||
'sage',
|
"sage",
|
||||||
'olive',
|
"olive",
|
||||||
'sand',
|
"sand",
|
||||||
];
|
];
|
||||||
|
|
||||||
export const PALETTES: Record<
|
export const PALETTES: Record<
|
||||||
|
|||||||
@@ -3,21 +3,21 @@ import {
|
|||||||
AttachmentBuilder,
|
AttachmentBuilder,
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
ButtonStyle,
|
ButtonStyle,
|
||||||
CacheType,
|
type CacheType,
|
||||||
ChatInputCommandInteraction,
|
ChatInputCommandInteraction,
|
||||||
InteractionReplyOptions,
|
type InteractionReplyOptions,
|
||||||
} from 'discord.js';
|
} from "discord.js";
|
||||||
import { InteractionRawReturnable, commands } from '..';
|
import { type InteractionRawReturnable, commands } from "..";
|
||||||
import { UserError } from '../../../core/blitzkit/userError';
|
import { UserError } from "../../../core/blitzkit/userError";
|
||||||
import { buttonLink } from '../../../core/discord/buttonLink';
|
import { buttonLink } from "../../../core/discord/buttonLink";
|
||||||
import { embedWarning } from '../../../core/discord/embedWarning';
|
import { embedWarning } from "../../../core/discord/embedWarning";
|
||||||
import { normalizeInteractionReturnable } from '../../../core/discord/normalizeInteractionReturnable';
|
import { normalizeInteractionReturnable } from "../../../core/discord/normalizeInteractionReturnable";
|
||||||
import { psa } from '../../../core/discord/psa';
|
import { psa } from "../../../core/discord/psa";
|
||||||
import { translator } from '../../../core/localization/translator';
|
import { translator } from "../../../core/localization/translator";
|
||||||
import { Writeable } from '../../../types/writable';
|
import type { Writeable } from "../../../types/writable";
|
||||||
|
|
||||||
export async function handleChatInputCommand(
|
export async function handleChatInputCommand(
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>
|
||||||
) {
|
) {
|
||||||
await interaction.deferReply();
|
await interaction.deferReply();
|
||||||
|
|
||||||
@@ -33,10 +33,10 @@ export async function handleChatInputCommand(
|
|||||||
|
|
||||||
(Array.isArray(returnable) ? returnable : [returnable]).forEach(
|
(Array.isArray(returnable) ? returnable : [returnable]).forEach(
|
||||||
(object) => {
|
(object) => {
|
||||||
if (typeof object === 'string') {
|
if (typeof object === "string") {
|
||||||
chunks.push([object]);
|
chunks.push([object]);
|
||||||
} else chunks.at(-1)?.push(object!);
|
} else chunks.at(-1)?.push(object!);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
let index = 0;
|
let index = 0;
|
||||||
@@ -49,17 +49,17 @@ export async function handleChatInputCommand(
|
|||||||
(psa.data.commands === undefined ||
|
(psa.data.commands === undefined ||
|
||||||
psa.data.commands.includes(interaction.commandName))
|
psa.data.commands.includes(interaction.commandName))
|
||||||
) {
|
) {
|
||||||
if (psa.data.type === undefined || psa.data.type === 'embed') {
|
if (psa.data.type === undefined || psa.data.type === "embed") {
|
||||||
if (!reply.embeds) reply.embeds = [];
|
if (!reply.embeds) reply.embeds = [];
|
||||||
|
|
||||||
const embed = embedWarning(psa.data.title, psa.data.description);
|
const embed = embedWarning(psa.data.title, psa.data.description);
|
||||||
|
|
||||||
if (psa.data.image) embed.setImage(psa.data.image);
|
if (psa.data.image) embed.setImage(psa.data.image);
|
||||||
(reply.embeds as Writeable<typeof reply.embeds>).push(embed);
|
(reply.embeds as Writeable<typeof reply.embeds>).push(embed);
|
||||||
} else if (psa.data.type === 'image') {
|
} else if (psa.data.type === "image") {
|
||||||
if (!reply.files) reply.files = [];
|
if (!reply.files) reply.files = [];
|
||||||
(reply.files as Writeable<typeof reply.files>).push(
|
(reply.files as Writeable<typeof reply.files>).push(
|
||||||
new AttachmentBuilder(psa.data.image),
|
new AttachmentBuilder(psa.data.image)
|
||||||
);
|
);
|
||||||
reply.content = reply.content ?? psa.data.title;
|
reply.content = reply.content ?? psa.data.title;
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ export async function handleChatInputCommand(
|
|||||||
(
|
(
|
||||||
reply.components[0] as ActionRowBuilder<ButtonBuilder>
|
reply.components[0] as ActionRowBuilder<ButtonBuilder>
|
||||||
).addComponents(
|
).addComponents(
|
||||||
psa.data.links.map(({ title, url }) => buttonLink(url, title)),
|
psa.data.links.map(({ title, url }) => buttonLink(url, title))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,17 +93,17 @@ export async function handleChatInputCommand(
|
|||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (psa.data.type === undefined || psa.data.type === 'embed') {
|
if (psa.data.type === undefined || psa.data.type === "embed") {
|
||||||
if (!followUp.embeds) followUp.embeds = [];
|
if (!followUp.embeds) followUp.embeds = [];
|
||||||
|
|
||||||
const embed = embedWarning(psa.data.title, psa.data.description);
|
const embed = embedWarning(psa.data.title, psa.data.description);
|
||||||
|
|
||||||
if (psa.data.image) embed.setImage(psa.data.image);
|
if (psa.data.image) embed.setImage(psa.data.image);
|
||||||
(followUp.embeds as Writeable<typeof followUp.embeds>).push(embed);
|
(followUp.embeds as Writeable<typeof followUp.embeds>).push(embed);
|
||||||
} else if (psa.data.type === 'image') {
|
} else if (psa.data.type === "image") {
|
||||||
if (!followUp.files) followUp.files = [];
|
if (!followUp.files) followUp.files = [];
|
||||||
(followUp.files as Writeable<typeof followUp.files>).push(
|
(followUp.files as Writeable<typeof followUp.files>).push(
|
||||||
new AttachmentBuilder(psa.data.image),
|
new AttachmentBuilder(psa.data.image)
|
||||||
);
|
);
|
||||||
followUp.content = followUp.content ?? psa.data.title;
|
followUp.content = followUp.content ?? psa.data.title;
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ export async function handleChatInputCommand(
|
|||||||
(
|
(
|
||||||
followUp.components[0] as ActionRowBuilder<ButtonBuilder>
|
followUp.components[0] as ActionRowBuilder<ButtonBuilder>
|
||||||
).addComponents(
|
).addComponents(
|
||||||
psa.data.links.map(({ title, url }) => buttonLink(url, title)),
|
psa.data.links.map(({ title, url }) => buttonLink(url, title))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,8 +132,8 @@ export async function handleChatInputCommand(
|
|||||||
new ActionRowBuilder<ButtonBuilder>().addComponents(
|
new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||||
new ButtonBuilder()
|
new ButtonBuilder()
|
||||||
.setLabel(strings.bot.common.errors.get_help)
|
.setLabel(strings.bot.common.errors.get_help)
|
||||||
.setURL('https://discord.gg/nDt7AjGJQH')
|
.setURL("https://discord.gg/nDt7AjGJQH")
|
||||||
.setStyle(ButtonStyle.Link),
|
.setStyle(ButtonStyle.Link)
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
if (error instanceof UserError) {
|
if (error instanceof UserError) {
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ import {
|
|||||||
AutocompleteInteraction,
|
AutocompleteInteraction,
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
ButtonInteraction,
|
ButtonInteraction,
|
||||||
CacheType,
|
type CacheType,
|
||||||
ChatInputCommandInteraction,
|
ChatInputCommandInteraction,
|
||||||
EmbedBuilder,
|
EmbedBuilder,
|
||||||
Interaction,
|
type Interaction,
|
||||||
REST,
|
REST,
|
||||||
Routes,
|
Routes,
|
||||||
SlashCommandBuilder,
|
SlashCommandBuilder,
|
||||||
SlashCommandOptionsOnlyBuilder,
|
type SlashCommandOptionsOnlyBuilder,
|
||||||
SlashCommandSubcommandsOnlyBuilder,
|
type SlashCommandSubcommandsOnlyBuilder,
|
||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
import { aboutCommand } from "../../commands/about";
|
import { aboutCommand } from "../../commands/about";
|
||||||
import { breakdownCommand } from "../../commands/breakdown";
|
import { breakdownCommand } from "../../commands/breakdown";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// a cleaner simplification of Blitz Stars' histories because it's a mess there
|
// a cleaner simplification of Blitz Stars' histories because it's a mess there
|
||||||
|
|
||||||
import { BlitzStats } from '@blitzkit/core';
|
import { type BlitzStats } from '@blitzkit/core';
|
||||||
|
|
||||||
export interface History {
|
export interface History {
|
||||||
all: BlitzStats;
|
all: BlitzStats;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { TankClass, TankType } from '../protos';
|
import { TankClass, TankType } from "../protos";
|
||||||
import { BlitzStats } from '../statistics';
|
import type { BlitzStats } from "../statistics";
|
||||||
|
|
||||||
export const TANK_TYPES = [
|
export const TANK_TYPES = [
|
||||||
TankType.RESEARCHABLE,
|
TankType.RESEARCHABLE,
|
||||||
@@ -8,9 +8,9 @@ export const TANK_TYPES = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const TANK_TYPE_COMMAND_NAMES = {
|
export const TANK_TYPE_COMMAND_NAMES = {
|
||||||
[TankType.RESEARCHABLE]: 'researchable',
|
[TankType.RESEARCHABLE]: "researchable",
|
||||||
[TankType.PREMIUM]: 'premium',
|
[TankType.PREMIUM]: "premium",
|
||||||
[TankType.COLLECTOR]: 'collector',
|
[TankType.COLLECTOR]: "collector",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TANK_CLASSES = [
|
export const TANK_CLASSES = [
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import { assertSecret, EventManager } from '../blitzkit';
|
import { assertSecret, EventManager } from "../blitzkit";
|
||||||
import { patientFetch } from '../blitzkit/patientFetch';
|
import { patientFetch } from "../blitzkit/patientFetch";
|
||||||
import { Region } from './regions';
|
import type { Region } from "./regions";
|
||||||
|
|
||||||
const RETRY_ERRORS = ['REQUEST_LIMIT_EXCEEDED', 'SOURCE_NOT_AVAILABLE'];
|
const RETRY_ERRORS = ["REQUEST_LIMIT_EXCEEDED", "SOURCE_NOT_AVAILABLE"];
|
||||||
|
|
||||||
export const retryAbleBlitzFetchEvent = new EventManager();
|
export const retryAbleBlitzFetchEvent = new EventManager();
|
||||||
export const blitzFetchQueueAvailableEvent = new EventManager();
|
export const blitzFetchQueueAvailableEvent = new EventManager();
|
||||||
|
|
||||||
type BlitzResponse<Data extends object> =
|
type BlitzResponse<Data extends object> =
|
||||||
| {
|
| {
|
||||||
status: 'error';
|
status: "error";
|
||||||
error: { field: string; message: string; code: 402; value: null };
|
error: { field: string; message: string; code: 402; value: null };
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
status: 'ok';
|
status: "ok";
|
||||||
data: Data;
|
data: Data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -36,11 +36,11 @@ async function manageQueue() {
|
|||||||
const request = queue.shift()!;
|
const request = queue.shift()!;
|
||||||
const data = (await patientFetch(request.url)
|
const data = (await patientFetch(request.url)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.catch((error) => ({ status: 'error', error }))) as BlitzResponse<
|
.catch((error) => ({ status: "error", error }))) as BlitzResponse<
|
||||||
typeof request.resolve
|
typeof request.resolve
|
||||||
>;
|
>;
|
||||||
|
|
||||||
if (data.status === 'ok') {
|
if (data.status === "ok") {
|
||||||
request.resolve(data.data);
|
request.resolve(data.data);
|
||||||
} else {
|
} else {
|
||||||
if (RETRY_ERRORS.includes(data.error.message)) {
|
if (RETRY_ERRORS.includes(data.error.message)) {
|
||||||
@@ -67,19 +67,19 @@ export type FetchBlitzParams = Record<string, string | number | undefined>;
|
|||||||
export function fetchBlitz<Data extends object>(
|
export function fetchBlitz<Data extends object>(
|
||||||
region: Region,
|
region: Region,
|
||||||
path: string,
|
path: string,
|
||||||
params: FetchBlitzParams = {},
|
params: FetchBlitzParams = {}
|
||||||
) {
|
) {
|
||||||
return new Promise<Data>((resolve) => {
|
return new Promise<Data>((resolve) => {
|
||||||
queue.push({
|
queue.push({
|
||||||
url: `https://api.wotblitz.${region}/wotb/${path}/?${Object.entries({
|
url: `https://api.wotblitz.${region}/wotb/${path}/?${Object.entries({
|
||||||
application_id: assertSecret(
|
application_id: assertSecret(
|
||||||
import.meta.env.PUBLIC_WARGAMING_APPLICATION_ID,
|
import.meta.env.PUBLIC_WARGAMING_APPLICATION_ID
|
||||||
),
|
),
|
||||||
...params,
|
...params,
|
||||||
})
|
})
|
||||||
.filter(([_, value]) => value !== undefined)
|
.filter(([_, value]) => value !== undefined)
|
||||||
.map(([key, value]) => `${key}=${encodeURIComponent(value!)}`)
|
.map(([key, value]) => `${key}=${encodeURIComponent(value!)}`)
|
||||||
.join('&')}`,
|
.join("&")}`,
|
||||||
resolve(data) {
|
resolve(data) {
|
||||||
resolve(data as Data);
|
resolve(data as Data);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { assertSecret } from '../blitzkit';
|
import { assertSecret } from "../blitzkit";
|
||||||
import { BlitzGlossary } from '../types';
|
import type { BlitzGlossary } from "../types";
|
||||||
|
|
||||||
export async function fetchGlossary(locale: string) {
|
export async function fetchGlossary(locale: string) {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${assertSecret(
|
`${assertSecret(
|
||||||
import.meta.env.WOTB_GLOSSARY_DOMAIN,
|
import.meta.env.WOTB_GLOSSARY_DOMAIN
|
||||||
)}/${locale}${assertSecret(import.meta.env.WOTB_GLOSSARY_PATH)}`,
|
)}/${locale}${assertSecret(import.meta.env.WOTB_GLOSSARY_PATH)}`
|
||||||
);
|
);
|
||||||
return (await response.json()) as BlitzGlossary;
|
return (await response.json()) as BlitzGlossary;
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
import { BlitzStats, calculateWN8 } from "../statistics";
|
import { type BlitzStats, calculateWN8 } from "../statistics";
|
||||||
|
|
||||||
export type Stat = keyof ReturnType<typeof generateStats>;
|
export type Stat = keyof ReturnType<typeof generateStats>;
|
||||||
|
|
||||||
export const STAT_NAMES: Record<Stat, string> = {
|
export const STAT_NAMES: Record<Stat, string> = {
|
||||||
battles: 'Battles',
|
battles: "Battles",
|
||||||
winrate: 'Winrate',
|
winrate: "Winrate",
|
||||||
wn8: 'WN8',
|
wn8: "WN8",
|
||||||
averageDamage: 'Damage',
|
averageDamage: "Damage",
|
||||||
damage: 'Accumulated damage',
|
damage: "Accumulated damage",
|
||||||
wins: 'Wins',
|
wins: "Wins",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const STAT_KEYS = Object.keys(STAT_NAMES) as Stat[];
|
export const STAT_KEYS = Object.keys(STAT_NAMES) as Stat[];
|
||||||
@@ -29,7 +29,7 @@ export function prettifyStats(s: ReturnType<typeof generateStats>) {
|
|||||||
battles: `${s.battles}`,
|
battles: `${s.battles}`,
|
||||||
wins: `${s.wins}`,
|
wins: `${s.wins}`,
|
||||||
winrate: `${(s.winrate * 100).toFixed(0)}%`,
|
winrate: `${(s.winrate * 100).toFixed(0)}%`,
|
||||||
wn8: s.wn8 ? s.wn8.toFixed(0) : '--',
|
wn8: s.wn8 ? s.wn8.toFixed(0) : "--",
|
||||||
damage: `${s.damage}`,
|
damage: `${s.damage}`,
|
||||||
averageDamage: s.averageDamage.toFixed(0),
|
averageDamage: s.averageDamage.toFixed(0),
|
||||||
} satisfies Record<Stat, string>;
|
} satisfies Record<Stat, string>;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { fetchBlitz } from "./fetchBlitz";
|
import { fetchBlitz } from "./fetchBlitz";
|
||||||
import { normalizeIds } from "./normalizeIds";
|
import { normalizeIds } from "./normalizeIds";
|
||||||
import { Region } from "./regions";
|
import type { Region } from "./regions";
|
||||||
|
|
||||||
interface IndividualAccountAchievements {
|
interface IndividualAccountAchievements {
|
||||||
achievements: {
|
achievements: {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { fetchBlitz } from "./fetchBlitz";
|
import { fetchBlitz } from "./fetchBlitz";
|
||||||
import { normalizeIds } from "./normalizeIds";
|
import { normalizeIds } from "./normalizeIds";
|
||||||
import { Region } from "./regions";
|
import type { Region } from "./regions";
|
||||||
|
|
||||||
type IndividualClanAccountInfo = {
|
type IndividualClanAccountInfo = {
|
||||||
account_id: number;
|
account_id: number;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { fetchBlitz } from "./fetchBlitz";
|
import { fetchBlitz } from "./fetchBlitz";
|
||||||
import { normalizeIds } from "./normalizeIds";
|
import { normalizeIds } from "./normalizeIds";
|
||||||
import { Region } from "./regions";
|
import type { Region } from "./regions";
|
||||||
|
|
||||||
interface IndividualClanInfo {
|
interface IndividualClanInfo {
|
||||||
recruiting_options: {
|
recruiting_options: {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { context } from "../blitzkit/context";
|
import { context } from "../blitzkit/context";
|
||||||
import { patientFetch } from "../blitzkit/patientFetch";
|
import { patientFetch } from "../blitzkit/patientFetch";
|
||||||
import { RatingLeague, RatingReward } from "./rating";
|
import type { RatingLeague, RatingReward } from "./rating";
|
||||||
import { Region } from "./regions";
|
import type { Region } from "./regions";
|
||||||
import { regionToRegionSubdomain } from "./regionToRegionSubdomain";
|
import { regionToRegionSubdomain } from "./regionToRegionSubdomain";
|
||||||
|
|
||||||
export type RatingInfo =
|
export type RatingInfo =
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { context } from "../blitzkit/context";
|
import { context } from "../blitzkit/context";
|
||||||
import { patientFetch } from "../blitzkit/patientFetch";
|
import { patientFetch } from "../blitzkit/patientFetch";
|
||||||
import { RatingPlayer } from "../statistics";
|
import type { RatingPlayer } from "../statistics";
|
||||||
import { LeagueTop } from "./rating";
|
import type { LeagueTop } from "./rating";
|
||||||
import { Region } from "./regions";
|
import type { Region } from "./regions";
|
||||||
import { regionToRegionSubdomain } from "./regionToRegionSubdomain";
|
import { regionToRegionSubdomain } from "./regionToRegionSubdomain";
|
||||||
|
|
||||||
export async function getRatingLeague(
|
export async function getRatingLeague(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { patientFetch } from "../blitzkit/patientFetch";
|
import { patientFetch } from "../blitzkit/patientFetch";
|
||||||
import { withCORSProxy } from "../blitzkit/withCORSProxy";
|
import { withCORSProxy } from "../blitzkit/withCORSProxy";
|
||||||
import { RatingNeighbors } from "./rating";
|
import type { RatingNeighbors } from "./rating";
|
||||||
import { Region } from "./regions";
|
import type { Region } from "./regions";
|
||||||
import { regionToRegionSubdomain } from "./regionToRegionSubdomain";
|
import { regionToRegionSubdomain } from "./regionToRegionSubdomain";
|
||||||
|
|
||||||
export async function getRatingNeighbors(
|
export async function getRatingNeighbors(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { TanksStats } from "../types";
|
import type { TanksStats } from "../types";
|
||||||
import { FetchBlitzParams, fetchBlitz } from "./fetchBlitz";
|
import { type FetchBlitzParams, fetchBlitz } from "./fetchBlitz";
|
||||||
import { Region } from "./regions";
|
import type { Region } from "./regions";
|
||||||
|
|
||||||
export async function getTankStats(
|
export async function getTankStats(
|
||||||
region: Region,
|
region: Region,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Region } from './regions';
|
import { type Region } from './regions';
|
||||||
|
|
||||||
export const MIN_REGION_IDS: Record<Region, number> = {
|
export const MIN_REGION_IDS: Record<Region, number> = {
|
||||||
asia: 20e8,
|
asia: 20e8,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { RatingPlayer } from '../statistics';
|
import { type RatingPlayer } from '../statistics';
|
||||||
|
|
||||||
export const LEAGUES = [
|
export const LEAGUES = [
|
||||||
{ name: 'diamond', minScore: 5000, index: 0, icon: 'YOw6mZ4' },
|
{ name: 'diamond', minScore: 5000, index: 0, icon: 'YOw6mZ4' },
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Region, RegionSubdomain } from "./regions";
|
import type { Region, RegionSubdomain } from "./regions";
|
||||||
|
|
||||||
export function regionSubdomainToRegion(regionDomain: RegionSubdomain): Region {
|
export function regionSubdomainToRegion(regionDomain: RegionSubdomain): Region {
|
||||||
return regionDomain === "na" ? "com" : regionDomain;
|
return regionDomain === "na" ? "com" : regionDomain;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Region, RegionSubdomain } from "./regions";
|
import { type Region, type RegionSubdomain } from "./regions";
|
||||||
|
|
||||||
export function regionToRegionSubdomain(regionDomain: Region): RegionSubdomain {
|
export function regionToRegionSubdomain(regionDomain: Region): RegionSubdomain {
|
||||||
return regionDomain === "com" ? "na" : regionDomain;
|
return regionDomain === "com" ? "na" : regionDomain;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ClanList } from "./clans";
|
import type { ClanList } from "./clans";
|
||||||
import { fetchBlitz } from "./fetchBlitz";
|
import { fetchBlitz } from "./fetchBlitz";
|
||||||
import { Region } from "./regions";
|
import type { Region } from "./regions";
|
||||||
|
|
||||||
export async function searchClansAcrossRegions(search: string, limit = 25) {
|
export async function searchClansAcrossRegions(search: string, limit = 25) {
|
||||||
const trimmed = search.trim();
|
const trimmed = search.trim();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { context } from "../blitzkit/context";
|
import { context } from "../blitzkit/context";
|
||||||
import { Region } from "./regions";
|
import { type Region } from "./regions";
|
||||||
import { regionToRegionSubdomain } from "./regionToRegionSubdomain";
|
import { regionToRegionSubdomain } from "./regionToRegionSubdomain";
|
||||||
|
|
||||||
type CurrentRatingPlayerSearch = Record<
|
type CurrentRatingPlayerSearch = Record<
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { fetchBlitz } from '../fetchBlitz';
|
import { fetchBlitz } from "../fetchBlitz";
|
||||||
import { Region } from '../regions';
|
import type { Region } from "../regions";
|
||||||
import { usernamePattern } from './constants';
|
import { usernamePattern } from "./constants";
|
||||||
|
|
||||||
export interface AccountListItem {
|
export interface AccountListItem {
|
||||||
nickname: string;
|
nickname: string;
|
||||||
@@ -19,7 +19,7 @@ export async function searchPlayersAcrossRegions(search: string, limit = 25) {
|
|||||||
if (usernamePattern.test(trimmed)) {
|
if (usernamePattern.test(trimmed)) {
|
||||||
return (
|
return (
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
fetchBlitz<AccountList>('com', 'account/list', {
|
fetchBlitz<AccountList>("com", "account/list", {
|
||||||
search,
|
search,
|
||||||
limit: normalizedLimit,
|
limit: normalizedLimit,
|
||||||
}).then(
|
}).then(
|
||||||
@@ -27,10 +27,10 @@ export async function searchPlayersAcrossRegions(search: string, limit = 25) {
|
|||||||
value &&
|
value &&
|
||||||
value.map((account) => ({
|
value.map((account) => ({
|
||||||
...account,
|
...account,
|
||||||
region: 'com' as Region,
|
region: "com" as Region,
|
||||||
})),
|
}))
|
||||||
),
|
),
|
||||||
fetchBlitz<AccountList>('eu', 'account/list', {
|
fetchBlitz<AccountList>("eu", "account/list", {
|
||||||
search,
|
search,
|
||||||
limit: normalizedLimit,
|
limit: normalizedLimit,
|
||||||
}).then(
|
}).then(
|
||||||
@@ -38,10 +38,10 @@ export async function searchPlayersAcrossRegions(search: string, limit = 25) {
|
|||||||
value &&
|
value &&
|
||||||
value.map((account) => ({
|
value.map((account) => ({
|
||||||
...account,
|
...account,
|
||||||
region: 'eu' as Region,
|
region: "eu" as Region,
|
||||||
})),
|
}))
|
||||||
),
|
),
|
||||||
fetchBlitz<AccountList>('asia', 'account/list', {
|
fetchBlitz<AccountList>("asia", "account/list", {
|
||||||
search,
|
search,
|
||||||
limit: normalizedLimit,
|
limit: normalizedLimit,
|
||||||
}).then(
|
}).then(
|
||||||
@@ -49,8 +49,8 @@ export async function searchPlayersAcrossRegions(search: string, limit = 25) {
|
|||||||
value &&
|
value &&
|
||||||
value.map((account) => ({
|
value.map((account) => ({
|
||||||
...account,
|
...account,
|
||||||
region: 'asia' as Region,
|
region: "asia" as Region,
|
||||||
})),
|
}))
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
@@ -61,4 +61,4 @@ export async function searchPlayersAcrossRegions(search: string, limit = 25) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from './constants';
|
export * from "./constants";
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { emptyAllStats } from '../../blitz/constants';
|
import { emptyAllStats } from '../../blitz/constants';
|
||||||
import { Samples } from '../../protos';
|
import { Samples } from '../../protos';
|
||||||
import { BlitzkitStats } from '../../statistics';
|
import type { BlitzkitStats } from '../../statistics';
|
||||||
|
|
||||||
export const emptyAverageDefinitionsAllStats: BlitzkitStats = {
|
export const emptyAverageDefinitionsAllStats: BlitzkitStats = {
|
||||||
...emptyAllStats,
|
...emptyAllStats,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Region } from "../blitz/regions";
|
import type { Region } from "../blitz/regions";
|
||||||
import { RatingLeaderboard } from "../protos";
|
import { RatingLeaderboard } from "../protos";
|
||||||
import { asset } from "./asset";
|
import { asset } from "./asset";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MessageFns } from '../protos';
|
import type { MessageFns } from '../protos';
|
||||||
|
|
||||||
export async function fetchPB<Type>(url: string, message: MessageFns<Type>) {
|
export async function fetchPB<Type>(url: string, message: MessageFns<Type>) {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { calculateWN8 } from '../calculateWN8';
|
import { calculateWN8 } from "../calculateWN8";
|
||||||
import {
|
import {
|
||||||
BlitzkitStats,
|
type BlitzkitStats,
|
||||||
CompositeStats,
|
type CompositeStats,
|
||||||
compositeStatsFormatting,
|
compositeStatsFormatting,
|
||||||
CompositeStatsKey,
|
type CompositeStatsKey,
|
||||||
} from './constants';
|
} from "./constants";
|
||||||
|
|
||||||
export function compositeStats(stats: BlitzkitStats, average: BlitzkitStats) {
|
export function compositeStats(stats: BlitzkitStats, average: BlitzkitStats) {
|
||||||
return {
|
return {
|
||||||
@@ -52,9 +52,9 @@ export function compositeStats(stats: BlitzkitStats, average: BlitzkitStats) {
|
|||||||
export function formatCompositeStat(
|
export function formatCompositeStat(
|
||||||
value: number,
|
value: number,
|
||||||
key: CompositeStatsKey,
|
key: CompositeStatsKey,
|
||||||
composite: CompositeStats,
|
composite: CompositeStats
|
||||||
) {
|
) {
|
||||||
if (composite.cumulative_battles === 0) return '--';
|
if (composite.cumulative_battles === 0) return "--";
|
||||||
|
|
||||||
const formatting = compositeStatsFormatting[key];
|
const formatting = compositeStatsFormatting[key];
|
||||||
const resolvedValue = (formatting.coefficient ?? 1) * value;
|
const resolvedValue = (formatting.coefficient ?? 1) * value;
|
||||||
@@ -62,7 +62,7 @@ export function formatCompositeStat(
|
|||||||
formatting.localeFormat
|
formatting.localeFormat
|
||||||
? Math.round(resolvedValue).toLocaleString()
|
? Math.round(resolvedValue).toLocaleString()
|
||||||
: resolvedValue.toFixed(formatting.fixed)
|
: resolvedValue.toFixed(formatting.fixed)
|
||||||
}${formatting.unit ?? ''}`;
|
}${formatting.unit ?? ""}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from './constants';
|
export * from "./constants";
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { IndividualTankStats, emptyIndividualTankStats } from '../types';
|
import { type IndividualTankStats, emptyIndividualTankStats } from "../types";
|
||||||
|
|
||||||
export function deltaTankStats(
|
export function deltaTankStats(
|
||||||
tanksA: IndividualTankStats[],
|
tanksA: IndividualTankStats[],
|
||||||
tanksB: IndividualTankStats[],
|
tanksB: IndividualTankStats[]
|
||||||
) {
|
) {
|
||||||
return tanksB
|
return tanksB
|
||||||
.map((b) => {
|
.map((b) => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { fetchTankDefinitions } from '../blitzkit';
|
import { fetchTankDefinitions } from '../blitzkit';
|
||||||
import { BlitzStats } from './compositeStats/constants';
|
import type { BlitzStats } from './compositeStats/constants';
|
||||||
|
|
||||||
export async function getTierWeights(
|
export async function getTierWeights(
|
||||||
stats: Record<number, BlitzStats>,
|
stats: Record<number, BlitzStats>,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { emptyAllStats } from '../blitz';
|
import { emptyAllStats } from '../blitz';
|
||||||
import { BlitzStats } from '../statistics';
|
import type { BlitzStats } from '../statistics';
|
||||||
|
|
||||||
export interface IndividualTankStats {
|
export interface IndividualTankStats {
|
||||||
all: BlitzStats;
|
all: BlitzStats;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import locales from "../locales.json";
|
import locales from "../locales.json";
|
||||||
import { BlitzKitStrings, STRINGS } from "./strings";
|
import { type BlitzKitStrings, STRINGS } from "./strings";
|
||||||
|
|
||||||
export function wrapper(slicer: (strings: BlitzKitStrings) => string) {
|
export function wrapper(slicer: (strings: BlitzKitStrings) => string) {
|
||||||
const defaultString = slicer(STRINGS[locales.default] as BlitzKitStrings);
|
const defaultString = slicer(STRINGS[locales.default] as BlitzKitStrings);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
AverageDefinitions,
|
AverageDefinitions,
|
||||||
AverageDefinitionsEntry,
|
AverageDefinitionsEntry,
|
||||||
AverageDefinitionsManifest,
|
type AverageDefinitionsManifest,
|
||||||
IndividualTankStats,
|
type IndividualTankStats,
|
||||||
REGIONS,
|
REGIONS,
|
||||||
Region,
|
type Region,
|
||||||
Samples,
|
Samples,
|
||||||
averageDefinitionsAllStatsKeys,
|
averageDefinitionsAllStatsKeys,
|
||||||
emptySamples,
|
emptySamples,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { BLITZKIT_TANK_ICON_SIZE, fetchTankDefinitions } from "@blitzkit/core";
|
|||||||
import { launch } from "puppeteer";
|
import { launch } from "puppeteer";
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import { commitAssets } from "../core/github/commitAssets";
|
import { commitAssets } from "../core/github/commitAssets";
|
||||||
import { FileChange } from "../core/github/commitMultipleFiles";
|
import { type FileChange } from "../core/github/commitMultipleFiles";
|
||||||
|
|
||||||
export async function blitzkitTankIcons() {
|
export async function blitzkitTankIcons() {
|
||||||
console.log("Building blitzkit tank icons...");
|
console.log("Building blitzkit tank icons...");
|
||||||
|
|||||||
Reference in new issue
Block a user