summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2016-02-05 15:45:30 +0100
committerVincent Petry <pvince81@owncloud.com>2016-02-05 15:45:30 +0100
commit142a2dd2eb071b268c2c114b5f29820602f18486 (patch)
treebeed08250ee96babe66b0480d28bfd6dcfa9185b
parent0196f0e54643e3a0b17588cb9f4c54d7d73c5b29 (diff)
downloadnextcloud-server-142a2dd2eb071b268c2c114b5f29820602f18486.tar.gz
nextcloud-server-142a2dd2eb071b268c2c114b5f29820602f18486.zip
Limit comment size to 1000 in UI
Whenever the limit is almost reached (90% of the length), a tooltip will appear. Once the limit is exceeded, the "Post" button will be disabled and the field will become red.
-rw-r--r--apps/comments/css/comments.css10
-rw-r--r--apps/comments/js/commentstabview.js30
-rw-r--r--apps/comments/tests/js/commentstabviewSpec.js78
3 files changed, 116 insertions, 2 deletions
diff --git a/apps/comments/css/comments.css b/apps/comments/css/comments.css
index b86ed38efe7..85569102e1d 100644
--- a/apps/comments/css/comments.css
+++ b/apps/comments/css/comments.css
@@ -14,7 +14,7 @@
#commentsTabView .newCommentForm .message {
width: 90%;
- resize: none;
+ resize: vertical;
}
#commentsTabView .newCommentForm .submitLoading {
@@ -77,6 +77,14 @@
visibility: hidden;
}
+#commentsTabView .message.error {
+ color: #e9322d;
+ border-color: #e9322d;
+ -webkit-box-shadow: 0 0 6px #f8b9b7;
+ -moz-box-shadow: 0 0 6px #f8b9b7;
+ box-shadow: 0 0 6px #f8b9b7;
+}
+
.app-files .action-comment>img {
margin-right: 5px;
}
diff --git a/apps/comments/js/commentstabview.js b/apps/comments/js/commentstabview.js
index 8faf98b35ab..d75cf39538c 100644
--- a/apps/comments/js/commentstabview.js
+++ b/apps/comments/js/commentstabview.js
@@ -71,6 +71,8 @@
'click .cancel': '_onClickCloseComment'
},
+ _commentMaxLength: 1000,
+
initialize: function() {
OCA.Files.DetailTabView.prototype.initialize.apply(this, arguments);
this.collection = new OCA.Comments.CommentCollection();
@@ -80,7 +82,10 @@
this._avatarsEnabled = !!OC.config.enable_avatars;
+ this._commentMaxThreshold = this._commentMaxLength * 0.9;
+
// TODO: error handling
+ _.bindAll(this, '_onTypeComment');
},
template: function(params) {
@@ -162,6 +167,7 @@
this.$el.find('.avatar').avatar(OC.getCurrentUser().uid, 28);
}
this.delegateEvents();
+ this.$el.find('textarea').on('keyup input change', this._onTypeComment);
},
_formatItem: function(commentModel) {
@@ -262,6 +268,7 @@
// spawn form
$comment.after($formRow);
$formRow.data('commentEl', $comment);
+ $formRow.find('textarea').on('keyup input change', this._onTypeComment);
// copy avatar element from original to avoid flickering
$formRow.find('.avatar').replaceWith($comment.find('.avatar').clone());
@@ -270,6 +277,27 @@
return false;
},
+ _onTypeComment: function(ev) {
+ var $field = $(ev.target);
+ var len = $field.val().length;
+ var $submitButton = $field.data('submitButtonEl');
+ if (!$submitButton) {
+ $submitButton = $field.closest('form').find('.submit');
+ $field.data('submitButtonEl', $submitButton);
+ }
+ $field.tooltip('hide');
+ if (len > this._commentMaxThreshold) {
+ $field.attr('data-original-title', t('comments', 'Allowed characters {count} of {max}', {count: len, max: this._commentMaxLength}));
+ $field.tooltip({trigger: 'manual'});
+ $field.tooltip('show');
+ $field.addClass('error');
+ }
+
+ var limitExceeded = (len > this._commentMaxLength);
+ $field.toggleClass('error', limitExceeded);
+ $submitButton.prop('disabled', limitExceeded);
+ },
+
_onClickCloseComment: function(ev) {
ev.preventDefault();
var $row = $(ev.target).closest('.comment');
@@ -318,7 +346,7 @@
var message = $textArea.val().trim();
e.preventDefault();
- if (!message.length) {
+ if (!message.length || message.length > this._commentMaxLength) {
return;
}
diff --git a/apps/comments/tests/js/commentstabviewSpec.js b/apps/comments/tests/js/commentstabviewSpec.js
index 9e986899f7d..70930da7520 100644
--- a/apps/comments/tests/js/commentstabviewSpec.js
+++ b/apps/comments/tests/js/commentstabviewSpec.js
@@ -25,6 +25,20 @@ describe('OCA.Comments.CommentsTabView tests', function() {
var testComments;
var clock;
+ /**
+ * Creates a dummy message with the given length
+ *
+ * @param {int} len length
+ * @return {string} message
+ */
+ function createMessageWithLength(len) {
+ var bigMessage = '';
+ for (var i = 0; i < len; i++) {
+ bigMessage += 'a';
+ }
+ return bigMessage;
+ }
+
beforeEach(function() {
clock = sinon.useFakeTimers(Date.UTC(2016, 1, 3, 10, 5, 9));
fetchStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'fetchNext');
@@ -201,7 +215,55 @@ describe('OCA.Comments.CommentsTabView tests', function() {
expect(createStub.notCalled).toEqual(true);
});
+ it('does not create a comment if the field length is too large', function() {
+ var bigMessage = '';
+ for (var i = 0; i < view._commentMaxLength * 2; i++) {
+ bigMessage += 'a';
+ }
+ view.$el.find('.message').val(bigMessage);
+ view.$el.find('form').submit();
+ expect(createStub.notCalled).toEqual(true);
+ });
+ describe('limit indicator', function() {
+ var tooltipStub;
+ var $message;
+ var $submitButton;
+
+ beforeEach(function() {
+ tooltipStub = sinon.stub($.fn, 'tooltip');
+ $message = view.$el.find('.message');
+ $submitButton = view.$el.find('.submit');
+ });
+ afterEach(function() {
+ tooltipStub.restore();
+ });
+
+ it('does not displays tooltip when limit is far away', function() {
+ $message.val(createMessageWithLength(3));
+ $message.trigger('change');
+
+ expect(tooltipStub.calledWith('show')).toEqual(false);
+ expect($submitButton.prop('disabled')).toEqual(false);
+ expect($message.hasClass('error')).toEqual(false);
+ });
+ it('displays tooltip when limit is almost reached', function() {
+ $message.val(createMessageWithLength(view._commentMaxLength - 2));
+ $message.trigger('change');
+
+ expect(tooltipStub.calledWith('show')).toEqual(true);
+ expect($submitButton.prop('disabled')).toEqual(false);
+ expect($message.hasClass('error')).toEqual(false);
+ });
+ it('displays tooltip and disabled button when limit is exceeded', function() {
+ $message.val(createMessageWithLength(view._commentMaxLength + 2));
+ $message.trigger('change');
+
+ expect(tooltipStub.calledWith('show')).toEqual(true);
+ expect($submitButton.prop('disabled')).toEqual(true);
+ expect($message.hasClass('error')).toEqual(true);
+ });
+ });
});
describe('editing comments', function() {
var saveStub;
@@ -336,6 +398,22 @@ describe('OCA.Comments.CommentsTabView tests', function() {
destroyStub.restore();
});
+ it('does not submit comment if the field is empty', function() {
+ var $comment = view.$el.find('.comment[data-id=1]');
+ $comment.find('.action.edit').click();
+ $comment.find('.message').val(' ');
+ $comment.find('form').submit();
+
+ expect(saveStub.notCalled).toEqual(true);
+ });
+ it('does not submit comment if the field length is too large', function() {
+ var $comment = view.$el.find('.comment[data-id=1]');
+ $comment.find('.action.edit').click();
+ $comment.find('.message').val(createMessageWithLength(view._commentMaxLength * 2));
+ $comment.find('form').submit();
+
+ expect(saveStub.notCalled).toEqual(true);
+ });
});
describe('read marker', function() {
var updateMarkerStub;