Mercurial > kallithea
changeset 6823:2e72d2d16a0f
comments: display comment previews while submitting
Instead of just saying 'Submitting' and not showing any progress to
the user until the comment has been accepted by the server, show a
preview of the comment above the comment box in a way which is makes
it obvious to the user the comment is being submitted. Apart from
that, also clear the comment box so that a repeated clicking the
submit button doesn't result in a duplicate comment.
The preview doesn't highlight URLs or support @mentions or *bold*,
which is a good enough approximation in this case. When/if we (re-)add
the rST/Markdown support, we will need a client-side parser for the
syntax we choose.
When the submission fails, display a message and offer the user to
retry or cancel the submission.
author | Andrew Shadura <andrew@shadura.me> |
---|---|
date | Mon, 10 Jul 2017 13:13:10 -0500 |
parents | 385c85f19d8d |
children | 2983dd668fd1 |
files | kallithea/public/css/style.css kallithea/public/js/base.js kallithea/templates/base/root.html kallithea/templates/changeset/changeset_file_comment.html |
diffstat | 4 files changed, 115 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/kallithea/public/css/style.css Mon Jul 03 22:17:28 2017 +0200 +++ b/kallithea/public/css/style.css Mon Jul 10 13:13:10 2017 -0500 @@ -2796,6 +2796,40 @@ border-radius: 4px !important; } +@keyframes animated-comment-background { + 0% { background-position: 0 0; } + 100% { background-position: 20px 0; } +} + +.comment-preview.failed .user, +.comment-preview.failed .panel-body { + color: #666; +} + +.comment-preview .comment-submission-status { + float: right; +} + +.comment-preview .comment-submission-status .btn-group { + margin-left: 10px; +} + +.comment-preview.submitting .panel-body { + background-image: linear-gradient( + -45deg, + #FAFAFA, + #FAFAFA 25%, + #FFF 25%, + #FFF 50%, + #FAFAFA 50%, + #FAFAFA 75%, + #FFF 75%, + #FFF 100% + ); + background-size: 20px 20px; + animation: animated-comment-background 0.4s linear infinite; +} + /**** PULL REQUESTS *****/
--- a/kallithea/public/js/base.js Mon Jul 03 22:17:28 2017 +0200 +++ b/kallithea/public/js/base.js Mon Jul 10 13:13:10 2017 -0500 @@ -647,6 +647,7 @@ .clone() .addClass('comment-inline-form'); $comment_div.append($form_div); + var $preview = $comment_div.find("div.comment-preview"); var $form = $comment_div.find("form"); var $textarea = $form.find('textarea'); @@ -678,7 +679,18 @@ } } - $form.find('.submitting-overlay').show(); + if (review_status) { + var $review_status = $preview.find('.automatic-comment'); + var review_status_lbl = $("#comment-inline-form-template input.status_change_radio[value='" + review_status + "']").parent().text().strip(); + $review_status.find('.comment-status-label').text(review_status_lbl); + $review_status.show(); + } + $preview.find('.comment-text div').text(text); + $preview.show(); + $textarea.val(''); + if (f_path && line_no) { + $form.hide(); + } var postData = { 'text': text, @@ -702,7 +714,33 @@ } } }; - ajaxPOST(AJAX_COMMENT_URL, postData, success); + var failure = function(x, s, e) { + $preview.removeClass('submitting').addClass('failed'); + var $status = $preview.find('.comment-submission-status'); + $('<span>', { + 'title': e, + text: _TM['Unable to post'] + }).replaceAll($status.contents()); + $('<div>', { + 'class': 'btn-group' + }).append( + $('<button>', { + 'class': 'btn btn-default btn-xs', + text: _TM['Retry'] + }).click(function() { + $status.text(_TM['Submitting ...']); + $preview.addClass('submitting').removeClass('failed'); + ajaxPOST(AJAX_COMMENT_URL, postData, success, failure); + }), + $('<button>', { + 'class': 'btn btn-default btn-xs', + text: _TM['Cancel'] + }).click(function() { + comment_div_state($comment_div, f_path, line_no); + }) + ).appendTo($status); + }; + ajaxPOST(AJAX_COMMENT_URL, postData, success, failure); }); // add event handler for hide/cancel buttons
--- a/kallithea/templates/base/root.html Mon Jul 03 22:17:28 2017 +0200 +++ b/kallithea/templates/base/root.html Mon Jul 10 13:13:10 2017 -0500 @@ -22,13 +22,17 @@ <script type="text/javascript"> ## JS translations map var TRANSLATION_MAP = { - 'Add Another Comment':${h.jshtml(_("Add Another Comment"))}, - 'Stop following this repository':${h.jshtml(_('Stop following this repository'))}, - 'Start following this repository':${h.jshtml(_('Start following this repository'))}, - 'Group':${h.jshtml(_('Group'))}, - 'members':${h.jshtml(_('members'))}, - 'Loading ...':${h.jshtml(_('Loading ...'))}, - 'loading ...':${h.jshtml(_('loading ...'))}, + 'Cancel': ${h.jshtml(_("Cancel"))}, + 'Retry': ${h.jshtml(_("Retry"))}, + 'Submitting ...': ${h.jshtml(_("Submitting ..."))}, + 'Unable to post': ${h.jshtml(_("Unable to post"))}, + 'Add Another Comment': ${h.jshtml(_("Add Another Comment"))}, + 'Stop following this repository': ${h.jshtml(_('Stop following this repository'))}, + 'Start following this repository': ${h.jshtml(_('Start following this repository'))}, + 'Group': ${h.jshtml(_('Group'))}, + 'members': ${h.jshtml(_('members'))}, + 'Loading ...': ${h.jshtml(_('Loading ...'))}, + 'loading ...': ${h.jshtml(_('loading ...'))}, 'Search truncated': ${h.jshtml(_('Search truncated'))}, 'No matching files': ${h.jshtml(_('No matching files'))}, 'Open New Pull Request from {0}': ${h.jshtml(_('Open New Pull Request from {0}'))},
--- a/kallithea/templates/changeset/changeset_file_comment.html Mon Jul 03 22:17:28 2017 +0200 +++ b/kallithea/templates/changeset/changeset_file_comment.html Mon Jul 10 13:13:10 2017 -0500 @@ -34,14 +34,16 @@ %if co.status_change: <div class="automatic-comment"> <p> - ${_("Status change")}: ${co.status_change[0].status_lbl} + ${_("Status change")}: <span class="comment-status-label">${co.status_change[0].status_lbl}</span> <i class="icon-circle changeset-status-${co.status_change[0].status}"></i> </p> </div> %endif + <div class="comment-text"> %if co.text: ${h.render_w_mentions(co.text, c.repo_name)|n} %endif + </div> </div> </div> </div> @@ -49,7 +51,33 @@ <%def name="comment_inline_form()"> -<div id='comment-inline-form-template' style="display:none"> +<div id='comment-inline-form-template' style="display: none;"> + <div class="comment comment-preview submitting" style="display: none;"> + <div class="panel panel-default"> + <div class="panel-heading"> + ${h.gravatar_div(request.authuser.email, size=20)} + <span class="user"> + ${request.authuser.full_name_or_username} + </span> + + <span class="comment-submission-status"> + ${_('Submitting ...')} + </span> + </div> + <div class="panel-body"> + <div class="automatic-comment" style="display: none;"> + <p> + ${_("Status change")}: <span class="comment-status-label"></span> + <i class="icon-circle"></i> + </p> + </div> + <div class="comment-text"> + <div class="formatted-fixed"> + </div> + </div> + </div> + </div> + </div> <div class="ac"> %if request.authuser.username != 'default': ${h.form('#', class_='inline-form')} @@ -97,7 +125,6 @@ </div> <div class="comment-button"> - <div class="submitting-overlay" style="display:none">${_('Submitting ...')}</div> ${h.submit('save', _('Comment'), class_='btn btn-default btn-sm save-inline-form')} ${h.reset('hide-inline-form', _('Cancel'), class_='btn btn-default btn-sm hide-inline-form')} </div>