feat: /inactive face lift

This commit is contained in:
TresAbhi committed 2023-06-06 01:31:16 +00:00
1 parent 26e78c72b9
commit 1875f30cf5
7 files changed
+129 -112

No files matched your search

-89
View File
@@ -1,89 +0,0 @@
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
import markdownEscape from 'markdown-escape';
import { NEGATIVE_COLOR, POSITIVE_COLOR } from '../constants/colors.js';
import clanAutocomplete from '../core/autocomplete/clan.js';
import getBlitzClan from '../core/blitz/getBlitzClan.js';
import getWargamingResponse from '../core/blitz/getWargamingResponse.js';
import cmdName from '../core/interaction/cmdName.js';
import addClanChoices from '../core/options/addClanChoices.js';
import { args } from '../core/process/args.js';
import { CommandRegistry } from '../events/interactionCreate.js';
import { AccountInfo } from '../types/accountInfo.js';
import { ClanInfo } from '../types/clanInfo.js';
const DEFAULT_THRESHOLD = 7;
export default {
inProduction: true,
inDevelopment: false,
inPublic: true,
command: new SlashCommandBuilder()
.setName(cmdName('inactive'))
.setDescription('Lists all inactive players')
.addStringOption(addClanChoices)
.addNumberOption((option) =>
option
.setName('threshold')
.setDescription(
`The number of days inactive (default: ${DEFAULT_THRESHOLD})`,
)
.setMinValue(0),
),
async execute(interaction) {
const clanName = interaction.options.getString('clan')!;
const clan = await getBlitzClan(interaction, clanName);
const { server, id } = clan;
const threshold =
interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD;
const time = new Date().getTime() / 1000;
const clanInfo = await getWargamingResponse<ClanInfo>(
`https://api.wotblitz.${server}/wotb/clans/info/?application_id=${args['wargaming-application-id']}&clan_id=${id}`,
);
const memberIds = clanInfo[id].members_ids;
const accountInfo = await getWargamingResponse<AccountInfo>(
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${
args['wargaming-application-id']
}&account_id=${memberIds.join(',')}`,
);
const inactiveInfo = memberIds
.map((memberId) => {
const member = accountInfo[memberId];
const inactiveDays = (time - member.last_battle_time) / 60 / 60 / 24;
return [member.nickname, inactiveDays] as const;
})
.filter(([, inactiveDays]) => inactiveDays >= threshold)
.sort((a, b) => b[1] - a[1])
.map(([nickname, inactiveDays]) => {
const days = Math.floor(inactiveDays);
return `**${markdownEscape(nickname)}**: ${days} day${
days === 1 ? '' : 's'
}`;
});
const hasInactiveMembers = inactiveInfo.length > 0;
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setColor(hasInactiveMembers ? NEGATIVE_COLOR : POSITIVE_COLOR)
.setTitle(
hasInactiveMembers
? `${markdownEscape(clanInfo[id].name)}'s inactive members`
: `No inactive members in ${markdownEscape(clanInfo[id].name)}`,
)
.setDescription(
hasInactiveMembers
? `Players that exceed the threshold of ${threshold} days:\n\n${inactiveInfo.join(
'\n',
)}`
: `No players exceed the threshold of ${threshold} days.`,
),
],
});
},
autocomplete: clanAutocomplete,
} satisfies CommandRegistry;
+92
View File
@@ -0,0 +1,92 @@
import { SlashCommandBuilder } from 'discord.js';
import GenericStats from '../components/GenericStats/index.js';
import NoData, { NoDataType } from '../components/NoData.js';
import PoweredByWargaming from '../components/PoweredByWargaming.js';
import TitleBar from '../components/TitleBar.js';
import Wrapper from '../components/Wrapper.js';
import { BLITZ_SERVERS } from '../constants/servers.js';
import clanAutocomplete from '../core/autocomplete/clan.js';
import getBlitzClan from '../core/blitz/getBlitzClan.js';
import getWargamingResponse from '../core/blitz/getWargamingResponse.js';
import cmdName from '../core/interaction/cmdName.js';
import addClanChoices from '../core/options/addClanChoices.js';
import { args } from '../core/process/args.js';
import render from '../core/ui/render.js';
import { CommandRegistry } from '../events/interactionCreate.js';
import { AccountInfo } from '../types/accountInfo.js';
import { ClanInfo } from '../types/clanInfo.js';
const DEFAULT_THRESHOLD = 7;
export default {
inProduction: true,
inDevelopment: true,
inPublic: true,
command: new SlashCommandBuilder()
.setName(cmdName('inactive'))
.setDescription('Lists all inactive players')
.addStringOption(addClanChoices)
.addNumberOption((option) =>
option
.setName('threshold')
.setDescription(
`The number of days inactive (default: ${DEFAULT_THRESHOLD})`,
)
.setMinValue(0),
),
async execute(interaction) {
const clanName = interaction.options.getString('clan')!;
const { server, id } = await getBlitzClan(interaction, clanName);
const threshold =
interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD;
const time = new Date().getTime() / 1000;
const clanData = (
await getWargamingResponse<ClanInfo>(
`https://api.wotblitz.${server}/wotb/clans/info/?application_id=${args['wargaming-application-id']}&clan_id=${id}`,
)
)[id];
const memberIds = clanData.members_ids;
const accounts = await getWargamingResponse<AccountInfo>(
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${
args['wargaming-application-id']
}&account_id=${memberIds.join(',')}`,
);
const inactive = memberIds
.map((memberId) => {
const member = accounts[memberId];
const inactiveDays = (time - member.last_battle_time) / 60 / 60 / 24;
return [member.nickname, inactiveDays] as [string, number];
})
.filter(([, inactiveDays]) => inactiveDays >= threshold)
.sort((a, b) => b[1] - a[1])
.map(
([name, days]) => [name, `${days.toFixed(0)} days`] as [string, string],
);
const hasInactiveMembers = inactive.length > 0;
const image = await render(
<Wrapper>
<TitleBar
name={clanData.name}
nameDiscriminator="(Inactivity)"
image={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanData.emblem_set_id}.png`}
description={`${threshold}+ Days • ${new Date().toDateString()} • ${
BLITZ_SERVERS[server]
}`}
/>
{!hasInactiveMembers && <NoData type={NoDataType.Players} />}
{hasInactiveMembers && <GenericStats stats={inactive} />}
<PoweredByWargaming />
</Wrapper>,
);
await interaction.editReply({ files: [image] });
},
autocomplete: clanAutocomplete,
} satisfies CommandRegistry;
+2 -2
View File
@@ -4,7 +4,7 @@ import {
SlashCommandBuilder,
} from 'discord.js';
import GenericAllStats from '../components/GenericAllStats.js';
import NoBattlesInPeriod from '../components/NoBattlesInPeriod.js';
import NoData, { NoDataType } from '../components/NoData.js';
import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js';
import TitleBar from '../components/TitleBar.js';
import Wrapper from '../components/Wrapper.js';
@@ -151,7 +151,7 @@ export default {
} • ${new Date().toDateString()} • ${BLITZ_SERVERS[server]}`}
/>
{stats.battles === 0 && <NoBattlesInPeriod />}
{stats.battles === 0 && <NoData type={NoDataType.Battles} />}
{stats.battles > 0 && (
<GenericAllStats
stats={stats}
+2 -2
View File
@@ -4,7 +4,7 @@ import {
SlashCommandBuilder,
} from 'discord.js';
import GenericAllStats from '../components/GenericAllStats.js';
import NoBattlesInPeriod from '../components/NoBattlesInPeriod.js';
import NoData, { NoDataType } from '../components/NoData.js';
import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js';
import TitleBar from '../components/TitleBar.js';
import Wrapper from '../components/Wrapper.js';
@@ -92,7 +92,7 @@ export default {
} • ${new Date().toDateString()} • ${BLITZ_SERVERS[server]}`}
/>
{stats.battles === 0 && <NoBattlesInPeriod />}
{stats.battles === 0 && <NoData type={NoDataType.Battles} />}
{stats.battles > 0 && (
<GenericAllStats
stats={stats}
+2 -2
View File
@@ -4,7 +4,7 @@ import {
SlashCommandBuilder,
} from 'discord.js';
import * as Breakdown from '../components/Breakdown/index.js';
import NoBattlesInPeriod from '../components/NoBattlesInPeriod.js';
import NoData, { NoDataType } from '../components/NoData.js';
import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js';
import TitleBar from '../components/TitleBar.js';
import Wrapper from '../components/Wrapper.js';
@@ -176,7 +176,7 @@ export default {
}`}
/>
{rows.length === 0 && <NoBattlesInPeriod />}
{rows.length === 0 && <NoData type={NoDataType.Battles} />}
{rows.length > 0 && <Breakdown.Root>{rows}</Breakdown.Root>}
<PoweredByBlitzStars />
-17
View File
@@ -1,17 +0,0 @@
import { theme } from '../stitches.config.js';
export default function NoBattlesInPeriod() {
return (
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
No battles played in this period
</span>
</div>
);
}
+31
View File
@@ -0,0 +1,31 @@
import { theme } from '../stitches.config.js';
export enum NoDataType {
Battles,
Players,
}
export interface NoDataProps {
type: NoDataType;
}
const NO_DATA_MESSAGES: Record<NoDataType, string> = {
[NoDataType.Battles]: 'No battles played in this period',
[NoDataType.Players]: 'No players in this period',
};
export default function NoData({ type }: NoDataProps) {
return (
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
{NO_DATA_MESSAGES[type]}
</span>
</div>
);
}