Skip to content

Commit 2cac9d8

Browse files
authored
Merge pull request #11 from teamboostify/fix/boosters
Added booster fixes & db cleanups
2 parents d716b84 + 8b2b74a commit 2cac9d8

6 files changed

Lines changed: 215 additions & 35 deletions

File tree

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
/node_modules
22
/dist
33
.env
4-
src/generated/
4+
src/generated/
5+
6+
src/commands/*.make.ts
7+
src/events/*.make.ts
8+
# ^ For commands/events that are being made - not ready for commits

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "boostify",
3-
"version": "1.0.1",
3+
"version": "1.0.2",
44
"description": "",
55
"main": "dist/index.js",
66
"type": "module",

src/commands/booster.ts

Lines changed: 132 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import {
55
ContainerBuilder,
66
TextDisplayBuilder,
77
MessageFlags,
8+
SeparatorSpacingSize,
9+
ButtonBuilder,
10+
ButtonStyle,
811
} from "discord.js";
912
import {
1013
getBooster,
@@ -14,54 +17,59 @@ import {
1417
getActiveBoosters,
1518
getTotalBoosts,
1619
registerBoost,
20+
removeBoost,
1721
} from "../services/boosterService.js";
1822
import { Command } from "../base/classes/command.js";
23+
import { logger } from "../libs/logger.js";
1924

2025
export default new Command({
2126
info: new SlashCommandBuilder()
22-
.setName("booster")
27+
.setName("booster")
2328
.setDescription("Booster management commands")
2429
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
2530
.addSubcommand((sub) =>
2631
sub
2732
.setName("check")
2833
.setDescription("Check booster info for a user")
2934
.addUserOption((opt) =>
30-
opt.setName("user").setDescription("The user to check").setRequired(true)
31-
)
35+
opt
36+
.setName("user")
37+
.setDescription("The user to check")
38+
.setRequired(true),
39+
),
3240
)
3341
.addSubcommand((sub) =>
3442
sub
3543
.setName("add")
3644
.setDescription("Add boost count to a user")
3745
.addUserOption((opt) =>
38-
opt.setName("user").setDescription("The user").setRequired(true)
46+
opt.setName("user").setDescription("The user").setRequired(true),
3947
)
4048
.addIntegerOption((opt) =>
4149
opt
4250
.setName("amount")
4351
.setDescription("Amount to add")
4452
.setRequired(true)
45-
.setMinValue(1)
46-
)
53+
.setMinValue(1),
54+
),
4755
)
4856
.addSubcommand((sub) =>
4957
sub
5058
.setName("remove")
5159
.setDescription("Remove boost count from a user")
5260
.addUserOption((opt) =>
53-
opt.setName("user").setDescription("The user").setRequired(true)
61+
opt.setName("user").setDescription("The user").setRequired(true),
5462
)
5563
.addIntegerOption((opt) =>
5664
opt
5765
.setName("amount")
5866
.setDescription("Amount to remove")
5967
.setRequired(true)
60-
.setMinValue(1)
61-
)
68+
.setMinValue(1),
69+
),
6270
)
6371
.addSubcommand((sub) =>
64-
sub.setName("stats").setDescription("View server boost statistics")
72+
sub.setName("stats").setDescription("View server boost statistics"),
6573
),
6674
async execute(interaction) {
6775
const sub = interaction.options.getSubcommand();
@@ -80,13 +88,18 @@ export default new Command({
8088
if (sub === "check") {
8189
const user = interaction.options.getUser("user", true);
8290
const result = await getBooster(user.id, interaction);
83-
const member = await discordGuild.members.fetch(user.id).catch(() => null);
91+
const member = await discordGuild.members
92+
.fetch(user.id)
93+
.catch(() => null);
8494
const isBoostingServer = member?.premiumSince !== null;
8595
const avatarUrl =
86-
member?.displayAvatarURL({ size: 256 }) ?? user.displayAvatarURL({ size: 256 });
96+
member?.displayAvatarURL({ size: 256 }) ??
97+
user.displayAvatarURL({ size: 256 });
8798

8899
if (!result?.success) {
89-
await interaction.editReply({ content: "Could not load booster info for this server." });
100+
await interaction.editReply({
101+
content: "Could not load booster info for this server.",
102+
});
90103
return;
91104
}
92105

@@ -98,10 +111,14 @@ export default new Command({
98111
.setTitle(`Here is the Booster Information for ${user.id}!`)
99112
.setThumbnail(avatarUrl)
100113
.addFields(
101-
{ name: "Status", value: "🟢 Active (Nitro Boost)", inline: true },
114+
{
115+
name: "Status",
116+
value: "🟢 Active (Nitro Boost)",
117+
inline: true,
118+
},
102119
{ name: "Discord boost", value: discordBoost, inline: true },
103120
{ name: "Custom Role", value: "None", inline: true },
104-
{ name: "User Ping", value: `<@${user.id}>`}
121+
{ name: "User Ping", value: `<@${user.id}>` },
105122
)
106123
.setTimestamp();
107124

@@ -113,7 +130,9 @@ export default new Command({
113130
.setAccentColor(0xe642a4)
114131
.addTextDisplayComponents(
115132
new TextDisplayBuilder().setContent("**Uh oh!**"),
116-
new TextDisplayBuilder().setContent(`It looks like ${user} is not a Booster.`)
133+
new TextDisplayBuilder().setContent(
134+
`It looks like ${user} is not a Booster.`,
135+
),
117136
);
118137

119138
await interaction.editReply({
@@ -125,19 +144,75 @@ export default new Command({
125144

126145
const booster = result.data;
127146

147+
if (booster.boostCounts == 0) {
148+
try {
149+
await removeBoost(booster.userId, interaction.guild.id);
150+
} catch (err) {
151+
logger.error(
152+
`An error occured while removing ${booster.userId}'s data: ${err}`,
153+
);
154+
155+
const supportButton = new ButtonBuilder()
156+
.setStyle(ButtonStyle.Link)
157+
.setLabel("Our Support Server")
158+
.setURL("https://discord.gg/NUtyKs7hA6");
159+
160+
const container = new ContainerBuilder()
161+
.setAccentColor(0xe642a4)
162+
.addTextDisplayComponents(
163+
new TextDisplayBuilder().setContent("**Uh oh!**"),
164+
new TextDisplayBuilder().setContent(
165+
`It looks like we ran into an issue\n-# If this issue is persistent, please consult your console logs if you're using a self-hosted version of Boostify, and create an issue on our [Repository](https://github.com/teamboostify/boostify/issues), or use our support server!.`,
166+
),
167+
)
168+
.addSeparatorComponents((sep) =>
169+
sep.setDivider(true).setSpacing(SeparatorSpacingSize.Small),
170+
)
171+
.addActionRowComponents((actrow) =>
172+
actrow.addComponents(supportButton),
173+
);
174+
175+
await interaction.editReply({
176+
flags: MessageFlags.Ephemeral | MessageFlags.IsComponentsV2,
177+
components: [container],
178+
});
179+
return;
180+
}
181+
}
182+
183+
const premiumSince = member?.premiumSince;
184+
const isActiveBooster =
185+
booster.active && booster.boostCounts > 0 && !!premiumSince;
186+
128187
const embed = new EmbedBuilder()
129188
.setColor(booster.active ? 0xf47fff : 0x99aab5)
130189
.setTitle(`Booster Info: ${user.username}`)
131190
.setThumbnail(avatarUrl)
132191
.addFields(
133-
{ name: "Status", value: booster.active ? "🟢 Active" : "🔴 Inactive", inline: true },
192+
{
193+
name: "Status",
194+
value: isActiveBooster ? "🟢 Active" : "🔴 Inactive",
195+
inline: true,
196+
},
134197
{
135198
name: "Custom Role",
136-
value: booster.customRole ? `<@&${booster.customRole.discordRoleId}>` : "None",
199+
value: booster.customRole
200+
? `<@&${booster.customRole.discordRoleId}>`
201+
: "None",
202+
inline: true,
203+
},
204+
{
205+
name: "Boosting since",
206+
value: premiumSince
207+
? `<t:${Math.floor(premiumSince.getTime() / 1000)}:D>`
208+
: "Not currently boosting",
209+
inline: true,
210+
},
211+
{
212+
name: "Boosts Counts",
213+
value: booster.boostCounts.toString(),
137214
inline: true,
138215
},
139-
{ name: "Boosting since", value: `<t:${Math.floor(member!.premiumSince!.getTime() / 1000)}:D>`, inline: true},
140-
{ name: "Boosts Counts", value: booster.boostCounts.toString(), inline: true}
141216
)
142217
.setTimestamp();
143218

@@ -149,32 +224,42 @@ export default new Command({
149224
const user = interaction.options.getUser("user", true);
150225
const amount = interaction.options.getInteger("amount", true);
151226

152-
const targetMember = await discordGuild.members.fetch(user.id).catch(() => null);
227+
const targetMember = await discordGuild.members
228+
.fetch(user.id)
229+
.catch(() => null);
153230
if (!targetMember?.premiumSince) {
154231
await interaction.editReply({
155232
content: `${user} is not currently boosting this server with Nitro, so boosts can't be added for them.`,
156233
});
157234
return;
158235
}
159236

160-
await registerBoost(user.id, discordGuild.id, discordGuild.name, discordGuild.iconURL());
237+
const registered = await registerBoost(
238+
user.id,
239+
discordGuild.id,
240+
discordGuild.name,
241+
discordGuild.iconURL(),
242+
);
161243

162-
const updated = await addBoostCount(user.id, discordGuild.id, amount);
244+
const updated =
245+
amount > 1
246+
? await addBoostCount(user.id, discordGuild.id, amount - 1)
247+
: registered;
163248
if (!updated) {
164-
await interaction.editReply({ content: "Failed to update boost count." });
249+
await interaction.editReply({
250+
content: "Failed to update boost count.",
251+
});
165252
return;
166253
}
167254

168255
const boostWord = amount === 1 ? "boost" : "boosts";
169256
const container = new ContainerBuilder()
170257
.setAccentColor(0xe642a4)
171258
.addTextDisplayComponents(
259+
new TextDisplayBuilder().setContent(`**Boost successfully added!**`),
172260
new TextDisplayBuilder().setContent(
173-
`**Boost successfully added!**`
261+
`We've successfully added ${amount} ${boostWord} to ${user}'s profile.`,
174262
),
175-
new TextDisplayBuilder().setContent(
176-
`We've successfully added ${amount} ${boostWord} to ${user}'s profile.`
177-
)
178263
);
179264

180265
await interaction.editReply({
@@ -190,7 +275,9 @@ export default new Command({
190275

191276
const updated = await removeBoostCount(user.id, discordGuild.id, amount);
192277
if (!updated) {
193-
await interaction.editReply({ content: `No booster record found for ${user.tag}.` });
278+
await interaction.editReply({
279+
content: `No booster record found for ${user.tag}.`,
280+
});
194281
return;
195282
}
196283

@@ -211,14 +298,26 @@ export default new Command({
211298
.setColor(0xf47fff)
212299
.setTitle("Server Boost Statistics")
213300
.addFields(
214-
{ name: "Current Boosters", value: String(activeBoosters.length), inline: true },
215-
{ name: "Total Boosts (All Time)", value: String(totalBoosts), inline: true },
216-
{ name: "Unique Boosters (All Time)", value: String(allBoosters.length), inline: true }
301+
{
302+
name: "Current Boosters",
303+
value: String(activeBoosters.length),
304+
inline: true,
305+
},
306+
{
307+
name: "Total Boosts (All Time)",
308+
value: String(totalBoosts),
309+
inline: true,
310+
},
311+
{
312+
name: "Unique Boosters (All Time)",
313+
value: String(allBoosters.length),
314+
inline: true,
315+
},
217316
)
218317
.setTimestamp();
219318

220319
await interaction.editReply({ embeds: [embed] });
221320
return;
222321
}
223322
},
224-
})
323+
});

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import fs from "fs";
66
import { fileURLToPath, pathToFileURL } from "url";
77
import { logger } from "./libs/logger.js";
88
import chalk from "chalk";
9+
import { loadLoops } from "./libs/loops.js";
910

1011
const __dirname = fileURLToPath(new URL(".", import.meta.url));
1112

@@ -99,6 +100,7 @@ const eventFiles = fs
99100
}
100101

101102
await loadCommands();
103+
await loadLoops();
102104

103105
try {
104106
client.login(process.env.BOT_TOKEN);

0 commit comments

Comments
 (0)