[AB-298] fixing various issues related to modmail:

fixing editing a message without messages but only embeds not possible in channel service
refactoring closing parameters to use an object instead of parameters always
adding a progress indicator to closing a modmail thread
adding a notification to contact in order to show where the thread was created
fixing configuration for category (this caused the setup to fail, because there was no default value) and threadMessage feature modes not being correct
refactored model for closing header and added additional information
refactored modmail message logging to use the message history instead of individually loading the messages
adding nicer exception in case the mod mail message update failed
adding creation of AUserInAServer in case the user did not interact on the server yet
changed ID of modmail thread to be identical to the channel it was created in, this is so we can load the channel easier
This commit is contained in:
Sheldan
2021-07-04 12:14:04 +02:00
parent 61eefd53c3
commit 18929c9a01
28 changed files with 483 additions and 363 deletions

View File

@@ -0,0 +1,16 @@
package dev.sheldan.abstracto.modmail.model;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Member;
@Getter
@Setter
@Builder
public class ClosingContext {
private Boolean notifyUser;
private Boolean log;
private Member closingMember;
private String note;
}

View File

@@ -26,7 +26,6 @@ import java.util.List;
public class ModMailThread implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;

View File

@@ -1,17 +0,0 @@
package dev.sheldan.abstracto.modmail.model.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import java.util.concurrent.CompletableFuture;
@Getter
@Setter
@Builder
public class LoadedModmailThreadMessage {
private CompletableFuture<Message> messageFuture;
private CompletableFuture<Member> memberFuture;
}

View File

@@ -1,24 +0,0 @@
package dev.sheldan.abstracto.modmail.model.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Getter
@Setter
@Builder
public class LoadedModmailThreadMessageList {
private List<LoadedModmailThreadMessage> messageList;
public List<CompletableFuture> getAllFutures() {
List<CompletableFuture> futures = new ArrayList<>();
messageList.forEach(loadedModmailThreadMessage -> {
futures.add(loadedModmailThreadMessage.getMemberFuture());
futures.add(loadedModmailThreadMessage.getMessageFuture());
});
return futures;
}
}

View File

@@ -0,0 +1,13 @@
package dev.sheldan.abstracto.modmail.model.template;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class ClosingProgressModel {
private Integer loggedMessages;
private Integer totalMessages;
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.modmail.model.template;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.TextChannel;
@Getter
@Setter
@Builder
public class ContactNotificationModel {
private Member targetMember;
private TextChannel createdChannel;
}

View File

@@ -4,8 +4,11 @@ import dev.sheldan.abstracto.modmail.model.database.ModMailThread;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import java.time.Duration;
import java.time.Instant;
/**
* This model is used when rendering the message before logging the messages in a closed {@link ModMailThread} and contains
@@ -22,13 +25,20 @@ public class ModMailClosingHeaderModel {
/**
* The {@link ModMailThread} which was closed
*/
private ModMailThread closedThread;
private Integer messageCount;
private Instant startDate;
private Long userId;
/**
* The duration between the creation and closed date of a {@link ModMailThread}
* @return The duration between the creation date and the date the thread has been closed
*/
public Duration getDuration() {
return Duration.between(closedThread.getCreated(), closedThread.getClosed());
return Duration.between(startDate, Instant.now());
}
private Member closingMember;
private Boolean silently;
private User user;
private Long serverId;
}

View File

@@ -1,12 +1,11 @@
package dev.sheldan.abstracto.modmail.model.template;
import dev.sheldan.abstracto.core.models.FullUserInServer;
import dev.sheldan.abstracto.modmail.model.database.ModMailMessage;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.User;
/**
* This model is used to render a message from a mod mail thread when closing the thread and logging the thread to the logging post target
@@ -25,9 +24,9 @@ public class ModMailLoggedMessageModel {
private ModMailMessage modMailMessage;
/**
* A reference to the {@link FullUserInServer} which is the author. The member part is null, if the member left the guild.
* A reference to the {@link User} which is the author. The member part is null, if the member left the guild.
*/
private Member author;
private User author;
}

View File

@@ -1,6 +1,5 @@
package dev.sheldan.abstracto.modmail.model.template;
import dev.sheldan.abstracto.core.models.FullUserInServer;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@@ -25,8 +24,8 @@ public class ModMailUserReplyModel {
*/
private Message postedMessage;
/**
* List of {@link FullUserInServer} which are registered as subscribers for a particular mod mail thread and will be pinged
* List of {@link Member} which are registered as subscribers for a particular mod mail thread and will be pinged
* when the user sends a new message
*/
private List<FullUserInServer> subscribers;
private List<Member> subscribers;
}

View File

@@ -0,0 +1,17 @@
package dev.sheldan.abstracto.modmail.model.template;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.User;
import java.util.List;
@Getter
@Setter
@Builder
public class ModmailLoggingThreadMessages {
private List<Message> messages;
private List<User> authors;
}

View File

@@ -1,19 +1,11 @@
package dev.sheldan.abstracto.modmail.service;
import dev.sheldan.abstracto.modmail.model.database.ModMailMessage;
import dev.sheldan.abstracto.modmail.model.dto.LoadedModmailThreadMessageList;
import net.dv8tion.jda.api.entities.Message;
import dev.sheldan.abstracto.modmail.model.template.ModmailLoggingThreadMessages;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Service to handle the messages of a {@link dev.sheldan.abstracto.modmail.model.database.ModMailThread}
*/
public interface ModMailMessageService {
/**
* Loads the given mod mail messages in the form of {@link Message} from Discord and returns the created promises, some of which might fail, if the message was already deleted
* @param modMailMessages The list of {@link ModMailMessage} to load
* @return A instance of {@link LoadedModmailThreadMessageList} which contain the individual results of actively loading the {@link Message} and the {@link net.dv8tion.jda.api.entities.Member}
*/
LoadedModmailThreadMessageList loadModMailMessages(List<ModMailMessage> modMailMessages);
CompletableFuture<ModmailLoggingThreadMessages> loadModMailMessages(List<ModMailMessage> modMailMessages);
}

View File

@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.models.UndoActionInstance;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.modmail.model.ClosingContext;
import dev.sheldan.abstracto.modmail.model.database.ModMailThread;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
@@ -79,13 +80,10 @@ public interface ModMailThreadService {
* post target. This also takes an optional note, which will be displayed in the first message of the logging. This method changes the state of the
* {@link ModMailThread} to CLOSED and notifies the user about closing.
* @param modMailThread The {@link ModMailThread} which is being closed.
* @param note The text of the note used for the header message of the logged mod mail thread.
* @param notifyUser Whether or not the user should be notified
* @param log whether or not the closed {@link ModMailThread} should be logged (if the {@link dev.sheldan.abstracto.core.config.FeatureMode} is enabled)
* @param undoActions A list of {@link dev.sheldan.abstracto.core.models.UndoAction actions} to be undone in case the operation fails. This list will be filled in the method.
* @return A {@link CompletableFuture future} which completes when the {@link ModMailThread thread} has been closed.
*/
CompletableFuture<Void> closeModMailThread(ModMailThread modMailThread, String note, boolean notifyUser, List<UndoActionInstance> undoActions, Boolean log);
CompletableFuture<Void> closeModMailThreadEvaluateLogging(ModMailThread modMailThread, ClosingContext closingConfig, List<UndoActionInstance> undoActions);
/**
* Closes the mod mail thread which means: deletes the {@link net.dv8tion.jda.api.entities.TextChannel} associated with the mod mail thread,
@@ -93,14 +91,11 @@ public interface ModMailThreadService {
* be displayed in the first message of the logging. This method changes the state of the {@link ModMailThread} to
* CLOSED and notifies the user about closing.
* @param modMailThread The {@link ModMailThread} which is being closed.
* @param note The text of the note used for the header message of the logged mod mail thread, this is only required when actually
* logging the mod mail thread
* @param notifyUser Whether or not the user should be notified
* @param logThread Whether or not the thread should be logged to the appropriate post target
* @param closingConfig The {@link ClosingContext config} how the thread shoudl be closed
* @param undoActions A list of {@link dev.sheldan.abstracto.core.models.UndoAction actions} to be undone in case the operation fails. This list will be filled in the method.
* @return A {@link CompletableFuture future} which completes when the {@link ModMailThread thread} has been closed
*/
CompletableFuture<Void> closeModMailThread(ModMailThread modMailThread, String note, boolean notifyUser, boolean logThread, List<UndoActionInstance> undoActions);
CompletableFuture<Void> closeModMailThread(ModMailThread modMailThread, ClosingContext closingConfig, List<UndoActionInstance> undoActions);
boolean isModMailThread(AChannel channel);
boolean isModMailThread(Long channelId);