Comments: More compact layout

This commit is contained in:
Pablo Vazquez 2017-09-25 00:39:34 +02:00
parent 6688ae66fa
commit 4eeccb6107
4 changed files with 234 additions and 288 deletions

View File

@ -27,17 +27,14 @@ $(document).on('click','body .comment-action-reply',function(e){
commentField.dataset.parentId = parentNodeId; commentField.dataset.parentId = parentNodeId;
// Start the comment field with @authorname: // Start the comment field with @authorname:
var replyAuthor = parentDiv.find('.comment-author:first span').html(); var replyAuthor = parentDiv.find('.comment-author:first').html();
$(commentField).val("**@" + replyAuthor.slice(1, -1) + ":** ");
$(commentField).val("**@" + replyAuthor + ":** ");
// Add class for styling // Add class for styling
$('.comment-container').removeClass('is-replying'); $('.comment-container').removeClass('is-replying');
parentDiv.addClass('is-replying'); parentDiv.addClass('is-replying');
// Rename Post Comment button to Reply
var commentSubmitButton = document.getElementById('comment_submit');
$(commentSubmitButton).text('Post Reply');
// Move comment-reply container field after the parent container // Move comment-reply container field after the parent container
var commentForm = $('.comment-reply-container').detach(); var commentForm = $('.comment-reply-container').detach();
parentDiv.after(commentForm); parentDiv.after(commentForm);
@ -46,9 +43,9 @@ $(document).on('click','body .comment-action-reply',function(e){
// Convert Markdown // Convert Markdown
var convert = new Markdown.getSanitizingConverter().makeHtml; var convert = new Markdown.getSanitizingConverter().makeHtml;
var preview = $('.comment-reply-preview'); var preview = $('.comment-reply-preview-md');
preview.html(convert($(commentField).val())); preview.html(convert($(commentField).val()));
$('.comment-reply-form').addClass('filled'); $('.comment-reply-field').addClass('filled');
}); });
@ -64,13 +61,10 @@ $(document).on('click','body .comment-action-cancel',function(e){
$(commentField).val(''); $(commentField).val('');
// Convert Markdown // Convert Markdown
var convert = new Markdown.getSanitizingConverter().makeHtml; var convert = new Markdown.getSanitizingConverter().makeHtml;
var preview = $('.comment-reply-preview'); var preview = $('.comment-reply-preview-md');
preview.html(convert($(commentField).val())); preview.html(convert($(commentField).val()));
var commentSubmitButton = document.getElementById('comment_submit'); $('.comment-reply-field').removeClass('filled');
$(commentSubmitButton).text('Post Comment');
$('.comment-reply-form').removeClass('filled');
$('.comment-container').removeClass('is-replying'); $('.comment-container').removeClass('is-replying');
}); });
@ -169,14 +163,14 @@ function show_comment_button_error(msg) {
var $button = $('.comment-action-submit'); var $button = $('.comment-action-submit');
var $textarea = $('#comment_field'); var $textarea = $('#comment_field');
$button.addClass('button-field-error'); $button.addClass('error');
$textarea.addClass('field-error'); $textarea.addClass('error');
$button.html(msg); $button.html(msg);
setTimeout(function(){ setTimeout(function(){
$button.html('Post Comment'); $button.html('<i class="pi-paper-plane"></i> Send');
$button.removeClass('button-field-error'); $button.removeClass('error');
$textarea.removeClass('field-error'); $textarea.removeClass('error');
}, 2500); }, 2500);
} }
@ -218,8 +212,7 @@ function comment_mode(clicked_item, mode)
$edit_buttons.find('.edit_cancel').hide(); $edit_buttons.find('.edit_cancel').hide();
$edit_buttons.find('.edit_save').hide(); $edit_buttons.find('.edit_save').hide();
$container.find('.comment-content').removeClass('editing'); $container.find('.comment-body').removeClass('editing');
$container.find('.comment-content-preview').html('').hide();
} }
} }
@ -241,7 +234,7 @@ function commentEditCancel(clicked_item, reload_comment) {
return loadComment(comment_id, {'properties.content': 1}) return loadComment(comment_id, {'properties.content': 1})
.done(function(data) { .done(function(data) {
var comment_html = data['properties']['content_html']; var comment_html = data['properties']['content_html'];
comment_container.find('.comment-content').html(comment_html); comment_container.find('.comment-body').html(comment_html);
}) })
.fail(function(xhr) { .fail(function(xhr) {
if (console) console.log('Error fetching comment: ', xhr); if (console) console.log('Error fetching comment: ', xhr);
@ -311,22 +304,22 @@ function post_comment($submit_button){
.progress(function() { .progress(function() {
$submit_button $submit_button
.addClass('submitting') .addClass('submitting')
.html('<i class="pi-spin spin"></i> Posting...'); .html('<i class="pi-spin spin"></i> Sending...');
}) })
.fail(function(xhr){ .fail(function(xhr){
if (typeof xhr === 'string') { if (typeof xhr === 'string') {
show_comment_button_error(xhr); show_comment_button_error(xhr);
} else { } else {
// If it's not a string, we assume it's a jQuery XHR object. // If it's not a string, we assume it's a jQuery XHR object.
if (console) console.log('Error saving comment:', xhr.responseText); if (console) console.log('Error posting comment: ', xhr.responseText);
show_comment_button_error("Houston! Try again?"); show_comment_button_error("Houston! Try again?");
} }
toastr.error(xhr.responseText, 'Error saving comment'); toastr.error(xhr.responseText, 'Error posting comment');
}) })
.done(function(comment_node_id) { .done(function(comment_node_id) {
$submit_button $submit_button
.removeClass('submitting') .removeClass('submitting')
.html('Post Comment'); .html('<i class="pi-paper-plane"></i> Send');
$('#comment_field').val(''); $('#comment_field').val('');
$('body').trigger('pillar:comment-posted', [comment_node_id]); $('body').trigger('pillar:comment-posted', [comment_node_id]);

View File

@ -3,9 +3,6 @@ $comments-width-max: 710px
.comments-container .comments-container
position: relative position: relative
&.texture
border-top: none
#comments-reload #comments-reload
text-align: center text-align: center
cursor: pointer cursor: pointer
@ -16,7 +13,7 @@ $comments-width-max: 710px
padding: 15px 0 10px 0 padding: 15px 0 10px 0
font-size: 1.3em font-size: 1.3em
font-weight: 300 font-weight: 300
color: $color-text-dark-primary color: $color-text-dark-hint
#comments-list-items-loading #comments-list-items-loading
font-size: 2em font-size: 2em
@ -43,7 +40,6 @@ $comments-width-max: 710px
.comment-container, .comment-container,
.comment-reply-container .comment-reply-container
display: flex display: flex
flex-direction: column
position: relative position: relative
padding: 15px 0 20px 0 padding: 15px 0 20px 0
@ -67,52 +63,43 @@ $comments-width-max: 710px
&.is-replying &.is-replying
margin-bottom: 15px !important margin-bottom: 15px !important
.comment-header .comment-avatar .comment-avatar
padding-right: 5px padding-right: 5px
padding-left: 5px padding-left: 5px
&.comment-linked+.comment-container.is-first &.comment-linked+.comment-container.is-first
border-top: none border-top: none
/* Header containing author, time, and badges if any*/ .comment-avatar
.comment-header padding-right: 10px
display: flex
align-items: center
.comment-avatar img
padding-right: 10px border-radius: 50%
height: 24px
margin-top: 5px
width: 24px
img p.comment-author
border-radius: 50% color: $color-text-dark
height: 24px display: inline-block
margin-top: 5px float: left
width: 24px font-weight: bold
margin-right: 10px
white-space: nowrap
.comment-author &.op
color: $color-primary-dark
.comment-time
padding-left: 10px
margin-left: 10px
color: $color-text-dark-hint
&:before
content: '·'
position: relative position: relative
color: $color-background-nav left: -10px
font: font-weight: 600
weight: 500
&.own
color: $color-success
&.op
color: $color-primary-dark
.username
padding-left: 5px
color: $color-text-dark-secondary
.comment-time
padding-left: 10px
margin-left: 10px
color: $color-text-dark-hint
&:before
content: '·'
position: relative
left: -10px
font-weight: 600
/* The actual comment body. */ /* The actual comment body. */
/* Here we style both the preview comment and posted comments */ /* Here we style both the preview comment and posted comments */
@ -128,7 +115,6 @@ $comments-width-max: 710px
+media-lg +media-lg
max-width: $comments-width-max max-width: $comments-width-max
padding: 0 0 0 34px
color: darken($color-text-dark, 10%) color: darken($color-text-dark, 10%)
font: font:
size: 1em size: 1em
@ -148,43 +134,34 @@ $comments-width-max: 710px
left: 0 left: 0
right: 0 right: 0
line-height: 1.5em line-height: 1.4em
margin-top: 5px margin-top: 5px
&:last-child &:last-child
margin-bottom: 10px margin-bottom: 10px
&.comment-author
margin-bottom: 0
strong, b strong, b
font-weight: 500 font-weight: 500
color: $color-info color: $color-info
textarea .editing
+node-details-description
background-color: white
padding: 0 0 0 5px
margin-left: 15px
width: 100%
color: $color-text-dark-primary
border: none
border-radius: 3px
font:
size: 1em
weight: normal
&:focus
outline: none
border: none
color: $color-text-dark
&.editing
background-color: $color-background-light background-color: $color-background-light
margin: 10px 0 margin-bottom: 10px
border-color: $color-background-dark border-color: $color-background-dark
border-radius: 3px border-radius: 3px
&.empty textarea
border-color: $color-danger box-shadow: none
width: 100%
.comment-content
display: flex
flex-direction: column
padding-bottom: 0
width: 100%
.comment-content-preview .comment-content-preview
display: none display: none
@ -233,17 +210,16 @@ $comments-width-max: 710px
left: 0 left: 0
right: 0 right: 0
display: flex
align-items: center align-items: center
padding-left: 35px
color: $color-text-dark-secondary color: $color-text-dark-secondary
display: flex
font-size: .9em
/* Small container for rating buttons and value */ /* Small container for rating buttons and value */
.comment-rating .comment-rating
display: flex display: flex
align-items: center align-items: center
&.rated &.rated
color: $color-text-dark-secondary color: $color-text-dark-secondary
.down .down
@ -327,10 +303,10 @@ $comments-width-max: 710px
&.is-reply &.is-reply
padding: padding:
top: 20px left: 20px
left: 15px top: 5px
margin-left: 30px margin-left: 35px
border-left: 3px solid $color-background-dark box-shadow: inset 3px 0 0 $color-background-dark
+media-xs +media-xs
padding-left: 15px padding-left: 15px
@ -340,6 +316,10 @@ $comments-width-max: 710px
border-top: thin solid $color-background-dark !important border-top: thin solid $color-background-dark !important
border-bottom: thin solid $color-background-dark !important border-bottom: thin solid $color-background-dark !important
&.is-replying+.comment-reply-container
margin-left: 35px
padding-left: 25px
&.is-first &.is-first
border-top: 1px solid lighten($color-text-dark-hint, 15%) border-top: 1px solid lighten($color-text-dark-hint, 15%)
@ -348,14 +328,12 @@ $comments-width-max: 710px
color: $color-success color: $color-success
&.is-replying &.is-replying
border-left: 3px solid $color-primary box-shadow: inset 5px 0 0 $color-primary
padding-left: 10px
// &.is-replying.is-first+.comment-reply-container
&.is-replying+.comment-reply-container &.is-replying+.comment-reply-container
border-left: 3px solid $color-primary box-shadow: inset 5px 0 0 $color-primary
margin-left: 0 margin-left: 0
padding-left: 30px padding-left: 55px
.comment-badge .comment-badge
display: inline-block display: inline-block
@ -382,9 +360,6 @@ $comments-width-max: 710px
.comment-reply-container .comment-reply-container
background-color: $color-background background-color: $color-background
// It's flex, like the others, but different direction
flex-direction: row
/* Little gravatar icon on the left */ /* Little gravatar icon on the left */
.comment-reply-avatar .comment-reply-avatar
img img
@ -395,33 +370,66 @@ $comments-width-max: 710px
/* textarea field, submit button and reply details */ /* textarea field, submit button and reply details */
.comment-reply-form .comment-reply-form
width: 100%
padding: padding:
top: 0 top: 0
left: 10px left: 10px
width: 100%
.comment-reply-field .comment-reply-field
background-color: white
border-radius: 3px
box-shadow: 1px 2px 2px rgba($color-background-dark, .5)
display: flex
position: relative position: relative
transition: border-color 300ms ease-in-out
textarea textarea
width: 100% +node-details-description
height: 45px
line-height: 1.5em
border: 1px solid $color-background-dark
border-radius: 3px
margin: 0 auto 5px auto
padding: 10px 0 10px 10px
color: $color-text-dark color: $color-text-dark
border: none
border-bottom-right-radius: 0
border-top-right-radius: 0
box-shadow: none
flex: 1
font:
size: 1em
weight: normal
line-height: 1.5em
margin: 0
min-height: 45px
padding: 10px 0 10px 10px
resize: vertical resize: vertical
transition: border-color 300ms ease-in-out width: 100%
transition: box-shadow 250ms ease-in-out
&:focus &:focus
border: 1px solid $color-success box-shadow: inset 2px 0 0 0 $color-success, inset 0 2px 0 0 $color-success, inset 0 -2px 0 0 $color-success
border: none
color: $color-text-dark
outline: none outline: none
&.field-error &+.comment-reply-meta button.comment-action-submit
border-color: $color-danger box-shadow: inset -2px 0 0 0 $color-success, inset 0 2px 0 0 $color-success, inset 0 -2px 0 0 $color-success
&.error
box-shadow: inset 2px 0 0 0 $color-danger, inset 0 2px 0 0 $color-danger, inset 0 -2px 0 0 $color-danger
&.filled
textarea:focus
border-bottom-left-radius: 0
&+.comment-reply-preview
display: flex
.comment-reply-meta
background-color: $color-success
.comment-action-submit
color: white
border-bottom-right-radius: 0
span.hotkey
display: block
&.sign-in &.sign-in
display: block display: block
@ -433,31 +441,23 @@ $comments-width-max: 710px
margin-right: 4px margin-right: 4px
.comment-reply-preview .comment-reply-preview
position: relative background-color: $color-background-light
margin: 10px auto 5px auto border-bottom-left-radius: 3px
padding: 10px border-bottom-right-radius: 3px
color: $color-text-dark-primary box-shadow: 1px 2px 2px rgba($color-background-dark, .5)
border-top: thin solid $color-background-dark color: $color-text-dark-primary
border-bottom: thin solid $color-background display: none // flex when comment-reply-field has .filled class
transition: all 150ms ease-in-out position: relative
transition: all 150ms ease-in-out
&:before p
content: 'Live Preview' padding-left: 0
position: absolute padding-right: 0
top: -20px
font-size: .9em
color: $color-text-dark-hint
transition: color 150ms ease-in-out
+media-md &-md
visibility: visible flex: 1
+media-sm padding: 5px 10px
visibility: hidden
p
padding-left: 0
padding-right: 0
.comment-reply-preview:empty .comment-reply-preview:empty
color: transparent color: transparent
@ -469,120 +469,65 @@ $comments-width-max: 710px
content: '' content: ''
color: transparent color: transparent
.comment-reply-info
background-color: $color-background-dark
display: flex
flex-direction: column
font-size: .8em
padding-bottom: 10px
text-align: center
width: 100px
.comment-action-cancel
cursor: pointer
padding: 10px
text-decoration: underline
&:hover
color: $color-primary
.comment-reply-meta .comment-reply-meta
display: flex display: flex
align-items: center align-items: center
border-bottom-right-radius: 3px
.comment-details border-top-right-radius: 3px
opacity: 0 transition: background-color 150ms ease-in-out, color 150ms ease-in-out
font-size: .9em width: 100px
display: flex
align-items: center
justify-content: flex-end
width: 100%
transition: opacity 300ms ease-in-out
.comment-author
padding:
right: 15px
color: $color-text-dark
font:
weight: 300
.author-name
padding-left: 3px
font:
weight: 500
.comment-rules
padding-right: 8px
margin-right: 8px
a
color: $color-text-dark-hint
&:hover
color: $color-primary
i
font-size: 1.5em
position: relative
top: 2px
button.comment-action-submit button.comment-action-submit
margin-left: auto border: none
min-width: 180px border-top-left-radius: 0
transition: all 200ms ease-in-out border-bottom-left-radius: 0
color: $color-success
+button($color-success, 3px) flex-direction: column
height: 100%
position: relative position: relative
transition: all 200ms ease-in-out
white-space: nowrap
width: 100%
&:focus
background-color: white
span.hint
position: absolute
top: 35px
left: 50%
transform: translateX(-50%)
font-size: .7em
text-transform: initial
display: block
color: $color-text-dark-hint
&.submitting &.submitting
background: linear-gradient(to left, transparent 50%, #7AC29A 50%) color: $color-info
background-size: 200% 100%
&.error
background-color: $color-danger
color: white color: white
animation:
name: background-fill-left-right
duration: .5s
delay: 0
fill-mode: forwards
iteration-count: 1
timing-function: ease-out
i span.hotkey
+spin color: white
display: none
font-weight: normal
&.button-field-error font-size: .9em
+button($color-danger, 3px)
background: transparent
pointer-events: none
i
position: relative
right: 2px
button.comment-action-cancel
display: none
margin-left: auto
margin-right: 5px
padding:
left: 15px
right: 15px
+button($color-text-dark-secondary, 3px)
border-color: transparent
i
margin-right: 0
&.filled
.comment-reply-field
textarea
height: 120px
.comment-reply-meta
.comment-details
opacity: 1
/* Style the comment container when we're replying */ /* Style the comment container when we're replying */
.comment-container + .comment-reply-container .comment-container + .comment-reply-container
margin-left: 30px margin-left: 30px
padding-top: 0 padding-top: 10px
.comment-reply-form .comment-reply-form
.comment-reply-meta .comment-reply-meta

View File

@ -4,41 +4,45 @@
data-node-id="{{ comment._id }}", data-node-id="{{ comment._id }}",
class="{% if is_reply %}is-reply{% else %}is-first{% endif %}") class="{% if is_reply %}is-reply{% else %}is-first{% endif %}")
.comment-header .comment-avatar
.comment-avatar img(src="{{ comment._user.email | gravatar }}")
img(src="{{ comment._user.email | gravatar }}")
.comment-author(class="{% if comment._is_own %}own{% endif %}") .comment-content
| {{ comment._user.full_name }} .comment-body
span.username ({{ comment._user.username }}) p.comment-author {{ comment._user.full_name }}
.comment-time {{ comment._created | pretty_date_time }} {% if comment._created != comment._updated %} (edited {{ comment._updated | pretty_date_time }}){% endif %} | {{comment.properties.content_html | safe }}
.comment-content {{comment.properties.content_html | safe }} // TODO: Markdown preview when editing
| {% if comment._is_own %}
.comment-content-preview
| {% endif %}
.comment-meta .comment-meta
.comment-rating( .comment-rating(
class="{% if comment._current_user_rating is not none %}rated{% if comment._current_user_rating %} positive{% endif %}{% endif %}") class="{% if comment._current_user_rating is not none %}rated{% if comment._current_user_rating %} positive{% endif %}{% endif %}")
.comment-rating-value(title="Number of likes") {{ comment._rating }} .comment-rating-value(title="Number of likes") {{ comment._rating }}
| {% if not comment._is_own %}
.comment-action-rating.up(title="Like comment") | {% if not comment._is_own %}
.comment-action-rating.up(title="Like comment")
| {% endif %}
.comment-action-reply(title="Reply to this comment")
span reply
| {% if comment._is_own %}
.comment-action-edit
span.edit_mode(title="Edit comment") edit
span.edit_save(title="Save comment")
i.pi-check
| save changes
span.edit_cancel(title="Cancel changes")
i.pi-cancel
| cancel
| {% endif %} | {% endif %}
.comment-action-reply(title="Reply to this comment") .comment-time
span reply | {{ comment._created | pretty_date_time }}
| {% if comment._is_own %} | {% if comment._created != comment._updated %}
.comment-action-edit span(title="edited {{ comment._updated | pretty_date_time }})") *
span.edit_mode(title="Edit comment") edit | {% endif %}
span.edit_save(title="Save comment")
i.pi-check
| save changes
span.edit_cancel(title="Cancel changes")
i.pi-cancel
| cancel
| {% endif %}
| {% for reply in comment['_replies']['_items'] %} | {% for reply in comment['_replies']['_items'] %}
| {{ render_comment(reply, True) }} | {{ render_comment(reply, True) }}

View File

@ -17,25 +17,29 @@
placeholder="Join the conversation...") placeholder="Join the conversation...")
.comment-reply-meta .comment-reply-meta
.comment-details
.comment-rules
a(
title="Markdown Supported",
target="_blank",
href="https://guides.github.com/features/mastering-markdown/")
i.pi-markdown
button.comment-action-cancel.btn.btn-outline( button.comment-action-submit(
type="button",
title="Cancel")
i.pi-cancel
button.comment-action-submit.btn.btn-outline(
id="comment_submit", id="comment_submit",
type="button", type="button",
title="Post Comment (Ctrl+Enter)") title="Post Comment (Ctrl+Enter)")
| Post Comment span
i.pi-paper-plane
| Send
span.hotkey Ctrl + Enter
.comment-reply-preview .comment-reply-preview
.comment-reply-preview-md
.comment-reply-info
.comment-action-cancel(
type="button",
title="Cancel")
span cancel
a(
title="Handy guide of Markdown syntax",
target="_blank",
href="https://guides.github.com/features/mastering-markdown/")
span markdown cheatsheet
| {% elif current_user.is_authenticated %} | {% elif current_user.is_authenticated %}
@ -119,7 +123,7 @@ script.
.on( 'keyup','body .comment-reply-field textarea',function(e){ .on( 'keyup','body .comment-reply-field textarea',function(e){
var $textarea = $(this); var $textarea = $(this);
var $container = $(this).parent(); var $container = $(this).parent();
var $preview = $textarea.next().next(); var $preview = $container.parent().find('.comment-reply-preview-md');
// TODO: communicate with back-end to do the conversion, // TODO: communicate with back-end to do the conversion,
// rather than relying on our JS-converted Markdown. // rather than relying on our JS-converted Markdown.
@ -149,13 +153,14 @@ script.
comment_mode(this, 'edit'); comment_mode(this, 'edit');
var parent_div = $(this).closest('.comment-container'); var $parent_div = $(this).closest('.comment-container');
var comment_id = parent_div.data('node-id'); var comment_id = $parent_div.data('node-id');
var comment_content = parent_div.find('.comment-content'); var comment_content = $parent_div.find('.comment-body');
var height = comment_content.height(); var height = comment_content.height();
loadComment(comment_id, {'properties.content': 1}) loadComment(comment_id, {'properties.content': 1})
.done(function(data) { .done(function(data) {
var comment_raw = data['properties']['content']; var comment_raw = data['properties']['content'];
comment_content.html($('<textarea>').text(comment_raw)); comment_content.html($('<textarea>').text(comment_raw));
@ -165,7 +170,6 @@ script.
.height(Math.max(150, height + 30)) .height(Math.max(150, height + 30))
.focus() .focus()
.trigger('keyup'); .trigger('keyup');
comment_content.siblings('.comment-content-preview').show();
}) })
.fail(function(xhr) { .fail(function(xhr) {
if (console) console.log('Error fetching comment: ', xhr); if (console) console.log('Error fetching comment: ', xhr);
@ -205,7 +209,7 @@ script.
.done(function(comment_id, comment_html) { .done(function(comment_id, comment_html) {
commentEditCancel($button, false) commentEditCancel($button, false)
$container.find('.comment-content') $container.find('.comment-body')
.html(comment_html) .html(comment_html)
.flashOnce(); .flashOnce();