Skip to content

Commit

Permalink
feat: implement autocomplete /dict delete <word>
Browse files Browse the repository at this point in the history
  • Loading branch information
yuimarudev committed Dec 1, 2024
1 parent 01c6cc3 commit 612484f
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 21 deletions.
36 changes: 35 additions & 1 deletion src/commands/dict.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
} from "@discordjs/builders";
import {
API,
APIApplicationCommandAutocompleteInteraction,
APIApplicationCommandInteractionDataStringOption,
APIApplicationCommandInteractionDataSubcommandOption,
APIChatInputApplicationCommandInteraction,
Expand All @@ -16,6 +17,11 @@ import { NonNullableByKey } from "../commons/types.js";
import { prisma } from "../index.js";
import { ICommand } from "./index.js";

const wordsCache = new Map<
string,
{ word: string; read: string; guildId: string; id: number }[]
>();

export default class Dict implements ICommand {
defition(): RESTPostAPIChatInputApplicationCommandsJSONBody {
return new SlashCommandBuilder()
Expand Down Expand Up @@ -46,7 +52,8 @@ export default class Dict implements ICommand {
new SlashCommandStringOption()
.setName("word")
.setDescription("単語")
.setRequired(true),
.setRequired(true)
.setAutocomplete(true),
),
)
.addSubcommand(
Expand Down Expand Up @@ -130,6 +137,7 @@ export default class Dict implements ICommand {
});

await prisma.dictionary.delete({ where: { id: dict.id } });
wordsCache.delete(i.guild_id);

return await api.interactions.editReply(i.application_id, i.token, {
embeds: [
Expand Down Expand Up @@ -166,6 +174,32 @@ export default class Dict implements ICommand {

throw "unreachable";
}

async autoComplete(
api: API,
i: APIApplicationCommandAutocompleteInteraction,
) {
if (!i.guild_id) return;

const command = i.data.options.at(
0,
) as APIApplicationCommandInteractionDataSubcommandOption;

if (command.name === "delete") {
let cache = wordsCache.get(i.guild_id);

if (!cache) {
cache = await prisma.dictionary.findMany({
where: { guildId: i.guild_id },
});
wordsCache.set(i.guild_id, cache);
}

await api.interactions.createAutocompleteResponse(i.id, i.token, {
choices: cache.map((x) => ({ name: x.word, value: x.word })),
});
}
}
}

function escapeCsvCell(input: string) {
Expand Down
5 changes: 5 additions & 0 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
API,
APIApplicationCommandAutocompleteInteraction,
APIChatInputApplicationCommandInteraction,
APIInteractionGuildMember,
RESTPostAPIChatInputApplicationCommandsJSONBody,
Expand Down Expand Up @@ -33,4 +34,8 @@ export interface ICommand {
APIInteractionGuildMember
>,
): Promise<unknown>;
autoComplete?: (
api: API,
i: APIApplicationCommandAutocompleteInteraction,
) => Promise<unknown>;
}
47 changes: 27 additions & 20 deletions src/handlers/interactionCreate.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
GatewayInteractionCreateDispatchData,
InteractionType,
MessageFlags,
ToEventProps,
} from "@discordjs/core";
Expand All @@ -11,30 +12,36 @@ export default async ({
api,
data,
}: ToEventProps<GatewayInteractionCreateDispatchData>) => {
const error = await api.interactions
.defer(data.id, data.token)
.catch((x) => x as Error);
if (data.type === InteractionType.ApplicationCommandAutocomplete) {
const command = commands.find((x) => x.defition().name === data.data.name);

if (error) return console.error(error);
if (!validate(data)) return false;
command?.autoComplete?.(api, data);
} else if (data.type === InteractionType.ApplicationCommand) {
const error = await api.interactions
.defer(data.id, data.token)
.catch((x) => x as Error);

const command = commands.find((x) => x.defition().name === data.data.name);
if (error) return console.error(error);
if (!validate(data)) return false;

if (!command && data.data.name !== "help")
return await api.interactions.followUp(data.application_id, data.token, {
content: "古いコマンドを参照しています.世界を削除します.",
flags: MessageFlags.Ephemeral,
});
const command = commands.find((x) => x.defition().name === data.data.name);

try {
await (command ?? new Help()).run(api, data);
} catch (e) {
await api.interactions.followUp(data.application_id, data.token, {
content: `エラーです. \`\`\`${
e instanceof Error ? e.message : String(e)
}\`\`\``,
flags: MessageFlags.Ephemeral,
});
if (!command && data.data.name !== "help")
return await api.interactions.followUp(data.application_id, data.token, {
content: "古いコマンドを参照しています.世界を削除します.",
flags: MessageFlags.Ephemeral,
});

try {
await (command ?? new Help()).run(api, data);
} catch (e) {
await api.interactions.followUp(data.application_id, data.token, {
content: `エラーです. \`\`\`${
e instanceof Error ? e.message : String(e)
}\`\`\``,
flags: MessageFlags.Ephemeral,
});
}
}

return true;
Expand Down

0 comments on commit 612484f

Please sign in to comment.