[AB-65] adding ability to join a reminder via button

This commit is contained in:
Sheldan
2022-08-28 23:13:40 +02:00
parent a43725df39
commit 30655dbfef
18 changed files with 444 additions and 15 deletions

View File

@@ -5,13 +5,17 @@ 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.interaction.ComponentPayloadService;
import dev.sheldan.abstracto.core.interaction.ComponentService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.template.display.MemberNameDisplay;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
@@ -23,6 +27,7 @@ import dev.sheldan.abstracto.remind.config.RemindFeatureDefinition;
import dev.sheldan.abstracto.remind.config.RemindSlashCommandNames;
import dev.sheldan.abstracto.remind.model.database.Reminder;
import dev.sheldan.abstracto.remind.model.template.commands.ReminderModel;
import dev.sheldan.abstracto.remind.payload.JoinReminderPayload;
import dev.sheldan.abstracto.remind.service.ReminderService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
@@ -41,6 +46,7 @@ public class Remind extends AbstractConditionableCommand {
public static final String REMINDER_EMBED_KEY = "remind_response";
public static final String DURATION_PARAMETER = "duration";
public static final String REMIND_TEXT_PARAMETER = "remindText";
public static final String REMINDER_JOIN_BUTTON_ORIGIN = "REMINDER_JOIN_BUTTON";
@Autowired
private ReminderService remindService;
@@ -60,6 +66,12 @@ public class Remind extends AbstractConditionableCommand {
@Autowired
private InteractionService interactionService;
@Autowired
private ComponentService componentService;
@Autowired
private ComponentPayloadService componentPayloadService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
@@ -68,13 +80,24 @@ public class Remind extends AbstractConditionableCommand {
Long serverId = commandContext.getGuild().getIdLong();
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
Reminder createdReminder = remindService.createReminderInForUser(aUserInAServer, text, remindTime, commandContext.getMessage());
String joinButtonId = componentService.generateComponentId();
ReminderModel remindModel = ReminderModel
.builder()
.remindText(text)
.member(commandContext.getAuthor())
.memberDisplay(MemberNameDisplay.fromMember(commandContext.getAuthor()))
.joinButtonId(joinButtonId)
.reminder(createdReminder)
.message(ServerChannelMessage.fromMessage(commandContext.getMessage()))
.build();
remindModel.setReminder(createdReminder);
JoinReminderPayload payload = JoinReminderPayload
.builder()
.remindedUserId(commandContext.getAuthor().getIdLong())
.reminderId(createdReminder.getId())
.serverId(serverId)
.build();
componentPayloadService.createButtonPayload(joinButtonId, payload, REMINDER_JOIN_BUTTON_ORIGIN, aUserInAServer.getServerReference());
log.info("Notifying user {} about reminder being scheduled.", commandContext.getAuthor().getId());
MessageToSend messageToSend = templateService.renderEmbedTemplate(REMINDER_EMBED_KEY, remindModel, serverId);
@@ -90,15 +113,26 @@ public class Remind extends AbstractConditionableCommand {
Long serverId = event.getGuild().getIdLong();
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(event.getMember());
Long snowFlake = SnowflakeUtils.createSnowFlake();
String joinButtonId = componentService.generateComponentId();
Reminder createdReminder = remindService.createReminderInForUser(aUserInAServer, reminderText, duration, event.getChannel().getIdLong(), snowFlake);
ReminderModel remindModel = ReminderModel
.builder()
.remindText(reminderText)
.member(event.getMember())
.joinButtonId(joinButtonId)
.memberDisplay(MemberNameDisplay.fromMember(event.getMember()))
.reminder(createdReminder)
.build();
remindModel.setReminder(createdReminder);
JoinReminderPayload payload = JoinReminderPayload
.builder()
.remindedUserId(event.getMember().getIdLong())
.reminderId(createdReminder.getId())
.serverId(serverId)
.build();
componentPayloadService.createButtonPayload(joinButtonId, payload, REMINDER_JOIN_BUTTON_ORIGIN, aUserInAServer.getServerReference());
log.info("Notifying user {} about reminder being scheduled.", event.getMember().getId());
MessageToSend messageToSend = templateService.renderEmbedTemplate(REMINDER_EMBED_KEY, remindModel, serverId);
return interactionService.replyMessageToSend(messageToSend, event)

View File

@@ -0,0 +1,86 @@
package dev.sheldan.abstracto.remind.listener;
import dev.sheldan.abstracto.core.command.execution.DriedCommandContext;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListener;
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerModel;
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerResult;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.remind.command.Remind;
import dev.sheldan.abstracto.remind.config.RemindFeatureDefinition;
import dev.sheldan.abstracto.remind.model.database.Reminder;
import dev.sheldan.abstracto.remind.model.database.ReminderParticipant;
import dev.sheldan.abstracto.remind.model.template.listener.ReminderJoiningModel;
import dev.sheldan.abstracto.remind.payload.JoinReminderPayload;
import dev.sheldan.abstracto.remind.service.management.ReminderManagementService;
import dev.sheldan.abstracto.remind.service.management.ReminderParticipantManagementServiceBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.Optional;
@Component
public class ReminderJoinButtonListener implements ButtonClickedListener {
public static final String REMIND_JOINING_NOTIFICATION_TEMPLATE = "remind_joining_notification";
@Autowired
private ReminderParticipantManagementServiceBean reminderParticipantManagementServiceBean;
@Autowired
private ReminderManagementService reminderManagementService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private InteractionService interactionService;
@Override
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
JoinReminderPayload payload = (JoinReminderPayload) model.getDeserializedPayload();
ReminderJoiningModel joiningNotificationModel = new ReminderJoiningModel();
if(payload.getRemindedUserId() == model.getEvent().getUser().getIdLong()) {
joiningNotificationModel.setSelfJoin(true);
} else {
Reminder reminder = reminderManagementService.loadReminder(payload.getReminderId());
AUserInAServer buttonClicker = userInServerManagementService.loadOrCreateUser(model.getEvent().getMember());
Optional<ReminderParticipant> existingParticipant = reminderParticipantManagementServiceBean.getReminderParticipant(reminder, buttonClicker);
boolean reminderIsInThePast = reminder.getTargetDate().isBefore(Instant.now());
if(reminderIsInThePast) {
joiningNotificationModel.setFailedToJoin(true);
} else {
if(existingParticipant.isPresent()) {
joiningNotificationModel.setJoined(false);
reminderParticipantManagementServiceBean.removeMemberFromReminder(existingParticipant.get());
} else {
joiningNotificationModel.setReminderDate(reminder.getTargetDate());
joiningNotificationModel.setJoined(true);
reminderParticipantManagementServiceBean.addMemberToReminder(reminder, buttonClicker);
}
}
}
interactionService.sendMessageToInteraction(REMIND_JOINING_NOTIFICATION_TEMPLATE, joiningNotificationModel, model.getEvent().getHook());
return ButtonClickedListenerResult.ACKNOWLEDGED;
}
@Override
public Boolean handlesEvent(ButtonClickedListenerModel model) {
return model.getEvent().isFromGuild() && model.getOrigin().equals(Remind.REMINDER_JOIN_BUTTON_ORIGIN);
}
@Override
public FeatureDefinition getFeature() {
return RemindFeatureDefinition.REMIND;
}
@Override
public Integer getPriority() {
return ListenerPriority.MEDIUM;
}
}

View File

@@ -0,0 +1,13 @@
package dev.sheldan.abstracto.remind.payload;
import dev.sheldan.abstracto.core.interaction.button.ButtonPayload;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class JoinReminderPayload implements ButtonPayload {
private Long reminderId;
private Long serverId;
private Long remindedUserId;
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.remind.repository;
import dev.sheldan.abstracto.remind.model.database.Reminder;
import dev.sheldan.abstracto.remind.model.database.ReminderParticipant;
import dev.sheldan.abstracto.remind.model.database.embed.ReminderUserId;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ReminderParticipantRepository extends JpaRepository<ReminderParticipant, ReminderUserId> {
List<ReminderParticipant> findAllByReminder(Reminder reminder);
}

View File

@@ -4,6 +4,8 @@ import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
import dev.sheldan.abstracto.core.models.template.display.MemberNameDisplay;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.GuildService;
import dev.sheldan.abstracto.core.service.MemberService;
@@ -14,8 +16,10 @@ import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.remind.exception.NotPossibleToSnoozeException;
import dev.sheldan.abstracto.remind.exception.ReminderNotFoundException;
import dev.sheldan.abstracto.remind.model.database.Reminder;
import dev.sheldan.abstracto.remind.model.database.ReminderParticipant;
import dev.sheldan.abstracto.remind.model.template.commands.ExecutedReminderModel;
import dev.sheldan.abstracto.remind.service.management.ReminderManagementService;
import dev.sheldan.abstracto.remind.service.management.ReminderParticipantManagementService;
import dev.sheldan.abstracto.scheduling.model.JobParameters;
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
import lombok.extern.slf4j.Slf4j;
@@ -29,10 +33,12 @@ import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Component
@Slf4j
@@ -63,6 +69,9 @@ public class RemindServiceBean implements ReminderService {
@Autowired
private ChannelService channelService;
@Autowired
private ReminderParticipantManagementService reminderParticipantManagementService;
@Autowired
@Qualifier("reminderScheduler")
private ScheduledExecutorService instantReminderScheduler;
@@ -131,17 +140,20 @@ public class RemindServiceBean implements ReminderService {
}
AServer server = reminderToRemindFor.getServer();
AChannel channel = reminderToRemindFor.getChannel();
Long userId = reminderToRemindFor.getRemindedUser().getUserReference().getId();
log.info("Executing reminder {} in channel {} in server {} for user {}.",
reminderId, channel.getId(), server.getId(), reminderToRemindFor.getRemindedUser().getUserReference().getId());
reminderId, channel.getId(), server.getId(), userId);
Optional<Guild> guildToAnswerIn = guildService.getGuildByIdOptional(server.getId());
if(guildToAnswerIn.isPresent()) {
Optional<GuildMessageChannel> channelToAnswerIn = channelService.getMessageChannelFromServerOptional(server.getId(), channel.getId());
// only send the message if the channel still exists, if not, only set the reminder to reminded.
if(channelToAnswerIn.isPresent()) {
memberService.getMemberInServerAsync(server.getId(), reminderToRemindFor.getRemindedUser().getUserReference().getId()).thenAccept(member ->
memberService.getMemberInServerAsync(server.getId(), userId).thenAccept(member ->
self.sendReminderText(reminderId, channelToAnswerIn.get(), member)
);
).exceptionally(throwable -> {
log.warn("Member {} not anymore in server {} - not reminding.", userId, server.getId(), throwable);
return null;
});
} else {
log.warn("Channel {} in server {} to remind user did not exist anymore. Ignoring reminder {}", channel.getId(), server.getId(), reminderId);
}
@@ -155,10 +167,16 @@ public class RemindServiceBean implements ReminderService {
public CompletableFuture<Void> sendReminderText(Long reminderId, GuildMessageChannel channelToAnswerIn, Member member) {
Reminder reminder = reminderManagementService.loadReminder(reminderId);
log.debug("Sending remind message for reminder {} to user user {} in server {}.", reminderId, member.getIdLong(), member.getGuild().getIdLong());
List<ReminderParticipant> participants = reminderParticipantManagementService.getReminderParticipants(reminder);
List<MemberDisplay> participantsDisplays = participants
.stream()
.map(reminderParticipant -> MemberDisplay.fromAUserInAServer(reminderParticipant.getParticipator()))
.collect(Collectors.toList());
ExecutedReminderModel build = ExecutedReminderModel
.builder()
.reminder(reminder)
.member(member)
.reminderParticipants(participantsDisplays)
.memberNameDisplay(MemberNameDisplay.fromMember(member))
.duration(Duration.between(reminder.getReminderDate(), reminder.getTargetDate()))
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate(REMINDER_TEMPLATE_TEXT, build, channelToAnswerIn.getGuild().getIdLong());

View File

@@ -0,0 +1,61 @@
package dev.sheldan.abstracto.remind.service.management;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.remind.model.database.Reminder;
import dev.sheldan.abstracto.remind.model.database.ReminderParticipant;
import dev.sheldan.abstracto.remind.model.database.embed.ReminderUserId;
import dev.sheldan.abstracto.remind.repository.ReminderParticipantRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
@Component
public class ReminderParticipantManagementServiceBean implements ReminderParticipantManagementService {
@Autowired
private ReminderParticipantRepository reminderParticipantRepository;
@Override
public ReminderParticipant addMemberToReminder(Reminder reminder, AUserInAServer aUserInAServer) {
ReminderUserId id = new ReminderUserId(reminder.getId(), aUserInAServer.getUserInServerId());
ReminderParticipant reminderParticipant = ReminderParticipant
.builder()
.reminder(reminder)
.participator(aUserInAServer)
.server(aUserInAServer.getServerReference())
.reminderParticipantId(id)
.build();
return reminderParticipantRepository.save(reminderParticipant);
}
@Override
public void removeMemberFromReminder(Reminder reminder, AUserInAServer aUserInAServer) {
ReminderUserId id = new ReminderUserId(reminder.getId(), aUserInAServer.getUserInServerId());
reminderParticipantRepository.deleteById(id);
}
@Override
public void removeMemberFromReminder(ReminderParticipant reminderParticipant) {
reminderParticipantRepository.delete(reminderParticipant);
}
@Override
public Optional<ReminderParticipant> getReminderParticipant(Reminder reminder, AUserInAServer aUserInAServer) {
ReminderUserId id = new ReminderUserId(reminder.getId(), aUserInAServer.getUserInServerId());
return reminderParticipantRepository.findById(id);
}
@Override
public boolean isReminderParticipator(Reminder reminder, AUserInAServer aUserInAServer) {
ReminderUserId id = new ReminderUserId(reminder.getId(), aUserInAServer.getUserInServerId());
return reminderParticipantRepository.existsById(id);
}
@Override
public List<ReminderParticipant> getReminderParticipants(Reminder reminder) {
return reminderParticipantRepository.findAllByReminder(reminder);
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,45 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<changeSet author="Sheldan" id="reminder_participant-table">
<createTable tableName="reminder_participant">
<column name="reminder_id" type="BIGINT">
<constraints nullable="false" />
</column>
<column name="reminder_participant_user_in_server_id" type="BIGINT">
<constraints nullable="false" />
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false" />
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
</createTable>
<addPrimaryKey columnNames="reminder_id, reminder_participant_user_in_server_id" tableName="reminder_participant" constraintName="pk_reminder_participant" validate="true"/>
<addForeignKeyConstraint baseColumnNames="reminder_id" baseTableName="reminder_participant" constraintName="fk_reminder_channel"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="id" referencedTableName="reminder" validate="true"/>
<addForeignKeyConstraint baseColumnNames="reminder_participant_user_in_server_id"
baseTableName="reminder_participant" constraintName="fk_reminder_participant_user_in_server"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="reminder" constraintName="fk_reminder_participant_server"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION"
onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS reminder_participant_update_trigger ON reminder_participant;
CREATE TRIGGER reminder_participant_update_trigger BEFORE UPDATE ON reminder_participant FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS reminder_participant_insert_trigger ON reminder_participant;
CREATE TRIGGER reminder_participant_insert_trigger BEFORE INSERT ON reminder_participant FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="reminder_participant.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -9,4 +9,5 @@
<include file="1.0-remind/collection.xml" relativeToChangelogFile="true"/>
<include file="1.2.10-remind/collection.xml" relativeToChangelogFile="true"/>
<include file="1.2.12/collection.xml" relativeToChangelogFile="true"/>
<include file="1.4.3/collection.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -12,11 +12,13 @@ import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.remind.exception.ReminderNotFoundException;
import dev.sheldan.abstracto.remind.model.database.Reminder;
import dev.sheldan.abstracto.remind.service.management.ReminderManagementService;
import dev.sheldan.abstracto.remind.service.management.ReminderParticipantManagementService;
import dev.sheldan.abstracto.scheduling.model.JobParameters;
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.utils.ImageProxy;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -75,6 +77,9 @@ public class RemindServiceBeanTest {
@Mock
private ScheduledExecutorService instantReminderScheduler;
@Mock
private ReminderParticipantManagementService reminderParticipantManagementService;
@Mock
private AServer server;
@@ -84,6 +89,9 @@ public class RemindServiceBeanTest {
@Mock
private AUser user;
@Mock
private User jdaUser;
@Mock
private AChannel aChannel;
@@ -238,6 +246,8 @@ public class RemindServiceBeanTest {
when(remindedMember.getGuild()).thenReturn(guild);
when(guild.getIdLong()).thenReturn(8L);
when(remindedMember.getIdLong()).thenReturn(9L);
when(remindedMember.getUser()).thenReturn(jdaUser);
when(jdaUser.getDefaultAvatar()).thenReturn(Mockito.mock(ImageProxy.class));
Reminder remindedReminder = Mockito.mock(Reminder.class);
when(remindedReminder.getTargetDate()).thenReturn(Instant.now());
when(remindedReminder.getReminderDate()).thenReturn(Instant.now());

View File

@@ -0,0 +1,44 @@
package dev.sheldan.abstracto.remind.model.database;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.remind.model.database.embed.ReminderUserId;
import lombok.*;
import javax.persistence.*;
import java.time.Instant;
@Entity
@Table(name="reminder_participant")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
public class ReminderParticipant {
@EmbeddedId
private ReminderUserId reminderParticipantId;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@MapsId("reminderId")
@JoinColumn(name = "reminder_id", nullable = false)
private Reminder reminder;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@MapsId("participantUserInServerId")
@JoinColumn(name = "reminder_participant_user_in_server_id", nullable = false)
private AUserInAServer participator;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "server_id", nullable = false)
private AServer server;
@Column(name = "created", nullable = false, insertable = false, updatable = false)
private Instant created;
@Column(name = "updated", insertable = false, updatable = false)
private Instant updated;
}

View File

@@ -0,0 +1,36 @@
package dev.sheldan.abstracto.remind.model.database.embed;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.io.Serializable;
import java.util.Objects;
@Embeddable
public class ReminderUserId implements Serializable {
@Column(name = "reminder_id")
private Long reminderId;
@Column(name = "reminder_participant_user_in_server_id")
private Long participantUserInServerId;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ReminderUserId counterId = (ReminderUserId) o;
return Objects.equals(reminderId, counterId.reminderId) &&
Objects.equals(participantUserInServerId, counterId.participantUserInServerId);
}
@Override
public int hashCode() {
return Objects.hash(reminderId, participantUserInServerId);
}
public ReminderUserId(Long reminderId, Long participantUserInServerId) {
this.reminderId = reminderId;
this.participantUserInServerId = participantUserInServerId;
}
public ReminderUserId() {
}
}

View File

@@ -1,21 +1,24 @@
package dev.sheldan.abstracto.remind.model.template.commands;
import dev.sheldan.abstracto.core.models.context.ServerContext;
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
import dev.sheldan.abstracto.core.models.template.display.MemberNameDisplay;
import dev.sheldan.abstracto.core.utils.MessageUtils;
import dev.sheldan.abstracto.remind.model.database.Reminder;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.dv8tion.jda.api.entities.Member;
import java.time.Duration;
import java.util.List;
@Getter
@Setter
@SuperBuilder
public class ExecutedReminderModel extends ServerContext {
private Reminder reminder;
private Member member;
private MemberNameDisplay memberNameDisplay;
private List<MemberDisplay> reminderParticipants;
private Duration duration;
public String getMessageUrl() {

View File

@@ -1,16 +1,20 @@
package dev.sheldan.abstracto.remind.model.template.commands;
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
import dev.sheldan.abstracto.core.models.template.display.MemberNameDisplay;
import dev.sheldan.abstracto.remind.model.database.Reminder;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Member;
@Getter
@Setter
@Builder
public class ReminderModel {
private String remindText;
private Member member;
private MemberNameDisplay memberDisplay;
private Reminder reminder;
private ServerChannelMessage message;
private String joinButtonId;
}

View File

@@ -0,0 +1,17 @@
package dev.sheldan.abstracto.remind.model.template.listener;
import lombok.*;
import java.time.Instant;
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ReminderJoiningModel {
private Instant reminderDate;
private boolean failedToJoin;
private boolean selfJoin;
private boolean joined;
}

View File

@@ -0,0 +1,18 @@
package dev.sheldan.abstracto.remind.service.management;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.remind.model.database.Reminder;
import dev.sheldan.abstracto.remind.model.database.ReminderParticipant;
import java.util.List;
import java.util.Optional;
public interface ReminderParticipantManagementService {
ReminderParticipant addMemberToReminder(Reminder reminder, AUserInAServer aUserInAServer);
void removeMemberFromReminder(Reminder reminder, AUserInAServer aUserInAServer);
void removeMemberFromReminder(ReminderParticipant reminderParticipant);
Optional<ReminderParticipant> getReminderParticipant(Reminder reminder, AUserInAServer aUserInAServer);
boolean isReminderParticipator(Reminder reminder, AUserInAServer aUserInAServer);
List<ReminderParticipant> getReminderParticipants(Reminder reminder);
}