Skip to content

Commit 1cac172

Browse files
committed
feat: app directory command handler
1 parent 1fe74b6 commit 1cac172

File tree

30 files changed

+1240
-75
lines changed

30 files changed

+1240
-75
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { MessageCommandContext, SlashCommandContext } from 'commandkit';
2+
import { ApplicationCommandOptionType } from 'discord.js';
3+
4+
export const command = {
5+
name: 'avatar',
6+
description: 'This is an avatar command.',
7+
options: [
8+
{
9+
name: 'user',
10+
description: 'The user to get the avatar for.',
11+
type: ApplicationCommandOptionType.User,
12+
},
13+
],
14+
};
15+
16+
export async function chatInput(ctx: SlashCommandContext) {
17+
const user = ctx.options.getUser('user') ?? ctx.interaction.user;
18+
19+
const { t } = ctx.locale();
20+
21+
const msg = await t('avatar', { user: user.username });
22+
23+
await ctx.interaction.reply({
24+
embeds: [
25+
{
26+
title: msg,
27+
image: {
28+
url: user.displayAvatarURL({ size: 2048 }),
29+
},
30+
color: 0x7289da,
31+
},
32+
],
33+
});
34+
}
35+
36+
export async function message(ctx: MessageCommandContext) {
37+
const user = ctx.options.getUser('user') ?? ctx.message.author;
38+
39+
const { t } = ctx.locale();
40+
41+
const msg = await t('avatar', { user: user.username });
42+
43+
await ctx.message.reply({
44+
embeds: [
45+
{
46+
title: msg,
47+
image: {
48+
url: user.displayAvatarURL({ size: 2048 }),
49+
},
50+
color: 0x7289da,
51+
},
52+
],
53+
});
54+
}

apps/test-bot/src/commands/misc/prompt.tsx renamed to apps/test-bot/src/app/commands/prompt/command.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import CommandKit, {
2-
SlashCommandProps,
32
CommandData,
43
Modal,
54
ShortInput,
65
ParagraphInput,
76
OnModalKitSubmit,
7+
MessageCommandContext,
8+
SlashCommandContext,
89
} from 'commandkit';
910
import { MessageFlags } from 'discord.js';
1011

11-
export const data: CommandData = {
12+
export const command: CommandData = {
1213
name: 'prompt',
1314
description: 'This is a prompt command.',
1415
};
@@ -25,17 +26,27 @@ const handleSubmit: OnModalKitSubmit = async (interaction, context) => {
2526
context.dispose();
2627
};
2728

28-
export async function run({ interaction }: SlashCommandProps) {
29+
export async function chatInput(ctx: SlashCommandContext) {
30+
const { t } = ctx.locale();
31+
32+
const title = await t('modal.title');
33+
const label = await t('input.label');
34+
const description = await t('input.placeholder');
35+
2936
const modal = (
30-
<Modal title="My Cool Modal" onSubmit={handleSubmit}>
37+
<Modal title={title} onSubmit={handleSubmit}>
3138
<ShortInput customId="name" label="Name" placeholder="John" required />
3239
<ParagraphInput
3340
customId="description"
34-
label="Description"
35-
placeholder="This is a description."
41+
label={label}
42+
placeholder={description}
3643
/>
3744
</Modal>
3845
);
3946

40-
await interaction.showModal(modal);
47+
await ctx.interaction.showModal(modal);
48+
}
49+
50+
export async function message(ctx: MessageCommandContext) {
51+
ctx.message.reply('Prompt is only available in slash commands.');
4152
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Client } from 'discord.js';
2+
3+
export default function ReadyEvent(client: Client<true>) {
4+
console.log(`Successfully logged in as ${client.user?.tag}`);
5+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"command": {
3+
"name": "avatar",
4+
"description": "This is an avatar command.",
5+
"options": [
6+
{
7+
"name": "user",
8+
"description": "The user to get the avatar for."
9+
}
10+
]
11+
},
12+
"translations": {
13+
"avatar": "{user}'s avatar"
14+
}
15+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"command": {
3+
"name": "prompt",
4+
"description": "This is a prompt command."
5+
},
6+
"translations": {
7+
"modal.title": "My Cool Modal",
8+
"input.label": "Description",
9+
"input.placeholder": "This is a description"
10+
}
11+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"command": {
3+
"name": "avatar",
4+
"description": "C'est une commande pour afficher l'avatar.",
5+
"options": [
6+
{
7+
"name": "user",
8+
"description": "L'utilisateur dont vous souhaitez voir l'avatar."
9+
}
10+
]
11+
},
12+
"translations": {
13+
"avatar": "Avatar de {user}"
14+
}
15+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"command": {
3+
"name": "prompt",
4+
"description": "Ceci est une commande de prompt."
5+
},
6+
"translations": {
7+
"modal.title": "Ma superbe modale",
8+
"input.label": "Description",
9+
"input.placeholder": "Ceci est une description"
10+
}
11+
}

apps/test-bot/src/commands/misc/ping.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export async function run({ interaction, client }: SlashCommandProps) {
6868
ephemeral: true,
6969
});
7070
},
71-
{ message, time: 10_000, autoReset: true },
71+
{ time: 10_000, autoReset: true },
7272
)
7373
.onEnd(() => {
7474
console.log('onEnd called');

apps/test-bot/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const client = new Client({
66
intents: ['Guilds', 'GuildMembers', 'GuildMessages', 'MessageContent'],
77
});
88

9-
new CommandKit({
9+
const commandkit = new CommandKit({
1010
// @ts-ignore
1111
client,
1212
commandsPath: `${__dirname}/commands`,

packages/commandkit/src/CommandKit.ts

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,19 @@ import { CacheProvider } from './cache/CacheProvider';
1515
import { MemoryCache } from './cache/MemoryCache';
1616
import { createElement, Fragment } from './components';
1717
import { EventInterceptor } from './components/common/EventInterceptor';
18-
import { Locale } from 'discord.js';
18+
import { Awaitable, Locale, Message } from 'discord.js';
1919
import { DefaultLocalizationStrategy } from './app/i18n/DefaultLocalizationStrategy';
2020
import { findAppDirectory } from './utils/utilities';
2121
import { join } from 'node:path';
2222
import { CommandsRouter, EventsRouter } from '@commandkit/router';
23-
import { COMMANDKIT_IS_DEV } from './utils/constants';
2423
import { AppCommandHandler } from './app/command-handler/AppCommandHandler';
24+
import { LocalizationStrategy } from './app/i18n/LocalizationStrategy';
25+
26+
export interface CommandKitConfiguration {
27+
defaultLocale: Locale;
28+
localizationStrategy: LocalizationStrategy;
29+
getMessageCommandPrefix: (message: Message) => Awaitable<string | string[]>;
30+
}
2531

2632
export class CommandKit extends EventEmitter {
2733
#data: CommandKitData;
@@ -30,9 +36,10 @@ export class CommandKit extends EventEmitter {
3036
public static readonly createElement = createElement;
3137
public static readonly Fragment = Fragment;
3238

33-
public readonly config = {
39+
public readonly config: CommandKitConfiguration = {
3440
defaultLocale: Locale.EnglishUS,
3541
localizationStrategy: new DefaultLocalizationStrategy(this),
42+
getMessageCommandPrefix: () => '!',
3643
};
3744

3845
public commandsRouter!: CommandsRouter;
@@ -95,6 +102,35 @@ export class CommandKit extends EventEmitter {
95102
}
96103
}
97104

105+
/**
106+
* Sets the prefix resolver for the command handler.
107+
* @param resolver The resolver function.
108+
*/
109+
setPrefixResolver(
110+
resolver: (message: Message) => Awaitable<string | string[]>,
111+
) {
112+
this.config.getMessageCommandPrefix = resolver;
113+
return this;
114+
}
115+
116+
/**
117+
* Sets the default locale for the command handler.
118+
* @param locale The default locale.
119+
*/
120+
setDefaultLocale(locale: Locale) {
121+
this.config.defaultLocale = locale;
122+
return this;
123+
}
124+
125+
/**
126+
* Sets the localization strategy for the command handler.
127+
* @param strategy The localization strategy.
128+
*/
129+
setLocalizationStrategy(strategy: LocalizationStrategy) {
130+
this.config.localizationStrategy = strategy;
131+
return this;
132+
}
133+
98134
/**
99135
* Resolves the current cache provider.
100136
*/
@@ -128,8 +164,6 @@ export class CommandKit extends EventEmitter {
128164
* (Private) Initialize CommandKit.
129165
*/
130166
async #init() {
131-
await this.#initApp();
132-
133167
// <!-- Setup event handler -->
134168
if (this.#data.eventsPath) {
135169
const eventHandler = new EventHandler({
@@ -168,9 +202,10 @@ export class CommandKit extends EventEmitter {
168202
bulkRegister: this.#data.bulkRegister || false,
169203
});
170204

171-
await commandHandler.init();
172-
173205
this.#data.commandHandler = commandHandler;
206+
207+
await this.#initApp();
208+
await commandHandler.init();
174209
}
175210
}
176211

@@ -197,6 +232,8 @@ export class CommandKit extends EventEmitter {
197232
if (this.commandsRouter.isValidPath()) {
198233
await this.commandsRouter.scan();
199234
}
235+
236+
await this.appCommandsHandler.loadCommands();
200237
}
201238

202239
async #initEvents() {

0 commit comments

Comments
 (0)