diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainServiceBase.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainServiceBase.cs new file mode 100644 index 0000000000..7f5c10783e --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainServiceBase.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Domain.Services; + +namespace Volo.CmsKit +{ + public class CmsKitDomainServiceBase : DomainService + { + + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitOptions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitOptions.cs new file mode 100644 index 0000000000..cc69f715ce --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitOptions.cs @@ -0,0 +1,16 @@ +using JetBrains.Annotations; +using Volo.CmsKit.Reactions; + +namespace Volo.CmsKit +{ + public class CmsKitOptions + { + [NotNull] + public ReactionDefinitionDictionary Reactions { get; } + + public CmsKitOptions() + { + Reactions = new ReactionDefinitionDictionary(); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/DefaultReactionDefinitionStore.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/DefaultReactionDefinitionStore.cs new file mode 100644 index 0000000000..ba41f5ab6e --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/DefaultReactionDefinitionStore.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.CmsKit.Reactions +{ + public class DefaultReactionDefinitionStore : IReactionDefinitionStore, ITransientDependency + { + protected CmsKitOptions Options { get; } + + public DefaultReactionDefinitionStore(IOptions options) + { + Options = options.Value; + } + + public virtual Task> GetAvailableReactionsAsync( + string entityType, + Guid? userId) + { + return Task.FromResult(Options.Reactions.Values.ToList()); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/IReactionDefinitionStore.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/IReactionDefinitionStore.cs new file mode 100644 index 0000000000..879c632428 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/IReactionDefinitionStore.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; + +namespace Volo.CmsKit.Reactions +{ + public interface IReactionDefinitionStore + { + Task> GetAvailableReactionsAsync([CanBeNull] string entityType, [CanBeNull] Guid? userId); + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/IUserReactionRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/IUserReactionRepository.cs new file mode 100644 index 0000000000..93828d2bdd --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/IUserReactionRepository.cs @@ -0,0 +1,16 @@ +using System; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Domain.Repositories; + +namespace Volo.CmsKit.Reactions +{ + public interface IUserReactionRepository : IBasicRepository + { + Task FindAsync( + Guid userId, + [NotNull] string entityType, + [NotNull] string entityId, + [NotNull] string reactionName); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/LocalizableIconDictionary.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/LocalizableIconDictionary.cs new file mode 100644 index 0000000000..b4e3461da8 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/LocalizableIconDictionary.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Volo.CmsKit.Reactions +{ + public class LocalizableIconDictionary : Dictionary + { + public string Default { get; set; } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/Reaction.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/Reaction.cs deleted file mode 100644 index abe0e4465b..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/Reaction.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; - -namespace Volo.CmsKit.Reactions -{ - public class Reaction : Entity, IAggregateRoot, IHasCreationTime, IMustHaveCreator - { - public string EntityName { get; set; } //TODO: int or create a more common EntityTypes entity/table/... - - public string EntityId { get; set; } - - public string ReactionType { get; set; } - - public DateTime CreationTime { get; set; } - - public Guid CreatorId { get; set; } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/ReactionDefinition.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/ReactionDefinition.cs new file mode 100644 index 0000000000..a734fdafe7 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/ReactionDefinition.cs @@ -0,0 +1,32 @@ +using JetBrains.Annotations; +using Volo.Abp; +using Volo.Abp.Localization; + +namespace Volo.CmsKit.Reactions +{ + public class ReactionDefinition + { + [NotNull] + public string Name { get; } + + [CanBeNull] + public ILocalizableString DisplayName { get; set; } + + [NotNull] + public LocalizableIconDictionary Icons { get; } + + public ReactionDefinition( + [NotNull] string name, + [NotNull] string defaultIcon, + [CanBeNull] ILocalizableString displayName = null) + { + Name = Check.NotNullOrWhiteSpace(name, nameof(name)); + DisplayName = displayName; + + Icons = new LocalizableIconDictionary + { + Default = Check.NotNullOrWhiteSpace(defaultIcon, nameof(defaultIcon)) + }; + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/ReactionDefinitionDictionary.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/ReactionDefinitionDictionary.cs new file mode 100644 index 0000000000..a42b246011 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/ReactionDefinitionDictionary.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Volo.CmsKit.Reactions +{ + public class ReactionDefinitionDictionary : Dictionary + { + + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/ReactionManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/ReactionManager.cs new file mode 100644 index 0000000000..343c7cd296 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/ReactionManager.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp; + +namespace Volo.CmsKit.Reactions +{ + public class ReactionManager : CmsKitDomainServiceBase + { + protected IReactionDefinitionStore ReactionDefinitionStore { get; } + protected IUserReactionRepository UserReactionRepository { get; } + + public ReactionManager( + IUserReactionRepository userReactionRepository, + IReactionDefinitionStore reactionDefinitionStore) + { + UserReactionRepository = userReactionRepository; + ReactionDefinitionStore = reactionDefinitionStore; + } + + public virtual async Task> GetAvailableReactionsAsync( + [CanBeNull] string entityType = null, + [CanBeNull] Guid? userId = null) + { + return await ReactionDefinitionStore.GetAvailableReactionsAsync(entityType, userId); + } + + public virtual Task GetSummariesAsync( + [NotNull] string entityType, + [NotNull] string entityId) + { + //TODO: ... + throw new NotImplementedException(); + } + + public virtual Task GetUserReactionsAsync( + Guid userId, + [NotNull] string entityType, + [NotNull] string entityId) + { + //TODO: ... + throw new NotImplementedException(); + } + + public virtual async Task CreateAsync( + Guid userId, + [NotNull] string entityType, + [NotNull] string entityId, + [NotNull] string reactionName) + { + Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); + Check.NotNullOrWhiteSpace(entityId, nameof(entityId)); + Check.NotNullOrWhiteSpace(reactionName, nameof(reactionName)); + + var existingReaction = await UserReactionRepository.FindAsync(userId, entityType, entityId, reactionName); + if (existingReaction != null) + { + return existingReaction; + } + + return await UserReactionRepository.InsertAsync( + new UserReaction( + GuidGenerator.Create(), + userId, + entityType, + entityId, + reactionName, + Clock.Now + ) + ); + } + + public virtual async Task DeleteAsync( + Guid userId, + [NotNull] string entityType, + [NotNull] string entityId, + [NotNull] string reactionName) + { + var existingReaction = await UserReactionRepository.FindAsync(userId, entityType, entityId, reactionName); + if (existingReaction == null) + { + return false; + } + + await UserReactionRepository.DeleteAsync(existingReaction); + return true; + } + } + + public class ReactionSummary + { + public ReactionDefinition Reaction { get; set; } + + public int Count { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/UserReaction.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/UserReaction.cs new file mode 100644 index 0000000000..34c3fa9bcd --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Reactions/UserReaction.cs @@ -0,0 +1,41 @@ +using System; +using JetBrains.Annotations; +using Volo.Abp; +using Volo.Abp.Domain.Entities; + +namespace Volo.CmsKit.Reactions +{ + public class UserReaction : Entity, IAggregateRoot + { + public virtual string EntityType { get; protected set; } + + public virtual string EntityId { get; protected set; } + + public virtual string ReactionName { get; protected set; } + + public virtual DateTime CreationTime { get; protected set; } + + public virtual Guid UserId { get; protected set; } + + protected UserReaction() + { + + } + + internal UserReaction( + Guid id, + Guid userId, + [NotNull] string entityType, + [NotNull] string entityId, + [NotNull] string reactionName, + DateTime creationTime) + : base(id) + { + EntityType = Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); + EntityId = Check.NotNullOrWhiteSpace(entityId, nameof(entityId)); + ReactionName = Check.NotNullOrWhiteSpace(reactionName, nameof(reactionName)); + UserId = userId; + CreationTime = creationTime; + } + } +}