diff --git a/RMuseum/Controllers/ArtifactController.cs b/RMuseum/Controllers/ArtifactController.cs index 777f6dc3..8f3f43f6 100644 --- a/RMuseum/Controllers/ArtifactController.cs +++ b/RMuseum/Controllers/ArtifactController.cs @@ -1220,7 +1220,7 @@ namespace RMuseum.Controllers RServiceResult res = await _artifactService.DeleteUserBookmark(bookmarkId); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); - return Ok();; + return Ok(); } /// diff --git a/RMuseum/Controllers/GanjoorController.cs b/RMuseum/Controllers/GanjoorController.cs index 18ea0eef..335dfb54 100644 --- a/RMuseum/Controllers/GanjoorController.cs +++ b/RMuseum/Controllers/GanjoorController.cs @@ -498,6 +498,39 @@ namespace RMuseum.Controllers return Ok(res.Result); } + /// + /// delete user's own comment + /// + /// + /// + [HttpDelete] + [Route("comment")] + [Authorize] + [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] + [ProducesResponseType((int)HttpStatusCode.NotFound)] + [ProducesResponseType((int)HttpStatusCode.Forbidden)] + public async Task DeleteMyComment(int id) + { + + Guid userId = + new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value); + Guid sessionId = + new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value); + RServiceResult sessionCheckResult = await _appUserService.SessionExists(userId, sessionId); + if (!string.IsNullOrEmpty(sessionCheckResult.ExceptionString)) + { + return StatusCode((int)HttpStatusCode.Forbidden); + } + + var res = + await _ganjoorService.DeleteMyComment(userId, id); + if (!string.IsNullOrEmpty(res.ExceptionString)) + return BadRequest(res.ExceptionString); + if (!res.Result) + return NotFound(); + return Ok(); + } + /// /// imports data from ganjoor SQLite database /// diff --git a/RMuseum/RMuseum.xml b/RMuseum/RMuseum.xml index e8448252..d79508b7 100644 --- a/RMuseum/RMuseum.xml +++ b/RMuseum/RMuseum.xml @@ -772,6 +772,13 @@ + + + delete user's own comment + + + + imports data from ganjoor SQLite database @@ -6045,6 +6052,14 @@ + + + delete user own comment + + + + + get recent comments @@ -6867,6 +6882,14 @@ + + + delete user own comment + + + + + get recent comments @@ -6986,7 +7009,12 @@ IAppUserService instance - + + + Messaging service + + + constructor @@ -6994,6 +7022,7 @@ + diff --git a/RMuseum/Services/IGanjoorService.cs b/RMuseum/Services/IGanjoorService.cs index 98ceb001..db6b47c3 100644 --- a/RMuseum/Services/IGanjoorService.cs +++ b/RMuseum/Services/IGanjoorService.cs @@ -170,6 +170,14 @@ namespace RMuseum.Services /// Task> NewComment(Guid userId, string ip, int poemId, string content, int? inReplyTo); + /// + /// delete user own comment + /// + /// + /// + /// + Task> DeleteMyComment(Guid userId, int commentId); + /// /// get recent comments /// diff --git a/RMuseum/Services/Implementation/GanjoorService.cs b/RMuseum/Services/Implementation/GanjoorService.cs index a875a15f..b15d5937 100644 --- a/RMuseum/Services/Implementation/GanjoorService.cs +++ b/RMuseum/Services/Implementation/GanjoorService.cs @@ -495,9 +495,7 @@ namespace RMuseum.Services.Implementation foreach(GanjoorCommentSummaryViewModel comment in allComments) { comment.AuthorName = comment.AuthorName.ToPersianNumbers().ApplyCorrectYeKe(); - comment.HtmlComment = comment.HtmlComment.ToPersianNumbers().ApplyCorrectYeKe(); - comment.HtmlComment = _Linkify(comment.HtmlComment); - comment.HtmlComment = $"

{comment.HtmlComment.Replace("\r\n", "\n").Replace("\n\n", "\n").Replace("\n", "
")}

"; + comment.HtmlComment = _PrepareCommentHtml(comment.HtmlComment); } GanjoorCommentSummaryViewModel[] rootComments = allComments.Where(c => c.InReplyToId == null).ToArray(); @@ -583,6 +581,59 @@ namespace RMuseum.Services.Implementation } } + /// + /// delete user own comment + /// + /// + /// + /// + public async Task> DeleteMyComment(Guid userId, int commentId) + { + try + { + GanjoorComment comment = await _context.GanjoorComments.Where(c => c.Id == commentId && c.UserId == userId).SingleOrDefaultAsync();//userId is not part of key but it helps making call secure + if(comment == null) + { + return new RServiceResult(false); //not found + } + + //if user has got replies, delete them and notify their owners of what happened + var replies = await _FindReplies(comment); + for(int i = replies.Count - 1; i >= 0; i--) + { + if(replies[i].UserId != null) + { + await _notificationService.PushNotification((Guid)replies[i].UserId, + "حذف پاسخ شما به حاشیه", + $"پاسخ شما به یکی از حاشیه‌های گنجور به دلیل حذف زنجیرهٔ حاشیه توسط یکی از حاشیه‌گذاران حذف شده است.{Environment.NewLine}" + + $"این متن حاشیهٔ حذف شدهٔ شماست: {Environment.NewLine}" + + $"{_PrepareCommentHtml(replies[i].HtmlComment)}" + ); + } + _context.GanjoorComments.Remove(replies[i]); + } + + _context.GanjoorComments.Remove(comment); + await _context.SaveChangesAsync(); + + return new RServiceResult(true); + } + catch (Exception exp) + { + return new RServiceResult(false, exp.ToString()); + } + } + + private async Task> _FindReplies(GanjoorComment comment) + { + List replies = await _context.GanjoorComments.Where(c => c.InReplyToId == comment.Id).ToListAsync(); + foreach (GanjoorComment reply in replies) + { + replies.AddRange(await _FindReplies(reply)); + } + return replies; + } + /// /// get recent comments @@ -631,9 +682,7 @@ namespace RMuseum.Services.Implementation foreach (GanjoorCommentFullViewModel comment in paginatedResult.Items) { comment.AuthorName = comment.AuthorName.ToPersianNumbers().ApplyCorrectYeKe(); - comment.HtmlComment = comment.HtmlComment.ToPersianNumbers().ApplyCorrectYeKe(); - comment.HtmlComment = _Linkify(comment.HtmlComment); - comment.HtmlComment = $"

{comment.HtmlComment.Replace("\r\n", "\n").Replace("\n\n", "\n").Replace("\n", "
")}

"; + comment.HtmlComment = _PrepareCommentHtml(comment.HtmlComment); } return new RServiceResult<(PaginationMetadata PagingMeta, GanjoorCommentFullViewModel[] Items)>(paginatedResult); @@ -644,6 +693,15 @@ namespace RMuseum.Services.Implementation } } + private string _PrepareCommentHtml(string comment) + { + comment = comment.ToPersianNumbers().ApplyCorrectYeKe(); + comment = _Linkify(comment); + comment = $"

{comment.Replace("\r\n", "\n").Replace("\n\n", "\n").Replace("\n", "
")}

"; + + return comment; + } + /// /// get poem images by id (some fields are intentionally field with blank or null), @@ -1322,6 +1380,12 @@ namespace RMuseum.Services.Implementation protected IAppUserService _appUserService; + /// + /// Messaging service + /// + protected readonly IRNotificationService _notificationService; + + /// /// constructor @@ -1330,11 +1394,13 @@ namespace RMuseum.Services.Implementation /// /// /// - public GanjoorService(RMuseumDbContext context, IConfiguration configuration, IBackgroundTaskQueue backgroundTaskQueue, IAppUserService appUserService) + /// + public GanjoorService(RMuseumDbContext context, IConfiguration configuration, IBackgroundTaskQueue backgroundTaskQueue, IAppUserService appUserService, IRNotificationService notificationService) { _context = context; _backgroundTaskQueue = backgroundTaskQueue; _appUserService = appUserService; + _notificationService = notificationService; Configuration = configuration; } }