Browse Source

updated the ui side

pull/15039/head
malik masis 4 years ago
parent
commit
4ff130d570
  1. 47
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs
  2. 47
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml
  3. 26
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.css
  4. 59
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js
  5. 30
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.scss

47
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -7,6 +8,7 @@ using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI; using Volo.Abp.AspNetCore.Mvc.UI;
using Volo.Abp.AspNetCore.Mvc.UI.Widgets; using Volo.Abp.AspNetCore.Mvc.UI.Widgets;
using Volo.CmsKit.Public.Application.Security.VoloCaptcha;
using Volo.CmsKit.Public.Comments; using Volo.CmsKit.Public.Comments;
using Volo.CmsKit.Web.Renderers; using Volo.CmsKit.Web.Renderers;
@ -24,15 +26,31 @@ public class CommentingViewComponent : AbpViewComponent
public ICommentPublicAppService CommentPublicAppService { get; } public ICommentPublicAppService CommentPublicAppService { get; }
public IMarkdownToHtmlRenderer MarkdownToHtmlRenderer { get; } public IMarkdownToHtmlRenderer MarkdownToHtmlRenderer { get; }
public AbpMvcUiOptions AbpMvcUiOptions { get; } public AbpMvcUiOptions AbpMvcUiOptions { get; }
public SimpleMathsCaptchaGenerator SimpleMathsCaptchaGenerator { get; }
[HiddenInput]
[BindProperty]
public string RecaptchaToken { get; set; }
[HiddenInput]
[BindProperty]
public Guid CaptchaId { get; set; }
[BindProperty]
public CommentingViewModel Input { get; set; }
public CaptchaOutput CaptchaOutput { get; set; }
public CommentingViewComponent( public CommentingViewComponent(
ICommentPublicAppService commentPublicAppService, ICommentPublicAppService commentPublicAppService,
IOptions<AbpMvcUiOptions> options, IOptions<AbpMvcUiOptions> options,
IMarkdownToHtmlRenderer markdownToHtmlRenderer) IMarkdownToHtmlRenderer markdownToHtmlRenderer,
SimpleMathsCaptchaGenerator simpleMathsCaptchaGenerator)
{ {
CommentPublicAppService = commentPublicAppService; CommentPublicAppService = commentPublicAppService;
MarkdownToHtmlRenderer = markdownToHtmlRenderer; MarkdownToHtmlRenderer = markdownToHtmlRenderer;
AbpMvcUiOptions = options.Value; AbpMvcUiOptions = options.Value;
SimpleMathsCaptchaGenerator = simpleMathsCaptchaGenerator;
} }
public virtual async Task<IViewComponentResult> InvokeAsync( public virtual async Task<IViewComponentResult> InvokeAsync(
@ -42,7 +60,6 @@ public class CommentingViewComponent : AbpViewComponent
var comments = (await CommentPublicAppService var comments = (await CommentPublicAppService
.GetListAsync(entityType, entityId)).Items; .GetListAsync(entityType, entityId)).Items;
var loginUrl = $"{AbpMvcUiOptions.LoginUrl}?returnUrl={HttpContext.Request.Path.ToString()}&returnUrlHash=#cms-comment_{entityType}_{entityId}"; var loginUrl = $"{AbpMvcUiOptions.LoginUrl}?returnUrl={HttpContext.Request.Path.ToString()}&returnUrlHash=#cms-comment_{entityType}_{entityId}";
var viewModel = new CommentingViewModel var viewModel = new CommentingViewModel
@ -52,10 +69,23 @@ public class CommentingViewComponent : AbpViewComponent
LoginUrl = loginUrl, LoginUrl = loginUrl,
Comments = comments.OrderByDescending(i => i.CreationTime).ToList() Comments = comments.OrderByDescending(i => i.CreationTime).ToList()
}; };
await ConvertMarkdownTextsToHtml(viewModel); await ConvertMarkdownTextsToHtml(viewModel);
return View("~/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml", viewModel); CaptchaOutput = SimpleMathsCaptchaGenerator.Generate(new CaptchaOptions(
number1MinValue: 1,
number1MaxValue: 10,
number2MinValue: 5,
number2MaxValue: 15)
);
viewModel.CaptchaImageBase64 = GetCaptchaImageBase64(CaptchaOutput.ImageBytes);
this.Input = viewModel;
return View("~/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml", this);
}
private string GetCaptchaImageBase64(byte[] bytes)
{
return $"data:image/jpg;base64,{Convert.ToBase64String(bytes)}";
} }
private async Task ConvertMarkdownTextsToHtml(CommentingViewModel viewModel) private async Task ConvertMarkdownTextsToHtml(CommentingViewModel viewModel)
@ -86,6 +116,15 @@ public class CommentingViewComponent : AbpViewComponent
public IReadOnlyList<CommentWithDetailsDto> Comments { get; set; } public IReadOnlyList<CommentWithDetailsDto> Comments { get; set; }
public Dictionary<Guid, string> RawCommentTexts { get; set; } public Dictionary<Guid, string> RawCommentTexts { get; set; }
[Required]
[StringLength(100, MinimumLength = 1)]
public string Captcha { get; set; }
public string CaptchaImageBase64 { get; set; }
} }
} }

47
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml

@ -11,7 +11,7 @@
@inject ICurrentUser CurrentUser @inject ICurrentUser CurrentUser
@inject IOptionsSnapshot<CmsKitUiOptions> cmsKitUiOptions; @inject IOptionsSnapshot<CmsKitUiOptions> cmsKitUiOptions;
@inject IHtmlLocalizer<CmsKitResource> L @inject IHtmlLocalizer<CmsKitResource> L
@model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting.CommentingViewComponent.CommentingViewModel @model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting.CommentingViewComponent
@{ @{
Func<dynamic, IHtmlContent> GetCommentTitle(CmsUserDto author, DateTime creationTime) => Func<dynamic, IHtmlContent> GetCommentTitle(CmsUserDto author, DateTime creationTime) =>
@ -36,9 +36,26 @@
<textarea class="form-control" name="commentText" placeholder="@(string.IsNullOrEmpty(repliedCommentId?.ToString() ?? "") ? L["YourComment"] : L["YourReply"])..." rows="3"></textarea> <textarea class="form-control" name="commentText" placeholder="@(string.IsNullOrEmpty(repliedCommentId?.ToString() ?? "") ? L["YourComment"] : L["YourReply"])..." rows="3"></textarea>
</div> </div>
</div> </div>
<div class="volo-captcha">
<label class="form-label" for="Input_Captcha">Captcha code</label>
<div class="d-flex">
<div class="bd-highlight">
<img src="@Model.Input.CaptchaImageBase64" />
</div>
<div class="flex-grow-1 bd-highlight">
<abp-input asp-for="@Model.Input.Captcha" suppress-label="true" class="d-inline-block" autocomplete="off" />
</div>
<abp-input asp-for="@Model.CaptchaId" value="@Model.CaptchaOutput.Id" />
</div>
</div>
<div class="col-auto"> <div class="col-auto">
<div class="text-end"> <div class="text-end">
<abp-button type="submit" button-type="Primary" size="Block"> <abp-button id="submit-button" type="submit" button-type="Primary" size="Block">
<i class="fa fa-comment-alt me-1"></i> @L["Send"] <i class="fa fa-comment-alt me-1"></i> @L["Send"]
</abp-button> </abp-button>
@if (cancelButton) @if (cancelButton)
@ -71,13 +88,13 @@
{ {
@if (CurrentUser.IsAuthenticated) @if (CurrentUser.IsAuthenticated)
{ {
<a href="#" class="comment-links comment-reply-link btn btn-sm shadow-sm btn-primary" data-reply-id="@id.ToString()" id="@($"cms-comment_{Model.EntityType}_{Model.EntityId}_{id}_link")"> <a href="#" class="comment-links comment-reply-link btn btn-sm shadow-sm btn-primary" data-reply-id="@id.ToString()" id="@($"cms-comment_{Model.Input.EntityType}_{Model.Input.EntityId}_{id}_link")">
<i class="fa fa-reply mr -1"></i> @L["Reply"] <i class="fa fa-reply mr -1"></i> @L["Reply"]
</a> </a>
} }
else else
{ {
<a href="@(Model.LoginUrl + "_" + id)" class="btn btn-sm btn-light shadow-sm"> @L["LoginToReply"]</a> <a href="@(Model.Input.LoginUrl + "_" + id)" class="btn btn-sm btn-light shadow-sm"> @L["LoginToReply"]</a>
} }
} }
@if (authorId == CurrentUser.Id) @if (authorId == CurrentUser.Id)
@ -93,9 +110,10 @@
} }
@{ @{
Func<dynamic, IHtmlContent> GetEditArea(Guid id, string text, string concurrencyStamp) => Func<dynamic, IHtmlContent> GetEditArea(Guid id, string text, string concurrencyStamp) =>
@<div class="cms-comment-edit-area" id="@($"cms-comment_{Model.EntityType}_{Model.EntityId}_{id}")" data-id="@id.ToString()" style="display:none"> @<div class="cms-comment-edit-area" id="@($"cms-comment_{Model.Input.EntityType}_{Model.Input.EntityId}_{id}")" data-id="@id.ToString()" style="display:none">
<div class="card bg-light p-3 mx-0 mt-3"> <div class="card bg-light p-3 mx-0 mt-3">
<form class="cms-comment-update-form"> <form id="ContactForm" class="cms-comment-update-form">
<abp-input asp-for="@Model.RecaptchaToken" />
<input hidden value="@id.ToString()" name="id" /> <input hidden value="@id.ToString()" name="id" />
<div class="row"> <div class="row">
<div class="col"> <div class="col">
@ -119,20 +137,20 @@
</div>; </div>;
} }
<div class="cms-comment-area mb-5" data-entity-type="@Model.EntityType" data-entity-id="@Model.EntityId"> <div class="cms-comment-area mb-5" data-entity-type="@Model.Input.EntityType" data-entity-id="@Model.Input.EntityId">
@if (CurrentUser.IsAuthenticated) @if (CurrentUser.IsAuthenticated)
{ {
<div id="@($"cms-comment_{Model.EntityType}_{Model.EntityId}")"> <div id="@($"cms-comment_{Model.Input.EntityType}_{Model.Input.EntityId}")">
@GetCommentArea(null).Invoke(null) @GetCommentArea(null).Invoke(null)
</div> </div>
} }
else if (!string.IsNullOrWhiteSpace(Model.LoginUrl)) else if (!string.IsNullOrWhiteSpace(Model.Input.LoginUrl))
{ {
<div class="text-end"> <div class="text-end">
<a href="@Model.LoginUrl" class="btn btn-primary"> @L["LoginToAddComment"]</a> <a href="@Model.Input.LoginUrl" class="btn btn-primary"> @L["LoginToAddComment"]</a>
</div> </div>
} }
@foreach (var comment in Model.Comments) @foreach (var comment in Model.Input.Comments)
{ {
<div class="comment"> <div class="comment">
<div class="card p-3 mx-0 my-3"> <div class="card p-3 mx-0 my-3">
@ -157,7 +175,7 @@
</div> </div>
</div> </div>
</div> </div>
@GetEditArea(comment.Id, Model.RawCommentTexts[comment.Id], comment.ConcurrencyStamp).Invoke(null) @GetEditArea(comment.Id, Model.Input.RawCommentTexts[comment.Id], comment.ConcurrencyStamp).Invoke(null)
@if (comment.Replies.Any()) @if (comment.Replies.Any())
{ {
@ -187,7 +205,7 @@
</div> </div>
</div> </div>
@GetEditArea(reply.Id, Model.RawCommentTexts[reply.Id], reply.ConcurrencyStamp).Invoke(null) @GetEditArea(reply.Id, Model.Input.RawCommentTexts[reply.Id], reply.ConcurrencyStamp).Invoke(null)
</div> </div>
</div> </div>
} }
@ -202,7 +220,7 @@
} }
else else
{ {
<a href="@(Model.LoginUrl + "_" + comment.Id)" class="btn btn-sm btn-light shadow-sm"> @L["LoginToReply"]</a> <a href="@(Model.Input.LoginUrl + "_" + comment.Id)" class="btn btn-sm btn-light shadow-sm"> @L["LoginToReply"]</a>
} }
</div> </div>
} }
@ -216,3 +234,4 @@
</div> </div>
} }
</div> </div>

26
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.css

@ -3,4 +3,28 @@
} }
.comment-links:hover { .comment-links:hover {
text-decoration: none; text-decoration: none;
} }
body .volo-captcha img {
border: 1px outset #dddcdc;
border-radius: 4px;
height: 45px;
}
body .volo-captcha .d-flex .form-group {
width: 100%;
}
@media (max-width: 800px) {
body .volo-captcha #Input_Captcha {
margin-left: 0px;
}
}
body .form-control {
border: 1px outset #e3e3e3 !important;
padding: 10px !important;
}
body #submit-button {
margin-top: 10px;
}

59
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js

@ -1,10 +1,10 @@
(function ($) { (function ($) {
var l = abp.localization.getResource('CmsKit'); let l = abp.localization.getResource('CmsKit');
abp.widgets.CmsCommenting = function ($widget) { abp.widgets.CmsCommenting = function ($widget) {
var widgetManager = $widget.data('abp-widget-manager'); let widgetManager = $widget.data('abp-widget-manager');
var $commentArea = $widget.find('.cms-comment-area'); let $commentArea = $widget.find('.cms-comment-area');
function getFilters() { function getFilters() {
return { return {
@ -15,14 +15,14 @@
function registerEditLinks($container) { function registerEditLinks($container) {
$container.find('.comment-edit-link').each(function () { $container.find('.comment-edit-link').each(function () {
var $link = $(this); let $link = $(this);
$link.on('click', function (e) { $link.on('click', function (e) {
e.preventDefault(); e.preventDefault();
var commentId = $link.data('id'); let commentId = $link.data('id');
var $relatedCommentContentArea = $container.find('.cms-comment-content-area[data-id=' + commentId + ']'); let $relatedCommentContentArea = $container.find('.cms-comment-content-area[data-id=' + commentId + ']');
var $relatedCommentEditFormArea = $container.find('.cms-comment-edit-area[data-id=' + commentId + ']'); let $relatedCommentEditFormArea = $container.find('.cms-comment-edit-area[data-id=' + commentId + ']');
$relatedCommentContentArea.hide(); $relatedCommentContentArea.hide();
$relatedCommentEditFormArea.show(); $relatedCommentEditFormArea.show();
@ -30,15 +30,15 @@
}); });
}); });
$container.find('.comment-edit-cancel-button').each(function () { $container.find('.comment-edit-cancel-button').each(function () {
var $button = $(this); let $button = $(this);
$button.on('click', function (e) { $button.on('click', function (e) {
e.preventDefault(); e.preventDefault();
var commentId = $button.data('id'); let commentId = $button.data('id');
var $relatedCommentContentArea = $container.find('.cms-comment-content-area[data-id=' + commentId + ']'); let $relatedCommentContentArea = $container.find('.cms-comment-content-area[data-id=' + commentId + ']');
var $relatedCommentEditFormArea = $container.find('.cms-comment-edit-area[data-id=' + commentId + ']'); let $relatedCommentEditFormArea = $container.find('.cms-comment-edit-area[data-id=' + commentId + ']');
var $link = $container.find('.comment-edit-link[data-id=' + commentId + ']'); let $link = $container.find('.comment-edit-link[data-id=' + commentId + ']');
$relatedCommentContentArea.show(); $relatedCommentContentArea.show();
$relatedCommentEditFormArea.hide(); $relatedCommentEditFormArea.hide();
@ -49,14 +49,14 @@
function registerReplyLinks($container) { function registerReplyLinks($container) {
$container.find('.comment-reply-link').each(function () { $container.find('.comment-reply-link').each(function () {
var $link = $(this); let $link = $(this);
$link.on('click', function (e) { $link.on('click', function (e) {
e.preventDefault(); e.preventDefault();
var replyCommentId = $link.data('reply-id'); let replyCommentId = $link.data('reply-id');
var $relatedCommentArea = $container.find('.cms-comment-form-area[data-reply-id=' + replyCommentId + ']'); let $relatedCommentArea = $container.find('.cms-comment-form-area[data-reply-id=' + replyCommentId + ']');
var $links = $container.find('.comment-reply-link[data-reply-id=' + replyCommentId + ']'); let $links = $container.find('.comment-reply-link[data-reply-id=' + replyCommentId + ']');
$relatedCommentArea.show(); $relatedCommentArea.show();
$relatedCommentArea.find('textarea').focus(); $relatedCommentArea.find('textarea').focus();
@ -64,14 +64,14 @@
}); });
}); });
$container.find('.reply-cancel-button').each(function () { $container.find('.reply-cancel-button').each(function () {
var $button = $(this); let $button = $(this);
$button.on('click', function (e) { $button.on('click', function (e) {
e.preventDefault(); e.preventDefault();
var replyCommentId = $button.data('reply-id'); let replyCommentId = $button.data('reply-id');
var $relatedCommentArea = $container.find('.cms-comment-form-area[data-reply-id=' + replyCommentId + ']'); let $relatedCommentArea = $container.find('.cms-comment-form-area[data-reply-id=' + replyCommentId + ']');
var $links = $container.find('.comment-reply-link[data-reply-id=' + replyCommentId + ']'); let $links = $container.find('.comment-reply-link[data-reply-id=' + replyCommentId + ']');
$relatedCommentArea.hide(); $relatedCommentArea.hide();
$links.removeClass('disabled'); $links.removeClass('disabled');
@ -81,7 +81,7 @@
function registerDeleteLinks($container) { function registerDeleteLinks($container) {
$container.find('.comment-delete-link').each(function () { $container.find('.comment-delete-link').each(function () {
var $link = $(this); let $link = $(this);
$link.on('click', '', function (e) { $link.on('click', '', function (e) {
e.preventDefault(); e.preventDefault();
@ -99,10 +99,10 @@
function registerUpdateOfNewComment($container) { function registerUpdateOfNewComment($container) {
$container.find('.cms-comment-update-form').each(function () { $container.find('.cms-comment-update-form').each(function () {
var $form = $(this); let $form = $(this);
$form.submit(function (e) { $form.submit(function (e) {
e.preventDefault(); e.preventDefault();
var formAsObject = $form.serializeFormToObject(); let formAsObject = $form.serializeFormToObject();
volo.cmsKit.public.comments.commentPublic.update( volo.cmsKit.public.comments.commentPublic.update(
formAsObject.id, formAsObject.id,
{ {
@ -118,21 +118,22 @@
function registerSubmissionOfNewComment($container) { function registerSubmissionOfNewComment($container) {
$container.find('.cms-comment-form').each(function () { $container.find('.cms-comment-form').each(function () {
var $form = $(this); let $form = $(this);
$form.submit(function (e) { $form.submit(function (e) {
e.preventDefault(); e.preventDefault();
var formAsObject = $form.serializeFormToObject(); let formAsObject = $form.serializeFormToObject();
if (formAsObject.repliedCommentId == ''){ if (formAsObject.repliedCommentId == '') {
formAsObject.repliedCommentId = null; formAsObject.repliedCommentId = null;
} }
volo.cmsKit.public.comments.commentPublic.create( volo.cmsKit.public.comments.commentPublic.create(
$commentArea.attr('data-entity-type'), $commentArea.attr('data-entity-type'),
$commentArea.attr('data-entity-id'), $commentArea.attr('data-entity-id'),
{ {
repliedCommentId: formAsObject.repliedCommentId, repliedCommentId: formAsObject.repliedCommentId,
text: formAsObject.commentText text: formAsObject.commentText,
captchaToken: formAsObject.captchaId,
captchaAnswer: formAsObject.input.captcha
} }
).then(function () { ).then(function () {
widgetManager.refresh($widget); widgetManager.refresh($widget);
@ -146,7 +147,7 @@
return; return;
} }
var $link = $(location.hash + '_link'); let $link = $(location.hash + '_link');
if ($link.length > 0) { if ($link.length > 0) {
$link.click(); $link.click();

30
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.scss

@ -0,0 +1,30 @@
body {
.volo-captcha {
img {
border: 1px outset #dddcdc;
border-radius: 4px;
height: 45px;
}
.d-flex {
.form-group {
width: 100%;
}
}
@media (max-width: 800px) {
#Input_Captcha {
margin-left: 0px;
}
}
}
.form-control {
border: 1px outset #e3e3e3 !important;
padding: 10px !important;
}
#submit-button {
margin-top: 10px;
}
}
Loading…
Cancel
Save