blob: a00baf86c4c55cc7f5e423019eac172fb4ae74e6 [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { callback as roleMenu } from "../actions/roleMenu.js";
pineafan73a7c4a2022-07-24 10:38:04 +01002import verify from "../reflex/verify.js";
3import create from "../actions/tickets/create.js";
4import close from "../actions/tickets/delete.js";
5import createTranscript from "../premium/createTranscript.js";
pineafan02ba0232022-07-24 22:16:15 +01006import Fuse from "fuse.js";
pineafan63fc5e22022-08-04 22:04:10 +01007import { autocomplete as tagAutocomplete } from "../commands/tag.js";
pineafan0f5cc782022-08-12 21:55:42 +01008import type { AutocompleteInteraction, Interaction, MessageComponentInteraction } from "discord.js";
9// @ts-expect-error
10import type { HaikuClient } from "jshaiku";
pineafanad54d752022-04-18 19:01:43 +010011
pineafan63fc5e22022-08-04 22:04:10 +010012export const event = "interactionCreate";
pineafanad54d752022-04-18 19:01:43 +010013
Skyler Greyf21323a2022-08-13 23:58:22 +010014function getAutocomplete(typed: string, options: string[]): { name: string; value: string }[] {
Skyler Grey75ea9172022-08-06 10:22:23 +010015 options = options.filter((option) => option.length <= 100); // thanks discord. 6000 character limit on slash command inputs but only 100 for autocomplete.
16 if (!typed)
17 return options
18 .slice(0, 25)
19 .sort()
20 .map((option) => ({ name: option, value: option }));
21 const fuse = new Fuse(options, {
22 useExtendedSearch: true,
23 findAllMatches: true,
24 minMatchCharLength: 0
25 }).search(typed);
Skyler Grey11236ba2022-08-08 21:13:33 +010026 return fuse.slice(0, 25).map((option) => ({ name: option.item, value: option.item }));
pineafan02ba0232022-07-24 22:16:15 +010027}
28
pineafan0f5cc782022-08-12 21:55:42 +010029function generateStatsChannelAutocomplete(typed: string) {
Skyler Grey11236ba2022-08-08 21:13:33 +010030 const validReplacements = ["serverName", "memberCount", "memberCount:bots", "memberCount:humans"];
pineafan63fc5e22022-08-04 22:04:10 +010031 const autocompletions = [];
32 const beforeLastOpenBracket = typed.match(/(.*){[^{}]{0,15}$/);
Skyler Grey75ea9172022-08-06 10:22:23 +010033 if (beforeLastOpenBracket !== null) {
34 for (const replacement of validReplacements) {
Skyler Grey11236ba2022-08-08 21:13:33 +010035 autocompletions.push(`${beforeLastOpenBracket[1]} {${replacement}}`);
Skyler Grey75ea9172022-08-06 10:22:23 +010036 }
37 } else {
38 for (const replacement of validReplacements) {
39 autocompletions.push(`${typed} {${replacement}}`);
40 }
41 }
pineafan63fc5e22022-08-04 22:04:10 +010042 return getAutocomplete(typed, autocompletions);
pineafan41d93562022-07-30 22:10:15 +010043}
pineafan0f5cc782022-08-12 21:55:42 +010044function generateWelcomeMessageAutocomplete(typed: string) {
Skyler Grey75ea9172022-08-06 10:22:23 +010045 const validReplacements = [
46 "serverName",
47 "memberCount",
48 "memberCount:bots",
49 "memberCount:humans",
50 "member:mention",
51 "member:name"
52 ];
pineafan63fc5e22022-08-04 22:04:10 +010053 const autocompletions = [];
54 const beforeLastOpenBracket = typed.match(/(.*){[^{}]{0,15}$/);
Skyler Grey75ea9172022-08-06 10:22:23 +010055 if (beforeLastOpenBracket !== null) {
56 for (const replacement of validReplacements) {
Skyler Grey11236ba2022-08-08 21:13:33 +010057 autocompletions.push(`${beforeLastOpenBracket[1]} {${replacement}}`);
Skyler Grey75ea9172022-08-06 10:22:23 +010058 }
59 } else {
60 for (const replacement of validReplacements) {
61 autocompletions.push(`${typed} {${replacement}}`);
62 }
63 }
pineafan63fc5e22022-08-04 22:04:10 +010064 return getAutocomplete(typed, autocompletions);
pineafan02ba0232022-07-24 22:16:15 +010065}
66
pineafan0f5cc782022-08-12 21:55:42 +010067async function interactionCreate(interaction: Interaction) {
Skyler Greyf21323a2022-08-13 23:58:22 +010068 if (
69 interaction.type === "MESSAGE_COMPONENT" &&
70 (interaction as MessageComponentInteraction).componentType === "BUTTON"
71 ) {
72 const int = interaction as MessageComponentInteraction;
pineafan0f5cc782022-08-12 21:55:42 +010073 switch (int.customId) {
Skyler Grey75ea9172022-08-06 10:22:23 +010074 case "rolemenu": {
75 return await roleMenu(interaction);
76 }
77 case "verifybutton": {
pineafan0f5cc782022-08-12 21:55:42 +010078 return verify(int);
Skyler Grey75ea9172022-08-06 10:22:23 +010079 }
80 case "createticket": {
81 return create(interaction);
82 }
83 case "closeticket": {
84 return close(interaction);
85 }
86 case "createtranscript": {
pineafan0f5cc782022-08-12 21:55:42 +010087 return createTranscript(int);
Skyler Grey75ea9172022-08-06 10:22:23 +010088 }
pineafan02ba0232022-07-24 22:16:15 +010089 }
pineafan02ba0232022-07-24 22:16:15 +010090 } else if (interaction.type === "APPLICATION_COMMAND_AUTOCOMPLETE") {
Skyler Greyf21323a2022-08-13 23:58:22 +010091 const int = interaction as AutocompleteInteraction;
92 switch (`${int.commandName} ${int.options.getSubcommandGroup(false)} ${int.options.getSubcommand(false)}`) {
Skyler Grey75ea9172022-08-06 10:22:23 +010093 case "tag null null": {
Skyler Greyf21323a2022-08-13 23:58:22 +010094 return int.respond(getAutocomplete(int.options.getString("tag") ?? "", await tagAutocomplete(int)));
Skyler Grey75ea9172022-08-06 10:22:23 +010095 }
96 case "settings null stats": {
pineafan0f5cc782022-08-12 21:55:42 +010097 return int.respond(generateStatsChannelAutocomplete(int.options.getString("name") ?? ""));
Skyler Grey75ea9172022-08-06 10:22:23 +010098 }
99 case "settings null welcome": {
Skyler Greyf21323a2022-08-13 23:58:22 +0100100 return int.respond(generateWelcomeMessageAutocomplete(int.options.getString("message") ?? ""));
Skyler Grey75ea9172022-08-06 10:22:23 +0100101 }
pineafan02ba0232022-07-24 22:16:15 +0100102 }
pineafanad54d752022-04-18 19:01:43 +0100103 }
104}
105
pineafan0f5cc782022-08-12 21:55:42 +0100106export async function callback(_client: HaikuClient, interaction: Interaction) {
pineafan63fc5e22022-08-04 22:04:10 +0100107 await interactionCreate(interaction);
Skyler Grey75ea9172022-08-06 10:22:23 +0100108}