diff --git a/src/main/java/com/eternalcode/discordapp/config/AppConfig.java b/src/main/java/com/eternalcode/discordapp/config/AppConfig.java index 44a1ffd0..76b3339e 100644 --- a/src/main/java/com/eternalcode/discordapp/config/AppConfig.java +++ b/src/main/java/com/eternalcode/discordapp/config/AppConfig.java @@ -53,6 +53,9 @@ public static class EmbedSettings { @Description("# Settings of the success embeds") public SuccessEmbed successEmbed = new SuccessEmbed(); + @Description("# Settings of the meeting embeds") + public MeetingEmbed meetingEmbed = new MeetingEmbed(); + @Contextual public static class ErrorEmbed { public String thumbnail = "https://i.imgur.com/2oTkWsr.png"; @@ -64,6 +67,12 @@ public static class SuccessEmbed { public String thumbnail = "https://i.imgur.com/QkNxIL3.png"; public String color = "#00ff77"; } + + @Contextual + public static class MeetingEmbed { + public String thumbnail = "https://imgur.com/a/fd0ukx7"; + public String color = "#62cdff"; + } } @Contextual diff --git a/src/main/java/com/eternalcode/discordapp/meeting/MeetingNotificationType.java b/src/main/java/com/eternalcode/discordapp/meeting/MeetingNotificationType.java new file mode 100644 index 00000000..ed31b72e --- /dev/null +++ b/src/main/java/com/eternalcode/discordapp/meeting/MeetingNotificationType.java @@ -0,0 +1,16 @@ +package com.eternalcode.discordapp.meeting; + +public enum MeetingNotificationType { + + DM, + SERVER, + BOTH; + + public boolean isDmNotify() { + return this == DM || this == BOTH; + } + + public boolean isServerNotify() { + return this == SERVER || this == BOTH; + } +} diff --git a/src/main/java/com/eternalcode/discordapp/meeting/MeetingService.java b/src/main/java/com/eternalcode/discordapp/meeting/MeetingService.java new file mode 100644 index 00000000..8352eaad --- /dev/null +++ b/src/main/java/com/eternalcode/discordapp/meeting/MeetingService.java @@ -0,0 +1,42 @@ +package com.eternalcode.discordapp.meeting; + +import com.eternalcode.discordapp.config.AppConfig; +import com.eternalcode.discordapp.config.ConfigManager; +import com.eternalcode.discordapp.meeting.command.child.CreateChild; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.channel.Channel; + +import java.awt.*; +import java.time.Instant; +import java.util.ArrayList; + +public class MeetingService { + + private final AppConfig appConfig; + private final ConfigManager configManager; + private final CreateChild createChild; + + public MeetingService(AppConfig appConfig, ConfigManager configManager, CreateChild createChild) { + this.appConfig = appConfig; + this.configManager = configManager; + this.createChild = createChild; + } + + public void createMeeting(String title, String description, String dateTime, Member requester, Member chairperson, Channel announcementChannel) { + ArrayList presentMembers = new ArrayList<>(); + ArrayList absentMembers = new ArrayList<>(); + + MessageEmbed embed = new EmbedBuilder() + .setTitle("📅 | Meeting requested") + .setColor(Color.decode(this.appConfig.embedSettings.meetingEmbed.color)) + .setThumbnail(this.appConfig.embedSettings.meetingEmbed.thumbnail) + .setDescription("") + .addField("Present", "", true) + .addField("Absent", "", true) + .setFooter("Requested by " + requester.getUser().getName(), requester.getAvatarUrl()) + .setTimestamp(Instant.now()) + .build(); + } +} diff --git a/src/main/java/com/eternalcode/discordapp/meeting/MeetingUser.java b/src/main/java/com/eternalcode/discordapp/meeting/MeetingUser.java new file mode 100644 index 00000000..2400d0eb --- /dev/null +++ b/src/main/java/com/eternalcode/discordapp/meeting/MeetingUser.java @@ -0,0 +1,37 @@ +package com.eternalcode.discordapp.meeting; + +import net.dzikoysk.cdn.entity.Contextual; +import net.dzikoysk.cdn.entity.Exclude; + +@Contextual +public class MeetingUser { + + private Long discordId; + private MeetingNotificationType notificationType; + private Boolean isPresent; + + public MeetingUser(Long discordId, MeetingNotificationType notificationType, Boolean isPresent) { + this.discordId = discordId; + this.notificationType = notificationType; + this.isPresent = isPresent; + } + + public MeetingUser() {} + + public MeetingNotificationType getNotificationType() { + return this.notificationType; + } + + @Exclude + public void setNotificationType(MeetingNotificationType notificationType) { + this.notificationType = notificationType; + } + + public Long getDiscordId() { + return this.discordId; + } + + public Boolean getIsPresent() { + return this.isPresent; + } +} diff --git a/src/main/java/com/eternalcode/discordapp/meeting/command/MeetingCommand.java b/src/main/java/com/eternalcode/discordapp/meeting/command/MeetingCommand.java new file mode 100644 index 00000000..c3f2d602 --- /dev/null +++ b/src/main/java/com/eternalcode/discordapp/meeting/command/MeetingCommand.java @@ -0,0 +1,48 @@ +package com.eternalcode.discordapp.meeting.command; + +import com.eternalcode.discordapp.config.AppConfig; +import com.eternalcode.discordapp.meeting.MeetingService; +import com.eternalcode.discordapp.meeting.command.child.CreateChild; +import com.eternalcode.discordapp.meeting.command.child.NotificationChild; +import com.jagrosh.jdautilities.command.SlashCommand; +import com.jagrosh.jdautilities.command.SlashCommandEvent; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.MessageEmbed; + +import java.awt.*; +import java.time.Instant; + +public class MeetingCommand extends SlashCommand { + + private final AppConfig appConfig; + private final MeetingService meetingService; + + public MeetingCommand(AppConfig appConfig, MeetingService meetingService) { + this.appConfig = appConfig; + this.meetingService = meetingService; + + this.name = "meeting"; + this.help = "Sheduling meetings and reminds team members about it"; + this.userPermissions = new Permission[]{ Permission.MESSAGE_MANAGE }; + + this.children = new SlashCommand[]{ + new CreateChild(this.appConfig, this.meetingService), + new NotificationChild() + }; + } + + @Override + public void execute(SlashCommandEvent event) { + + MessageEmbed build = new EmbedBuilder() + .setTitle("📅 | Dzisiaj spotkanie!") + .setColor(Color.decode(this.appConfig.embedSettings.successEmbed.color)) + .setThumbnail(this.appConfig.embedSettings.successEmbed.thumbnail) + .addField("Będę obecny", "", true) + .addField("Nie będzie mnie", "", true) + .setFooter("Requested by " + event.getUser().getName(), event.getUser().getAvatarUrl()) + .setTimestamp(Instant.now()) + .build(); + } +} diff --git a/src/main/java/com/eternalcode/discordapp/meeting/command/child/CreateChild.java b/src/main/java/com/eternalcode/discordapp/meeting/command/child/CreateChild.java new file mode 100644 index 00000000..e8cdda0d --- /dev/null +++ b/src/main/java/com/eternalcode/discordapp/meeting/command/child/CreateChild.java @@ -0,0 +1,86 @@ +package com.eternalcode.discordapp.meeting.command.child; + +import com.eternalcode.discordapp.config.AppConfig; +import com.eternalcode.discordapp.meeting.MeetingService; +import com.jagrosh.jdautilities.command.SlashCommand; +import com.jagrosh.jdautilities.command.SlashCommandEvent; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.channel.Channel; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.interactions.components.ActionRow; +import net.dv8tion.jda.api.interactions.components.text.TextInput; +import net.dv8tion.jda.api.interactions.components.text.TextInputStyle; +import net.dv8tion.jda.api.interactions.modals.Modal; + +import java.util.List; + +public class CreateChild extends SlashCommand { + + private final AppConfig appConfig; + private final MeetingService meetingService; + + public CreateChild(AppConfig appConfig, MeetingService meetingService) { + this.appConfig = appConfig; + this.meetingService = meetingService; + + this.name = "create"; + this.help = "Create meeting"; + this.userPermissions = new Permission[]{ Permission.ADMINISTRATOR }; + + this.options = List.of( + new OptionData(OptionType.CHANNEL, "channel", "Notification channel") + .setRequired(false), + + new OptionData(OptionType.USER, "chairperson", "Chairperson of meeting") + .setRequired(true) + ); + } + + @Override + public void execute(SlashCommandEvent event) { + event.replyModal(this.getModal()).queue(); + + Member chairperson = event.getOption("chairperson").getAsMember(); + Channel announcementChannel = event.getOption("channel").getAsChannel(); + + this.meetingService.createMeeting(this.getSubject(), this.getDescription(), this.getDateTime(), (Member) event.getUser(), chairperson, announcementChannel); + } + + Modal getModal() { + TextInput subject = TextInput.create("subject", "Subject", TextInputStyle.SHORT) + .setPlaceholder("Subject of meeting") + .setRequiredRange(1, 100) + .setRequired(true) + .build(); + + TextInput description = TextInput.create("description", "Description", TextInputStyle.PARAGRAPH) + .setPlaceholder("Description of meeting") + .setRequiredRange(30, 1000) + .setRequired(false) + .build(); + + TextInput dateTime = TextInput.create("dateTime", "Date and time", TextInputStyle.SHORT) + .setPlaceholder("01/01/2024 19:00") + .setRequiredRange(16, 16) + .setRequired(true) + .build(); + + return Modal.create("meetingModal", "Create meeting") + .addComponents(ActionRow.of(subject), ActionRow.of(description), ActionRow.of(dateTime)) + .build(); + } + + public String getSubject() { + return this.getModal().getComponents().get(1).toString(); + } + + public String getDescription() { + return this.getModal().getComponents().get(2).toString(); + } + + public String getDateTime() { + return this.getModal().getComponents().get(3).toString(); + } +} diff --git a/src/main/java/com/eternalcode/discordapp/meeting/command/child/NotificationChild.java b/src/main/java/com/eternalcode/discordapp/meeting/command/child/NotificationChild.java new file mode 100644 index 00000000..5ea69dd6 --- /dev/null +++ b/src/main/java/com/eternalcode/discordapp/meeting/command/child/NotificationChild.java @@ -0,0 +1,30 @@ +package com.eternalcode.discordapp.meeting.command.child; + +import com.eternalcode.discordapp.meeting.MeetingNotificationType; +import com.jagrosh.jdautilities.command.SlashCommand; +import com.jagrosh.jdautilities.command.SlashCommandEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +import java.util.List; + +public class NotificationChild extends SlashCommand { + + public NotificationChild() { + this.name = "notification"; + + this.options = List.of( + new OptionData(OptionType.STRING, "notification-type", "type of notification send by review system") + .addChoice("DM", MeetingNotificationType.DM.toString()) + .addChoice("SERVER", MeetingNotificationType.SERVER.toString()) + .addChoice("BOTH", MeetingNotificationType.BOTH.toString()) + .setRequired(true) + ); + } + + @Override + public void execute(SlashCommandEvent slashCommandEvent) { + String notificationTypeString = slashCommandEvent.getOption("notification-type").getAsString(); + MeetingNotificationType notificationType = MeetingNotificationType.valueOf(notificationTypeString); + } +}