mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
feat: start on amending slugs
This commit is contained in:
1 parent
dd0b2bade7
commit
3d69d464f5
5 files changed
+38
-177
No files matched your search
Vendored
+1
@@ -86,6 +86,7 @@
|
||||
"Fullscreen",
|
||||
"fullstats",
|
||||
"fuzzysort",
|
||||
"gamemode",
|
||||
"gameplay",
|
||||
"glsl",
|
||||
"GLTF",
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
import {
|
||||
BlitzTankClass,
|
||||
Region,
|
||||
regionToRegionSubdomain,
|
||||
} from '@blitzkit/core';
|
||||
import { literals } from '@blitzkit/i18n';
|
||||
import { tankDefinitions } from '../core/blitzkit/nonBlockingPromises';
|
||||
import { chunkLines } from '../core/discord/chunkLines';
|
||||
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
|
||||
import { translator } from '../core/localization/translator';
|
||||
import { CommandRegistry } from '../events/interactionCreate';
|
||||
|
||||
type Auction = null | {
|
||||
count: number;
|
||||
has_next: boolean;
|
||||
results: Result[];
|
||||
};
|
||||
|
||||
type Result =
|
||||
| {
|
||||
id?: number;
|
||||
type: 'vehicle';
|
||||
countable?: boolean;
|
||||
entity?: Entity;
|
||||
initial_count: number;
|
||||
current_count: number;
|
||||
saleable?: boolean;
|
||||
available_from?: Date;
|
||||
available_before?: Date;
|
||||
price?: Price;
|
||||
next_price: Price | null;
|
||||
available: true;
|
||||
display?: boolean;
|
||||
next_price_datetime: Date;
|
||||
next_price_timestamp: number;
|
||||
}
|
||||
| {
|
||||
available: false;
|
||||
type: 'vehicle';
|
||||
};
|
||||
|
||||
interface Entity {
|
||||
id: number;
|
||||
name: string;
|
||||
nation: string;
|
||||
subnation: string;
|
||||
use_subnation_flag: boolean;
|
||||
type_slug: BlitzTankClass;
|
||||
level: number;
|
||||
roman_level: string;
|
||||
user_string: string;
|
||||
image_url: string;
|
||||
preview_image_url: string;
|
||||
is_premium: boolean;
|
||||
is_collectible: boolean;
|
||||
}
|
||||
|
||||
interface Price {
|
||||
currency: Currency;
|
||||
value: number;
|
||||
}
|
||||
|
||||
interface Currency {
|
||||
name: 'gold';
|
||||
count: number;
|
||||
title: 'Gold';
|
||||
image_url: string;
|
||||
sizes: unknown;
|
||||
type: 'currency';
|
||||
}
|
||||
|
||||
const WARNING_COUNT = 500;
|
||||
|
||||
export const auctionCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
resolve({
|
||||
command: createLocalizedCommand('auction'),
|
||||
|
||||
async handler(interaction) {
|
||||
const { strings } = translator(interaction.locale);
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
const region: Region = 'com';
|
||||
const pageSize = 80;
|
||||
const saleable = true;
|
||||
const data = await fetch(
|
||||
`https://${regionToRegionSubdomain(
|
||||
region,
|
||||
)}.wotblitz.com/en/api/events/items/auction/?page_size=${
|
||||
pageSize
|
||||
}&type[]=vehicle&saleable=${saleable}`,
|
||||
).then((response) => response.json() as Promise<Auction>);
|
||||
|
||||
if (data === null) {
|
||||
return strings.bot.commands.auction.errors.no_auction;
|
||||
}
|
||||
|
||||
const saleableTanks = data.results.filter((result) => result.available);
|
||||
const nextPricesTimestamp = saleableTanks[0].next_price_timestamp;
|
||||
|
||||
const title = `# ${strings.bot.commands.auction.body.title}`;
|
||||
const subtitle = `${literals(strings.bot.commands.auction.body.subtitle, [
|
||||
`${saleableTanks.length} / ${data.results.length}`,
|
||||
`<t:${nextPricesTimestamp}:R>`,
|
||||
'<https://wotblitz.com/auction/>',
|
||||
])}`;
|
||||
const body = saleableTanks.map((data, index) => {
|
||||
const tank = awaitedTankDefinitions.tanks[data.entity!.id];
|
||||
|
||||
if (!tank) return '';
|
||||
|
||||
const name = `[${tank.name}](<https://blitzkit.app/tanks/${
|
||||
tank.slug
|
||||
}>)`;
|
||||
const next =
|
||||
data.next_price === null
|
||||
? ''
|
||||
: `\n-# ${literals(strings.bot.commands.auction.body.next, [
|
||||
`<:gold:1317173197082333244> ${data.next_price.value.toLocaleString(
|
||||
interaction.locale,
|
||||
)}`,
|
||||
])}`;
|
||||
const available = literals(
|
||||
strings.bot.commands.auction.body.available,
|
||||
[
|
||||
data.current_count.toLocaleString(interaction.locale),
|
||||
data.initial_count.toLocaleString(interaction.locale),
|
||||
],
|
||||
);
|
||||
const isOut = data.current_count === 0;
|
||||
const outString = isOut ? '~~' : '';
|
||||
const isLow = data.current_count <= WARNING_COUNT;
|
||||
|
||||
return `${index + 1}. ${
|
||||
outString
|
||||
}${name} <:gold:1317173197082333244> ${data.price!.value.toLocaleString(
|
||||
interaction.locale,
|
||||
)}${outString}\n-#${isLow ? ' ‼️ ' : ' '}${available}${isOut ? '' : next}`;
|
||||
});
|
||||
const header = `${title}\n${subtitle}`;
|
||||
const lines = [header, ...body];
|
||||
|
||||
return chunkLines(lines, '\n\n');
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -1,44 +1,44 @@
|
||||
import { getAccountInfo, getClanInfo } from '@blitzkit/core';
|
||||
import { literals } from '@blitzkit/i18n';
|
||||
import { Locale } from 'discord.js';
|
||||
import { CommandWrapper } from '../components/CommandWrapper';
|
||||
import { GenericStats } from '../components/GenericStats';
|
||||
import { NoData } from '../components/NoData';
|
||||
import { TitleBar } from '../components/TitleBar';
|
||||
import { addClanChoices } from '../core/discord/addClanChoices';
|
||||
import { autocompleteClan } from '../core/discord/autocompleteClan';
|
||||
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
|
||||
import { localizationObject } from '../core/discord/localizationObject';
|
||||
import { resolveClanFromCommand } from '../core/discord/resolveClanFromCommand';
|
||||
import { translator } from '../core/localization/translator';
|
||||
import { CommandRegistry } from '../events/interactionCreate';
|
||||
import { getAccountInfo, getClanInfo } from "@blitzkit/core";
|
||||
import { literals } from "@blitzkit/i18n";
|
||||
import { Locale } from "discord.js";
|
||||
import { CommandWrapper } from "../components/CommandWrapper";
|
||||
import { GenericStats } from "../components/GenericStats";
|
||||
import { NoData } from "../components/NoData";
|
||||
import { TitleBar } from "../components/TitleBar";
|
||||
import { addClanChoices } from "../core/discord/addClanChoices";
|
||||
import { autocompleteClan } from "../core/discord/autocompleteClan";
|
||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
||||
import { localizationObject } from "../core/discord/localizationObject";
|
||||
import { resolveClanFromCommand } from "../core/discord/resolveClanFromCommand";
|
||||
import { translator } from "../core/localization/translator";
|
||||
import { CommandRegistry } from "../events/interactionCreate";
|
||||
|
||||
const DEFAULT_THRESHOLD = 7;
|
||||
|
||||
export const inactiveCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
resolve({
|
||||
command: createLocalizedCommand('inactive')
|
||||
command: createLocalizedCommand("inactive")
|
||||
.addStringOption(addClanChoices)
|
||||
.addNumberOption((option) => {
|
||||
const { strings } = translator(Locale.EnglishUS);
|
||||
|
||||
return option
|
||||
.setName('threshold')
|
||||
.setName("threshold")
|
||||
.setNameLocalizations(
|
||||
localizationObject(
|
||||
(strings) => strings.bot.commands.inactive.options.threshold.name,
|
||||
undefined,
|
||||
true,
|
||||
),
|
||||
true
|
||||
)
|
||||
)
|
||||
.setDescription(
|
||||
strings.bot.commands.inactive.options.threshold.description,
|
||||
strings.bot.commands.inactive.options.threshold.description
|
||||
)
|
||||
.setDescriptionLocalizations(
|
||||
localizationObject(
|
||||
(strings) =>
|
||||
strings.bot.commands.inactive.options.threshold.description,
|
||||
),
|
||||
strings.bot.commands.inactive.options.threshold.description
|
||||
)
|
||||
)
|
||||
.setMinValue(0);
|
||||
}),
|
||||
@@ -47,7 +47,7 @@ export const inactiveCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
const { strings } = translator(interaction.locale);
|
||||
const { region, id } = await resolveClanFromCommand(interaction);
|
||||
const threshold =
|
||||
interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD;
|
||||
interaction.options.getNumber("threshold")! ?? DEFAULT_THRESHOLD;
|
||||
const time = new Date().getTime() / 1000;
|
||||
const clanInfo = await getClanInfo(region, id);
|
||||
const accountInfo = await getAccountInfo(region, clanInfo.members_ids);
|
||||
@@ -57,7 +57,7 @@ export const inactiveCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
[
|
||||
account.nickname,
|
||||
(time - account.last_battle_time) / 60 / 60 / 24,
|
||||
] as [string, number],
|
||||
] as [string, number]
|
||||
)
|
||||
.filter(([, inactiveDays]) => inactiveDays >= threshold)
|
||||
.sort((a, b) => b[1] - a[1])
|
||||
@@ -65,10 +65,10 @@ export const inactiveCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
([name, days]) =>
|
||||
[
|
||||
name,
|
||||
literals(strings.bot.commands.inactive.body.listing, [
|
||||
days.toFixed(0),
|
||||
]),
|
||||
] as [string, string],
|
||||
literals(strings.bot.commands.inactive.body.listing, {
|
||||
days: days.toFixed(0),
|
||||
}),
|
||||
] as [string, string]
|
||||
);
|
||||
const hasInactiveMembers = inactive.length > 0;
|
||||
|
||||
@@ -79,7 +79,7 @@ export const inactiveCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
image={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanInfo.emblem_set_id}.png`}
|
||||
description={`${literals(
|
||||
strings.bot.commands.inactive.body.subtitle,
|
||||
[`${threshold}`],
|
||||
{ days: threshold }
|
||||
)} • ${new Date().toLocaleDateString(interaction.locale)}`}
|
||||
/>
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
export function literals(string: string, literals: string[]) {
|
||||
return literals.reduce((accumulator, literal, index) => {
|
||||
return accumulator.replace(`%s${index + 1}`, literal);
|
||||
}, string);
|
||||
export function literals(
|
||||
string: string,
|
||||
literals?: Record<string, string | number>
|
||||
) {
|
||||
for (const key in literals) {
|
||||
string = string.replaceAll(`{${key}}`, `${literals[key]}`);
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
@@ -57,7 +57,6 @@ const title = literals(strings.website.tools.tankopedia.tank_seo_title, [
|
||||
],
|
||||
strings.common.tank_class_short[tank.class],
|
||||
"BlitzKit",
|
||||
strings.common.nations[tank.nation as keyof typeof strings.common.nations],
|
||||
]);
|
||||
const url = import.meta.env.SITE + Astro.url.pathname;
|
||||
|
||||
|
||||
Reference in new issue
Block a user