From 48e2e705c2f687579170a0199ec786c22556c1ff Mon Sep 17 00:00:00 2001 From: Sheldan <5037282+Sheldan@users.noreply.github.com> Date: Sun, 17 Jul 2022 18:34:06 +0200 Subject: [PATCH] [SIS-6] adding ability to declare "no_time" for a meetup adding meetup id to meetup message refactoring meetup cancellation to be a command adding command to change the meetup time and notify meetup members fixing meetup components not being cleaned when cancelling or cleaning up changing label for no button --- .../module/meetup/commands/CancelMeetup.java | 111 +++++++++++ .../meetup/commands/ChangeMeetupTime.java | 173 ++++++++++++++++++ .../module/meetup/commands/ListMeetups.java | 2 +- .../commands/NotifyMeetupParticipants.java | 121 ++++++++++++ .../config/MeetupSlashCommandNames.java | 1 + .../NotMeetupOrganizerException.java | 15 ++ .../MeetupChangeTimeConfirmationListener.java | 78 ++++++++ .../listener/MeetupConfirmationListener.java | 37 ++-- .../listener/MeetupDecisionListener.java | 15 +- .../MeetupChangeTimeConfirmationModel.java | 21 +++ .../module/meetup/model/database/Meetup.java | 10 +- .../model/database/MeetupComponent.java | 40 ++++ .../meetup/model/database/MeetupDecision.java | 2 +- ...rticipator.java => MeetupParticipant.java} | 4 +- .../database/embed/MeetupComponentId.java | 25 +++ .../MeetupChangeTimeConfirmationPayload.java | 18 ++ .../model/template/MeetupMessageModel.java | 4 +- .../template/MeetupNotificationModel.java | 14 ++ .../MeetupTimeChangedNotificationModel.java | 17 ++ .../repository/MeetupComponentRepository.java | 10 + .../MeetupParticipatorRepository.java | 4 +- .../meetup/service/MeetupServiceBean.java | 159 ++++++++++++++-- .../MeetupComponentManagementServiceBean.java | 40 ++++ ...etupParticipatorManagementServiceBean.java | 17 +- .../resources/migrations/1.2.0/collection.xml | 11 ++ .../migrations/1.2.0/seedData/command.xml | 30 +++ .../migrations/1.2.0/seedData/data.xml | 10 + .../1.2.0/tables/meetup_component.xml | 37 ++++ .../1.2.0/tables/meetup_participator.xml | 16 ++ .../migrations/1.2.0/tables/tables.xml | 11 ++ .../resources/migrations/meetup-changeLog.xml | 1 + .../cancelMeetup_response_embed_en_US.ftl | 6 + ...meetup_cancel_notification_embed_en_US.ftl | 2 +- ...ngeMeetupTime_confirmation_embed_en_US.ftl | 25 +++ ...ngeMeetupTime_notification_embed_en_US.ftl | 13 ++ ...pants_notification_message_embed_en_US.ftl | 5 + ...eetupParticipants_response_embed_en_US.ftl | 6 + .../meetup_not_organizer_exception_en_US.ftl | 1 + .../general/meetup_display_embed_en_US.ftl | 14 +- .../cancelMeetup_response_text_en_US.ftl | 1 + .../help/cancelMeetup_description_en_US.ftl | 1 + .../help/cancelMeetup_long_help_en_US.ftl | 3 + .../cancelMeetup_parameter_meetupId_en_US.ftl | 1 + ..._cancel_notification_description_en_US.ftl | 0 ...angeMeetupTime_notification_text_en_US.ftl | 2 + .../changeMeetupTime_description_en_US.ftl | 1 + .../help/changeMeetupTime_long_help_en_US.ftl | 3 + ...ngeMeetupTime_parameter_meetupId_en_US.ftl | 1 + ...eetupTime_parameter_newTimeStamp_en_US.ftl | 1 + ...fyMeetupParticipants_description_en_US.ftl | 1 + ...tifyMeetupParticipants_long_help_en_US.ftl | 2 + ...pParticipants_parameter_meetupId_en_US.ftl | 1 + ...ts_parameter_notificationMessage_en_US.ftl | 1 + ...MeetupParticipants_response_text_en_US.ftl | 1 + ..._not_organizer_exception_message_en_US.ftl | 1 + .../meetup_display_description_en_US.ftl | 4 +- ...etup_message_cancel_button_label_en_US.ftl | 1 - .../meetup_message_id_display_en_US.ftl | 1 + .../meetup_message_no_button_label_en_US.ftl | 2 +- ...tup_message_no_time_button_label_en_US.ftl | 1 + 60 files changed, 1099 insertions(+), 57 deletions(-) create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/CancelMeetup.java create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/ChangeMeetupTime.java create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/NotifyMeetupParticipants.java create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/exception/NotMeetupOrganizerException.java create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupChangeTimeConfirmationListener.java create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/command/MeetupChangeTimeConfirmationModel.java create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupComponent.java rename application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/{MeetupParticipator.java => MeetupParticipant.java} (95%) create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/embed/MeetupComponentId.java create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/payload/MeetupChangeTimeConfirmationPayload.java create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupNotificationModel.java create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupTimeChangedNotificationModel.java create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/repository/MeetupComponentRepository.java create mode 100644 application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/management/MeetupComponentManagementServiceBean.java create mode 100644 application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/collection.xml create mode 100644 application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/seedData/command.xml create mode 100644 application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/seedData/data.xml create mode 100644 application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/meetup_component.xml create mode 100644 application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/meetup_participator.xml create mode 100644 application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/tables.xml create mode 100644 templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/cancelMeetup/cancelMeetup_response_embed_en_US.ftl rename templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/{general => commands/cancelMeetup}/meetup_cancel_notification_embed_en_US.ftl (87%) create mode 100644 templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_confirmation_embed_en_US.ftl create mode 100644 templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_notification_embed_en_US.ftl create mode 100644 templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_notification_message_embed_en_US.ftl create mode 100644 templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_response_embed_en_US.ftl create mode 100644 templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/exception/meetup_not_organizer_exception_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/cancelMeetup_response_text_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_description_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_long_help_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_parameter_meetupId_en_US.ftl rename templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/{general => commands/cancelMeetup}/meetup_cancel_notification_description_en_US.ftl (100%) create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_notification_text_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_description_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_long_help_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_parameter_meetupId_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_parameter_newTimeStamp_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_description_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_long_help_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_parameter_meetupId_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_parameter_notificationMessage_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_response_text_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/exception/meetup_not_organizer_exception_message_en_US.ftl delete mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_cancel_button_label_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_id_display_en_US.ftl create mode 100644 templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_no_time_button_label_en_US.ftl diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/CancelMeetup.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/CancelMeetup.java new file mode 100644 index 00000000..80efd9e8 --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/CancelMeetup.java @@ -0,0 +1,111 @@ +package dev.sheldan.sissi.module.meetup.commands; + +import dev.sheldan.abstracto.core.command.UtilityModuleDefinition; +import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; +import dev.sheldan.abstracto.core.command.config.CommandConfiguration; +import dev.sheldan.abstracto.core.command.config.HelpInfo; +import dev.sheldan.abstracto.core.command.config.Parameter; +import dev.sheldan.abstracto.core.command.config.SlashCommandConfig; +import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.execution.CommandResult; +import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.interaction.InteractionService; +import dev.sheldan.abstracto.core.utils.FutureUtils; +import dev.sheldan.sissi.module.meetup.config.MeetupFeatureDefinition; +import dev.sheldan.sissi.module.meetup.config.MeetupSlashCommandNames; +import dev.sheldan.sissi.module.meetup.exception.NotMeetupOrganizerException; +import dev.sheldan.sissi.module.meetup.model.database.Meetup; +import dev.sheldan.sissi.module.meetup.service.MeetupServiceBean; +import dev.sheldan.sissi.module.meetup.service.management.MeetupManagementServiceBean; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@Component +public class CancelMeetup extends AbstractConditionableCommand { + + private static final String MEETUP_ID_PARAMETER = "meetupId"; + private static final String CANCEL_MEETUP_COMMAND = "cancelMeetup"; + private static final String CANCEL_MEETUP_RESPONSE = "cancelMeetup_response"; + + @Autowired + private MeetupServiceBean meetupServiceBean; + + @Autowired + private SlashCommandParameterService slashCommandParameterService; + + @Autowired + private InteractionService interactionService; + + @Autowired + private MeetupManagementServiceBean meetupManagementServiceBean; + + @Override + public CompletableFuture executeAsync(CommandContext commandContext) { + Long meetupId = (Long) commandContext.getParameters().getParameters().get(0); + Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, commandContext.getGuild().getIdLong()); + if(!meetup.getOrganizer().getUserReference().getId().equals(commandContext.getAuthor().getIdLong())) { + throw new NotMeetupOrganizerException(); + } + return meetupServiceBean.cancelMeetup(meetup) + .thenApply(interactionHook -> CommandResult.fromSuccess()); + } + + @Override + public CompletableFuture executeSlash(SlashCommandInteractionEvent event) { + event.deferReply().queue(); + Long meetupId = slashCommandParameterService.getCommandOption(MEETUP_ID_PARAMETER, event, Integer.class).longValue(); + Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, event.getGuild().getIdLong()); + if(!meetup.getOrganizer().getUserReference().getId().equals(event.getMember().getIdLong())) { + throw new NotMeetupOrganizerException(); + } + return meetupServiceBean.cancelMeetup(meetup) + .thenCompose(unused -> FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(CANCEL_MEETUP_RESPONSE, new Object(), event.getHook()))) + .thenApply(interactionHook -> CommandResult.fromSuccess()); + } + + @Override + public CommandConfiguration getConfiguration() { + Parameter meetupIdParameter = Parameter + .builder() + .templated(true) + .name(MEETUP_ID_PARAMETER) + .type(Long.class) + .build(); + + List parameters = Arrays.asList(meetupIdParameter); + HelpInfo helpInfo = HelpInfo + .builder() + .templated(true) + .build(); + + SlashCommandConfig slashCommandConfig = SlashCommandConfig + .builder() + .enabled(true) + .rootCommandName(MeetupSlashCommandNames.MEETUP) + .commandName("cancel") + .build(); + + return CommandConfiguration.builder() + .name(CANCEL_MEETUP_COMMAND) + .module(UtilityModuleDefinition.UTILITY) + .templated(true) + .slashCommandConfig(slashCommandConfig) + .async(true) + .supportsEmbedException(true) + .causesReaction(true) + .parameters(parameters) + .help(helpInfo) + .build(); + } + + @Override + public FeatureDefinition getFeature() { + return MeetupFeatureDefinition.MEETUP; + } +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/ChangeMeetupTime.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/ChangeMeetupTime.java new file mode 100644 index 00000000..4f1cfa3b --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/ChangeMeetupTime.java @@ -0,0 +1,173 @@ +package dev.sheldan.sissi.module.meetup.commands; + +import dev.sheldan.abstracto.core.command.UtilityModuleDefinition; +import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; +import dev.sheldan.abstracto.core.command.config.CommandConfiguration; +import dev.sheldan.abstracto.core.command.config.HelpInfo; +import dev.sheldan.abstracto.core.command.config.Parameter; +import dev.sheldan.abstracto.core.command.config.SlashCommandConfig; +import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.execution.CommandResult; +import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.interaction.InteractionService; +import dev.sheldan.abstracto.core.service.ChannelService; +import dev.sheldan.abstracto.core.service.ComponentService; +import dev.sheldan.abstracto.core.templating.model.MessageToSend; +import dev.sheldan.abstracto.core.templating.service.TemplateService; +import dev.sheldan.abstracto.core.utils.FutureUtils; +import dev.sheldan.sissi.module.meetup.config.MeetupFeatureDefinition; +import dev.sheldan.sissi.module.meetup.config.MeetupSlashCommandNames; +import dev.sheldan.sissi.module.meetup.exception.MeetupPastTimeException; +import dev.sheldan.sissi.module.meetup.exception.NotMeetupOrganizerException; +import dev.sheldan.sissi.module.meetup.model.command.MeetupChangeTimeConfirmationModel; +import dev.sheldan.sissi.module.meetup.model.database.Meetup; +import dev.sheldan.sissi.module.meetup.service.MeetupServiceBean; +import dev.sheldan.sissi.module.meetup.service.management.MeetupManagementServiceBean; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.Instant; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@Component +public class ChangeMeetupTime extends AbstractConditionableCommand { + + private static final String CHANGE_MEETUP_TIME_COMMAND = "changeMeetupTime"; + private static final String MEETUP_ID_PARAMETER = "meetupId"; + private static final String MEETUP_NEW_TIMESTAMP_PARAMETER = "newTimeStamp"; + private static final String CHANGE_MEETUP_TIME_CONFIRMATION = "changeMeetupTime_confirmation"; + + @Autowired + private SlashCommandParameterService slashCommandParameterService; + + @Autowired + private MeetupManagementServiceBean meetupManagementServiceBean; + + @Autowired + private ComponentService componentService; + + @Autowired + private InteractionService interactionService; + + @Autowired + private MeetupServiceBean meetupServiceBean; + + @Autowired + private ChannelService channelService; + + @Autowired + private TemplateService templateService; + + @Override + public CompletableFuture executeAsync(CommandContext commandContext) { + List parameters = commandContext.getParameters().getParameters(); + Long meetupId = (Long) parameters.get(0); + Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, commandContext.getGuild().getIdLong()); + if(!meetup.getOrganizer().getUserReference().getId().equals(commandContext.getAuthor().getIdLong())) { + throw new NotMeetupOrganizerException(); + } + Long newTimestamp = (Long) parameters.get(1); + Instant newMeetupTime = Instant.ofEpochSecond(newTimestamp); + if(newMeetupTime.isBefore(Instant.now())) { + throw new MeetupPastTimeException(); + } + String confirmationId = componentService.generateComponentId(); + String cancelId = componentService.generateComponentId(); + MeetupChangeTimeConfirmationModel model = MeetupChangeTimeConfirmationModel + .builder() + .meetupTime(newMeetupTime) + .topic(meetup.getTopic()) + .description(meetup.getDescription()) + .userId(commandContext.getAuthor().getIdLong()) + .guildId(commandContext.getGuild().getIdLong()) + .meetupId(meetupId) + .confirmationId(confirmationId) + .cancelId(cancelId) + .build(); + MessageToSend messageToSend = templateService.renderEmbedTemplate(CHANGE_MEETUP_TIME_CONFIRMATION, model, commandContext.getGuild().getIdLong()); + return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel())) + .thenAccept(unused -> meetupServiceBean.storeMeetupChangeTimeConfirmation(model)) + .thenApply(unused -> CommandResult.fromSuccess()); + } + + @Override + public CompletableFuture executeSlash(SlashCommandInteractionEvent event) { + Long meetupId = slashCommandParameterService.getCommandOption(MEETUP_ID_PARAMETER, event, Integer.class).longValue(); + Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, event.getGuild().getIdLong()); + if(!meetup.getOrganizer().getUserReference().getId().equals(event.getMember().getIdLong())) { + throw new NotMeetupOrganizerException(); + } + Integer time = slashCommandParameterService.getCommandOption(MEETUP_NEW_TIMESTAMP_PARAMETER, event, Long.class, Integer.class); + Instant meetupTime = Instant.ofEpochSecond(time); + if(meetupTime.isBefore(Instant.now())) { + throw new MeetupPastTimeException(); + } + String confirmationId = componentService.generateComponentId(); + String cancelId = componentService.generateComponentId(); + MeetupChangeTimeConfirmationModel model = MeetupChangeTimeConfirmationModel + .builder() + .meetupTime(meetupTime) + .topic(meetup.getTopic()) + .description(meetup.getDescription()) + .userId(event.getMember().getIdLong()) + .guildId(event.getGuild().getIdLong()) + .meetupId(meetupId) + .confirmationId(confirmationId) + .cancelId(cancelId) + .build(); + return interactionService.replyEmbed(CHANGE_MEETUP_TIME_CONFIRMATION, model, event) + .thenAccept(interactionHook -> meetupServiceBean.storeMeetupChangeTimeConfirmation(model)) + .thenApply(interactionHook -> CommandResult.fromSuccess()); + } + + @Override + public CommandConfiguration getConfiguration() { + Parameter meetupIdParameter = Parameter + .builder() + .templated(true) + .name(MEETUP_ID_PARAMETER) + .type(Long.class) + .build(); + + Parameter newTimeStampParameter = Parameter + .builder() + .templated(true) + .name(MEETUP_NEW_TIMESTAMP_PARAMETER) + .type(Long.class) + .build(); + + List parameters = Arrays.asList(meetupIdParameter, newTimeStampParameter); + HelpInfo helpInfo = HelpInfo + .builder() + .templated(true) + .build(); + + SlashCommandConfig slashCommandConfig = SlashCommandConfig + .builder() + .enabled(true) + .rootCommandName(MeetupSlashCommandNames.MEETUP) + .commandName("changeTime") + .build(); + + return CommandConfiguration.builder() + .name(CHANGE_MEETUP_TIME_COMMAND) + .module(UtilityModuleDefinition.UTILITY) + .templated(true) + .async(true) + .slashCommandConfig(slashCommandConfig) + .supportsEmbedException(true) + .causesReaction(true) + .parameters(parameters) + .help(helpInfo) + .build(); + } + + @Override + public FeatureDefinition getFeature() { + return MeetupFeatureDefinition.MEETUP; + } +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/ListMeetups.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/ListMeetups.java index c65e669a..f1faded1 100644 --- a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/ListMeetups.java +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/ListMeetups.java @@ -86,7 +86,7 @@ public class ListMeetups extends AbstractConditionableCommand { SlashCommandConfig slashCommandConfig = SlashCommandConfig .builder() .enabled(true) - .rootCommandName(MeetupSlashCommandNames.MEETUP) + .rootCommandName(MeetupSlashCommandNames.MEETUP_PUBLIC) .commandName("list") .build(); diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/NotifyMeetupParticipants.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/NotifyMeetupParticipants.java new file mode 100644 index 00000000..abc3fdc0 --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/commands/NotifyMeetupParticipants.java @@ -0,0 +1,121 @@ +package dev.sheldan.sissi.module.meetup.commands; + +import dev.sheldan.abstracto.core.command.UtilityModuleDefinition; +import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; +import dev.sheldan.abstracto.core.command.config.CommandConfiguration; +import dev.sheldan.abstracto.core.command.config.HelpInfo; +import dev.sheldan.abstracto.core.command.config.Parameter; +import dev.sheldan.abstracto.core.command.config.SlashCommandConfig; +import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.execution.CommandResult; +import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.interaction.InteractionService; +import dev.sheldan.sissi.module.meetup.config.MeetupFeatureDefinition; +import dev.sheldan.sissi.module.meetup.config.MeetupSlashCommandNames; +import dev.sheldan.sissi.module.meetup.exception.NotMeetupOrganizerException; +import dev.sheldan.sissi.module.meetup.model.database.Meetup; +import dev.sheldan.sissi.module.meetup.service.MeetupServiceBean; +import dev.sheldan.sissi.module.meetup.service.management.MeetupManagementServiceBean; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@Component +public class NotifyMeetupParticipants extends AbstractConditionableCommand { + + @Autowired + private SlashCommandParameterService slashCommandParameterService; + + @Autowired + private MeetupManagementServiceBean meetupManagementServiceBean; + + @Autowired + private MeetupServiceBean meetupServiceBean; + + @Autowired + private InteractionService interactionService; + + private static final String MEETUP_ID_PARAMETER = "meetupId"; + private static final String NOTIFICATION_MESSAGE_PARAMETER = "notificationMessage"; + private static final String NOTIFY_MEETUP_PARTICIPANTS_COMMAND = "notifyMeetupParticipants"; + private static final String NOTIFY_MEETUP_PARTICIPANTS_RESPONSE = "notifyMeetupParticipants_response"; + + @Override + public CompletableFuture executeAsync(CommandContext commandContext) { + List parameters = commandContext.getParameters().getParameters(); + Long meetupId = (Long) parameters.get(0); + Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, commandContext.getGuild().getIdLong()); + if(!meetup.getOrganizer().getUserReference().getId().equals(commandContext.getAuthor().getIdLong())) { + throw new NotMeetupOrganizerException(); + } + String notificationMessage = (String) parameters.get(1); + return meetupServiceBean.notifyMeetupParticipants(meetup, notificationMessage) + .thenApply(unused -> CommandResult.fromSuccess()); + } + + @Override + public CompletableFuture executeSlash(SlashCommandInteractionEvent event) { + Long meetupId = slashCommandParameterService.getCommandOption(MEETUP_ID_PARAMETER, event, Integer.class).longValue(); + Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, event.getGuild().getIdLong()); + if(!meetup.getOrganizer().getUserReference().getId().equals(event.getMember().getIdLong())) { + throw new NotMeetupOrganizerException(); + } + String notificationMessage = slashCommandParameterService.getCommandOption(NOTIFICATION_MESSAGE_PARAMETER, event, String.class); + return meetupServiceBean.notifyMeetupParticipants(meetup, notificationMessage) + .thenCompose(unused -> interactionService.replyEmbed(NOTIFY_MEETUP_PARTICIPANTS_RESPONSE, event)) + .thenApply(unused -> CommandResult.fromSuccess()); + } + + @Override + public CommandConfiguration getConfiguration() { + Parameter meetupIdParameter = Parameter + .builder() + .templated(true) + .name(MEETUP_ID_PARAMETER) + .type(Long.class) + .build(); + + Parameter notificationMessage = Parameter + .builder() + .templated(true) + .name(NOTIFICATION_MESSAGE_PARAMETER) + .type(String.class) + .remainder(true) + .build(); + + List parameters = Arrays.asList(meetupIdParameter, notificationMessage); + HelpInfo helpInfo = HelpInfo + .builder() + .templated(true) + .build(); + + SlashCommandConfig slashCommandConfig = SlashCommandConfig + .builder() + .enabled(true) + .rootCommandName(MeetupSlashCommandNames.MEETUP) + .commandName("notify") + .build(); + + return CommandConfiguration.builder() + .name(NOTIFY_MEETUP_PARTICIPANTS_COMMAND) + .module(UtilityModuleDefinition.UTILITY) + .templated(true) + .slashCommandConfig(slashCommandConfig) + .async(true) + .supportsEmbedException(true) + .causesReaction(true) + .parameters(parameters) + .help(helpInfo) + .build(); + } + + @Override + public FeatureDefinition getFeature() { + return MeetupFeatureDefinition.MEETUP; + } +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/config/MeetupSlashCommandNames.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/config/MeetupSlashCommandNames.java index 42addbc2..ce192652 100644 --- a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/config/MeetupSlashCommandNames.java +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/config/MeetupSlashCommandNames.java @@ -2,4 +2,5 @@ package dev.sheldan.sissi.module.meetup.config; public class MeetupSlashCommandNames { public static final String MEETUP = "meetup"; + public static final String MEETUP_PUBLIC = "meetupPublic"; } diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/exception/NotMeetupOrganizerException.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/exception/NotMeetupOrganizerException.java new file mode 100644 index 00000000..5c4fc7d5 --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/exception/NotMeetupOrganizerException.java @@ -0,0 +1,15 @@ +package dev.sheldan.sissi.module.meetup.exception; + +import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException; + +public class NotMeetupOrganizerException extends AbstractoTemplatableException { + @Override + public String getTemplateName() { + return "meetup_not_organizer_exception"; + } + + @Override + public Object getTemplateModel() { + return new Object(); + } +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupChangeTimeConfirmationListener.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupChangeTimeConfirmationListener.java new file mode 100644 index 00000000..c3a4161f --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupChangeTimeConfirmationListener.java @@ -0,0 +1,78 @@ +package dev.sheldan.sissi.module.meetup.listener; + +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.config.ListenerPriority; +import dev.sheldan.abstracto.core.listener.ButtonClickedListenerResult; +import dev.sheldan.abstracto.core.listener.async.jda.ButtonClickedListener; +import dev.sheldan.abstracto.core.models.listener.ButtonClickedListenerModel; +import dev.sheldan.abstracto.core.service.MessageService; +import dev.sheldan.abstracto.core.service.management.ComponentPayloadManagementService; +import dev.sheldan.sissi.module.meetup.config.MeetupFeatureDefinition; +import dev.sheldan.sissi.module.meetup.model.database.Meetup; +import dev.sheldan.sissi.module.meetup.model.payload.MeetupChangeTimeConfirmationPayload; +import dev.sheldan.sissi.module.meetup.service.MeetupServiceBean; +import dev.sheldan.sissi.module.meetup.service.management.MeetupManagementServiceBean; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.Instant; + +@Component +@Slf4j +public class MeetupChangeTimeConfirmationListener implements ButtonClickedListener { + + @Autowired + private MeetupManagementServiceBean meetupManagementServiceBean; + + @Autowired + private MessageService messageService; + + @Autowired + private ComponentPayloadManagementService componentPayloadManagementService; + + @Autowired + private MeetupServiceBean meetupServiceBean; + + @Override + public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) { + MeetupChangeTimeConfirmationPayload payload = (MeetupChangeTimeConfirmationPayload) model.getDeserializedPayload(); + if(model.getEvent().getUser().getIdLong() != payload.getOrganizerUserId()) { + return ButtonClickedListenerResult.IGNORED; + } + if(model.getEvent().getComponentId().equals(payload.getConfirmationId())) { + Meetup meetup = meetupManagementServiceBean.getMeetup(payload.getMeetupId(), payload.getGuildId()); + meetupServiceBean.changeMeetupTimeAndNotifyParticipants(meetup, Instant.ofEpochSecond(payload.getNewTime())); + messageService.deleteMessage(model.getEvent().getMessage()); + cleanupConfirmationMessagePayloads(payload); + } else if(model.getEvent().getComponentId().equals(payload.getCancelId())) { + messageService.deleteMessage(model.getEvent().getMessage()); + cleanupConfirmationMessagePayloads(payload); + return ButtonClickedListenerResult.ACKNOWLEDGED; + } else { + return ButtonClickedListenerResult.IGNORED; + } + return ButtonClickedListenerResult.IGNORED; + } + + private void cleanupConfirmationMessagePayloads(MeetupChangeTimeConfirmationPayload payload) { + componentPayloadManagementService.deletePayload(payload.getCancelId()); + componentPayloadManagementService.deletePayload(payload.getConfirmationId()); + } + + @Override + public Boolean handlesEvent(ButtonClickedListenerModel model) { + return model.getOrigin().equals(MeetupServiceBean.MEETUP_CHANGE_TIME_CONFIRMATION_BUTTON) && + model.getEvent().isFromGuild(); + } + + @Override + public FeatureDefinition getFeature() { + return MeetupFeatureDefinition.MEETUP; + } + + @Override + public Integer getPriority() { + return ListenerPriority.LOWEST; + } +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupConfirmationListener.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupConfirmationListener.java index 43ca5dd8..f196cfbb 100644 --- a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupConfirmationListener.java +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupConfirmationListener.java @@ -6,6 +6,7 @@ import dev.sheldan.abstracto.core.listener.ButtonClickedListenerResult; import dev.sheldan.abstracto.core.listener.async.jda.ButtonClickedListener; import dev.sheldan.abstracto.core.models.database.AChannel; import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.abstracto.core.models.database.ComponentPayload; import dev.sheldan.abstracto.core.models.listener.ButtonClickedListenerModel; import dev.sheldan.abstracto.core.service.ChannelService; import dev.sheldan.abstracto.core.service.ComponentPayloadService; @@ -24,6 +25,7 @@ import dev.sheldan.sissi.module.meetup.model.payload.MeetupDecisionPayload; import dev.sheldan.sissi.module.meetup.model.payload.MeetupConfirmationPayload; import dev.sheldan.sissi.module.meetup.model.template.MeetupMessageModel; import dev.sheldan.sissi.module.meetup.service.MeetupServiceBean; +import dev.sheldan.sissi.module.meetup.service.management.MeetupComponentManagementServiceBean; import dev.sheldan.sissi.module.meetup.service.management.MeetupManagementServiceBean; import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.entities.Message; @@ -71,6 +73,9 @@ public class MeetupConfirmationListener implements ButtonClickedListener { @Autowired private ComponentPayloadManagementService componentPayloadManagementService; + @Autowired + private MeetupComponentManagementServiceBean meetupComponentManagementServiceBean; + @Override public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) { MeetupConfirmationPayload payload = (MeetupConfirmationPayload) model.getDeserializedPayload(); @@ -83,22 +88,22 @@ public class MeetupConfirmationListener implements ButtonClickedListener { } else if(model.getEvent().getComponentId().equals(payload.getCancelId())){ meetup.setState(MeetupState.CANCELLED); messageService.deleteMessage(model.getEvent().getMessage()); - cleanupConfirmationMessage(payload); + cleanupConfirmationMessagePayloads(payload); meetupManagementServiceBean.deleteMeetup(meetup); return ButtonClickedListenerResult.ACKNOWLEDGED; } else { return ButtonClickedListenerResult.IGNORED; } - cleanupConfirmationMessage(payload); + cleanupConfirmationMessagePayloads(payload); String yesButtonId = componentService.generateComponentId(); String noButtonId = componentService.generateComponentId(); String maybeButtonId = componentService.generateComponentId(); - String cancelButtonId = componentService.generateComponentId(); + String noTimeButtonId = componentService.generateComponentId(); MeetupMessageModel messageModel = meetupServiceBean.getMeetupMessageModel(meetup); messageModel.setYesId(yesButtonId); messageModel.setNoId(noButtonId); messageModel.setMaybeId(maybeButtonId); - messageModel.setCancelId(cancelButtonId); + messageModel.setNoTimeId(noTimeButtonId); messageModel.setCancelled(false); Long meetupId = payload.getMeetupId(); Long serverId = payload.getGuildId(); @@ -108,7 +113,7 @@ public class MeetupConfirmationListener implements ButtonClickedListener { messageService.deleteMessage(model.getEvent().getMessage()); Message meetupMessage = messageFutures.get(0).join(); messageService.pinMessage(meetupMessage); - self.persistPayloads(meetupId, serverId, yesButtonId, noButtonId, maybeButtonId, cancelButtonId, meetupMessage); + self.persistPayloads(meetupId, serverId, yesButtonId, noButtonId, maybeButtonId, noTimeButtonId, meetupMessage); }).exceptionally(throwable -> { log.error("Failed to send meetup message for meetup {}.", meetupId, throwable); return null; @@ -116,30 +121,36 @@ public class MeetupConfirmationListener implements ButtonClickedListener { return ButtonClickedListenerResult.ACKNOWLEDGED; } - private void cleanupConfirmationMessage(MeetupConfirmationPayload payload) { + private void cleanupConfirmationMessagePayloads(MeetupConfirmationPayload payload) { componentPayloadManagementService.deletePayload(payload.getCancelId()); componentPayloadManagementService.deletePayload(payload.getConfirmationId()); } @Transactional - public void persistPayloads(Long meetupId, Long serverId, String yesButtonId, String noButtonId, String maybeButtonId, String cancelButtonId, Message meetupMessage) { + public void persistPayloads(Long meetupId, Long serverId, String yesButtonId, String noButtonId, String maybeButtonId, String noTimeButtonId, Message meetupMessage) { MeetupDecisionPayload decisionPayload = MeetupDecisionPayload .builder() .meetupId(meetupId) .guildId(serverId) - .componentPayloads(Arrays.asList(yesButtonId, noButtonId, maybeButtonId)) + .componentPayloads(Arrays.asList(yesButtonId, noButtonId, maybeButtonId, noTimeButtonId)) .build(); AServer server = serverManagementService.loadServer(serverId); decisionPayload.setMeetupDecision(MeetupDecision.YES); - componentPayloadService.createButtonPayload(yesButtonId, decisionPayload, MEETUP_DECISION_BUTTON, server); + ComponentPayload yesPayload = componentPayloadService.createButtonPayload(yesButtonId, decisionPayload, MEETUP_DECISION_BUTTON, server); decisionPayload.setMeetupDecision(MeetupDecision.NO); - componentPayloadService.createButtonPayload(noButtonId, decisionPayload, MEETUP_DECISION_BUTTON, server); + ComponentPayload noPayload = componentPayloadService.createButtonPayload(noButtonId, decisionPayload, MEETUP_DECISION_BUTTON, server); decisionPayload.setMeetupDecision(MeetupDecision.MAYBE); - componentPayloadService.createButtonPayload(maybeButtonId, decisionPayload, MEETUP_DECISION_BUTTON, server); - decisionPayload.setMeetupDecision(MeetupDecision.CANCEL); - componentPayloadService.createButtonPayload(cancelButtonId, decisionPayload, MEETUP_DECISION_BUTTON, server); + ComponentPayload maybePayload = componentPayloadService.createButtonPayload(maybeButtonId, decisionPayload, MEETUP_DECISION_BUTTON, server); + decisionPayload.setMeetupDecision(MeetupDecision.NO_TIME); + ComponentPayload noTimePayload = componentPayloadService.createButtonPayload(noTimeButtonId, decisionPayload, MEETUP_DECISION_BUTTON, server); Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, serverId); + // storing the button IDs, so we can remove them independently + meetupComponentManagementServiceBean.createComponent(meetup, yesButtonId, yesPayload); + meetupComponentManagementServiceBean.createComponent(meetup, noButtonId, noPayload); + meetupComponentManagementServiceBean.createComponent(meetup, maybeButtonId, maybePayload); + meetupComponentManagementServiceBean.createComponent(meetup, noTimeButtonId, noTimePayload); + meetupServiceBean.scheduleReminders(meetup); meetup.setMessageId(meetupMessage.getIdLong()); AChannel channel = channelManagementService.loadChannel(meetupMessage.getChannel()); diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupDecisionListener.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupDecisionListener.java index 8680389b..dab41eb6 100644 --- a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupDecisionListener.java +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/listener/MeetupDecisionListener.java @@ -13,7 +13,7 @@ import dev.sheldan.abstracto.core.templating.model.MessageToSend; import dev.sheldan.sissi.module.meetup.config.MeetupFeatureDefinition; import dev.sheldan.sissi.module.meetup.model.database.Meetup; import dev.sheldan.sissi.module.meetup.model.database.MeetupDecision; -import dev.sheldan.sissi.module.meetup.model.database.MeetupParticipator; +import dev.sheldan.sissi.module.meetup.model.database.MeetupParticipant; import dev.sheldan.sissi.module.meetup.model.payload.MeetupDecisionPayload; import dev.sheldan.sissi.module.meetup.model.template.MeetupMessageModel; import dev.sheldan.sissi.module.meetup.service.MeetupServiceBean; @@ -49,17 +49,9 @@ public class MeetupDecisionListener implements ButtonClickedListener { public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) { MeetupDecisionPayload payload = (MeetupDecisionPayload) model.getDeserializedPayload(); Meetup meetup = meetupManagementServiceBean.getMeetup(payload.getMeetupId(), payload.getGuildId()); - if(payload.getMeetupDecision().equals(MeetupDecision.CANCEL)) { - if(model.getEvent().getUser().getIdLong() == meetup.getOrganizer().getUserReference().getId()) { - meetupServiceBean.cancelMeetup(meetup, payload.getComponentPayloads()); - return ButtonClickedListenerResult.ACKNOWLEDGED; - } else { - return ButtonClickedListenerResult.IGNORED; - } - } AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(model.getEvent().getMember()); - Optional participationOptional = meetupParticipatorManagementServiceBean.getParticipation(meetup, userInAServer); + Optional participationOptional = meetupParticipatorManagementServiceBean.getParticipation(meetup, userInAServer); if(participationOptional.isPresent()) { participationOptional.get().setDecision(payload.getMeetupDecision()); } else { @@ -84,7 +76,8 @@ public class MeetupDecisionListener implements ButtonClickedListener { addIfMissing(model.getParticipants(), aUserInAServer); } else if(decision.equals(MeetupDecision.MAYBE)) { addIfMissing(model.getMaybeParticipants(), aUserInAServer); - } + } else if(decision.equals(MeetupDecision.NO_TIME)) + addIfMissing(model.getNoTimeParticipants(), aUserInAServer); } private void addIfMissing(List list, AUserInAServer aUserInAServer) { diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/command/MeetupChangeTimeConfirmationModel.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/command/MeetupChangeTimeConfirmationModel.java new file mode 100644 index 00000000..b5e5c1cd --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/command/MeetupChangeTimeConfirmationModel.java @@ -0,0 +1,21 @@ +package dev.sheldan.sissi.module.meetup.model.command; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.time.Instant; + +@Getter +@Setter +@Builder +public class MeetupChangeTimeConfirmationModel { + private Instant meetupTime; + private String topic; + private Long userId; + private String description; + private Long meetupId; + private Long guildId; + private String confirmationId; + private String cancelId; +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/Meetup.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/Meetup.java index 38eef576..ad8030f3 100644 --- a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/Meetup.java +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/Meetup.java @@ -49,7 +49,15 @@ public class Meetup { cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "meetup") @Builder.Default - private List participants = new ArrayList<>(); + private List participants = new ArrayList<>(); + + @OneToMany( + fetch = FetchType.LAZY, + orphanRemoval = true, + cascade = {CascadeType.PERSIST, CascadeType.MERGE}, + mappedBy = "meetup") + @Builder.Default + private List meetupComponents = new ArrayList<>(); @Getter @Enumerated(EnumType.STRING) diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupComponent.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupComponent.java new file mode 100644 index 00000000..39c1be95 --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupComponent.java @@ -0,0 +1,40 @@ +package dev.sheldan.sissi.module.meetup.model.database; + +import dev.sheldan.abstracto.core.models.database.ComponentPayload; +import dev.sheldan.sissi.module.meetup.model.database.embed.MeetupComponentId; +import lombok.*; + +import javax.persistence.*; +import java.time.Instant; + +@Builder +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "meetup_component") +@Getter +@Setter +@EqualsAndHashCode +public class MeetupComponent { + + @EmbeddedId + @Getter + private MeetupComponentId id; + + @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY) + @MapsId("componentId") + @JoinColumn(name = "component_id", nullable = false) + private ComponentPayload payload; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumns( + { + @JoinColumn(updatable = false, insertable = false, name = "meetup_id", referencedColumnName = "id"), + @JoinColumn(updatable = false, insertable = false, name = "server_id", referencedColumnName = "server_id") + }) + private Meetup meetup; + + @Column(name = "created") + private Instant created; + +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupDecision.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupDecision.java index 91b520ad..b57366af 100644 --- a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupDecision.java +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupDecision.java @@ -1,5 +1,5 @@ package dev.sheldan.sissi.module.meetup.model.database; public enum MeetupDecision { - YES, NO, MAYBE, CANCEL + YES, NO, MAYBE, NO_TIME } diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupParticipator.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupParticipant.java similarity index 95% rename from application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupParticipator.java rename to application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupParticipant.java index 8d427337..c8be8301 100644 --- a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupParticipator.java +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/MeetupParticipant.java @@ -15,14 +15,14 @@ import java.time.Instant; @Getter @Setter @EqualsAndHashCode -public class MeetupParticipator { +public class MeetupParticipant { @EmbeddedId @Getter private MeetupParticipationId id; @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY) - @MapsId("voterId") + @MapsId("participatorId") @JoinColumn(name = "meetup_participator_user_in_server_id", nullable = false) private AUserInAServer participator; diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/embed/MeetupComponentId.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/embed/MeetupComponentId.java new file mode 100644 index 00000000..179af3bc --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/database/embed/MeetupComponentId.java @@ -0,0 +1,25 @@ +package dev.sheldan.sissi.module.meetup.model.database.embed; + +import lombok.*; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.io.Serializable; + +@Embeddable +@Getter +@Setter +@Builder +@EqualsAndHashCode +@NoArgsConstructor +@AllArgsConstructor +public class MeetupComponentId implements Serializable { + @Column(name = "component_id") + private String componentId; + + @Column(name = "meetup_id") + private Long meetupId; + + @Column(name = "server_id") + private Long serverId; +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/payload/MeetupChangeTimeConfirmationPayload.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/payload/MeetupChangeTimeConfirmationPayload.java new file mode 100644 index 00000000..e725fa8b --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/payload/MeetupChangeTimeConfirmationPayload.java @@ -0,0 +1,18 @@ +package dev.sheldan.sissi.module.meetup.model.payload; + +import dev.sheldan.abstracto.core.models.template.button.ButtonPayload; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@Getter +@Setter +public class MeetupChangeTimeConfirmationPayload implements ButtonPayload { + private Long organizerUserId; + private Long meetupId; + private Long newTime; + private Long guildId; + private String confirmationId; + private String cancelId; +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupMessageModel.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupMessageModel.java index 99b4738b..3c9abe37 100644 --- a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupMessageModel.java +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupMessageModel.java @@ -16,12 +16,14 @@ public class MeetupMessageModel { private String description; private Instant meetupTime; private MemberDisplay organizer; + private Long meetupId; private String yesId; private String noId; private String maybeId; - private String cancelId; + private String noTimeId; private Boolean cancelled; private List participants; private List maybeParticipants; + private List noTimeParticipants; private List declinedParticipants; } diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupNotificationModel.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupNotificationModel.java new file mode 100644 index 00000000..3e4c4d22 --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupNotificationModel.java @@ -0,0 +1,14 @@ +package dev.sheldan.sissi.module.meetup.model.template; + +import dev.sheldan.abstracto.core.models.template.display.MemberDisplay; +import lombok.Builder; +import lombok.Getter; + +import java.util.List; + +@Builder +@Getter +public class MeetupNotificationModel { + private List participants; + private String notificationMessage; +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupTimeChangedNotificationModel.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupTimeChangedNotificationModel.java new file mode 100644 index 00000000..a62c7175 --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/model/template/MeetupTimeChangedNotificationModel.java @@ -0,0 +1,17 @@ +package dev.sheldan.sissi.module.meetup.model.template; + +import dev.sheldan.abstracto.core.models.ServerChannelMessage; +import lombok.Builder; +import lombok.Getter; + +import java.time.Instant; + +@Builder +@Getter +public class MeetupTimeChangedNotificationModel { + private String meetupTopic; + private String meetupDescription; + private Instant oldDate; + private Instant newDate; + private ServerChannelMessage meetupMessage; +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/repository/MeetupComponentRepository.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/repository/MeetupComponentRepository.java new file mode 100644 index 00000000..80040881 --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/repository/MeetupComponentRepository.java @@ -0,0 +1,10 @@ +package dev.sheldan.sissi.module.meetup.repository; + +import dev.sheldan.sissi.module.meetup.model.database.MeetupComponent; +import dev.sheldan.sissi.module.meetup.model.database.embed.MeetupComponentId; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface MeetupComponentRepository extends JpaRepository { +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/repository/MeetupParticipatorRepository.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/repository/MeetupParticipatorRepository.java index 16728c6e..6806e97c 100644 --- a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/repository/MeetupParticipatorRepository.java +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/repository/MeetupParticipatorRepository.java @@ -1,10 +1,10 @@ package dev.sheldan.sissi.module.meetup.repository; -import dev.sheldan.sissi.module.meetup.model.database.MeetupParticipator; +import dev.sheldan.sissi.module.meetup.model.database.MeetupParticipant; import dev.sheldan.sissi.module.meetup.model.database.embed.MeetupParticipationId; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository -public interface MeetupParticipatorRepository extends JpaRepository { +public interface MeetupParticipatorRepository extends JpaRepository { } diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/MeetupServiceBean.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/MeetupServiceBean.java index 008af75d..3cbeb09d 100644 --- a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/MeetupServiceBean.java +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/MeetupServiceBean.java @@ -1,5 +1,6 @@ package dev.sheldan.sissi.module.meetup.service; +import dev.sheldan.abstracto.core.models.ServerChannelMessage; import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.template.display.MemberDisplay; import dev.sheldan.abstracto.core.service.*; @@ -7,27 +8,33 @@ import dev.sheldan.abstracto.core.service.management.ComponentPayloadManagementS import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.templating.model.MessageToSend; import dev.sheldan.abstracto.core.templating.service.TemplateService; +import dev.sheldan.abstracto.core.utils.FutureUtils; import dev.sheldan.abstracto.scheduling.model.JobParameters; import dev.sheldan.abstracto.scheduling.service.SchedulerService; +import dev.sheldan.sissi.module.meetup.model.command.MeetupChangeTimeConfirmationModel; import dev.sheldan.sissi.module.meetup.model.command.MeetupConfirmationModel; import dev.sheldan.sissi.module.meetup.model.database.Meetup; import dev.sheldan.sissi.module.meetup.model.database.MeetupDecision; -import dev.sheldan.sissi.module.meetup.model.database.MeetupParticipator; +import dev.sheldan.sissi.module.meetup.model.database.MeetupParticipant; import dev.sheldan.sissi.module.meetup.model.database.MeetupState; +import dev.sheldan.sissi.module.meetup.model.payload.MeetupChangeTimeConfirmationPayload; import dev.sheldan.sissi.module.meetup.model.payload.MeetupConfirmationPayload; import dev.sheldan.sissi.module.meetup.model.template.MeetupMessageModel; +import dev.sheldan.sissi.module.meetup.model.template.MeetupNotificationModel; +import dev.sheldan.sissi.module.meetup.model.template.MeetupTimeChangedNotificationModel; +import dev.sheldan.sissi.module.meetup.service.management.MeetupComponentManagementServiceBean; import dev.sheldan.sissi.module.meetup.service.management.MeetupManagementServiceBean; +import dev.sheldan.sissi.module.meetup.service.management.MeetupParticipatorManagementServiceBean; import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.entities.GuildMessageChannel; +import net.dv8tion.jda.api.entities.MessageChannel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.time.Instant; import java.time.temporal.ChronoUnit; -import java.util.Date; -import java.util.HashMap; -import java.util.List; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; @@ -36,9 +43,11 @@ import java.util.stream.Collectors; public class MeetupServiceBean { public static final String MEETUP_CONFIRMATION_BUTTON = "MEETUP_CONFIRMATION_BUTTON"; + public static final String MEETUP_CHANGE_TIME_CONFIRMATION_BUTTON = "MEETUP_CHANGE_TIME_CONFIRMATION_BUTTON"; public static final String MEETUP_DECISION_BUTTON = "MEETUP_DECISION_BUTTON"; private static final String MEETUP_DISPLAY_TEMPLATE = "meetup_display"; private static final String MEETUP_CANCELLATION_TEMPLATE = "meetup_cancel_notification"; + private static final String MEETUP_CHANGE_TIME_NOTIFICATION_TEMPLATE = "changeMeetupTime_notification"; private static final String MEETUP_REMINDER_TEMPLATE = "meetup_reminder_notification"; private static final String MEETUP_LATE_REMINDER_CONFIG_KEY = "meetupLateReminderSeconds"; private static final String MEETUP_EARLY_REMINDER_CONFIG_KEY = "meetupEarlyReminderSeconds"; @@ -77,6 +86,12 @@ public class MeetupServiceBean { @Autowired private SchedulerService schedulerService; + @Autowired + private MeetupParticipatorManagementServiceBean meetupParticipatorManagementServiceBean; + + @Autowired + private MeetupComponentManagementServiceBean meetupComponentManagementServiceBean; + public void storeMeetupConfirmation(MeetupConfirmationModel model) { AServer server = serverManagementService.loadServer(model.getGuildId()); MeetupConfirmationPayload confirmationPayload = MeetupConfirmationPayload @@ -91,35 +106,56 @@ public class MeetupServiceBean { componentPayloadService.createButtonPayload(model.getCancelId(), confirmationPayload, MEETUP_CONFIRMATION_BUTTON, server); } + public void storeMeetupChangeTimeConfirmation(MeetupChangeTimeConfirmationModel model) { + AServer server = serverManagementService.loadServer(model.getGuildId()); + MeetupChangeTimeConfirmationPayload confirmationPayload = MeetupChangeTimeConfirmationPayload + .builder() + .newTime(model.getMeetupTime().getEpochSecond()) + .confirmationId(model.getConfirmationId()) + .meetupId(model.getMeetupId()) + .organizerUserId(model.getUserId()) + .cancelId(model.getCancelId()) + .guildId(model.getGuildId()) + .build(); + componentPayloadService.createButtonPayload(model.getConfirmationId(), confirmationPayload, MEETUP_CHANGE_TIME_CONFIRMATION_BUTTON, server); + componentPayloadService.createButtonPayload(model.getCancelId(), confirmationPayload, MEETUP_CHANGE_TIME_CONFIRMATION_BUTTON, server); + } + public MeetupMessageModel getMeetupMessageModel(Meetup meetup) { - List allParticipants = meetup.getParticipants(); - List participating = allParticipants + List allParticipants = meetup.getParticipants(); + List participating = allParticipants .stream() .filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.YES)) .collect(Collectors.toList()); - List maybe = allParticipants + List maybe = allParticipants .stream() .filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.MAYBE)) .collect(Collectors.toList()); - List notParticipating = allParticipants + List notParticipating = allParticipants .stream() .filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.NO)) .collect(Collectors.toList()); + List notTimeParticipating = allParticipants + .stream() + .filter(meetupParticipator -> meetupParticipator.getDecision().equals(MeetupDecision.NO_TIME)) + .collect(Collectors.toList()); return MeetupMessageModel .builder() .description(meetup.getDescription()) .topic(meetup.getTopic()) .meetupTime(meetup.getMeetupTime()) + .meetupId(meetup.getId().getId()) .participants(getMemberDisplays(participating)) .declinedParticipants(getMemberDisplays(notParticipating)) + .noTimeParticipants(getMemberDisplays(notTimeParticipating)) .maybeParticipants(getMemberDisplays(maybe)) .cancelled(meetup.getState().equals(MeetupState.CANCELLED)) .organizer(MemberDisplay.fromAUserInAServer(meetup.getOrganizer())) .build(); } - private List getMemberDisplays(List participants) { + private List getMemberDisplays(List participants) { return participants .stream() .map(meetupParticipator -> MemberDisplay.fromAUserInAServer(meetupParticipator.getParticipator())) @@ -130,11 +166,16 @@ public class MeetupServiceBean { return templateService.renderEmbedTemplate(MEETUP_DISPLAY_TEMPLATE, model); } - public CompletableFuture cancelMeetup(Meetup meetup, List componentPayloads) { + public CompletableFuture cancelMeetup(Meetup meetup) { Long serverId = meetup.getServer().getId(); Long meetupId = meetup.getId().getId(); GuildMessageChannel channel = channelService.getMessageChannelFromServer(serverId, meetup.getMeetupChannel().getId()); MeetupMessageModel model = getMeetupMessageModel(meetup); + List componentPayloads = meetup + .getMeetupComponents() + .stream() + .map(meetupComponent -> meetupComponent.getId().getComponentId()) + .collect(Collectors.toList()); model.setCancelled(true); MessageToSend meetupMessage = getMeetupMessage(model); return messageService.editMessageInChannel(channel, meetupMessage, meetup.getMessageId()) @@ -157,7 +198,11 @@ public class MeetupServiceBean { Long userId = meetupParticipator.getParticipator().getUserReference().getId(); userService.retrieveUserForId(userId) .thenCompose(user -> messageService.sendMessageToSendToUser(user, messageToSend)) - .thenAccept(message -> log.info("Notified user {} about cancellation of meetup {} in server {}.", userId, meetupId, serverId)); + .thenAccept(message -> log.info("Notified user {} about cancellation of meetup {} in server {}.", userId, meetupId, serverId)) + .exceptionally(throwable -> { + log.warn("Failed to notify user {} about cancellation of meetup {} in server {}.", userId, meetupId, serverId); + return null; + }); }); } @@ -165,6 +210,7 @@ public class MeetupServiceBean { public void cleanupMeetup(Long meetupId, Long serverId, List componentPayloads) { Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, serverId); meetup.setState(MeetupState.CANCELLED); + meetupComponentManagementServiceBean.deleteAllComponents(meetup); log.info("Cleanup meetup {} in server {}.", meetup, serverId); if(meetup.getEarlyReminderJobTriggerKey() != null) { schedulerService.stopTrigger(meetup.getEarlyReminderJobTriggerKey()); @@ -203,6 +249,25 @@ public class MeetupServiceBean { } } + public CompletableFuture notifyMeetupParticipants(Meetup meetup, String message) { + List decisionsToBeNotified = Arrays.asList(MeetupDecision.MAYBE, MeetupDecision.YES); + List participants = meetup + .getParticipants() + .stream() + .filter(meetupParticipator -> decisionsToBeNotified.contains(meetupParticipator.getDecision())) + .map(meetupParticipator -> MemberDisplay.fromAUserInAServer(meetupParticipator.getParticipator())) + .collect(Collectors.toList()); + + MeetupNotificationModel model = MeetupNotificationModel + .builder() + .notificationMessage(message) + .participants(participants) + .build(); + MessageChannel channel = channelService.getMessageChannelFromServer(meetup.getServer().getId(), meetup.getMeetupChannel().getId()); + MessageToSend messageToSend = templateService.renderEmbedTemplate("notifyMeetupParticipants_notification_message", model, meetup.getServer().getId()); + return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, channel)); + } + @Transactional public void remindParticipants(Long meetupId, Long serverId) { Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, serverId); @@ -236,7 +301,79 @@ public class MeetupServiceBean { if(meetup.getMessageId() != null) { messageService.deleteMessageInChannelInServer(meetup.getServer().getId(), meetup.getMeetupChannel().getId(), meetup.getMessageId()); } + meetupComponentManagementServiceBean.deleteAllComponents(meetup); }); meetupManagementServiceBean.deleteMeetups(oldMeetups); } + + public CompletableFuture changeMeetupTimeAndNotifyParticipants(Meetup meetup, Instant newTime) { + List decisions = Arrays.asList(MeetupDecision.MAYBE, MeetupDecision.NO_TIME, MeetupDecision.YES); + List participants = meetup + .getParticipants() + .stream() + .filter(meetupParticipator -> decisions.contains(meetupParticipator.getDecision())) + .collect(Collectors.toList()); + List userIdsToNotify = participants + .stream() + .map(meetupParticipator -> meetupParticipator.getParticipator().getUserReference().getId()) + .collect(Collectors.toList()); + + Long serverId = meetup.getServer().getId(); + + ServerChannelMessage meetupMessage = ServerChannelMessage + .builder() + .serverId(serverId) + .channelId(meetup.getMeetupChannel().getId()) + .messageId(meetup.getMessageId()) + .build(); + MeetupTimeChangedNotificationModel notificationModel = MeetupTimeChangedNotificationModel + .builder() + .meetupDescription(meetup.getDescription()) + .meetupTopic(meetup.getTopic()) + .meetupMessage(meetupMessage) + .newDate(newTime) + .oldDate(meetup.getMeetupTime()) + .build(); + + if(meetup.getEarlyReminderJobTriggerKey() != null) { + schedulerService.stopTrigger(meetup.getEarlyReminderJobTriggerKey()); + } + if(meetup.getLateReminderJobTriggerKey() != null) { + schedulerService.stopTrigger(meetup.getLateReminderJobTriggerKey()); + } + // set the new time here, so that we can use it in schedule + meetup.setMeetupTime(newTime); + scheduleReminders(meetup); + + MessageToSend messageToSend = templateService.renderEmbedTemplate(MEETUP_CHANGE_TIME_NOTIFICATION_TEMPLATE, notificationModel, serverId); + Long meetupId = meetup.getId().getId(); + userIdsToNotify.forEach(userId -> { + userService.retrieveUserForId(userId).thenCompose(user -> messageService.sendMessageToSendToUser(user, messageToSend) + .exceptionally(throwable -> { + log.warn("Failed to notify user {} about changed time of meetup {} in server {}.", userId, meetupId, serverId); + return null; + })); + }); + + meetupParticipatorManagementServiceBean.deleteParticipants(participants); + List userInServerIds = participants + .stream() + .map(meetupParticipant -> meetupParticipant.getParticipator().getUserInServerId()) + .collect(Collectors.toList()); + meetup + .getParticipants().removeIf(meetupParticipant -> userInServerIds.contains(meetupParticipant.getParticipator().getUserInServerId())); + MeetupMessageModel meetupMessageModel = getMeetupMessageModel(meetup); + meetupMessageModel.setParticipants(new ArrayList<>()); + meetupMessageModel.setMaybeParticipants(new ArrayList<>()); + meetupMessageModel.setNoTimeParticipants(new ArrayList<>()); + + MessageToSend updatedMeetupMessage = getMeetupMessage(meetupMessageModel); + GuildMessageChannel meetupChannel = channelService.getMessageChannelFromServer(serverId, meetup.getMeetupChannel().getId()); + return channelService.editEmbedMessageInAChannel(updatedMeetupMessage.getEmbeds().get(0), meetupChannel, meetup.getMessageId()) + .thenAccept(message -> log.info("Updated message of meetup {} in channel {} in server {}.", meetupId, meetup.getMeetupChannel().getId(), serverId)) + .exceptionally(throwable -> { + log.info("Failed to update message of meetup {} in channel {} in server {}.", meetupId, meetup.getMeetupChannel().getId(), serverId, throwable); + return null; + }); + } } diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/management/MeetupComponentManagementServiceBean.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/management/MeetupComponentManagementServiceBean.java new file mode 100644 index 00000000..10c236d2 --- /dev/null +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/management/MeetupComponentManagementServiceBean.java @@ -0,0 +1,40 @@ +package dev.sheldan.sissi.module.meetup.service.management; + +import dev.sheldan.abstracto.core.models.database.ComponentPayload; +import dev.sheldan.sissi.module.meetup.model.database.Meetup; +import dev.sheldan.sissi.module.meetup.model.database.MeetupComponent; +import dev.sheldan.sissi.module.meetup.model.database.embed.MeetupComponentId; +import dev.sheldan.sissi.module.meetup.repository.MeetupComponentRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MeetupComponentManagementServiceBean { + + @Autowired + private MeetupComponentRepository meetupComponentRepository; + + public MeetupComponent createComponent(Meetup meetup, String componentId, ComponentPayload payload) { + MeetupComponentId id = MeetupComponentId + .builder() + .meetupId(meetup.getId().getId()) + .serverId(meetup.getServer().getId()) + .componentId(componentId) + .build(); + MeetupComponent component = MeetupComponent + .builder() + .id(id) + .payload(payload) + .meetup(meetup) + .build(); + return meetupComponentRepository.save(component); + } + + public void deleteComponent(MeetupComponent meetupComponent) { + meetupComponentRepository.delete(meetupComponent); + } + + public void deleteAllComponents(Meetup meetup) { + meetupComponentRepository.deleteAll(meetup.getMeetupComponents()); + } +} diff --git a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/management/MeetupParticipatorManagementServiceBean.java b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/management/MeetupParticipatorManagementServiceBean.java index 751f2573..e83a45cb 100644 --- a/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/management/MeetupParticipatorManagementServiceBean.java +++ b/application/sissi-modules/meetup/src/main/java/dev/sheldan/sissi/module/meetup/service/management/MeetupParticipatorManagementServiceBean.java @@ -3,21 +3,24 @@ package dev.sheldan.sissi.module.meetup.service.management; import dev.sheldan.abstracto.core.models.database.AUserInAServer; import dev.sheldan.sissi.module.meetup.model.database.Meetup; import dev.sheldan.sissi.module.meetup.model.database.MeetupDecision; -import dev.sheldan.sissi.module.meetup.model.database.MeetupParticipator; +import dev.sheldan.sissi.module.meetup.model.database.MeetupParticipant; import dev.sheldan.sissi.module.meetup.model.database.embed.MeetupParticipationId; import dev.sheldan.sissi.module.meetup.repository.MeetupParticipatorRepository; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.List; import java.util.Optional; @Component +@Slf4j public class MeetupParticipatorManagementServiceBean { @Autowired private MeetupParticipatorRepository repository; - public Optional getParticipation(Meetup meetup, AUserInAServer aUserInAServer) { + public Optional getParticipation(Meetup meetup, AUserInAServer aUserInAServer) { MeetupParticipationId id = MeetupParticipationId .builder() .meetupId(meetup.getId().getId()) @@ -27,14 +30,20 @@ public class MeetupParticipatorManagementServiceBean { return repository.findById(id); } - public MeetupParticipator createParticipation(Meetup meetup, AUserInAServer aUserInAServer, MeetupDecision meetupDecision) { + public void deleteParticipants(List participants) { + log.info("Deleting {} participants", participants.size()); + repository.deleteAll(participants); + participants.forEach(meetupParticipant -> meetupParticipant.setMeetup(null)); + } + + public MeetupParticipant createParticipation(Meetup meetup, AUserInAServer aUserInAServer, MeetupDecision meetupDecision) { MeetupParticipationId id = MeetupParticipationId .builder() .meetupId(meetup.getId().getId()) .serverId(meetup.getServer().getId()) .participatorId(aUserInAServer.getUserInServerId()) .build(); - MeetupParticipator participator = MeetupParticipator + MeetupParticipant participator = MeetupParticipant .builder() .id(id) .meetup(meetup) diff --git a/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/collection.xml b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/collection.xml new file mode 100644 index 00000000..30263db2 --- /dev/null +++ b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/collection.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/seedData/command.xml b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/seedData/command.xml new file mode 100644 index 00000000..5008734c --- /dev/null +++ b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/seedData/command.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/seedData/data.xml b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/seedData/data.xml new file mode 100644 index 00000000..c048f6f5 --- /dev/null +++ b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/seedData/data.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/meetup_component.xml b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/meetup_component.xml new file mode 100644 index 00000000..744950b6 --- /dev/null +++ b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/meetup_component.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + DROP TRIGGER IF EXISTS meetup_component_insert_trigger ON meetup_component; + CREATE TRIGGER meetup_component_insert_trigger BEFORE INSERT ON meetup_component FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure(); + + + + \ No newline at end of file diff --git a/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/meetup_participator.xml b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/meetup_participator.xml new file mode 100644 index 00000000..f3e8859b --- /dev/null +++ b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/meetup_participator.xml @@ -0,0 +1,16 @@ + + + + + ALTER TABLE meetup_participator DROP CONSTRAINT check_meetup_participator_decision; + ALTER TABLE meetup_participator ADD CONSTRAINT check_meetup_participator_decision CHECK (decision IN ('YES','NO', 'MAYBE', 'NO_TIME')); + + + + \ No newline at end of file diff --git a/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/tables.xml b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/tables.xml new file mode 100644 index 00000000..2f23a46d --- /dev/null +++ b/application/sissi-modules/meetup/src/main/resources/migrations/1.2.0/tables/tables.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/application/sissi-modules/meetup/src/main/resources/migrations/meetup-changeLog.xml b/application/sissi-modules/meetup/src/main/resources/migrations/meetup-changeLog.xml index 997ee5f8..5eaad8b2 100644 --- a/application/sissi-modules/meetup/src/main/resources/migrations/meetup-changeLog.xml +++ b/application/sissi-modules/meetup/src/main/resources/migrations/meetup-changeLog.xml @@ -7,4 +7,5 @@ http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" > + \ No newline at end of file diff --git a/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/cancelMeetup/cancelMeetup_response_embed_en_US.ftl b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/cancelMeetup/cancelMeetup_response_embed_en_US.ftl new file mode 100644 index 00000000..1036f38a --- /dev/null +++ b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/cancelMeetup/cancelMeetup_response_embed_en_US.ftl @@ -0,0 +1,6 @@ +{ + "additionalMessage": "<@safe_include "cancelMeetup_response_text"/>", + "messageConfig": { + "ephemeral": true + } +} \ No newline at end of file diff --git a/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/general/meetup_cancel_notification_embed_en_US.ftl b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/cancelMeetup/meetup_cancel_notification_embed_en_US.ftl similarity index 87% rename from templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/general/meetup_cancel_notification_embed_en_US.ftl rename to templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/cancelMeetup/meetup_cancel_notification_embed_en_US.ftl index 85b664bc..d7547efc 100644 --- a/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/general/meetup_cancel_notification_embed_en_US.ftl +++ b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/cancelMeetup/meetup_cancel_notification_embed_en_US.ftl @@ -2,7 +2,7 @@ { "embeds": [ { - <#include "abstracto_color">, + <#include "abstracto_color">, <#assign time><@format_instant_date_time instant=meetupTime/> <#assign topicText>${topic?json_string} "description": "<#include "meetup_cancel_notification_description">" diff --git a/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_confirmation_embed_en_US.ftl b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_confirmation_embed_en_US.ftl new file mode 100644 index 00000000..0fd68d02 --- /dev/null +++ b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_confirmation_embed_en_US.ftl @@ -0,0 +1,25 @@ +<#include "format_instant"> +{ + "embeds": [ + { + <#include "abstracto_color">, + "title": { + "title": "${topic?json_string}" + }, + "description": "<@format_instant_date_time instant=meetupTime/> +${description?json_string}" + } + ], + "buttons": [ + { + "label": "<@safe_include "createMeetup_confirm_button_label"/>", + "id": "${confirmationId}", + "buttonStyle": "success" + }, + { + "label": "<@safe_include "createMeetup_cancel_button_label"/>", + "id": "${cancelId}", + "buttonStyle": "danger" + } + ] +} \ No newline at end of file diff --git a/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_notification_embed_en_US.ftl b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_notification_embed_en_US.ftl new file mode 100644 index 00000000..2353a078 --- /dev/null +++ b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_notification_embed_en_US.ftl @@ -0,0 +1,13 @@ +<#include "format_instant"> +{ + "embeds": [ + { + <#include "abstracto_color">, + <#assign topicText=meetupTopic> + <#assign oldTime><@format_instant_date_time instant=oldDate/> + <#assign newTime><@format_instant_date_time instant=newDate/> + <#assign messageLink=meetupMessage.jumpUrl> + "description": "<@safe_include "changeMeetupTime_notification_text"/>" + } + ] +} \ No newline at end of file diff --git a/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_notification_message_embed_en_US.ftl b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_notification_message_embed_en_US.ftl new file mode 100644 index 00000000..63a8d3ff --- /dev/null +++ b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_notification_message_embed_en_US.ftl @@ -0,0 +1,5 @@ +{ + <#assign userMentions><#list participants as user>${user.memberMention}<#sep>, + "additionalMessage": "${userMentions?json_string} +${notificationMessage}" +} \ No newline at end of file diff --git a/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_response_embed_en_US.ftl b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_response_embed_en_US.ftl new file mode 100644 index 00000000..c286ea7c --- /dev/null +++ b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_response_embed_en_US.ftl @@ -0,0 +1,6 @@ +{ + "additionalMessage": "<@safe_include "notifyMeetupParticipants_response_text"/>", + "messageConfig": { + "ephemeral": true + } +} \ No newline at end of file diff --git a/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/exception/meetup_not_organizer_exception_en_US.ftl b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/exception/meetup_not_organizer_exception_en_US.ftl new file mode 100644 index 00000000..b27a29fc --- /dev/null +++ b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/exception/meetup_not_organizer_exception_en_US.ftl @@ -0,0 +1 @@ +<#include "meetup_not_organizer_exception_message"> \ No newline at end of file diff --git a/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/general/meetup_display_embed_en_US.ftl b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/general/meetup_display_embed_en_US.ftl index 4e310f18..0f7f6c69 100644 --- a/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/general/meetup_display_embed_en_US.ftl +++ b/templates/sissi-templates/module-templates/meetup-templates/src/main/resources/en_US/general/meetup_display_embed_en_US.ftl @@ -6,16 +6,18 @@ { <#include "abstracto_color">, "title": { - "title": "${topic?json_string}" + "title": "${topic?json_string} - <@safe_include "meetup_message_id_display"/>" }, <#assign time><@format_instant_date_time instant=meetupTime/> <#assign timeRelative><@format_instant_relative instant=meetupTime/> <#assign organizerText>${organizer.memberMention} + <#assign meetupId=meetupId/> <#assign descriptionText>${description?json_string} <#assign participantsText> (${participants?size}) <#list participants as member>${member.memberMention}<#sep>, <#else><#include "meetup_message_no_member"> <#assign maybeParticipantsText> (${maybeParticipants?size}) <#list maybeParticipants as member>${member.memberMention}<#sep>, <#else><#include "meetup_message_no_member"> + <#assign noTimeParticipantsText> (${noTimeParticipants?size}) <#list noTimeParticipants as member>${member.memberMention}<#sep>, <#else><#include "meetup_message_no_member"> <#assign declinedParticipantsText> (${declinedParticipants?size}) <#list declinedParticipants as member>${member.memberMention}<#sep>, <#else><#include "meetup_message_no_member"> - "description": "<#if cancelled>~~<#include "meetup_display_description"><#if cancelled>~~" + "description": "<#if cancelled>~~<@safe_include "meetup_display_description"/><#if cancelled>~~" } ], <#if yesId?has_content && noId?has_content && maybeId?has_content && !cancelled> @@ -31,13 +33,13 @@ "buttonStyle": "secondary" }, { - "label": "<@safe_include "meetup_message_no_button_label"/>", - "id": "${noId}", + "label": "<@safe_include "meetup_message_no_time_button_label"/>", + "id": "${noTimeId}", "buttonStyle": "danger" }, { - "label": "<@safe_include "meetup_message_cancel_button_label"/>", - "id": "${cancelId}", + "label": "<@safe_include "meetup_message_no_button_label"/>", + "id": "${noId}", "buttonStyle": "danger" } ], diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/cancelMeetup_response_text_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/cancelMeetup_response_text_en_US.ftl new file mode 100644 index 00000000..8eacee3d --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/cancelMeetup_response_text_en_US.ftl @@ -0,0 +1 @@ +Meetup has been cancelled. \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_description_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_description_en_US.ftl new file mode 100644 index 00000000..ed4d52ed --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_description_en_US.ftl @@ -0,0 +1 @@ +Cancels a meetup \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_long_help_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_long_help_en_US.ftl new file mode 100644 index 00000000..3b6d8dad --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_long_help_en_US.ftl @@ -0,0 +1,3 @@ +This command is used to cancel a meetup. +This includes notifying all current participants, who either said yes or maybe, that the meetup has been cancelled and updating the message to reflect this. +Cancelled meetups are deleted after one to two days completely. diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_parameter_meetupId_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_parameter_meetupId_en_US.ftl new file mode 100644 index 00000000..b020fc41 --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/help/cancelMeetup_parameter_meetupId_en_US.ftl @@ -0,0 +1 @@ +The ID of the meetup to cancel \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_cancel_notification_description_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/meetup_cancel_notification_description_en_US.ftl similarity index 100% rename from templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_cancel_notification_description_en_US.ftl rename to templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/cancelMeetup/meetup_cancel_notification_description_en_US.ftl diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_notification_text_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_notification_text_en_US.ftl new file mode 100644 index 00000000..cfb81397 --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/changeMeetupTime_notification_text_en_US.ftl @@ -0,0 +1,2 @@ +Meetup with topic ${topicText} has been moved from ${oldTime} to ${newTime}. +Your response has been removed, please click [here](${messageLink}) to respond again. diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_description_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_description_en_US.ftl new file mode 100644 index 00000000..d8ede4c6 --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_description_en_US.ftl @@ -0,0 +1 @@ +Changes the time at which a meetup happens \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_long_help_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_long_help_en_US.ftl new file mode 100644 index 00000000..df53b5e4 --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_long_help_en_US.ftl @@ -0,0 +1,3 @@ +This command is used to change the time of a meetup. +This includes notifying all current participants, who either said yes, maybe or no time, that the time of the meetup has changed. +All previous responses are deleted (except no) and the message is updated accordingly. \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_parameter_meetupId_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_parameter_meetupId_en_US.ftl new file mode 100644 index 00000000..44aec92d --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_parameter_meetupId_en_US.ftl @@ -0,0 +1 @@ +The ID of the meetup to change the timestamp of \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_parameter_newTimeStamp_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_parameter_newTimeStamp_en_US.ftl new file mode 100644 index 00000000..cdacd593 --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/changeMeetupTime/help/changeMeetupTime_parameter_newTimeStamp_en_US.ftl @@ -0,0 +1 @@ +New time of the meetup (https://www.unixtimestamp.com/) \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_description_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_description_en_US.ftl new file mode 100644 index 00000000..bee0010e --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_description_en_US.ftl @@ -0,0 +1 @@ +Notifies all participant of the meetup \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_long_help_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_long_help_en_US.ftl new file mode 100644 index 00000000..a78b9036 --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_long_help_en_US.ftl @@ -0,0 +1,2 @@ +This command is used to notify all participants of a meetup. +This means every participant will get mentioned and the message will be sent. \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_parameter_meetupId_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_parameter_meetupId_en_US.ftl new file mode 100644 index 00000000..63fcc05a --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_parameter_meetupId_en_US.ftl @@ -0,0 +1 @@ +The ID of the meetup to notify the participants for \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_parameter_notificationMessage_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_parameter_notificationMessage_en_US.ftl new file mode 100644 index 00000000..21a7cab6 --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/help/notifyMeetupParticipants_parameter_notificationMessage_en_US.ftl @@ -0,0 +1 @@ +The message to send to the participants \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_response_text_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_response_text_en_US.ftl new file mode 100644 index 00000000..8a78695f --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/commands/notifyMeetupParticipants/notifyMeetupParticipants_response_text_en_US.ftl @@ -0,0 +1 @@ +Participants have been notified. \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/exception/meetup_not_organizer_exception_message_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/exception/meetup_not_organizer_exception_message_en_US.ftl new file mode 100644 index 00000000..9715ced3 --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/exception/meetup_not_organizer_exception_message_en_US.ftl @@ -0,0 +1 @@ +You are not the organizer of the meetup. \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_display_description_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_display_description_en_US.ftl index 2004bd61..45a55298 100644 --- a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_display_description_en_US.ftl +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_display_description_en_US.ftl @@ -6,4 +6,6 @@ Participants: ${participantsText} Maybe: ${maybeParticipantsText} -Declined: ${declinedParticipantsText} \ No newline at end of file +Declined: ${declinedParticipantsText} + +No time: ${noTimeParticipantsText} \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_cancel_button_label_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_cancel_button_label_en_US.ftl deleted file mode 100644 index d075cdd7..00000000 --- a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_cancel_button_label_en_US.ftl +++ /dev/null @@ -1 +0,0 @@ -Cancel \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_id_display_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_id_display_en_US.ftl new file mode 100644 index 00000000..d82d9778 --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_id_display_en_US.ftl @@ -0,0 +1 @@ +ID ${meetupId} \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_no_button_label_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_no_button_label_en_US.ftl index 289cc91e..f66085ee 100644 --- a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_no_button_label_en_US.ftl +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_no_button_label_en_US.ftl @@ -1 +1 @@ -No \ No newline at end of file +Not interested \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_no_time_button_label_en_US.ftl b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_no_time_button_label_en_US.ftl new file mode 100644 index 00000000..9d17ee93 --- /dev/null +++ b/templates/sissi-translations/module-translations/meetup-translations/src/main/resources/en_US/general/meetup_message_no_time_button_label_en_US.ftl @@ -0,0 +1 @@ +No time \ No newline at end of file