Skip to content
This repository has been archived by the owner on Apr 23, 2023. It is now read-only.

Commit

Permalink
better help
Browse files Browse the repository at this point in the history
  • Loading branch information
sebasptsch committed Jan 10, 2022
1 parent 4119574 commit 4750325
Show file tree
Hide file tree
Showing 25 changed files with 307 additions and 262 deletions.
26 changes: 24 additions & 2 deletions src/Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,36 @@ import {
SlashCommandBuilder,
SlashCommandSubcommandsOnlyBuilder,
} from "@discordjs/builders";
import { Interaction } from "discord.js";
import { CommandInteraction } from "discord.js";
import { Check } from "./utils/conditions";

export interface Command {
/**
* Conditions that the command requires to be successful in order to run.
*/
conditions: Check[];
/**
* Help text for the `/help` command.
*/
helpText: {
/**
* Short bot description.
*/
short: string;
/**
* Long bot description.
*/
long?: string;
};
/**
* The command's structure.
*/
data:
| SlashCommandBuilder
| SlashCommandSubcommandsOnlyBuilder
| Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">;
execute: (interaction: Interaction) => Promise<void>;
/**
* The function to be executed if all the conditions have passed.
*/
execute: (interaction: CommandInteraction) => Promise<void>;
}
39 changes: 22 additions & 17 deletions src/autocompletes/help.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
import Fuse from "fuse.js";
import { getCommands } from "../utils/getCached";
import { Autocomplete } from "../Autocomplete";
import * as commands from "../commands";

export const help = {
export const help: Autocomplete = {
name: "help",
execute: async (interaction) => {
const { value } = interaction.options.getFocused(true);
const commands = await getCommands(
interaction.guild?.commands,
interaction.client.application?.commands
);
const value = interaction.options.getFocused();
const commandValues = Object.values(commands);

const fuse = new Fuse(
commands?.map(({ name }) => ({
name,
value: name,
commandValues?.map(({ data, helpText }) => ({
name: data.name,
short: helpText.short,
long: helpText.long,
})),
{ keys: ["name"] }
{
keys: [
{ name: "name", weight: 3 },
{ name: "short", weight: 2 },
{ name: "long", weight: 1 },
],
}
);
commands?.map(({ name }) => ({
name,
value: name,
}));

const query = fuse.search(value.toString());

interaction.respond(query.map((result) => result.item));
interaction.respond(
query.map((result) => ({
name: result.item.name,
value: result.item.name,
}))
);
},
};
5 changes: 2 additions & 3 deletions src/commands/about.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Embed, SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
import { Command } from "../Command";

export const about: Command = {
conditions: [],
data: new SlashCommandBuilder()
.setName("about")
.setDescription(`About the bot.`),

async execute(interaction: CommandInteraction) {
helpText: { short: `A command that links to the bot's website.` },
async execute(interaction) {
interaction.reply({
embeds: [
new Embed()
Expand Down
32 changes: 14 additions & 18 deletions src/commands/alias.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Embed, quote, SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
import { Command } from "../Command";
import { checkManager } from "../utils/conditions";
import { SuccessEmbed } from "../utils/discordEmbeds";
Expand Down Expand Up @@ -47,16 +46,17 @@ export const alias: Command = {
.addSubcommand((subcommand) =>
subcommand.setName("list").setDescription("List currently set aliases.")
),

async execute(interaction: CommandInteraction) {
if (!interaction.guild?.members) return;

if (interaction.options.getSubcommand() === "add") {
const activity = interaction.options.getString("activity", true);
helpText: {
short:
"Adds an alternative name for a game that replaces the default one in the channel name.",
long: `The alias command allows you to shorten the name of a game in the channel's title. This can be helpful for shortening the names of some games or, if your group has another name they refer to a game by.\n\n**add**\nThe add command adds a new alias. So if you were playing "F1 2021" /alias add "F1 2021" "F1" every time the channel name updates instead of F1 2021 F1 would appear.\n\n**remove**\nThis does exactly as you would expect, it removes an alias for a given activity. For example /alias remove "F1 2021" would remove the alias that we set before for F1 2021.\n\n**list**\nLists the aliases that you've created for the channel you are in.`,
},
async execute(interaction) {
const subcommand = interaction.options.getSubcommand(true);
const activity = interaction.options.getString("activity", true);
if (subcommand === "add") {
const alias = interaction.options.getString("alias", true);

await updateAlias(activity, alias, interaction.guildId);

await interaction.reply({
ephemeral: true,
embeds: [
Expand All @@ -65,21 +65,17 @@ export const alias: Command = {
),
],
});
} else if (interaction.options.getSubcommand() === "remove") {
const activity = interaction.options.getString("activity", true);

await deleteAlias(activity, interaction.guildId);

await interaction.reply({
} else if (subcommand === "remove") {
deleteAlias(activity, interaction.guildId);
return interaction.reply({
ephemeral: true,
embeds: [
SuccessEmbed(`Successfully removed alias for ${quote(activity)}`),
],
});
} else if (interaction.options.getSubcommand() === "list") {
} else if (subcommand === "list") {
const aliases = await listAliases(interaction.guildId);

await interaction.reply({
return interaction.reply({
ephemeral: true,
embeds: [new Embed().addFields(...aliases).setTitle("Alias List")],
});
Expand Down
9 changes: 6 additions & 3 deletions src/commands/allowjoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@ export const allowjoin: Command = {
.setDescription("Whether to enable or disable join requests.")
.setRequired(true)
),

helpText: {
short:
"Toggles whether or not members of your sever are allowed to request to join private channels.",
},
async execute(interaction: CommandInteraction) {
const state = interaction.options.getBoolean("state", true);
await db.guild.update({
db.guild.update({
where: { id: interaction.guild.id },
data: {
allowJoinRequests: state,
},
});
await interaction.reply({
return interaction.reply({
ephemeral: true,
embeds: [
SuccessEmbed(`${!state ? "Disabled" : "Enabled"} Join Requests`),
Expand Down
15 changes: 8 additions & 7 deletions src/commands/allyourbase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ export const allyourbase: Command = {
.setDescription(
"If you are an admin you become the owner of the channel you are in."
),

helpText: {
short:
"Transfers the ownership of the current channel to the person who ran the command. (Must be an admin)",
},
async execute(interaction: CommandInteraction): Promise<void> {
if (!interaction.guild) return;

const guildMember = await getGuildMember(
interaction.guild.members,
interaction.user.id
Expand All @@ -25,16 +26,16 @@ export const allyourbase: Command = {
const channel = guildMember?.voice.channel;

if (!channel) return;
if (!guildMember?.voice.channel) return;

await db.secondary.update({
db.secondary.update({
where: { id: channel.id },
data: { creator: interaction.user.id },
});
await interaction.reply({

return interaction.reply({
embeds: [
SuccessEmbed(
`Owner of <#${guildMember.voice.channel.id}> changed to <@${guildMember.user.id}>`
`Owner of <#${channel.id}> changed to <@${guildMember.user.id}>`
),
],
});
Expand Down
12 changes: 8 additions & 4 deletions src/commands/avc.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { hyperlink, SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
import { Command } from "../Command";

export const avc: Command = {
conditions: [],
data: new SlashCommandBuilder()
.setName("avc")
.setDescription("About the original Auto Voice Channels bot by pixaal."),

async execute(interaction: CommandInteraction): Promise<void> {
interaction.reply(
helpText: {
short: `Replies with a reference to the ideas for the bot which can be found ${hyperlink(
"here",
"https://dynamica.dev/docs/avc"
)}.`,
},
async execute(interaction) {
return interaction.reply(
`This bot was heavily inspired by the ${hyperlink(
"Auto Voice Channels",
"https://wiki.dotsbots.com/"
Expand Down
37 changes: 18 additions & 19 deletions src/commands/bitrate.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
import { Command } from "../Command";
import { checkCreator, checkSecondary } from "../utils/conditions";
import { ErrorEmbed, SuccessEmbed } from "../utils/discordEmbeds";
Expand All @@ -13,47 +12,47 @@ export const bitrate: Command = {
.addIntegerOption((option) =>
option
.setDescription("The bitrate to set the channel to.")
.setName("number")
.setName("bitrate")
),

async execute(interaction: CommandInteraction): Promise<void> {
const bitrate = interaction.options.getInteger("number");

if (!interaction.guild) return;
helpText: { short: "Changes the bitrate of the current channel." },
async execute(interaction) {
const bitrate = interaction.options.getInteger("bitrate");

const guildMember = await getGuildMember(
interaction.guild.members,
interaction.user.id
);

const channel = guildMember?.voice.channel;
const { channel } = guildMember.voice;

if (!channel) return;
if (!guildMember?.voice.channel) return;
if (!channel.manageable) {
return interaction.reply({
embeds: [ErrorEmbed("Unable to manage channel.")],
});
}

if (!bitrate) {
guildMember.voice.channel.edit({ bitrate: 64000 });
interaction.reply({
ephemeral: true,
embeds: [SuccessEmbed("Set bitrate to default.")],
return channel.edit({ bitrate: 64000 }).then(() => {
interaction.reply({
ephemeral: true,
embeds: [SuccessEmbed("Set bitrate to default.")],
});
});
return;
}

if (!(bitrate <= 96 && bitrate >= 8)) {
interaction.reply({
return interaction.reply({
embeds: [
ErrorEmbed(
"Bitrate (in kbps) should be greater than or equal to 4 or less than or equal to 96."
),
],
});
return;
}
await guildMember.voice.channel.edit({
await channel.edit({
bitrate: bitrate ? bitrate * 1000 : 64000,
});
await interaction.reply({
return interaction.reply({
ephemeral: true,
embeds: [
SuccessEmbed(`Channel bitrate changed to ${bitrate ?? "default"}kbps.`),
Expand Down
12 changes: 8 additions & 4 deletions src/commands/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,29 @@ export const create: Command = {
)
.setRequired(false)
),

helpText: {
short:
"It creates a new Primary channel which your users are able to join in order to create more secondary channels.",
},
async execute(interaction: CommandInteraction): Promise<void> {
const section = interaction.options.getChannel(
"section"
) as GuildChannel | null;

if (!interaction.guild?.me?.permissions.has("MANAGE_CHANNELS")) {
await interaction.reply({
return interaction.reply({
ephemeral: true,
embeds: [ErrorEmbed("Bot requires manage channel permissions.")],
});
return;
}

await createPrimary(
interaction.guild.channels,
interaction.user.id,
section
);
await interaction.reply({

return interaction.reply({
embeds: [SuccessEmbed(`New voice channel successfully created.`)],
});
},
Expand Down
8 changes: 5 additions & 3 deletions src/commands/general.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { SlashCommandBuilder } from "@discordjs/builders";
import { CommandInteraction } from "discord.js";
import { Command } from "../Command";
import { checkManager } from "../utils/conditions";
import { db } from "../utils/db";
Expand All @@ -23,8 +22,11 @@ export const general: Command = {
.setDescription("The new template for the general channel.")
.setRequired(true)
),

async execute(interaction: CommandInteraction): Promise<void> {
helpText: {
short:
"Using the /general command you can set the template for the channel name of the channel you're in when nobody is playing a game.",
},
async execute(interaction) {
const name = interaction.options.getString("name", true);
const channel = interaction.options.getString("channel", true);

Expand Down
Loading

0 comments on commit 4750325

Please sign in to comment.