Compare commits

..

9 commits

Author SHA1 Message Date
Slincnik
50d8e2cd90
Merge f54f50565c into 12054c35c5 2025-01-16 18:35:59 +03:00
Slincnik
f54f50565c
refactor: delete unusable command 2025-01-16 18:34:53 +03:00
Slincnik
50f33d2509
fix(birthdate): fixing args when clear birthdate 2025-01-16 18:33:00 +03:00
Slincnik
af5de7d886
refactor: refactoring birthdate command 2025-01-16 18:24:50 +03:00
Slincnik
b104578259
fix: fixing extenders func types 2025-01-16 18:23:51 +03:00
Slincnik
33363f64fc
fix(models): birthdate on user has maybe null 2025-01-16 18:23:03 +03:00
Slincnik
4272ae63b0
feat: added support to giveaways manager 2025-01-16 17:38:30 +03:00
Slincnik
0327e8069f
feat: added support discord-player and him events 2025-01-16 17:27:23 +03:00
Slincnik
cd5d1f2e66
fix: fixing console log in debug logger 2025-01-16 17:15:46 +03:00
8 changed files with 181 additions and 27 deletions

View file

@ -0,0 +1,143 @@
import { replyError, replySuccess } from "@/helpers/extenders.js";
import { CommandData, SlashCommandProps } from "@/types.js";
import useClient from "@/utils/use-client.js";
import { ApplicationCommandOptionType, ApplicationIntegrationType, InteractionContextType } from "discord.js";
const client = useClient();
export const data: CommandData = {
name: "birthdate",
description: client.translate("economy/birthdate:DESCRIPTION"),
// eslint-disable-next-line camelcase
description_localizations: {
uk: client.translate("economy/birthdate:DESCRIPTION", { lng: "uk-UA" }),
ru: client.translate("economy/birthdate:DESCRIPTION", { lng: "ru-RU" }),
},
// eslint-disable-next-line camelcase
integration_types: [ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall],
contexts: [InteractionContextType.BotDM, InteractionContextType.Guild, InteractionContextType.PrivateChannel],
options: [
{
name: "day",
description: client.translate("economy/birthdate:DAY"),
type: ApplicationCommandOptionType.Integer,
// eslint-disable-next-line camelcase
description_localizations: {
uk: client.translate("economy/birthdate:DAY", { lng: "uk-UA" }),
ru: client.translate("economy/birthdate:DAY", { lng: "ru-RU" }),
},
},
{
name: "month",
description: client.translate("economy/birthdate:MONTH"),
type: ApplicationCommandOptionType.Integer,
// eslint-disable-next-line camelcase
description_localizations: {
uk: client.translate("economy/birthdate:MONTH", { lng: "uk-UA" }),
ru: client.translate("economy/birthdate:MONTH", { lng: "ru-RU" }),
},
choices: [
{ name: client.translate("misc:MONTHS:JANUARY"), value: 1 },
{ name: client.translate("misc:MONTHS:FEBRUARY"), value: 2 },
{ name: client.translate("misc:MONTHS:MARCH"), value: 3 },
{ name: client.translate("misc:MONTHS:APRIL"), value: 4 },
{ name: client.translate("misc:MONTHS:MAY"), value: 5 },
{ name: client.translate("misc:MONTHS:JUNE"), value: 6 },
{ name: client.translate("misc:MONTHS:JULY"), value: 7 },
{ name: client.translate("misc:MONTHS:AUGUST"), value: 8 },
{ name: client.translate("misc:MONTHS:SEPTEMBER"), value: 9 },
{ name: client.translate("misc:MONTHS:OCTOBER"), value: 10 },
{ name: client.translate("misc:MONTHS:NOVEMBER"), value: 11 },
{ name: client.translate("misc:MONTHS:DECEMBER"), value: 12 },
],
},
{
name: "year",
description: client.translate("economy/birthdate:YEAR"),
type: ApplicationCommandOptionType.Integer,
// eslint-disable-next-line camelcase
description_localizations: {
uk: client.translate("economy/birthdate:YEAR", { lng: "uk-UA" }),
ru: client.translate("economy/birthdate:YEAR", { lng: "ru-RU" }),
},
},
{
name: "clear",
type: ApplicationCommandOptionType.Boolean,
description: client.translate("economy/birthdate:CLEAR"),
// eslint-disable-next-line camelcase
description_localizations: {
uk: client.translate("economy/birthdate:CLEAR", { lng: "uk-UA" }),
ru: client.translate("economy/birthdate:CLEAR", { lng: "ru-RU" }),
},
},
{
name: "ephemeral",
type: ApplicationCommandOptionType.Boolean,
description: client.translate("misc:EPHEMERAL_RESPONSE"),
// eslint-disable-next-line camelcase
description_localizations: {
uk: client.translate("misc:EPHEMERAL_RESPONSE", { lng: "uk-UA" }),
ru: client.translate("misc:EPHEMERAL_RESPONSE", { lng: "ru-RU" }),
},
},
],
};
export const run = async ({ interaction, client }: SlashCommandProps) => {
await interaction.deferReply({
ephemeral: interaction.options.getBoolean("ephemeral") || false,
});
const userData = await client.getUserData(interaction.user.id);
if (interaction.options.getBoolean("clear")) {
userData.birthdate = null;
await userData.save();
return replySuccess(
interaction,
"economy/birthdate:SUCCESS",
{ date: "none" },
{
edit: true,
},
);
}
const day = interaction.options.getInteger("day")!,
month = interaction.options.getInteger("month")!,
year = interaction.options.getInteger("year")!,
date = new Date(year, month - 1, day);
date.setHours(12);
const d = Math.floor(date.getTime() / 1000);
if (!(day === date.getDate() && month - 1 === date.getMonth() && year === date.getFullYear())) {
return replyError(interaction, "economy/birthdate:INVALID_DATE", null, { edit: true });
}
if (date.getTime() > Date.now()) {
return replyError(interaction, "economy/birthdate:DATE_TOO_HIGH", null, { edit: true });
}
if (date.getTime() < Date.now() - 2.523e12) {
replyError(interaction, "economy/birthdate:DATE_TOO_LOW", null, { edit: true });
}
userData.birthdate = d;
await userData.save();
return replySuccess(
interaction,
"economy/birthdate:SUCCESS",
{
date: `<t:${d}:D>`,
},
{
edit: true,
},
);
};

View file

@ -1,8 +0,0 @@
export const data = {
name: "8ball",
description: "8ball",
};
export const run = () => {
console.log("8ball");
};

View file

@ -63,9 +63,15 @@ export class EventHandler {
}
$registerEvents() {
for (const { data, run } of this.events) {
if (data.once) this.client.once(data.name, (...args) => run(...args));
else this.client.on(data.name, (...args) => run(...args));
}
const player = useMainPlayer();
this.events.forEach(event => {
if (event.data.player) {
player.events.on(event.data.name as keyof GuildQueueEvents, event.run);
} else if (event.data.once) {
this.client.once(event.data.name, event.run);
} else {
this.client.on(event.data.name, event.run);
}
});
}
}

View file

@ -2,7 +2,7 @@ import { BaseInteraction, CacheType, Interaction, InteractionReplyOptions, Messa
import useClient from "@/utils/use-client.js";
interface Options extends InteractionReplyOptions {
prefixEmoji: string;
prefixEmoji?: string;
locale?: string;
edit?: boolean;
mention?: boolean;
@ -20,7 +20,7 @@ const getAppEmojis = () => {
return client.application.emojis.cache;
};
const formatReply = (prefixEmoji: string, message: string) => {
const formatReply = (message: string, prefixEmoji?: string) => {
const emojis = getAppEmojis();
const emoji = emojis.find(emoji => emoji.name === prefixEmoji);
return prefixEmoji ? `${emoji?.toString()} ${message}` : `${message}`;
@ -28,7 +28,7 @@ const formatReply = (prefixEmoji: string, message: string) => {
export const getUsername = (user: User) => (user.discriminator === "0" ? user.username : user.tag);
export const replyTranslated = async <T extends CacheType = CacheType>(context: Interaction<T> | Message, key: string, args: unknown[], options: Options) => {
export const replyTranslated = async <T extends CacheType = CacheType>(context: Interaction<T> | Message, key: string, args: Record<string, unknown> | null, options: Options) => {
const client = useClient();
const locale = options.locale || client.configService.get("defaultLang");
const translated = client.translate(key, {
@ -36,7 +36,7 @@ export const replyTranslated = async <T extends CacheType = CacheType>(context:
...args,
});
const content = formatReply(options.prefixEmoji, translated);
const content = formatReply(translated, options.prefixEmoji);
if (context instanceof BaseInteraction) {
if (!context.isRepliable()) return;
@ -65,12 +65,10 @@ export const replyTranslated = async <T extends CacheType = CacheType>(context:
});
};
export const replySuccess = async <T extends CacheType = CacheType>(context: Interaction<T> | Message, key: string, args: unknown[], options: Options) => {
options.prefixEmoji = "success";
return await replyTranslated(context, key, args, options);
};
export const replySuccess = async <T extends CacheType = CacheType>
(context: Interaction<T> | Message, key: string, args: Record<string, unknown> | null,
options: Options = { prefixEmoji: "success" }) => await replyTranslated(context, key, args, options);
export const replyError = async <T extends CacheType = CacheType>(context: Interaction<T> | Message, key: string, args: unknown[], options: Options) => {
options.prefixEmoji = "error";
return await replyTranslated(context, key, args, options);
};
export const replyError = async <T extends CacheType = CacheType>
(context: Interaction<T> | Message, key: string, args: Record<string, unknown> | null,
options: Options = { prefixEmoji: "error" }) => await replyTranslated(context, key, args, options);

View file

@ -37,7 +37,6 @@ export default {
debug(...content: unknown[]) {
const client = useClient();
const isProd = client.configService.get("production");
console.log(isProd);
if (isProd) return;
return console.log(`[${format(Date.now())}]: ${logLevels.DEBUG} ${content.join(" ")}`);
},

View file

@ -35,7 +35,7 @@ export const data = {
const user = users.find(u => u.id === userID);
if (!user) return;
const userData = new Date(user.birthdate).getFullYear() <= 1970 ? new Date(user.birthdate * 1000) : new Date(user.birthdate);
const userData = new Date(user.birthdate!).getFullYear() <= 1970 ? new Date(user.birthdate! * 1000) : new Date(user.birthdate!);
const userYear = userData.getFullYear();
const userMonth = userData.getMonth();
const userDate = userData.getDate();

View file

@ -11,7 +11,7 @@ interface IUserSchema extends Document {
id: string;
rep: number;
bio: string;
birthdate: number;
birthdate: number | null;
lover: string;
registeredAt: number;
achievements: {

View file

@ -1,4 +1,5 @@
import { Client, ClientOptions } from "discord.js";
import { GiveawaysManager } from "discord-giveaways";
import { TOptionsBase } from "i18next";
import { Handlers } from "@/handlers/index.js";
import MongooseAdapter from "@/adapters/database/MongooseAdapter.js";
@ -7,6 +8,7 @@ import ConfigService from "@/services/config/index.js";
import InternationalizationService from "@/services/languages/index.js";
import { SUPER_CONTEXT } from "@/constants/index.js";
import { cacheRemindsData } from "@/types.js";
import { Player } from "discord-player";
export class ExtendedClient extends Client<true> {
configService = new ConfigService();
@ -22,6 +24,17 @@ export class ExtendedClient extends Client<true> {
},
) => string;
// @ts-ignore - because ExtendedClient != Client<boolean> from discord.js
giveaways = new GiveawaysManager(this, {
storage: "../../giveaways.json",
default: {
botsCanWin: false,
embedColor: this.configService.get("embed.color"),
embedColorEnd: "#FF0000",
reaction: "🎉",
},
});
constructor(options: ClientOptions) {
if (SUPER_CONTEXT.getStore()) {
return SUPER_CONTEXT.getStore() as ExtendedClient;
@ -29,6 +42,9 @@ export class ExtendedClient extends Client<true> {
super(options);
new Handlers(this);
// @ts-ignore - because ExtendedClient != Client<boolean> from discord.js
new Player(this);
SUPER_CONTEXT.enterWith(this);
}