11import type { Command , MyContext } from "../interfaces" ;
2- import type { ButtonInteraction , CommandInteraction , Interaction , Message , SelectMenuInteraction } from "discord.js" ;
2+ import type {
3+ AutocompleteInteraction ,
4+ ButtonInteraction ,
5+ CommandInteraction ,
6+ Interaction ,
7+ Message ,
8+ SelectMenuInteraction ,
9+ } from "discord.js" ;
310import type { APIEmbed } from "discord-api-types" ;
411
512import { commandCooldownCheck , commandPermissionCheck , deleteButton } from "../utils/CommandUtils" ;
6- import { getSingleMDNSearchResults } from "../commands/docs/mdn" ;
13+ import { getSingleMDNSearchResults , getSources } from "../commands/docs/mdn" ;
714import { searchDJSDoc } from "../commands/docs/djs" ;
815import { MessageActionRow } from "discord.js" ;
916
1017import glob from "glob" ;
1118import Doc from "discord.js-docs" ;
1219
1320export async function interactionCreateHandler ( context : MyContext , interaction : Interaction < "cached" > ) {
14- if ( interaction . isCommand ( ) ) {
15- commandInteractionHandler ( context , interaction ) ;
16- } else if ( interaction . isButton ( ) ) {
17- buttonInteractionHandler ( context , interaction ) ;
18- } else if ( interaction . isSelectMenu ( ) ) {
19- selectMenuInteractionHandler ( context , interaction ) ;
21+ try {
22+ if ( interaction . isCommand ( ) ) {
23+ await commandInteractionHandler ( context , interaction ) ;
24+ } else if ( interaction . isButton ( ) ) {
25+ await buttonInteractionHandler ( context , interaction ) ;
26+ } else if ( interaction . isSelectMenu ( ) ) {
27+ await selectMenuInteractionHandler ( context , interaction ) ;
28+ } else if ( interaction . isAutocomplete ( ) ) {
29+ await autocompleteInteractionHandler ( context , interaction ) ;
30+ }
31+ } catch ( e ) {
32+ console . error ( e ) ;
2033 }
2134}
2235/**
@@ -45,8 +58,10 @@ export function loadCommands(context: MyContext) {
4558 } ) ;
4659}
4760async function commandInteractionHandler ( context : MyContext , interaction : CommandInteraction ) {
61+ await interaction . deferReply ( { ephemeral : true } ) . catch ( console . error ) ;
62+
4863 const command = context . commands . get ( interaction . commandName ) ;
49- if ( ! command ) return interaction . reply ( { content : "Command not found" , ephemeral : true } ) ;
64+ if ( ! command ) return interaction . editReply ( { content : "Command not found" } ) . catch ( console . error ) ;
5065
5166 if ( commandPermissionCheck ( interaction , command ) ) return ;
5267 if ( commandCooldownCheck ( interaction , command , context ) ) return ;
@@ -55,15 +70,13 @@ async function commandInteractionHandler(context: MyContext, interaction: Comman
5570 } catch ( e ) {
5671 console . error ( e ) ;
5772 const errorMessage = "An error has occurred" ;
58- interaction
59- . reply ( {
60- content : errorMessage ,
61- ephemeral : true ,
62- } )
63- . catch ( console . error ) ;
73+ await interaction [ interaction . replied ? "editReply" : "reply" ] ?.( {
74+ content : errorMessage ,
75+ } ) . catch ( console . error ) ;
6476 }
6577}
6678async function selectMenuInteractionHandler ( context : MyContext , interaction : SelectMenuInteraction ) {
79+ await interaction . deferUpdate ( ) . catch ( console . error ) ;
6780 const CommandName = interaction . customId . split ( "/" ) [ 0 ] ;
6881 switch ( CommandName ) {
6982 case "mdnselect" : {
@@ -74,7 +87,7 @@ async function selectMenuInteractionHandler(context: MyContext, interaction: Sel
7487
7588 // Remove the menu and update the ephemeral message
7689 await interaction
77- . update ( { content : "Sent documentations for " + selectedValue , components : [ ] } )
90+ . editReply ( { content : "Sent documentations for " + selectedValue , components : [ ] } )
7891 . catch ( console . error ) ;
7992 // Send documentation
8093 await interaction . followUp ( { embeds : [ resultEmbed ] , components : [ deleteButtonRow ] } ) . catch ( console . error ) ;
@@ -92,14 +105,14 @@ async function selectMenuInteractionHandler(context: MyContext, interaction: Sel
92105
93106 // Remove the menu and update the ephemeral message
94107 await interaction
95- . update ( { content : "Sent documentations for " + selectedValue , components : [ ] } )
108+ . editReply ( { content : "Sent documentations for " + selectedValue , components : [ ] } )
96109 . catch ( console . error ) ;
97110 // Send documentation
98111 await interaction . followUp ( { embeds : [ resultEmbed ] , components : [ deleteButtonRow ] } ) . catch ( console . error ) ;
99112 break ;
100113 }
101114 default : {
102- interaction . reply ( { content : "Unknown menu" , ephemeral : true } ) . catch ( console . error ) ;
115+ interaction . editReply ( { content : "Unknown menu" } ) . catch ( console . error ) ;
103116 }
104117 }
105118}
@@ -119,5 +132,40 @@ async function buttonInteractionHandler(context: MyContext, interaction: ButtonI
119132 . catch ( console . error ) ;
120133 }
121134}
122- // TODO add autocomplete
123- // async function autocompleteInteractionHandler(context: MyContext, interaction: AutocompleteInteraction) {}s
135+
136+ async function autocompleteInteractionHandler ( context : MyContext , interaction : AutocompleteInteraction ) {
137+ switch ( interaction . commandName ) {
138+ case "djs" : {
139+ // Check the cache, the command will force fetch anyway
140+ const doc = await Doc . fetch ( "stable" , { force : false } ) ;
141+ const query = interaction . options . getFocused ( ) as string ;
142+ const singleElement = doc . get ( ...query . split ( / \. | # / ) ) ;
143+ if ( singleElement ) {
144+ await interaction
145+ . respond ( [ { name : singleElement . formattedName , value : singleElement . formattedName } ] )
146+ . catch ( console . error ) ;
147+ return ;
148+ }
149+ const searchResults = doc . search ( query , { excludePrivateElements : false } ) ;
150+ if ( ! searchResults ) {
151+ await interaction . respond ( [ ] ) . catch ( console . error ) ;
152+ return ;
153+ }
154+ await interaction
155+ . respond ( searchResults . map ( ( elem ) => ( { name : elem . formattedName , value : elem . formattedName } ) ) )
156+ . catch ( console . error ) ;
157+ break ;
158+ }
159+ case "mdn" : {
160+ const query = interaction . options . getFocused ( ) as string ;
161+
162+ const { index, sitemap } = await getSources ( ) ;
163+ const search = index . search ( query , { limit : 10 } ) . map ( ( id ) => {
164+ const val = sitemap [ < number > id ] . loc ;
165+ const parsed = val . length >= 99 ? val . split ( "/" ) . slice ( - 2 ) . join ( "/" ) : val ;
166+ return { name : parsed , value : parsed } ;
167+ } ) ;
168+ await interaction . respond ( search ) . catch ( console . error ) ;
169+ }
170+ }
171+ }
0 commit comments