fix: some more changes in design
This commit is contained in:
parent
04518f4a66
commit
e62f2627e0
7 changed files with 157 additions and 144 deletions
|
|
@ -1,5 +1,6 @@
|
|||
:root {
|
||||
--comment-timeline-height: 60px;
|
||||
--comment-timeline-bottom: 60px;
|
||||
--comment-timeline-top: 8px;
|
||||
}
|
||||
|
||||
.blog-list {
|
||||
|
|
@ -102,26 +103,54 @@
|
|||
}
|
||||
|
||||
|
||||
.feedback-button svg, .comment-count svg {
|
||||
.feedback-item svg {
|
||||
vertical-align: sub;
|
||||
}
|
||||
|
||||
.blog-feedback {
|
||||
.feedback-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
|
||||
.like-dislike {
|
||||
display: flex;
|
||||
.like-icon {
|
||||
cursor: pointer;
|
||||
|
||||
.like-icon, .dislike-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
&.gray use {
|
||||
fill: var(--gray-600);
|
||||
stroke: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-comment-button {
|
||||
margin-left: 35px;
|
||||
}
|
||||
|
||||
.timeline-dot {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 22px;
|
||||
background-color: var(--fg-color);
|
||||
border: 1px solid var(--dark-border-color);
|
||||
|
||||
&:before {
|
||||
content: ' ';
|
||||
background: var(--gray-600);
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
border-radius: 50%;
|
||||
height: 4px;
|
||||
width: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.blog-comments {
|
||||
.comment-form-wrapper {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.add-comment-section {
|
||||
.login-required {
|
||||
padding: var(--padding-sm);
|
||||
|
|
@ -160,13 +189,12 @@
|
|||
#comment-list {
|
||||
position: relative;
|
||||
padding-left: var(--padding-xl);
|
||||
padding-top: var(--padding-lg);
|
||||
|
||||
&::before {
|
||||
&:before {
|
||||
content: " ";
|
||||
top: 0;
|
||||
position: absolute;
|
||||
bottom: var(--comment-timeline-height);
|
||||
top: var(--comment-timeline-top);
|
||||
bottom: var(--comment-timeline-bottom);
|
||||
border-left: 1px solid var(--dark-border-color);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{% from "frappe/templates/includes/avatar_macro.html" import avatar %}
|
||||
|
||||
<div class="comment-row media my-3">
|
||||
<div class="comment-row media my-5">
|
||||
<div class="comment-avatar">
|
||||
{{ avatar(user_id=(comment.comment_email or comment.sender), size='avatar-medium') }}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,33 +1,35 @@
|
|||
<div class="comment-view mb-6">
|
||||
{% if not comment_list %}
|
||||
<div class="no-comment">
|
||||
<p class="text-muted small">{{ _("No comments yet. Start a new discussion.") }}</p>
|
||||
<p class="text-muted small">{{ _("No comments yet. ") }}
|
||||
<span class="hidden login-required">
|
||||
<a href="/login?redirect-to={{ pathname }}">{{ _("Login to start a new discussion") }}</a>
|
||||
</span>
|
||||
<span class="hidden start-discussion">{{ _("Start a new discussion") }}</span>
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if not is_communication %}
|
||||
<div class="add-comment-section">
|
||||
<div class="text-muted hidden login-required">
|
||||
<a href="/login?redirect-to={{ pathname }}">{{ _("Login to comment") }}</a>
|
||||
</div>
|
||||
<div class="add-comment-section mb-5">
|
||||
<div class="comment-form-wrapper">
|
||||
<div id="comment-form">
|
||||
<form class="new-comment">
|
||||
<fieldset class="new-comment-fields">
|
||||
<div class="user-details row" style="margin-bottom: 15px; display:none;">
|
||||
<div class="comment-by col-sm-6 pb-4">
|
||||
<div class="form-label mb-1">Your Name</div>
|
||||
<div class="form-label mb-1">{{ _("Your Name") }}</div>
|
||||
<input class="form-control comment_by" name="comment_by" type="text">
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-label mb-1">Email</div>
|
||||
<div class="form-label mb-1">{{ _("Email") }}</div>
|
||||
<input class="form-control comment_email" name="comment_email" type="email">
|
||||
</div>
|
||||
</div>
|
||||
<div class="comment-text-area">
|
||||
<div class="form-label mb-1">Add a comment</div>
|
||||
<div class="form-label mb-1">{{ _("Add a comment") }}</div>
|
||||
<textarea class="form-control" name="comment" rows=5 ></textarea>
|
||||
<div class="text-muted small mt-1 mb-4">Ctrl+Enter to add comment</div>
|
||||
<div class="text-muted small mt-1 mb-4">{{ _("Ctrl+Enter to add comment") }}</div>
|
||||
</div>
|
||||
<button class="btn btn-sm small" id="submit-comment">{{ _("Comment") }}</button>
|
||||
</fieldset>
|
||||
|
|
@ -37,77 +39,109 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
<hr class="add-comment-hr my-5">
|
||||
|
||||
<div itemscope itemtype="http://schema.org/UserComments" id="comment-list">
|
||||
{% for comment in comment_list %}
|
||||
{% include "templates/includes/comments/comment.html" %}
|
||||
{% endfor %}
|
||||
<div class="add-comment mb-5">
|
||||
<div class="timeline-dot"></div>
|
||||
<button class="btn btn-sm small add-comment-button">{{ _("Add a comment") }}</button>
|
||||
</div>
|
||||
<div class="comment-list">
|
||||
{% for comment in comment_list %}
|
||||
{% include "templates/includes/comments/comment.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
frappe.ready(function() {
|
||||
let guest_allowed = "{{ guest_allowed or ''}}";
|
||||
let guest_allowed = parseInt("{{ guest_allowed or 0}}");
|
||||
let comment_count = "{{ comment_text }}";
|
||||
let full_name = ""
|
||||
let user_id = "";
|
||||
|
||||
let update_timeline_line_length = function(direction, size) {
|
||||
if (direction == 'top') {
|
||||
$('.blog-container')[0].style.setProperty('--comment-timeline-top', size);
|
||||
} else {
|
||||
let comment_timeline_bottom = $('.comment-list .comment-row:last-child').height() - 10;
|
||||
$('.blog-container')[0].style.setProperty('--comment-timeline-bottom', comment_timeline_bottom +'px');
|
||||
}
|
||||
}
|
||||
|
||||
let show_comment_box = function() {
|
||||
$('.comment-form-wrapper').show();
|
||||
update_timeline_line_length('top', '-20px');
|
||||
$('.add-comment-hr').hide();
|
||||
$('.add-comment').hide();
|
||||
}
|
||||
|
||||
let hide_comment_box = function() {
|
||||
$('.comment-form-wrapper').hide();
|
||||
update_timeline_line_length('top', '8px');
|
||||
update_timeline_line_length('bottom');
|
||||
$('.add-comment-hr').show();
|
||||
$('.add-comment').show();
|
||||
}
|
||||
|
||||
let $comment_count = $(`
|
||||
<div class="comment-count">
|
||||
${frappe.utils.icon('small-message', 'md')}
|
||||
<div class="feedback-item">
|
||||
<span class="comment-icon">${frappe.utils.icon('small-message', 'md')}</span>
|
||||
<span class="comment-count"></span>
|
||||
</div>
|
||||
`);
|
||||
|
||||
$('.feedback-header').append($comment_count);
|
||||
|
||||
$('form').keydown(function(event) {
|
||||
if (event.ctrlKey && event.keyCode === 13) {
|
||||
$(this).find('#submit-comment').trigger('click');
|
||||
}
|
||||
})
|
||||
|
||||
let comment_timeline_height = $('#comment-list .comment-row:last-child').height() - 10;
|
||||
$('.blog-container')[0].style.setProperty('--comment-timeline-height', comment_timeline_height +'px');
|
||||
|
||||
let update_count = function(name, count) {
|
||||
let text = count == 0 || count == 1 ? name : `${name}s`;
|
||||
|
||||
$(`.${name.toLowerCase()}-count`).find('span').remove();
|
||||
|
||||
$(`.${name.toLowerCase()}-count`).append(`
|
||||
<span>${text} ${count}</span>
|
||||
`);
|
||||
}
|
||||
|
||||
update_count('Comment', comment_count);
|
||||
|
||||
if (!frappe.is_user_logged_in()) {
|
||||
!guest_allowed && $(".login-required, .comment-form-wrapper").toggleClass("hidden");
|
||||
$(".user-details").toggle('hide');
|
||||
if (guest_allowed) {
|
||||
$('.start-discussion').removeClass('hidden');
|
||||
} else {
|
||||
$(".login-required, .comment-form-wrapper").toggleClass("hidden");
|
||||
|
||||
$('.add-comment-button').text('{{ _("Login to comment") }}');
|
||||
$('.add-comment-button').click(() => {
|
||||
window.location.href = '/login?redirect-to={{ pathname }}';
|
||||
});
|
||||
}
|
||||
} else {
|
||||
$('input.comment_by').prop("disabled", true);
|
||||
$('input.comment_email').prop("disabled", true);
|
||||
}
|
||||
|
||||
var n_comments = $(".comment-row").length;
|
||||
|
||||
if(n_comments) {
|
||||
$(".no_comment").toggle(false);
|
||||
}
|
||||
if(n_comments > 50) {
|
||||
$(".add-comment").toggle(false)
|
||||
.parent().append("<div class='text-muted'>Comments are closed.</div>")
|
||||
}
|
||||
|
||||
var full_name = "", user_id = "";
|
||||
if(frappe.is_user_logged_in()) {
|
||||
full_name = frappe.get_cookie("full_name");
|
||||
user_id = frappe.get_cookie("user_id");
|
||||
if(user_id != "Guest") {
|
||||
$("[name='comment_email']").val(user_id);
|
||||
$("[name='comment_by']").val(full_name);
|
||||
}
|
||||
} else {
|
||||
$(".user-details").toggle('hide');
|
||||
|
||||
$('.start-discussion').removeClass('hidden');
|
||||
}
|
||||
|
||||
$('.blog-feedback').append($comment_count);
|
||||
$('.comment-count').text(comment_count);
|
||||
$("#comment-form textarea").val("");
|
||||
|
||||
update_timeline_line_length('bottom');
|
||||
|
||||
let n_comments = $(".comment-row").length;
|
||||
n_comments ? $(".no_comment").toggle(false) : show_comment_box();
|
||||
|
||||
if(n_comments > 50) {
|
||||
$(".add-comment").toggle(false)
|
||||
.parent().append("<div class='text-muted'>Comments are closed.</div>")
|
||||
}
|
||||
|
||||
$('.add-comment-button').click(() => {
|
||||
show_comment_box();
|
||||
});
|
||||
|
||||
$("#submit-comment").click(function() {
|
||||
var args = {
|
||||
comment_by: $("[name='comment_by']").val(),
|
||||
|
|
@ -120,17 +154,17 @@
|
|||
}
|
||||
|
||||
if(!args.comment_by || !args.comment_email || !args.comment) {
|
||||
frappe.msgprint("{{ _("All fields are necessary to submit the comment.") }}");
|
||||
frappe.msgprint('{{ _("All fields are necessary to submit the comment.") }}');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.comment_email!=='Administrator' && !validate_email(args.comment_email)) {
|
||||
frappe.msgprint("{{ _("Please enter a valid email address.") }}");
|
||||
frappe.msgprint('{{ _("Please enter a valid email address.") }}');
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!args.comment || !args.comment.trim()) {
|
||||
frappe.msgprint("{{ _("Please add a valid comment.") }}");
|
||||
frappe.msgprint('{{ _("Please add a valid comment.") }}');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -145,12 +179,13 @@
|
|||
frappe.msgprint(r._server_messages);
|
||||
} else {
|
||||
if (r.message) {
|
||||
$(r.message).prependTo("#comment-list");
|
||||
$(r.message).prependTo(".comment-list");
|
||||
comment_count = cint(comment_count) + 1;
|
||||
update_count('Comment', comment_count);
|
||||
$('.comment-count').text(comment_count);
|
||||
}
|
||||
$(".no-comment, .add-comment").toggle(false);
|
||||
$(".no-comment").toggle(false);
|
||||
$("#comment-form textarea").val("");
|
||||
hide_comment_box();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,64 +1,31 @@
|
|||
<div class="feedback-header mb-0">
|
||||
<div class="like-dislike">
|
||||
<div class="feedback-button mr-3">
|
||||
<span class="like-icon"></span>
|
||||
<span class="like-count"></span>
|
||||
</div>
|
||||
<div class="feedback-button mr-3">
|
||||
<span class="dislike-icon"></span>
|
||||
<span class="dislike-count"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feedback-item mr-3">
|
||||
<span class="like-icon"></span>
|
||||
<span class="like-count"></span>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
frappe.ready(() => {
|
||||
let like = parseInt("{{ user_feedback.like or 0 }}");
|
||||
let dislike = parseInt("{{ user_feedback.dislike or 0 }}");
|
||||
let like_count = parseInt("{{ like_count or 0 }}");
|
||||
let dislike_count = parseInt("{{ dislike_count or 0 }}");
|
||||
|
||||
$('.like-icon').append(frappe.utils.icon(like ? 'like-active' : 'like', 'md'));
|
||||
$('.dislike-icon').append(frappe.utils.icon(dislike ? 'dislike-active' : 'dislike', 'md'));
|
||||
|
||||
let update_count = function(name, count) {
|
||||
let text = count == 0 || count == 1 ? name : `${name}s`;
|
||||
|
||||
$(`.${name.toLowerCase()}-count`).text('');
|
||||
$(`.${name.toLowerCase()}-count`).text(`${text} ${count}`);
|
||||
}
|
||||
|
||||
let update_like = function() {
|
||||
like = !like;
|
||||
like ? like_count++ : like_count--;
|
||||
toggle_icon('like', like);
|
||||
update_count('Like', like_count);
|
||||
toggle_like_icon(like);
|
||||
$('.like-count').text(like_count);
|
||||
}
|
||||
|
||||
let update_dislike = function() {
|
||||
dislike = !dislike;
|
||||
dislike ? dislike_count++ : dislike_count--;
|
||||
toggle_icon('dislike', dislike);
|
||||
update_count('Dislike', dislike_count);
|
||||
let toggle_like_icon = function(active) {
|
||||
active ? $('.like-icon').addClass('gray') : $('.like-icon').removeClass('gray');
|
||||
}
|
||||
|
||||
let toggle_icon = function(icon_name, active) {
|
||||
let icon = active ? `${icon_name}-active` : icon_name;
|
||||
$(`.${icon_name}-icon svg`).replaceWith(frappe.utils.icon(icon, 'md'));
|
||||
}
|
||||
$('.like-icon').append(frappe.utils.icon('heart', 'md'))
|
||||
toggle_like_icon(like);
|
||||
|
||||
update_count('Like', like_count);
|
||||
update_count('Dislike', dislike_count);
|
||||
$('.like-count').text(like_count);
|
||||
|
||||
$('.like-icon').click(() => {
|
||||
update_like();
|
||||
dislike && update_dislike();
|
||||
update_feedback();
|
||||
})
|
||||
|
||||
$('.dislike-icon').click(() => {
|
||||
update_dislike();
|
||||
like && update_like();
|
||||
update_feedback();
|
||||
})
|
||||
|
||||
|
|
@ -68,8 +35,7 @@
|
|||
args: {
|
||||
reference_doctype: "{{ reference_doctype or doctype }}",
|
||||
reference_name: "{{ reference_name or name }}",
|
||||
like,
|
||||
dislike
|
||||
like
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,8 @@ from frappe.website.doctype.blog_settings.blog_settings import get_feedback_limi
|
|||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(key='reference_name', limit=get_feedback_limit, seconds=60*60)
|
||||
def give_feedback(reference_doctype, reference_name, like, dislike):
|
||||
def give_feedback(reference_doctype, reference_name, like):
|
||||
like = frappe.parse_json(like)
|
||||
dislike = frappe.parse_json(dislike)
|
||||
doc = frappe.get_doc(reference_doctype, reference_name)
|
||||
if doc.disable_feedback == 1:
|
||||
return
|
||||
|
|
@ -31,7 +30,6 @@ def give_feedback(reference_doctype, reference_name, like, dislike):
|
|||
doc.reference_name = reference_name
|
||||
doc.ip_address = frappe.local.request_ip
|
||||
doc.like = like
|
||||
doc.dislike = dislike
|
||||
doc.save(ignore_permissions=True)
|
||||
|
||||
subject = _('Feedback on {0}: {1}').format(reference_doctype, reference_name)
|
||||
|
|
@ -41,9 +39,7 @@ def give_feedback(reference_doctype, reference_name, like, dislike):
|
|||
def send_mail(feedback, subject):
|
||||
doc = frappe.get_doc(feedback.reference_doctype, feedback.reference_name)
|
||||
if feedback.like:
|
||||
message = "<p>Hey, </p><p>You have received a 👍 like on your blog post <b>{0}</b></p>".format(feedback.reference_name)
|
||||
elif feedback.dislike:
|
||||
message = "<p>Hey, </p><p>You have received a 👎 dislike on your blog post <b>{0}</b></p>".format(feedback.reference_name)
|
||||
message = "<p>Hey, </p><p>You have received a ❤️ heart on your blog post <b>{0}</b></p>".format(feedback.reference_name)
|
||||
else:
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ class BlogPost(WebsiteGenerator):
|
|||
user = frappe.session.user
|
||||
|
||||
feedback = frappe.get_all('Feedback',
|
||||
fields=['like', 'dislike'],
|
||||
fields=['like'],
|
||||
filters=dict(
|
||||
reference_doctype=self.doctype,
|
||||
reference_name=self.name,
|
||||
|
|
@ -157,7 +157,6 @@ class BlogPost(WebsiteGenerator):
|
|||
)
|
||||
|
||||
like_count = 0
|
||||
dislike_count = 0
|
||||
|
||||
if frappe.db.count('Feedback'):
|
||||
like_count = frappe.db.count('Feedback',
|
||||
|
|
@ -168,17 +167,8 @@ class BlogPost(WebsiteGenerator):
|
|||
)
|
||||
)
|
||||
|
||||
dislike_count = frappe.db.count('Feedback',
|
||||
filters = dict(
|
||||
reference_doctype = self.doctype,
|
||||
reference_name = self.name,
|
||||
dislike = True
|
||||
)
|
||||
)
|
||||
|
||||
context.user_feedback = feedback[0] if feedback else ''
|
||||
context.like_count = like_count
|
||||
context.dislike_count = dislike_count
|
||||
|
||||
def set_read_time(self):
|
||||
content = self.content or self.content_html or ''
|
||||
|
|
|
|||
|
|
@ -43,30 +43,28 @@
|
|||
) }}
|
||||
{%- endif -%}
|
||||
<div class="blog-footer">
|
||||
<div>
|
||||
{{ _('Published on') }} <time datetime="{{ published_on }}">{{ frappe.format_date(published_on) }}</time>
|
||||
</div>
|
||||
<div>
|
||||
{% if social_links %}
|
||||
{% if social_links %}
|
||||
<div>
|
||||
{% for link in social_links %}
|
||||
<a href="{{ link.link }}" class="text-muted ml-2 fa fa-{{ link.icon }}" target="_blank"></a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="blog-feedback">
|
||||
{% if not disable_feedback %}
|
||||
{% include 'templates/includes/feedback/feedback.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{{ _('Published on') }} <time datetime="{{ published_on }}">{{ frappe.format_date(published_on) }}</time>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if blogger_info %}
|
||||
<hr class="my-5">
|
||||
<hr class="mt-2 mb-5">
|
||||
{% include "templates/includes/blog/blogger.html" %}
|
||||
{% endif %}
|
||||
|
||||
{% if not disable_feedback %}
|
||||
<div class="blog-feedback my-5">
|
||||
{% include 'templates/includes/feedback/feedback.html' %}
|
||||
<hr class="mt-2 mb-5">
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if not disable_comments %}
|
||||
<div class="my-5 blog-comments">
|
||||
{% include 'templates/includes/comments/comments.html' %}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue