Skip to content

Commit 377a989

Browse files
committed
[INSTALL] New select menus, starboard limit-channels
1 parent 395469a commit 377a989

File tree

11 files changed

+146
-9
lines changed

11 files changed

+146
-9
lines changed

languages/en-US.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,13 +1509,18 @@
15091509
"STARBOARD_CHANNEL_DESCRIPTION": "Set the channel starred messages will be sent to",
15101510
"STARBOARD_MINIMUM_DESCRIPTION": "Set the minimum amount of stars needed to get on the starboard (Defaults to 5)",
15111511
"STARBOARD_EMOJI_DESCRIPTION": "Set a custom starboard emoji (Requires Premium)",
1512+
"STARBOARD_LIMIT_CHANNELS_DESCRIPTION": "Limit which channels can have their messages starred",
15121513
"STARBOARD_CHANNEL_RESET": "Successfully disabled starboard",
15131514
"STARBOARD_CHANNEL_SET": "Successfully enabled starboard and set the channel to {{channel}}. All starred messages will be sent there",
15141515
"STARBOARD_MINIMUM_TOO_LOW": "The minimum must be at least 2!",
15151516
"STARBOARD_MINIMUM_RESET": "Successfully reset the starboard minimum! Messages will now need 5 stars to appear on the starboard",
15161517
"STARBOARD_MINIMUM_SET": "Successfully set the starboard minimum! Messages will now need {{min}} stars to appear on the starboard",
15171518
"STARBOARD_EMOJI_INVALID": "That emoji isn't valid! It must be a default emoji or an emoji from this server",
15181519
"STARBOARD_EMOJI_SET": "Successfully set the starboard emoji to {{emoji}}",
1520+
"STARBOARD_LIMIT_CHANNELS_SELECT_PLACEHOLDER": "Select up to 25 channels",
1521+
"STARBOARD_LIMIT_CHANNELS_MESSAGE": "Select channels below to limit where messages can be starred",
1522+
"STARBOARD_LIMIT_CHANNELS_SET": "Successfully limited starboard to messages from the following channels:\n{{channels}}",
1523+
"STARBOARD_LIMIT_CHANNELS_RESET": "Successfully removed channel restrictions from the starboard. Any message in this server can now be starred",
15191524
"STARBOARD_CONTAINS_VIDEO": "__Message contains a video__",
15201525
"STARBOARD_CONTAINS_AUDIO": "__Message contains an audio file__",
15211526
"STARBOARD_JUMP_TO": "Jump to message",

lib/extensions/appcommandmessage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ export class ApplicationCommandMessage {
5656
type: MessageType = "DEFAULT";
5757
latestResponseId: Snowflake;
5858
latestResponse: FireMessage;
59+
private _flags: number = 0;
5960
mentions: MessageMentions;
60-
private _flags: number;
6161
channel: FakeChannel;
6262
content: string = "";
6363
deleteReason: string;

lib/extensions/componentmessage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ export class ComponentMessage {
4141
latestResponseId: Snowflake;
4242
latestResponse: FireMessage;
4343
type: MessageComponentType;
44+
private _flags: number = 0;
4445
ephemeralSource: boolean;
45-
private _flags: number;
4646
message: FireMessage;
4747
channel: FakeChannel;
4848
member: FireMember;

lib/extensions/contextcommandmessage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ export class ContextCommandMessage {
5555
type: MessageType = "DEFAULT";
5656
latestResponseId: Snowflake;
5757
latestResponse: FireMessage;
58+
private _flags: number = 0;
5859
mentions: MessageMentions;
59-
private _flags: number;
6060
content: string = "";
6161
channel: FakeChannel;
6262
deleteReason: string;

lib/extensions/message.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,13 @@ export class FireMessage extends Message {
12031203
const starboard = this.guild.starboard;
12041204
if (!starboard || this.channel.id == starboard.id) return;
12051205

1206+
const limitedChannels = this.guild.settings.get<Snowflake[]>(
1207+
"starboard.limitchannels",
1208+
[]
1209+
);
1210+
if (limitedChannels.length && !limitedChannels.includes(this.channel.id))
1211+
return;
1212+
12061213
if (!this.guild.starboardReactions)
12071214
await this.guild.loadStarboardReactions();
12081215

lib/extensions/modalmessage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ export class ModalMessage {
4040
sent: false | "ack" | "message";
4141
latestResponse: FireMessage;
4242
latestResponseId: Snowflake;
43+
private _flags: number = 0;
4344
ephemeralSource: boolean;
44-
private _flags: number;
4545
message?: FireMessage;
4646
channel: FakeChannel;
4747
member: FireMember;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { ApplicationCommandMessage } from "@fire/lib/extensions/appcommandmessage";
2+
import { Command } from "@fire/lib/util/command";
3+
import { Language } from "@fire/lib/util/language";
4+
import { PermissionFlagsBits } from "discord-api-types/v9";
5+
import { ChannelSelectMenu, MessageActionRow } from "discord.js";
6+
7+
export default class StarboardLimitChannels extends Command {
8+
constructor() {
9+
super("starboard-limit-channels", {
10+
description: (language: Language) =>
11+
language.get("STARBOARD_LIMIT_CHANNELS_DESCRIPTION"),
12+
userPermissions: [PermissionFlagsBits.ManageChannels],
13+
restrictTo: "guild",
14+
parent: "starboard",
15+
slashOnly: true,
16+
});
17+
}
18+
19+
async run(command: ApplicationCommandMessage) {
20+
const current = command.guild.settings.get("starboard.limitchannels", []);
21+
const select = new ChannelSelectMenu()
22+
.setCustomId("starboard-limit-channels")
23+
.setPlaceholder(
24+
command.language.get("STARBOARD_LIMIT_CHANNELS_SELECT_PLACEHOLDER")
25+
)
26+
.setMinValues(0)
27+
.setMaxValues(25);
28+
if (current.length)
29+
select.setDefaultValues(
30+
current.map((current) => ({ type: "channel", id: current }))
31+
);
32+
const row = new MessageActionRow().addComponents(select);
33+
return await command.send("STARBOARD_LIMIT_CHANNELS_MESSAGE", {
34+
components: [row],
35+
});
36+
}
37+
}

src/listeners/channelSelect.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { ComponentMessage } from "@fire/lib/extensions/componentmessage";
2+
import { Listener } from "@fire/lib/util/listener";
3+
import { ChannelSelectMenu } from "discord.js";
4+
5+
export default class ChannelSelect extends Listener {
6+
constructor() {
7+
super("channelSelect", {
8+
emitter: "client",
9+
event: "channelSelect",
10+
});
11+
}
12+
13+
async exec(select: ComponentMessage) {
14+
if (select.type != "CHANNEL_SELECT") return;
15+
16+
const guild = select.guild;
17+
18+
if (select.customId == "starboard-limit-channels") {
19+
const channels = select.values,
20+
row = select.message.components[0];
21+
if (channels.length) {
22+
await guild.settings.set(
23+
"starboard.limitchannels",
24+
channels,
25+
select.author
26+
);
27+
(row.components[0] as unknown as ChannelSelectMenu).setDefaultValues(
28+
channels.map((c) => ({ type: "channel", id: c }))
29+
);
30+
} else {
31+
await guild.settings.delete("starboard.limitchannels", select.author);
32+
(row.components[0] as unknown as ChannelSelectMenu).setDefaultValues(
33+
[]
34+
);
35+
}
36+
await select
37+
.edit({
38+
components: [row],
39+
})
40+
.catch(() => {});
41+
return await select.success(
42+
channels.length
43+
? "STARBOARD_LIMIT_CHANNELS_SET"
44+
: "STARBOARD_LIMIT_CHANNELS_RESET",
45+
{ channels: channels.map((c) => `<#${c}>`).join(", ") }
46+
);
47+
}
48+
}
49+
}

src/listeners/interaction.ts

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,10 @@ export default class InteractionListener extends Listener {
157157
);
158158
else if (interaction.isButton())
159159
return await this.handleButton(interaction);
160-
else if (interaction.isSelectMenu())
161-
return await this.handleSelect(interaction);
160+
else if (interaction.isStringSelectMenu())
161+
return await this.handleStringSelect(interaction);
162+
else if (interaction.isChannelSelectMenu())
163+
return await this.handleChannelSelect(interaction);
162164
else if (interaction.isModalSubmit())
163165
return await this.handleModalSubmit(interaction);
164166
}
@@ -315,7 +317,8 @@ export default class InteractionListener extends Listener {
315317
}
316318
}
317319

318-
async handleSelect(select: MessageComponentInteraction) {
320+
async handleStringSelect(select: MessageComponentInteraction) {
321+
if (!select.isStringSelectMenu()) return;
319322
try {
320323
// should be cached if in guild or fetch if dm channel
321324
await this.client.channels.fetch(select.channelId).catch(() => {});
@@ -350,6 +353,42 @@ export default class InteractionListener extends Listener {
350353
}
351354
}
352355

356+
async handleChannelSelect(select: MessageComponentInteraction) {
357+
if (!select.isChannelSelectMenu()) return;
358+
try {
359+
// should be cached if in guild or fetch if dm channel
360+
await this.client.channels.fetch(select.channelId).catch(() => {});
361+
const message = new ComponentMessage(this.client, select);
362+
if (!message.customId.startsWith("!")) await message.channel.ack();
363+
else message.customId = message.customId.slice(1);
364+
this.client.emit("channelSelect", message);
365+
} catch (error) {
366+
await this.error(select, error).catch(() => {
367+
select.reply(
368+
`${this.client.util.useEmoji("error")} Something went wrong...`
369+
);
370+
});
371+
if (typeof this.client.sentry != "undefined") {
372+
const sentry = this.client.sentry;
373+
sentry.captureException(error, {
374+
extra: {
375+
button: JSONStringifyBigint(select),
376+
member: select.member
377+
? select.member.toString()
378+
: select.user.toString(),
379+
channel_id: select.channelId,
380+
guild_id: select.guildId,
381+
env: process.env.NODE_ENV,
382+
},
383+
user: {
384+
id: select.user.id,
385+
username: select.user.toString(),
386+
},
387+
});
388+
}
389+
}
390+
}
391+
353392
async handleModalSubmit(modal: ModalSubmitInteraction) {
354393
try {
355394
// should be cached if in guild or fetch if dm channel

src/listeners/select.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export default class Select extends Listener {
5757

5858
// used to handle generic dropdowns like the rank selector
5959
async exec(select: ComponentMessage) {
60-
if (select.type != "SELECT_MENU") return;
60+
if (select.type != "SELECT_MENU" && select.type != "STRING_SELECT") return;
6161

6262
if (select.customId == "quote_copy") {
6363
select.flags = 64;

0 commit comments

Comments
 (0)