-
Notifications
You must be signed in to change notification settings - Fork 0
feat:News follow #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat:News follow #51
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| using CCE.Application.Common; | ||
| using MediatR; | ||
|
|
||
| namespace CCE.Application.Content.Commands.ToggleNewsFollow; | ||
|
|
||
| public sealed record ToggleNewsFollowCommand : IRequest<Response<VoidData>>; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| using CCE.Application.Common; | ||
| using CCE.Application.Common.Interfaces; | ||
| using CCE.Application.Messages; | ||
| using CCE.Application.Notifications; | ||
| using CCE.Domain.Common; | ||
| using CCE.Domain.Content; | ||
| using CCE.Domain.Notifications; | ||
| using MediatR; | ||
| using Microsoft.EntityFrameworkCore; | ||
|
|
||
| namespace CCE.Application.Content.Commands.ToggleNewsFollow; | ||
|
|
||
| internal sealed class ToggleNewsFollowCommandHandler( | ||
| IRepository<NewsFollow, System.Guid> _repo, | ||
| IUserNotificationSettingsRepository _settingsRepo, | ||
| ICceDbContext _db, | ||
| ICurrentUserAccessor _currentUser, | ||
| ISystemClock _clock, | ||
| MessageFactory _msg) | ||
| : IRequestHandler<ToggleNewsFollowCommand, Response<VoidData>> | ||
| { | ||
| public async Task<Response<VoidData>> Handle(ToggleNewsFollowCommand request, CancellationToken ct) | ||
| { | ||
| var userId = _currentUser.GetUserId(); | ||
| if (userId is null) | ||
| return _msg.Unauthorized<VoidData>("NOT_AUTHENTICATED"); | ||
|
|
||
| var existing = await _db.NewsFollows | ||
| .FirstOrDefaultAsync(f => f.UserId == userId.Value, ct) | ||
| .ConfigureAwait(false); | ||
|
|
||
| if (existing is not null) | ||
| _db.Attach(existing); | ||
|
|
||
| if (existing is null) | ||
| { | ||
| var follow = NewsFollow.Follow(userId.Value, userId.Value, _clock); | ||
| await _repo.AddAsync(follow, ct).ConfigureAwait(false); | ||
|
|
||
| var settings = await _settingsRepo.GetAsync( | ||
| userId.Value, NotificationChannel.InApp, "NEWS_PUBLISHED", ct) | ||
| .ConfigureAwait(false); | ||
|
|
||
| if (settings is null) | ||
| { | ||
| var ns = UserNotificationSettings.Create( | ||
| userId.Value, NotificationChannel.InApp, true, "NEWS_PUBLISHED"); | ||
| await _settingsRepo.AddAsync(ns, ct).ConfigureAwait(false); | ||
| } | ||
| else if (!settings.IsEnabled) | ||
| { | ||
| settings.Update(true); | ||
| } | ||
|
|
||
| await _db.SaveChangesAsync(ct).ConfigureAwait(false); | ||
| return _msg.Ok("NEWS_FOLLOWED"); | ||
| } | ||
|
|
||
| if (existing.Status == FollowStatus.Followed) | ||
| { | ||
| existing.Unfollow(userId.Value, _clock); | ||
| await _db.SaveChangesAsync(ct).ConfigureAwait(false); | ||
| return _msg.Ok("NEWS_UNFOLLOWED"); | ||
| } | ||
|
|
||
| existing.ReFollow(userId.Value, _clock); | ||
| await _db.SaveChangesAsync(ct).ConfigureAwait(false); | ||
| return _msg.Ok("NEWS_FOLLOWED"); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| using CCE.Application.Common; | ||
| using CCE.Application.Common.Interfaces; | ||
| using CCE.Application.Identity.Dtos; | ||
| using CCE.Application.InterestManagement.Dtos; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ignore this file |
||
| using CCE.Application.Identity.Public; | ||
| using CCE.Application.InterestManagement.Dtos; | ||
| using CCE.Application.Messages; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| namespace CCE.Domain.Content; | ||
|
|
||
| public enum FollowStatus | ||
| { | ||
| Followed = 0, | ||
| Unfollowed = 1, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| using CCE.Domain.Common; | ||
|
|
||
| namespace CCE.Domain.Content; | ||
|
|
||
| public sealed class NewsFollow : AuditableEntity<System.Guid> | ||
| { | ||
| private NewsFollow(System.Guid id, System.Guid userId) : base(id) | ||
| { | ||
| UserId = userId; | ||
| Status = FollowStatus.Followed; | ||
| } | ||
|
|
||
| public System.Guid UserId { get; private set; } | ||
| public FollowStatus Status { get; private set; } | ||
| public System.DateTimeOffset? UnfollowedOn { get; private set; } | ||
|
|
||
| public static NewsFollow Follow(System.Guid userId, System.Guid createdBy, ISystemClock clock) | ||
| { | ||
| if (userId == System.Guid.Empty) throw new DomainException("UserId is required."); | ||
| var follow = new NewsFollow(System.Guid.NewGuid(), userId); | ||
| follow.MarkAsCreated(createdBy, clock); | ||
| return follow; | ||
| } | ||
|
|
||
| public void ReFollow(System.Guid modifiedBy, ISystemClock clock) | ||
| { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why you are using refollow insted of follow |
||
| Status = FollowStatus.Followed; | ||
| UnfollowedOn = null; | ||
| MarkAsModified(modifiedBy, clock); | ||
| } | ||
|
|
||
| public void Unfollow(System.Guid modifiedBy, ISystemClock clock) | ||
| { | ||
| Status = FollowStatus.Unfollowed; | ||
| UnfollowedOn = clock.UtcNow; | ||
| MarkAsModified(modifiedBy, clock); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| using CCE.Domain.Common; | ||
|
|
||
| namespace CCE.Domain.Content; | ||
|
|
||
| public sealed class NewsFollowLog : Entity<System.Guid> | ||
| { | ||
| private NewsFollowLog( | ||
| System.Guid id, | ||
| System.Guid userId, | ||
| System.Guid newsId, | ||
| System.DateTimeOffset timestamp) : base(id) | ||
| { | ||
| UserId = userId; | ||
| NewsId = newsId; | ||
| Timestamp = timestamp; | ||
| } | ||
|
|
||
| public System.Guid UserId { get; private set; } | ||
| public System.Guid NewsId { get; private set; } | ||
| public System.DateTimeOffset Timestamp { get; private set; } | ||
|
|
||
| public static NewsFollowLog Log(System.Guid userId, System.Guid newsId, ISystemClock clock) | ||
| { | ||
| return new NewsFollowLog(System.Guid.NewGuid(), userId, newsId, clock.UtcNow); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -182,15 +182,6 @@ public void SetLocalePreference(string locale) | |
|
|
||
| public void SetKnowledgeLevel(KnowledgeLevel level) => KnowledgeLevel = level; | ||
|
|
||
| public void UpdateInterests(IEnumerable<System.Guid> interestTopicIds) | ||
| { | ||
| if (interestTopicIds is null) | ||
| throw new DomainException("interestTopicIds collection cannot be null."); | ||
| UserInterestTopics.Clear(); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need for this file |
||
| foreach (var id in interestTopicIds.Distinct()) | ||
| UserInterestTopics.Add(new UserInterestTopic { UserId = Id, InterestTopicId = id }); | ||
| } | ||
|
|
||
| public bool IsDeleted { get; private set; } | ||
|
|
||
| public DateTimeOffset? DeletedOn { get; private set; } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ignore the appsetting.json