Skip to content

Commit cfb5c03

Browse files
committed
feat: Add shared docs commands utils
1 parent ddf520e commit cfb5c03

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

src/commands/docs/utils.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { type CommandInteraction, MessageFlags } from 'discord.js';
2+
import { logToChannel } from '../../util/channel-logging.js';
3+
import type { ProviderConfig } from './types.js';
4+
5+
export const SEARCH_TERM = '%SEARCH%';
6+
export const TERM = '%TERM%';
7+
8+
// Utility functions
9+
export const getSearchUrl = (url: string, search: string) =>
10+
url.replace(SEARCH_TERM, encodeURIComponent(search));
11+
12+
export const createBaseConfig = (options: {
13+
color: number;
14+
icon: string;
15+
commandDescription: string;
16+
directUrl?: string;
17+
}) => ({
18+
color: options.color,
19+
icon: options.icon,
20+
commandDescription: options.commandDescription,
21+
directUrl: options.directUrl,
22+
});
23+
24+
export const executeDocCommand = async (
25+
config: ProviderConfig,
26+
interaction: CommandInteraction
27+
): Promise<void> => {
28+
if (!interaction.isChatInputCommand()) return;
29+
30+
const query = interaction.options.getString('query', true).trim();
31+
32+
try {
33+
const items = await config.getFilteredData(query);
34+
35+
if (items.length === 0) {
36+
await interaction.reply({
37+
content: `No results found for "${query}"`,
38+
flags: MessageFlags.Ephemeral,
39+
});
40+
return;
41+
}
42+
43+
const collection = config.createCollection(items);
44+
const { selectRow, buttonRow } = config.createActionBuilders(collection);
45+
46+
const choiceInteraction = await interaction.reply({
47+
content: config.getSelectionMessage(query),
48+
components: [selectRow, buttonRow],
49+
flags: MessageFlags.Ephemeral,
50+
});
51+
52+
const collector = choiceInteraction.createMessageComponentCollector({
53+
filter: (i) => i.user.id === interaction.user.id,
54+
});
55+
56+
collector.once('collect', async (i) => {
57+
if (i.isStringSelectMenu()) {
58+
const selectedSet = new Set(i.values);
59+
const selectedItems = collection.filter((_, key) => selectedSet.has(key));
60+
const selectedTitles = selectedItems.map(config.getDisplayTitle);
61+
62+
await interaction.editReply({
63+
content: config.getDisplayMessage(selectedTitles),
64+
components: [],
65+
});
66+
67+
const embeds = config.createResultEmbeds(selectedItems);
68+
69+
logToChannel({
70+
channel: interaction.channel,
71+
content: {
72+
type: 'embed',
73+
embed: embeds,
74+
content: interaction.options.getUser('user')
75+
? `<@${interaction.options.getUser('user')?.id}>`
76+
: undefined,
77+
},
78+
});
79+
} else if (i.isButton()) {
80+
await choiceInteraction.delete();
81+
}
82+
});
83+
} catch (error) {
84+
console.error('Error executing doc command:', error);
85+
await interaction.reply({
86+
content: `Error: ${error}`,
87+
flags: MessageFlags.Ephemeral,
88+
});
89+
}
90+
};

0 commit comments

Comments
 (0)