Skip to content

Commit d191696

Browse files
committed
feat: Rework report feature
1 parent 2a4f76c commit d191696

3 files changed

Lines changed: 134 additions & 51 deletions

File tree

src/commands/user/report.ts

Lines changed: 110 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,20 @@ import {
44
ButtonBuilder,
55
ButtonStyle,
66
ChatInputCommandInteraction,
7-
EmbedBuilder,
7+
ContainerBuilder,
8+
FileUploadBuilder,
9+
ForumChannel,
810
GuildMember,
11+
LabelBuilder,
12+
MediaGalleryBuilder,
13+
MediaGalleryItemBuilder,
14+
MessageFlags,
915
ModalBuilder,
16+
ModalSubmitFields,
17+
SeparatorBuilder,
18+
SeparatorSpacingSize,
1019
SlashCommandBuilder,
20+
TextDisplayBuilder,
1121
TextInputBuilder,
1222
TextInputStyle,
1323
} from "discord.js";
@@ -32,32 +42,54 @@ export async function run(
3242
interaction: ChatInputCommandInteraction,
3343
) {
3444
const user = interaction.options.getMember("użytkownik") as GuildMember;
45+
46+
if (user.user.id === interaction.user.id) {
47+
return interaction.reply({
48+
content: "Nie możesz zgłosić samego siebie!",
49+
flags: 64,
50+
});
51+
}
52+
3553
const reportTimestamp = Date.now();
3654

3755
const reportModal = new ModalBuilder()
3856
.setTitle("Zgłoś użytkownika")
39-
.setCustomId("report_user_" + reportTimestamp)
40-
.addComponents(
41-
new ActionRowBuilder<TextInputBuilder>().addComponents(
57+
.setCustomId("reportmodal_user_" + reportTimestamp)
58+
.addLabelComponents(
59+
new LabelBuilder()
60+
.setLabel("Powód zgłoszenia")
61+
.setTextInputComponent(
4262
new TextInputBuilder()
43-
.setLabel("Powód zgłoszenia")
44-
.setStyle(TextInputStyle.Paragraph)
63+
.setStyle(TextInputStyle.Short)
4564
.setCustomId("report_reason")
4665
.setPlaceholder("Podaj powód zgłoszenia")
4766
.setMinLength(10)
4867
.setMaxLength(2000)
4968
.setRequired(true),
50-
),
51-
new ActionRowBuilder<TextInputBuilder>().addComponents(
69+
)
70+
)
71+
.addLabelComponents(
72+
new LabelBuilder()
73+
.setLabel("Uzasadnienie zgłoszenia")
74+
.setTextInputComponent(
5275
new TextInputBuilder()
53-
.setLabel("Dowody (linki)")
5476
.setStyle(TextInputStyle.Paragraph)
55-
.setCustomId("report_link")
56-
.setPlaceholder("Podaj link do dowodu (każdy w nowej linii)")
77+
.setCustomId("report_explanation")
78+
.setPlaceholder("Uzasadnij swoje zgłoszenie")
5779
.setMinLength(10)
5880
.setMaxLength(4000)
5981
.setRequired(true),
60-
),
82+
)
83+
)
84+
.addLabelComponents(
85+
new LabelBuilder()
86+
.setLabel("Dowody")
87+
.setFileUploadComponent(
88+
new FileUploadBuilder()
89+
.setCustomId("report_attachments")
90+
.setMaxValues(10)
91+
.setRequired(false),
92+
)
6193
)
6294
.toJSON();
6395

@@ -75,33 +107,54 @@ export async function run(
75107
flags: 64,
76108
});
77109

78-
const reason = modalUse.fields.getTextInputValue("report_reason");
79-
const links = modalUse.fields.getTextInputValue("report_link");
80-
81-
const embed = new EmbedBuilder()
82-
.setColor("#daa520")
83-
.setTitle("Nowe zgłoszenie")
84-
.setTimestamp()
85-
.setFields([
86-
{
87-
name: "Zgłaszający",
88-
value: interaction.member.toString(),
89-
inline: true,
90-
},
91-
{
92-
name: "Zgłoszony",
93-
value: user.toString(),
94-
inline: true,
95-
},
96-
{
97-
name: "Powód",
98-
value: reason,
99-
},
100-
{
101-
name: "Dowody",
102-
value: links,
103-
},
104-
]);
110+
const reason = (modalUse.fields as ModalSubmitFields).getTextInputValue("report_reason");
111+
const explanation = (modalUse.fields as ModalSubmitFields).getTextInputValue("report_explanation");
112+
const attachments = (modalUse.fields as ModalSubmitFields).getUploadedFiles("report_attachments");
113+
114+
const galleryItems: MediaGalleryItemBuilder[] = [];
115+
116+
for(const attachment of attachments.values()) {
117+
const contentType = attachment.contentType.split("/")[0];
118+
if(contentType !== "image" && contentType !== "video") continue;
119+
120+
galleryItems.push(
121+
new MediaGalleryItemBuilder()
122+
.setURL(attachment.url)
123+
.setDescription(attachment.name || "Załącznik")
124+
);
125+
}
126+
127+
const container = new ContainerBuilder()
128+
.addTextDisplayComponents(
129+
new TextDisplayBuilder().setContent(`## Zgłoszenie <@${user.id}> (${user.user.username}, ${user.id})`),
130+
)
131+
.addSeparatorComponents(
132+
new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Small).setDivider(true),
133+
)
134+
.addTextDisplayComponents(
135+
new TextDisplayBuilder().setContent("### Powód"),
136+
)
137+
.addTextDisplayComponents(
138+
new TextDisplayBuilder().setContent(reason),
139+
)
140+
.addSeparatorComponents(
141+
new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Small).setDivider(true),
142+
)
143+
.addTextDisplayComponents(
144+
new TextDisplayBuilder().setContent("### Uzasadnienie"),
145+
)
146+
.addTextDisplayComponents(
147+
new TextDisplayBuilder().setContent(explanation),
148+
)
149+
.addSeparatorComponents(
150+
new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Small).setDivider(true),
151+
);
152+
153+
if(galleryItems.length > 0) {
154+
container.addMediaGalleryComponents(
155+
new MediaGalleryBuilder().addItems(...galleryItems),
156+
);
157+
}
105158

106159
const components = new ActionRowBuilder<ButtonBuilder>().addComponents(
107160
new ButtonBuilder()
@@ -114,9 +167,22 @@ export async function run(
114167
.setCustomId("report_reject_" + reportTimestamp),
115168
);
116169

117-
await (
118-
client.channels.cache.get(
119-
client.config.report_channel,
120-
) as BaseGuildTextChannel
121-
)?.send({ embeds: [embed], components: [components] });
170+
171+
const channel = client.channels.cache.get(
172+
client.config.report_channel,
173+
) as BaseGuildTextChannel | ForumChannel;
174+
175+
if(channel instanceof ForumChannel) {
176+
await channel.threads.create({
177+
name: `Zgłoszenie - ${user.user.username}`,
178+
autoArchiveDuration: 1440,
179+
reason: `Zgłoszenie użytkownika ${user.user.username} (${user.id})`,
180+
message: {
181+
flags: MessageFlags.IsComponentsV2,
182+
components: [container, components],
183+
}
184+
})
185+
} else {
186+
await channel.send({ flags: MessageFlags.IsComponentsV2, components: [container, components] });
187+
}
122188
}

src/interactions/report.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {
22
ButtonInteraction,
33
EmbedBuilder,
4+
ForumChannel,
5+
ForumThreadChannel,
46
GuildMemberRoleManager,
57
} from "discord.js";
68
import Ryneczek from "#client";
@@ -26,20 +28,35 @@ export async function run(client: Ryneczek, interaction: ButtonInteraction) {
2628
const embed = EmbedBuilder.from(interaction.message.embeds[0]);
2729

2830
if (action === "accept") {
29-
embed.setColor("#87b55b").setFooter({
30-
text: "Zaakceptowane przez " + interaction.user.tag,
31-
});
31+
interaction.channel.send({
32+
content: `Zakceptowane przez: <@${interaction.user.id}> (${interaction.user.username})`,
33+
})
3234
await interaction.reply({
3335
content:
3436
"Zgłoszenie zostało zaakceptowane! W celu ukarania użytkownika użyj `ban` znajdującego się w context menu (PPM na użytkownika).",
3537
flags: 64,
3638
});
39+
40+
if(interaction.channel.parent instanceof ForumChannel) {
41+
const acceptTag = interaction.channel.parent.availableTags.find(tag => tag.emoji.name === "✅");
42+
if(acceptTag) {
43+
await (interaction.channel as ForumThreadChannel).edit({
44+
appliedTags: [acceptTag.id],
45+
});
46+
}
47+
}
3748
} else {
38-
embed.setColor("#b55b5b").setFooter({
39-
text: "Odrzucone przez " + interaction.user.tag,
49+
interaction.channel.send({
50+
content: `Odrzucone przez: <@${interaction.user.id}> (${interaction.user.username})`,
4051
});
52+
if(interaction.channel.parent instanceof ForumChannel) {
53+
const rejectTag = interaction.channel.parent.availableTags.find(tag => tag.emoji.name === "❌");
54+
if(rejectTag) {
55+
await (interaction.channel as ForumThreadChannel).edit({
56+
appliedTags: [rejectTag.id],
57+
});
58+
}
59+
}
4160
await interaction.deferUpdate();
4261
}
43-
44-
await interaction.message.edit({ embeds: [embed], components: [] });
4562
}

0 commit comments

Comments
 (0)