added subscribe and unsubscribe command

This commit is contained in:
Sheldan
2020-05-08 17:02:22 +02:00
parent 5ace3e2abb
commit 1c67d96887
23 changed files with 358 additions and 16 deletions

View File

@@ -0,0 +1,64 @@
package dev.sheldan.abstracto.modmail.commands;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.condition.CommandCondition;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.modmail.commands.condition.RequiresModMailCondition;
import dev.sheldan.abstracto.modmail.config.ModMailFeatures;
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
import dev.sheldan.abstracto.modmail.service.ModMailSubscriptionService;
import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class Subscribe extends AbstractConditionableCommand {
@Autowired
private RequiresModMailCondition requiresModMailCondition;
@Autowired
private ModMailThreadManagementService modMailThreadManagementService;
@Autowired
private ModMailSubscriptionService modMailSubscriptionService;
@Override
public CommandResult execute(CommandContext commandContext) {
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(commandContext.getChannel().getIdLong());
modMailSubscriptionService.subscribeToThread(commandContext.getUserInitiatedContext().getAUserInAServer(), modMailThread);
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("subscribe")
.module(ModMailModuleInterface.MODMAIL)
.parameters(new ArrayList<>())
.help(helpInfo)
.templated(true)
.causesReaction(true)
.build();
}
@Override
public FeatureEnum getFeature() {
return ModMailFeatures.MODMAIL;
}
@Override
public List<CommandCondition> getConditions() {
List<CommandCondition> conditions = super.getConditions();
conditions.add(requiresModMailCondition);
return conditions;
}
}

View File

@@ -0,0 +1,64 @@
package dev.sheldan.abstracto.modmail.commands;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.condition.CommandCondition;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.modmail.commands.condition.RequiresModMailCondition;
import dev.sheldan.abstracto.modmail.config.ModMailFeatures;
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
import dev.sheldan.abstracto.modmail.service.ModMailSubscriptionService;
import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class UnSubscribe extends AbstractConditionableCommand {
@Autowired
private RequiresModMailCondition requiresModMailCondition;
@Autowired
private ModMailThreadManagementService modMailThreadManagementService;
@Autowired
private ModMailSubscriptionService modMailSubscriptionService;
@Override
public CommandResult execute(CommandContext commandContext) {
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(commandContext.getChannel().getIdLong());
modMailSubscriptionService.unsubscribeFromThread(commandContext.getUserInitiatedContext().getAUserInAServer(), modMailThread);
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("unSubscribe")
.module(ModMailModuleInterface.MODMAIL)
.parameters(new ArrayList<>())
.help(helpInfo)
.templated(true)
.causesReaction(true)
.build();
}
@Override
public FeatureEnum getFeature() {
return ModMailFeatures.MODMAIL;
}
@Override
public List<CommandCondition> getConditions() {
List<CommandCondition> conditions = super.getConditions();
conditions.add(requiresModMailCondition);
return conditions;
}
}

View File

@@ -0,0 +1,16 @@
package dev.sheldan.abstracto.modmail.repository;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
import dev.sheldan.abstracto.modmail.models.database.ModMailThreadSubscriber;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ModMailSubscriberRepository extends JpaRepository<ModMailThreadSubscriber, Long> {
List<ModMailThreadSubscriber> findByThreadReference(ModMailThread thread);
boolean existsBySubscriberAndThreadReference(AUserInAServer aUserInAServer, ModMailThread modMailThread);
void deleteBySubscriberAndThreadReference(AUserInAServer aUserInAServer, ModMailThread modMailThread);
}

View File

@@ -0,0 +1,34 @@
package dev.sheldan.abstracto.modmail.service;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.modmail.exception.AlreadySubscribedException;
import dev.sheldan.abstracto.modmail.exception.NotSubscribedException;
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
import dev.sheldan.abstracto.modmail.service.management.ModMailSubscriberManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ModMailSubscriptionServiceBean implements ModMailSubscriptionService {
@Autowired
private ModMailSubscriberManagementService modMailSubscriberManagementService;
@Override
public void subscribeToThread(AUserInAServer aUserInAServer, ModMailThread modMailThread) {
if(!modMailSubscriberManagementService.isSubscribedToThread(aUserInAServer, modMailThread)){
modMailSubscriberManagementService.createSubscriber(aUserInAServer, modMailThread);
} else {
throw new AlreadySubscribedException("The user is already subscribed to the thread.");
}
}
@Override
public void unsubscribeFromThread(AUserInAServer aUserInAServer, ModMailThread modMailThread) {
if(modMailSubscriberManagementService.isSubscribedToThread(aUserInAServer, modMailThread)){
modMailSubscriberManagementService.removeSubscriber(aUserInAServer, modMailThread);
} else {
throw new NotSubscribedException("The user is not subscribed to the thread.");
}
}
}

View File

@@ -10,14 +10,12 @@ import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerService;
import dev.sheldan.abstracto.modmail.config.ModMailFeature;
import dev.sheldan.abstracto.modmail.models.database.ModMailMessage;
import dev.sheldan.abstracto.modmail.models.database.ModMailRole;
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
import dev.sheldan.abstracto.modmail.models.database.ModMailThreadState;
import dev.sheldan.abstracto.modmail.models.database.*;
import dev.sheldan.abstracto.modmail.models.dto.ServerChoice;
import dev.sheldan.abstracto.modmail.models.template.*;
import dev.sheldan.abstracto.modmail.service.management.ModMailMessageManagementService;
import dev.sheldan.abstracto.modmail.service.management.ModMailRoleManagementService;
import dev.sheldan.abstracto.modmail.service.management.ModMailSubscriberManagementService;
import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
@@ -84,6 +82,9 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
@Autowired
private ModMailRoleManagementService modMailRoleManagementService;
@Autowired
private ModMailSubscriberManagementService modMailSubscriberManagementService;
@Autowired
private ModMailThreadServiceBean self;
@@ -229,11 +230,23 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
.aUserInAServer(modMailThread.getUser())
.member(botService.getMemberInServer(modMailThread.getUser()))
.build();
ModMailModeratorReplyModel modMailUserReplyModel = ModMailModeratorReplyModel
List<FullUser> subscribers = new ArrayList<>();
List<ModMailThreadSubscriber> subscriberList = modMailSubscriberManagementService.getSubscribersForThread(modMailThread);
subscriberList.forEach(modMailThreadSubscriber -> {
FullUser subscriber = FullUser
.builder()
.aUserInAServer(modMailThreadSubscriber.getSubscriber())
.member(botService.getMemberInServer(modMailThreadSubscriber.getSubscriber()))
.build();
subscribers.add(subscriber);
});
ModMailUserReplyModel modMailUserReplyModel = ModMailUserReplyModel
.builder()
.modMailThread(modMailThread)
.postedMessage(message)
.threadUser(fullUser)
.subscribers(subscribers)
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate("modmail_user_message", modMailUserReplyModel);
List<CompletableFuture<Message>> completableFutures = channelService.sendMessageToSendToChannel(messageToSend, textChannel);

View File

@@ -0,0 +1,45 @@
package dev.sheldan.abstracto.modmail.service.management;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
import dev.sheldan.abstracto.modmail.models.database.ModMailThreadSubscriber;
import dev.sheldan.abstracto.modmail.repository.ModMailSubscriberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class ModMailSubscriberManagementServiceBean implements ModMailSubscriberManagementService {
@Autowired
private ModMailSubscriberRepository modMailSubscriberRepository;
@Override
public List<ModMailThreadSubscriber> getSubscribersForThread(ModMailThread modMailThread) {
return modMailSubscriberRepository.findByThreadReference(modMailThread);
}
@Override
public boolean isSubscribedToThread(AUserInAServer aUserInAServer, ModMailThread modMailThread) {
return modMailSubscriberRepository.existsBySubscriberAndThreadReference(aUserInAServer, modMailThread);
}
@Override
public ModMailThreadSubscriber createSubscriber(AUserInAServer aUserInAServer, ModMailThread modMailThread) {
ModMailThreadSubscriber subscriber = ModMailThreadSubscriber
.builder()
.subscriber(aUserInAServer)
.threadReference(modMailThread)
.build();
modMailSubscriberRepository.save(subscriber);
return subscriber;
}
@Override
public void removeSubscriber(AUserInAServer aUserInAServer, ModMailThread modMailThread) {
modMailSubscriberRepository.deleteBySubscriberAndThreadReference(aUserInAServer, modMailThread);
}
}

View File

@@ -17,4 +17,7 @@
<#if postedMessage.attachments?size gt 0>
,"imageUrl": "${postedMessage.attachments[0].proxyUrl}"
</#if>
<#if subscribers?size gt 0>
,"additionalMessage": "<#list subscribers as subscriber>${subscriber.member.asMention}<#sep>,</#list>"
</#if>
}

View File

@@ -0,0 +1,20 @@
package dev.sheldan.abstracto.modmail.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
public class AlreadySubscribedException extends AbstractoRunTimeException implements Templatable {
public AlreadySubscribedException(String message) {
super(message);
}
@Override
public String getTemplateName() {
return "modmail_already_subscribed_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -0,0 +1,20 @@
package dev.sheldan.abstracto.modmail.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
public class NotSubscribedException extends AbstractoRunTimeException implements Templatable {
public NotSubscribedException(String message) {
super(message);
}
@Override
public String getTemplateName() {
return "modmail_not_subscribed_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -55,6 +55,15 @@ public class ModMailThread {
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<ModMailMessage> messages = new ArrayList<>();
@OneToMany(
fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE},
orphanRemoval = true)
@JoinColumn(name = "modMailThread")
@Builder.Default
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<ModMailThreadSubscriber> subscribers = new ArrayList<>();
@Enumerated(EnumType.STRING)
@Column
private ModMailThreadState state;

View File

@@ -2,15 +2,4 @@ package dev.sheldan.abstracto.modmail.models.database;
public enum ModMailThreadState {
INITIAL, USER_REPLIED, MOD_REPLIED, CLOSED, CLOSING;
public static ModMailThreadState getState(ModMailThreadState type) {
switch (type) {
case INITIAL: return ModMailThreadState.INITIAL;
case USER_REPLIED: return ModMailThreadState.USER_REPLIED;
case CLOSED: return ModMailThreadState.CLOSED;
case CLOSING: return ModMailThreadState.CLOSING;
default:
case MOD_REPLIED: return ModMailThreadState.MOD_REPLIED;
}
}
}

View File

@@ -0,0 +1,31 @@
package dev.sheldan.abstracto.modmail.models.database;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
@Builder
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "modmail_subscribers")
@Cacheable
@Getter
@Setter
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class ModMailThreadSubscriber {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long subscriberId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "modmail_message_subscriber", nullable = false)
private AUserInAServer subscriber;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "modMailThread", nullable = false)
private ModMailThread threadReference;
}

View File

@@ -7,6 +7,8 @@ import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Message;
import java.util.List;
@Getter
@Setter
@Builder
@@ -14,4 +16,5 @@ public class ModMailUserReplyModel {
private FullUser threadUser;
private Message postedMessage;
private ModMailThread modMailThread;
private List<FullUser> subscribers;
}

View File

@@ -0,0 +1,9 @@
package dev.sheldan.abstracto.modmail.service;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
public interface ModMailSubscriptionService {
void subscribeToThread(AUserInAServer aUserInAServer, ModMailThread modMailThread);
void unsubscribeFromThread(AUserInAServer aUserInAServer, ModMailThread modMailThread);
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.modmail.service.management;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
import dev.sheldan.abstracto.modmail.models.database.ModMailThreadSubscriber;
import java.util.List;
public interface ModMailSubscriberManagementService {
List<ModMailThreadSubscriber> getSubscribersForThread(ModMailThread modMailThread);
boolean isSubscribedToThread(AUserInAServer aUserInAServer, ModMailThread modMailThread);
ModMailThreadSubscriber createSubscriber(AUserInAServer aUserInAServer, ModMailThread modMailThread);
void removeSubscriber(AUserInAServer aUserInAServer, ModMailThread modMailThread);
}

View File

@@ -0,0 +1 @@
Subscribes to the current mod mail thread and pings you whenever there is a new message from the user until you un-subscribe.

View File

@@ -0,0 +1 @@
Causes you to not be pinged in case the user sends another message to this mod mail thread.

View File

@@ -0,0 +1 @@
You are already subscribed to this mod mail thread.

View File

@@ -0,0 +1 @@
You are not subscribed to this mod mail thread.