import { SlashCommandBuilder, Interaction, CommandInteraction, AutocompleteInteraction, GuildMember, EmbedBuilder, MessageFlags, ChatInputCommandInteraction, ModalSubmitFields } 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") .addStringOption(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") ) .addAttachmentOption((option) => option .setName("calendar-entry") .setDescription("Optional, you can upload a iCal file and the from and to-values are read from it.") ) ) .addSubcommand((subcommand) => subcommand .setName("list") .setDescription("Lists all playdates") .addStringOption(GroupSelection.createOptionSetup()) ) .addSubcommand((subcommand) => subcommand .setName("remove") .setDescription("Removes a playdate") .addStringOption(GroupSelection.createOptionSetup()) .addIntegerOption((option) => option .setName("playdate") .setDescription("Selects a playdate") .setRequired(true) .setAutocomplete(true) ) ); } async execute(interaction: ChatInputCommandInteraction): Promise { 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 { const fromDate = Date.parse(interaction.options.get("from")?.value ?? ''); const toDate = Date.parse(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."); } const playdate: Partial = { group: group, from_time: new Date(fromDate), to_time: new Date(toDate), } const id = Container.get(PlaydateRepository.name).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.") .setFooter({ text: `Group: ${group.name}` }) await interaction.reply({ embeds: [ embed ], flags: MessageFlags.Ephemeral, }) } async handleAutocomplete(interaction: AutocompleteInteraction): Promise { const option = interaction.options.getFocused(true); if (option.name == "group") { await GroupSelection.handleAutocomplete(interaction); return; } if (option.name != 'playdate') { return; } const groupname = interaction.options.getString("group") const group = Container.get(GroupRepository.name).findGroupByName((groupname ?? '').toString()); if (!group) { throw new UserError("No group found"); } const playdates = Container.get(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.name).findFromGroup(group); const embed = new EmbedBuilder() .setTitle("The next playdates:") .setFields( playdates.map((playdate) => { return { name: `${playdate.from_time.toLocaleString()} - ${playdate.to_time.toLocaleString()}`, value: `` } }) ) .setFooter({ text: `Group: ${group.name}` }) await interaction.reply({ embeds: [ embed ], flags: MessageFlags.Ephemeral, }) } private async delete(interaction: ChatInputCommandInteraction, group: GroupModel): Promise { const playdateId = interaction.options.getInteger("playdate", true) const repo = Container.get(PlaydateRepository.name); const selected = repo.getById(playdateId); if (!selected) { throw new UserError("No playdate found"); } console.log(selected, group); 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, }) } }