diff --git a/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/java/dev/sheldan/abstracto/modmail/commands/CloseNoLog.java b/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/java/dev/sheldan/abstracto/modmail/commands/CloseNoLog.java index 433433d64..78eff3190 100644 --- a/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/java/dev/sheldan/abstracto/modmail/commands/CloseNoLog.java +++ b/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/java/dev/sheldan/abstracto/modmail/commands/CloseNoLog.java @@ -7,8 +7,10 @@ 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.core.config.FeatureMode; import dev.sheldan.abstracto.modmail.commands.condition.RequiresModMailCondition; import dev.sheldan.abstracto.modmail.config.ModMailFeatures; +import dev.sheldan.abstracto.modmail.config.ModMailMode; import dev.sheldan.abstracto.modmail.models.database.ModMailThread; import dev.sheldan.abstracto.modmail.service.ModMailThreadService; import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService; @@ -16,6 +18,7 @@ import dev.sheldan.abstracto.templating.service.TemplateService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.Arrays; import java.util.List; @Component @@ -54,7 +57,7 @@ public class CloseNoLog extends AbstractConditionableCommand { @Override public FeatureEnum getFeature() { - return ModMailFeatures.MOD_MAIL_LOGGING; + return ModMailFeatures.MOD_MAIL; } @Override @@ -63,4 +66,9 @@ public class CloseNoLog extends AbstractConditionableCommand { conditions.add(requiresModMailCondition); return conditions; } + + @Override + public List getFeatureModeLimitations() { + return Arrays.asList(ModMailMode.LOGGING); + } } diff --git a/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/java/dev/sheldan/abstracto/modmail/service/ModMailThreadServiceBean.java b/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/java/dev/sheldan/abstracto/modmail/service/ModMailThreadServiceBean.java index 3311c8c81..71d943ba0 100644 --- a/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/java/dev/sheldan/abstracto/modmail/service/ModMailThreadServiceBean.java +++ b/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/java/dev/sheldan/abstracto/modmail/service/ModMailThreadServiceBean.java @@ -12,9 +12,7 @@ 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.core.utils.CompletableFutureList; -import dev.sheldan.abstracto.modmail.config.ModMailFeature; -import dev.sheldan.abstracto.modmail.config.ModMailLoggingFeature; -import dev.sheldan.abstracto.modmail.config.ModMailPostTargets; +import dev.sheldan.abstracto.modmail.config.*; import dev.sheldan.abstracto.modmail.exception.ModMailThreadNotFoundException; import dev.sheldan.abstracto.modmail.models.database.*; import dev.sheldan.abstracto.modmail.models.dto.ServerChoice; @@ -97,7 +95,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService { private EventWaiter eventWaiter; @Autowired - private ModMailLoggingFeature modMailLoggingFeature; + private FeatureModeService featureModeService; @Autowired @@ -354,8 +352,9 @@ public class ModMailThreadServiceBean implements ModMailThreadService { @Override public synchronized void closeModMailThread(ModMailThread modMailThread, MessageChannel feedBack, String note, Boolean notifyUser) { - boolean loggingEnabled = featureFlagService.isFeatureEnabled(modMailLoggingFeature, modMailThread.getServer()); - closeModMailThread(modMailThread, feedBack, note, notifyUser, loggingEnabled); + AFeatureMode aFeatureMode = featureModeService.getFeatureMode(ModMailFeatures.MOD_MAIL, modMailThread.getServer()); + boolean loggingMode = aFeatureMode.getMode().equalsIgnoreCase(ModMailMode.LOGGING.getKey()); + closeModMailThread(modMailThread, feedBack, note, notifyUser, loggingMode); } @Override diff --git a/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/resources/config/modmail.properties b/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/resources/config/modmail.properties index dd695d33d..da1d0590f 100644 --- a/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/resources/config/modmail.properties +++ b/abstracto-application/abstracto-modules/modmail/modmail-impl/src/main/resources/config/modmail.properties @@ -2,6 +2,4 @@ abstracto.postTargets.modmail=modmailLog,modmailPing abstracto.emoteNames.readReaction=readReaction abstracto.defaultEmotes.readReaction=\uD83D\uDC40 abstracto.features.modmail.enabled=false -abstracto.features.modmail.defaultMode=log - -abstracto.features.modmail_logging.enabled=false \ No newline at end of file +abstracto.features.modmail.defaultMode=log \ No newline at end of file diff --git a/abstracto-application/abstracto-modules/modmail/modmail-int/src/main/java/dev/sheldan/abstracto/modmail/config/ModMailFeature.java b/abstracto-application/abstracto-modules/modmail/modmail-int/src/main/java/dev/sheldan/abstracto/modmail/config/ModMailFeature.java index def70db49..d79ccb873 100644 --- a/abstracto-application/abstracto-modules/modmail/modmail-int/src/main/java/dev/sheldan/abstracto/modmail/config/ModMailFeature.java +++ b/abstracto-application/abstracto-modules/modmail/modmail-int/src/main/java/dev/sheldan/abstracto/modmail/config/ModMailFeature.java @@ -18,19 +18,11 @@ public class ModMailFeature implements FeatureConfig { @Autowired private ModMailFeatureValidator modMailFeatureValidator; - @Autowired - private ModMailLoggingFeature modMailLoggingFeature; - @Override public FeatureEnum getFeature() { return ModMailFeatures.MOD_MAIL; } - @Override - public List getDependantFeatures() { - return Arrays.asList(modMailLoggingFeature); - } - @Override public List getRequiredPostTargets() { return Arrays.asList(ModMailPostTargets.MOD_MAIL_PING); diff --git a/abstracto-application/abstracto-modules/modmail/modmail-int/src/main/java/dev/sheldan/abstracto/modmail/config/ModMailFeatures.java b/abstracto-application/abstracto-modules/modmail/modmail-int/src/main/java/dev/sheldan/abstracto/modmail/config/ModMailFeatures.java index d7f20484d..865317e8b 100644 --- a/abstracto-application/abstracto-modules/modmail/modmail-int/src/main/java/dev/sheldan/abstracto/modmail/config/ModMailFeatures.java +++ b/abstracto-application/abstracto-modules/modmail/modmail-int/src/main/java/dev/sheldan/abstracto/modmail/config/ModMailFeatures.java @@ -3,7 +3,7 @@ package dev.sheldan.abstracto.modmail.config; import dev.sheldan.abstracto.core.config.FeatureEnum; public enum ModMailFeatures implements FeatureEnum { - MOD_MAIL("modmail"), MOD_MAIL_LOGGING("modmail_logging"); + MOD_MAIL("modmail"); private String key; diff --git a/abstracto-application/abstracto-modules/modmail/modmail-int/src/main/java/dev/sheldan/abstracto/modmail/config/ModMailLoggingFeature.java b/abstracto-application/abstracto-modules/modmail/modmail-int/src/main/java/dev/sheldan/abstracto/modmail/config/ModMailLoggingFeature.java deleted file mode 100644 index d63e0bf77..000000000 --- a/abstracto-application/abstracto-modules/modmail/modmail-int/src/main/java/dev/sheldan/abstracto/modmail/config/ModMailLoggingFeature.java +++ /dev/null @@ -1,32 +0,0 @@ -package dev.sheldan.abstracto.modmail.config; - -import dev.sheldan.abstracto.core.config.FeatureConfig; -import dev.sheldan.abstracto.core.config.FeatureEnum; -import dev.sheldan.abstracto.core.config.PostTargetEnum; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.Arrays; -import java.util.List; - -@Component -public class ModMailLoggingFeature implements FeatureConfig { - - @Autowired - private ModMailFeature modMailFeature; - - @Override - public FeatureEnum getFeature() { - return ModMailFeatures.MOD_MAIL_LOGGING; - } - - @Override - public List getRequiredFeatures() { - return Arrays.asList(modMailFeature); - } - - @Override - public List getRequiredPostTargets() { - return Arrays.asList(ModMailPostTargets.MOD_MAIL_LOG); - } -} diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/FeatureFlagListener.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/FeatureFlagListener.java index c80fa8344..af186880f 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/FeatureFlagListener.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/FeatureFlagListener.java @@ -49,12 +49,16 @@ public class FeatureFlagListener implements ServerConfigListener { featureFlagService.getAllFeatureConfigs().forEach((featureFlagKey) -> { String featureKey = featureFlagKey.getFeature().getKey(); AFeature feature = featureManagementService.getFeature(featureKey); - FeaturePropertiesConfig featurePropertiesConfig = featureConfigLoader.getFeatures().get(featureKey); - if(service.getFeatureFlag(feature, server.getId()) == null) { - service.createFeatureFlag(feature, server.getId(), featurePropertiesConfig.getEnabled()); - } - if(featurePropertiesConfig.getDefaultMode() != null && !featureModeManagementService.featureModeSet(feature, server)) { - featureModeService.createMode(feature, server, featurePropertiesConfig.getDefaultMode()); + if(featureConfigLoader.getFeatures().containsKey(featureKey)) { + FeaturePropertiesConfig featurePropertiesConfig = featureConfigLoader.getFeatures().get(featureKey); + if(service.getFeatureFlag(feature, server.getId()) == null) { + service.createFeatureFlag(feature, server.getId(), featurePropertiesConfig.getEnabled()); + } + if(featurePropertiesConfig.getDefaultMode() != null && !featureModeManagementService.featureModeSet(feature, server)) { + featureModeService.createMode(feature, server, featurePropertiesConfig.getDefaultMode()); + } + } else { + log.warn("Feature {} was found as interface, but not in the properties configuration. It will not be setup.", featureKey); } }); } diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/FeatureModeServiceBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/FeatureModeServiceBean.java index 8efda6154..75b5e8b68 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/FeatureModeServiceBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/FeatureModeServiceBean.java @@ -117,5 +117,17 @@ public class FeatureModeServiceBean implements FeatureModeService { return featureModeManagementService.createMode(featureFlag, mode); } + @Override + public AFeatureMode getFeatureMode(FeatureEnum featureEnum, AServer server) { + AFeature feature = featureManagementService.getFeature(featureEnum.getKey()); + return getFeatureMode(feature, server); + } + + @Override + public AFeatureMode getFeatureMode(AFeature feature, AServer server) { + AFeatureFlag featureFlag = featureFlagManagementService.getFeatureFlag(feature, server); + return featureModeManagementService.getModeForFeature(featureFlag); + } + } diff --git a/abstracto-application/core/core-impl/src/main/resources/seedData/templates/exceptions/feature_mode_not_correct_message_en_US.ftl b/abstracto-application/core/core-impl/src/main/resources/seedData/templates/exceptions/feature_mode_not_correct_message_en_US.ftl new file mode 100644 index 000000000..c846231c5 --- /dev/null +++ b/abstracto-application/core/core-impl/src/main/resources/seedData/templates/exceptions/feature_mode_not_correct_message_en_US.ftl @@ -0,0 +1 @@ +<#assign featureName><#include "${featureConfig.feature.key}_feature"><#assign featureKey>${featureConfig.feature.key}<#assign requiredModes><#list command.featureModeLimitations as mode>`${mode.key}`, <#include "feature_mode_not_correct_text"> \ No newline at end of file diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/command/condition/AbstractConditionableCommand.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/command/condition/AbstractConditionableCommand.java index 493c5e5fb..609d3c5ae 100644 --- a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/command/condition/AbstractConditionableCommand.java +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/command/condition/AbstractConditionableCommand.java @@ -22,9 +22,12 @@ public abstract class AbstractConditionableCommand implements ConditionalCommand @Autowired protected ImmuneUserCondition immuneUserCondition; + @Autowired + private FeatureModeCondition featureModeCondition; + @Override public List getConditions() { - return new ArrayList<>(Arrays.asList(featureEnabledCondition, commandDisabledCondition, commandDisallowedCondition)); + return new ArrayList<>(Arrays.asList(featureEnabledCondition, commandDisabledCondition, commandDisallowedCondition, featureModeCondition)); } } diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/command/condition/FeatureModeCondition.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/command/condition/FeatureModeCondition.java new file mode 100644 index 000000000..5fe8746c4 --- /dev/null +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/command/condition/FeatureModeCondition.java @@ -0,0 +1,52 @@ +package dev.sheldan.abstracto.core.command.condition; + +import dev.sheldan.abstracto.core.command.Command; +import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.models.IncorrectFeatureModeMessage; +import dev.sheldan.abstracto.core.config.FeatureEnum; +import dev.sheldan.abstracto.core.models.database.AFeatureMode; +import dev.sheldan.abstracto.core.service.FeatureConfigService; +import dev.sheldan.abstracto.core.service.FeatureFlagService; +import dev.sheldan.abstracto.core.service.FeatureModeService; +import dev.sheldan.abstracto.templating.service.TemplateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class FeatureModeCondition implements CommandCondition { + + @Autowired + private TemplateService templateService; + + @Autowired + private FeatureConfigService featureConfigService; + + @Autowired + private FeatureFlagService featureFlagService; + + @Autowired + private FeatureModeService modeService; + + @Override + public ConditionResult shouldExecute(CommandContext context, Command command) { + String reason = ""; + boolean featureModeFits = true; + if(!command.getFeatureModeLimitations().isEmpty()){ + FeatureEnum feature = command.getFeature(); + if(feature != null) { + AFeatureMode featureMode = modeService.getFeatureMode(feature, context.getUserInitiatedContext().getServer()); + featureModeFits = command.getFeatureModeLimitations().stream().anyMatch(featureMode1 -> featureMode1.getKey().equalsIgnoreCase(featureMode.getMode())); + if(!featureModeFits) { + IncorrectFeatureModeMessage featureDisabledMessage = IncorrectFeatureModeMessage + .builder() + .featureConfig(featureConfigService.getFeatureDisplayForFeature(feature)) + .command(command) + .build(); + reason = templateService.renderTemplate("feature_mode_not_correct_message", featureDisabledMessage); + } + } + } + + return ConditionResult.builder().reason(reason).result(featureModeFits).build(); + } +} diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/command/models/IncorrectFeatureModeMessage.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/command/models/IncorrectFeatureModeMessage.java new file mode 100644 index 000000000..06a280540 --- /dev/null +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/command/models/IncorrectFeatureModeMessage.java @@ -0,0 +1,15 @@ +package dev.sheldan.abstracto.core.command.models; + +import dev.sheldan.abstracto.core.command.Command; +import dev.sheldan.abstracto.core.config.FeatureConfig; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +@Builder +public class IncorrectFeatureModeMessage { + private FeatureConfig featureConfig; + private Command command; +} diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/listener/FeatureAware.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/listener/FeatureAware.java index e09935a23..3fc298105 100644 --- a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/listener/FeatureAware.java +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/listener/FeatureAware.java @@ -1,7 +1,12 @@ package dev.sheldan.abstracto.core.listener; import dev.sheldan.abstracto.core.config.FeatureEnum; +import dev.sheldan.abstracto.core.config.FeatureMode; + +import java.util.Collections; +import java.util.List; public interface FeatureAware { FeatureEnum getFeature(); + default List getFeatureModeLimitations() { return Collections.emptyList();} } diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/models/database/AFeatureMode.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/models/database/AFeatureMode.java index a229247e0..5fdebaff2 100644 --- a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/models/database/AFeatureMode.java +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/models/database/AFeatureMode.java @@ -28,6 +28,7 @@ public class AFeatureMode { @Column @Setter + @Getter private String mode; @Column(name = "created") diff --git a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/service/FeatureModeService.java b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/service/FeatureModeService.java index 3819def2d..318692573 100644 --- a/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/service/FeatureModeService.java +++ b/abstracto-application/core/core-interface/src/main/java/dev/sheldan/abstracto/core/service/FeatureModeService.java @@ -23,4 +23,7 @@ public interface FeatureModeService { AFeatureMode createMode(FeatureEnum featureEnum, AServer server, FeatureMode mode); AFeatureMode createMode(AFeature feature, AServer server, FeatureMode mode); AFeatureMode createMode(AFeatureFlag featureFlag, FeatureMode mode); + + AFeatureMode getFeatureMode(FeatureEnum featureEnum, AServer server); + AFeatureMode getFeatureMode(AFeature feature, AServer server); } diff --git a/abstracto-application/documentation/src/main/docs/asciidoc/features/modmail.adoc b/abstracto-application/documentation/src/main/docs/asciidoc/features/modmail.adoc index 7c369ee9a..f23bf6f91 100644 --- a/abstracto-application/documentation/src/main/docs/asciidoc/features/modmail.adoc +++ b/abstracto-application/documentation/src/main/docs/asciidoc/features/modmail.adoc @@ -16,6 +16,11 @@ Feature key: `modmail` ==== Post targets `modmailPing`:: Will be used to send the notification when a new thread is opened. +`modmailLog`:: Will be used to log the interactions when a thread is closed. + +=== Modes +`log`:: The messages should be logged into the `modmailLog` post target when the thread is closed (by the respective commands) +`nogLog`:: The messages should not be logged into the `modmailLog` post target when the thread is closed. ==== Emotes @@ -58,13 +63,13 @@ Closing the mod mail thread without notifying the user:: * Usage: `closeSilently [note]` * Description: Closes the thread, deletes the text channel containing the thread and logs the interactions between the member and the moderators in the `modmailLog` post target. (only if `modmail_logging` is enabled) When closing a thread, a closing header with general information will be send and the note will be displayed there. - +Close a thread without logging +* Usage: `closeNoLog` +* Description: Closes the thread without notifying the user and without logging the messages. +* Mode Restriction: This command is only available when mod mail is in the mode `log`. === Mod mail thread logging -This feature enables the logging of mod mail threads into a channel when they are closed. The individual log messages will have a mod mail header which contains some information about the thread. -Feature key: `modmail_logging` ==== Post targets -`modmailLog`:: Will be used to log the interactions when a thread is closed. \ No newline at end of file diff --git a/abstracto-application/template-config/src/main/resources/templates/en_US/core/exception/feature_mode_not_correct_text_en_US.ftl b/abstracto-application/template-config/src/main/resources/templates/en_US/core/exception/feature_mode_not_correct_text_en_US.ftl new file mode 100644 index 000000000..6d418a0c3 --- /dev/null +++ b/abstracto-application/template-config/src/main/resources/templates/en_US/core/exception/feature_mode_not_correct_text_en_US.ftl @@ -0,0 +1 @@ +The feature `${featureName}` (with the key `${featureKey}`) is in the wrong mode to execute this command. One of the following is required: ${requiredModes}. \ No newline at end of file