211 lines
No EOL
7.7 KiB
TypeScript
211 lines
No EOL
7.7 KiB
TypeScript
import {
|
|
SlashCommandBuilder,
|
|
Interaction,
|
|
CommandInteraction,
|
|
AutocompleteInteraction,
|
|
GuildMember,
|
|
EmbedBuilder, MessageFlags, ChatInputCommandInteraction, ModalSubmitFields, time, User
|
|
} from "discord.js";
|
|
import {AutocompleteCommand, ChatInteractionCommand, Command} from "./Command";
|
|
import {Container} from "../../Container/Container";
|
|
import {GroupRepository} from "../../Repositories/GroupRepository";
|
|
import {GroupSelection} from "../CommandPartials/GroupSelection";
|
|
import {setFlagsFromString} from "node:v8";
|
|
import {UserError} from "../UserError";
|
|
import Playdate from "../../Database/tables/Playdate";
|
|
import {PlaydateModel} from "../../Models/PlaydateModel";
|
|
import {PlaydateRepository} from "../../Repositories/PlaydateRepository";
|
|
import {GroupModel} from "../../Models/GroupModel";
|
|
import playdate from "../../Database/tables/Playdate";
|
|
|
|
export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInteractionCommand {
|
|
static REGEX = [
|
|
|
|
]
|
|
|
|
definition(): SlashCommandBuilder {
|
|
// @ts-ignore
|
|
return new SlashCommandBuilder()
|
|
.setName("playdates")
|
|
.setDescription("Manage your playdates")
|
|
.addSubcommand((subcommand) => subcommand
|
|
.setName("create")
|
|
.setDescription("Creates a new playdate")
|
|
.addIntegerOption(GroupSelection.createOptionSetup())
|
|
.addStringOption((option) => option
|
|
.setName("from")
|
|
.setDescription("Defines the start date & time. Format: YYYY-MM-DD HH:mm")
|
|
)
|
|
.addStringOption((option) => option
|
|
.setName("to")
|
|
.setDescription("Defines the end date & time. Format: YYYY-MM-DD HH:mm")
|
|
)
|
|
)
|
|
.addSubcommand((subcommand) => subcommand
|
|
.setName("list")
|
|
.setDescription("Lists all playdates")
|
|
.addIntegerOption(GroupSelection.createOptionSetup())
|
|
)
|
|
.addSubcommand((subcommand) => subcommand
|
|
.setName("remove")
|
|
.setDescription("Removes a playdate")
|
|
.addIntegerOption(GroupSelection.createOptionSetup())
|
|
.addIntegerOption((option) => option
|
|
.setName("playdate")
|
|
.setDescription("Selects a playdate")
|
|
.setRequired(true)
|
|
.setAutocomplete(true)
|
|
)
|
|
);
|
|
}
|
|
|
|
async execute(interaction: ChatInputCommandInteraction): Promise<void> {
|
|
const group = GroupSelection.getGroup(interaction);
|
|
|
|
switch (interaction.options.getSubcommand()) {
|
|
case "create":
|
|
await this.create(interaction, group);
|
|
break;
|
|
case "remove":
|
|
await this.delete(interaction, group);
|
|
break;
|
|
case "list":
|
|
await this.list(interaction, group);
|
|
break;
|
|
default:
|
|
throw new UserError("This subcommand is not yet implemented.");
|
|
}
|
|
}
|
|
|
|
async create(interaction: CommandInteraction, group: GroupModel): Promise<void> {
|
|
const fromDate = Date.parse(<string>interaction.options.get("from")?.value ?? '');
|
|
const toDate = Date.parse(<string>interaction.options.get("to")?.value ?? '');
|
|
|
|
if (isNaN(fromDate)) {
|
|
throw new UserError("No date or invalid date format for the from parameter.");
|
|
}
|
|
|
|
if (isNaN(toDate)) {
|
|
throw new UserError("No date or invalid date format for the to parameter.");
|
|
}
|
|
|
|
if (fromDate > toDate) {
|
|
throw new UserError("The to-date can't be earlier than the from-date");
|
|
}
|
|
|
|
const playdateRepo = Container.get<PlaydateRepository>(PlaydateRepository.name);
|
|
|
|
const collidingTimes = playdateRepo.findPlaydatesInRange(fromDate, toDate, group);
|
|
if (collidingTimes.length > 0) {
|
|
throw new UserError("The playdate collides with another playdate. Please either remove the old one or choose a different time.")
|
|
}
|
|
|
|
const playdate: Partial<PlaydateModel> = {
|
|
group: group,
|
|
from_time: new Date(fromDate),
|
|
to_time: new Date(toDate),
|
|
}
|
|
|
|
const id = playdateRepo.create(playdate);
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setTitle("Created a play-date.")
|
|
.setDescription(":white_check_mark: Your playdate has been created! You and your group get notified, when its time.")
|
|
.setFields({
|
|
name: "Created playdate",
|
|
value: `${time(new Date(fromDate),'F')} - ${time(new Date(toDate), 'F')}`,
|
|
})
|
|
.setFooter({
|
|
text: `Group: ${group.name}`
|
|
})
|
|
|
|
await interaction.reply({
|
|
embeds: [
|
|
embed
|
|
],
|
|
flags: MessageFlags.Ephemeral,
|
|
})
|
|
}
|
|
|
|
async handleAutocomplete(interaction: AutocompleteInteraction): Promise<void> {
|
|
const option = interaction.options.getFocused(true);
|
|
if (option.name == "group") {
|
|
await GroupSelection.handleAutocomplete(interaction);
|
|
return;
|
|
}
|
|
|
|
if (option.name != 'playdate') {
|
|
return;
|
|
}
|
|
|
|
const group = GroupSelection.getGroup(interaction);
|
|
|
|
const playdates = Container.get<PlaydateRepository>(PlaydateRepository.name).findFromGroup(group);
|
|
await interaction.respond(
|
|
playdates.map(playdate => {
|
|
return {
|
|
name: `${playdate.from_time.toLocaleString()} - ${playdate.to_time.toLocaleString()}`,
|
|
value: playdate.id
|
|
}
|
|
})
|
|
)
|
|
}
|
|
|
|
private async list(interaction: ChatInputCommandInteraction, group: GroupModel) {
|
|
const playdates = Container.get<PlaydateRepository>(PlaydateRepository.name).findFromGroup(group);
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setTitle("The next playdates:")
|
|
.setFields(
|
|
playdates.map((playdate) =>
|
|
{
|
|
return {
|
|
name: `${time(playdate.from_time, 'F')} - ${time(playdate.to_time, 'F')}`,
|
|
value: `${time(playdate.from_time, 'R')}`
|
|
}
|
|
})
|
|
)
|
|
.setFooter({
|
|
text: `Group: ${group.name}`
|
|
})
|
|
|
|
await interaction.reply({
|
|
embeds: [
|
|
embed
|
|
],
|
|
flags: MessageFlags.Ephemeral,
|
|
})
|
|
}
|
|
|
|
private async delete(interaction: ChatInputCommandInteraction, group: GroupModel): Promise<void> {
|
|
const playdateId = interaction.options.getInteger("playdate", true)
|
|
|
|
const repo = Container.get<PlaydateRepository>(PlaydateRepository.name);
|
|
const selected = repo.getById(playdateId);
|
|
if (!selected) {
|
|
throw new UserError("No playdate found");
|
|
}
|
|
|
|
if (selected.group?.id != group.id) {
|
|
throw new UserError("No playdate found");
|
|
}
|
|
|
|
repo.delete(playdateId);
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setTitle("Playdate deleted")
|
|
.setDescription(
|
|
`:x: Deleted \`${selected.from_time.toLocaleString()} - ${selected.to_time.toLocaleString()}\``
|
|
)
|
|
.setFooter({
|
|
text: `Group: ${group.name}`
|
|
})
|
|
|
|
await interaction.reply({
|
|
embeds: [
|
|
embed
|
|
],
|
|
flags: MessageFlags.Ephemeral,
|
|
})
|
|
}
|
|
} |