mirror of
https://github.com/artiemis/artemis.js.git
synced 2026-02-14 10:21:54 +00:00
112 lines
3.1 KiB
TypeScript
112 lines
3.1 KiB
TypeScript
import { bold, inlineCode, SlashCommandBuilder } from "discord.js";
|
|
import { defineCommand } from "..";
|
|
import { getDefinitions, getSuggestions } from "../../utils/wiktionary";
|
|
import { stripHtml } from "../../utils/functions";
|
|
import { PaginatedMessage } from "@sapphire/discord.js-utilities";
|
|
import { LRUCache } from "lru-cache";
|
|
import { abort } from "../../utils/error";
|
|
|
|
const titleCache = new LRUCache<string, string>({ max: 100 });
|
|
|
|
export default defineCommand({
|
|
data: new SlashCommandBuilder()
|
|
.setName("wiktionary")
|
|
.setDescription("Looks up a term on Wiktionary")
|
|
.addStringOption((option) =>
|
|
option
|
|
.setName("term")
|
|
.setDescription("The term to look up")
|
|
.setRequired(true)
|
|
.setAutocomplete(true)
|
|
),
|
|
|
|
async autocomplete(interaction) {
|
|
const term = interaction.options.getFocused().trim();
|
|
if (term.length < 3) {
|
|
await interaction.respond([]);
|
|
return;
|
|
}
|
|
|
|
const suggestions = await getSuggestions(term);
|
|
if (!suggestions) {
|
|
await interaction.respond([]);
|
|
return;
|
|
}
|
|
|
|
suggestions.forEach((suggestion) => {
|
|
titleCache.set(suggestion.key, suggestion.title);
|
|
});
|
|
|
|
const choices = suggestions
|
|
.map((suggestion) => ({
|
|
name: suggestion.title,
|
|
value: `:${suggestion.key}`,
|
|
}))
|
|
.slice(0, 25);
|
|
|
|
await interaction.respond(choices);
|
|
},
|
|
|
|
async execute(interaction) {
|
|
let term = interaction.options.getString("term", true);
|
|
|
|
// autocomplete value vs user value
|
|
if (term.startsWith(":")) {
|
|
term = term.slice(1);
|
|
} else {
|
|
const suggestions = await getSuggestions(term);
|
|
if (!suggestions) {
|
|
abort("No definitions found");
|
|
}
|
|
term = suggestions[0].key;
|
|
}
|
|
|
|
const definitions = await getDefinitions(term);
|
|
if (!definitions?.length) {
|
|
abort("No definitions found");
|
|
}
|
|
|
|
const title = titleCache.get(term) ?? term;
|
|
const msg = new PaginatedMessage();
|
|
msg.setSelectMenuOptions((i) => ({
|
|
label: definitions[i - 1].language,
|
|
description: `Page ${i}`,
|
|
}));
|
|
|
|
definitions.forEach((definition) => {
|
|
const description = definition.entries
|
|
.map((entry) => {
|
|
const name = entry.partOfSpeech;
|
|
const definitions = entry.definitions
|
|
.filter((def) => def.definition)
|
|
.map((def, i) => {
|
|
const prefix = inlineCode(`${i + 1}.`);
|
|
const definition = stripHtml(def.definition);
|
|
return `${prefix} ${definition.trim()}`;
|
|
})
|
|
.join("\n");
|
|
|
|
return `${bold(name)}\n${definitions}`;
|
|
})
|
|
.join("\n\n");
|
|
|
|
msg.addPageEmbed((embed) =>
|
|
embed
|
|
.setAuthor({
|
|
name: `Wiktionary - ${definition.language}`,
|
|
iconURL:
|
|
"https://en.wiktionary.org/static/apple-touch/wiktionary/en.png",
|
|
url: `https://${
|
|
definition.languageCode
|
|
}.wiktionary.org/wiki/${encodeURIComponent(term)}`,
|
|
})
|
|
.setTitle(title)
|
|
.setColor(0xfefefe)
|
|
.setDescription(description)
|
|
);
|
|
});
|
|
|
|
msg.run(interaction);
|
|
},
|
|
});
|