diff options
author | Vincent Petry <pvince81@owncloud.com> | 2016-02-03 18:44:14 +0100 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2016-02-03 21:06:55 +0100 |
commit | bbefe1ed64c0b4a9b77dc8d9b06b9f56c6b7f6e8 (patch) | |
tree | f304cf2e608a05fdc50f7366046b64e71328155e /apps/comments | |
parent | da0462015507053c4424f62c32a4a182301fae22 (diff) | |
download | nextcloud-server-bbefe1ed64c0b4a9b77dc8d9b06b9f56c6b7f6e8.tar.gz nextcloud-server-bbefe1ed64c0b4a9b77dc8d9b06b9f56c6b7f6e8.zip |
Comment owner can now edit or delete
Diffstat (limited to 'apps/comments')
-rw-r--r-- | apps/comments/css/comments.css | 27 | ||||
-rw-r--r-- | apps/comments/js/commentmodel.js | 13 | ||||
-rw-r--r-- | apps/comments/js/commentstabview.js | 183 |
3 files changed, 185 insertions, 38 deletions
diff --git a/apps/comments/css/comments.css b/apps/comments/css/comments.css index 5e247aaeb71..f4e7d144ec5 100644 --- a/apps/comments/css/comments.css +++ b/apps/comments/css/comments.css @@ -47,9 +47,36 @@ #commentsTabView .comment .date { position: absolute; + right: 20px; +} + +#commentsTabView .comment .action { + opacity: 0; + vertical-align: middle; + display: inline-block; +} + +#commentsTabView .comment:hover .action { + opacity: 0.3; +} + +#commentsTabView .comment .action:hover { + opacity: 1; +} + +#commentsTabView .comment .action.delete { + position: absolute; right: 0; } +#commentsTabView .comment.disabled { + opacity: 0.3; +} + +#commentsTabView .comment.disabled .action { + visibility: hidden; +} + .app-files .action-comment>img { margin-right: 5px; } diff --git a/apps/comments/js/commentmodel.js b/apps/comments/js/commentmodel.js index ba04fd61de3..89492707b61 100644 --- a/apps/comments/js/commentmodel.js +++ b/apps/comments/js/commentmodel.js @@ -39,8 +39,17 @@ }, parse: function(data) { - data.isUnread = (data.isUnread === 'true'); - return data; + return { + id: data.id, + message: data.message, + actorType: data.actorType, + actorId: data.actorId, + actorDisplayName: data.actorDisplayName, + creationDateTime: data.creationDateTime, + objectType: data.objectType, + objectId: data.objectId, + isUnread: (data.isUnread === 'true') + }; } }); diff --git a/apps/comments/js/commentstabview.js b/apps/comments/js/commentstabview.js index 188d8c5943c..9db39408c70 100644 --- a/apps/comments/js/commentstabview.js +++ b/apps/comments/js/commentstabview.js @@ -8,27 +8,34 @@ * */ +/* global Handlebars */ + (function(OC, OCA) { var TEMPLATE = - '<div class="newCommentRow comment">' + + '<ul class="comments">' + + '</ul>' + + '<div class="empty hidden">{{emptyResultLabel}}</div>' + + '<input type="button" class="showMore hidden" value="{{moreLabel}}"' + + ' name="show-more" id="show-more" />' + + '<div class="loading hidden" style="height: 50px"></div>'; + + var EDIT_COMMENT_TEMPLATE = + '<div class="newCommentRow comment" data-id="{{id}}">' + ' <div class="authorRow">' + ' {{#if avatarEnabled}}' + - ' <div class="avatar" data-username="{{userId}}"></div>' + + ' <div class="avatar" data-username="{{actorId}}"></div>' + ' {{/if}}' + - ' <div class="author">{{userDisplayName}}</div>' + + ' <div class="author">{{actorDisplayName}}</div>' + + '{{#if isEditMode}}' + + ' <a href="#" class="action close icon icon-close has-tooltip" title="{{closeTooltip}}"></a>' + + '{{/if}}' + ' </div>' + ' <form class="newCommentForm">' + - ' <textarea class="message" placeholder="{{newMessagePlaceholder}}"></textarea>' + + ' <textarea class="message" placeholder="{{newMessagePlaceholder}}">{{{message}}}</textarea>' + ' <input class="submit" type="submit" value="{{submitText}}" />' + ' <div class="submitLoading icon-loading-small hidden"></div>'+ ' </form>' + - ' <ul class="comments">' + - ' </ul>' + - '</div>' + - '<div class="empty hidden">{{emptyResultLabel}}</div>' + - '<input type="button" class="showMore hidden" value="{{moreLabel}}"' + - ' name="show-more" id="show-more" />' + - '<div class="loading hidden" style="height: 50px"></div>'; + '</div>'; var COMMENT_TEMPLATE = '<li class="comment{{#if isUnread}} unread{{/if}}" data-id="{{id}}">' + @@ -37,7 +44,13 @@ ' <div class="avatar" data-username="{{actorId}}"> </div>' + ' {{/if}}' + ' <div class="author">{{actorDisplayName}}</div>' + + '{{#if isUserAuthor}}' + + ' <a href="#" class="action edit icon icon-rename has-tooltip" title="{{editTooltip}}"></a>' + + '{{/if}}' + ' <div class="date has-tooltip" title="{{altDate}}">{{date}}</div>' + + '{{#if isUserAuthor}}' + + ' <a href="#" class="action delete icon icon-delete has-tooltip" title="{{deleteTooltip}}"></a>' + + '{{/if}}' + ' </div>' + ' <div class="message">{{{formattedMessage}}}</div>' + '</li>'; @@ -52,7 +65,10 @@ events: { 'submit .newCommentForm': '_onSubmitComment', - 'click .showMore': '_onClickShowMore' + 'click .showMore': '_onClickShowMore', + 'click .action.edit': '_onClickEditComment', + 'click .action.delete': '_onClickDeleteComment', + 'click .action.close': '_onClickCloseComment' }, initialize: function() { @@ -65,7 +81,6 @@ this._avatarsEnabled = !!OC.config.enable_avatars; // TODO: error handling - _.bindAll(this, '_onSubmitComment'); }, template: function(params) { @@ -75,6 +90,18 @@ var currentUser = OC.getCurrentUser(); return this._template(_.extend({ avatarEnabled: this._avatarsEnabled, + actorId: currentUser.uid, + actorDisplayName: currentUser.displayName + }, params)); + }, + + editCommentTemplate: function(params) { + if (!this._editCommentTemplate) { + this._editCommentTemplate = Handlebars.compile(EDIT_COMMENT_TEMPLATE); + } + var currentUser = OC.getCurrentUser(); + return this._editCommentTemplate(_.extend({ + avatarEnabled: this._avatarsEnabled, userId: currentUser.uid, userDisplayName: currentUser.displayName, newMessagePlaceholder: t('comments', 'Type in a new comment...'), @@ -87,7 +114,10 @@ this._commentTemplate = Handlebars.compile(COMMENT_TEMPLATE); } return this._commentTemplate(_.extend({ - avatarEnabled: this._avatarsEnabled + avatarEnabled: this._avatarsEnabled, + deleteTooltip: t('comments', 'Delete comment'), + editTooltip: t('comments', 'Edit comment'), + isUserAuthor: OC.getCurrentUser().uid === params.actorId }, params)); }, @@ -115,6 +145,7 @@ emptyResultLabel: t('comments', 'No other comments available'), moreLabel: t('comments', 'More comments...') })); + this.$el.find('.comments').before(this.editCommentTemplate({})); this.$el.find('.has-tooltip').tooltip(); this.$container = this.$el.find('ul.comments'); this.$el.find('.avatar').avatar(OC.getCurrentUser().uid, 28); @@ -203,13 +234,65 @@ this.collection.fetchNext(); }, + _onClickEditComment: function(ev) { + ev.preventDefault(); + var $comment = $(ev.target).closest('.comment'); + var commentId = $comment.data('id'); + var commentToEdit = this.collection.get(commentId); + var $formRow = $(this.editCommentTemplate(_.extend({ + isEditMode: true, + submitText: t('comments', 'Save') + }, commentToEdit.attributes))); + + $comment.addClass('hidden'); + // spawn form + $comment.after($formRow); + $formRow.data('commentEl', $comment); + + // copy avatar element from original to avoid flickering + $formRow.find('.avatar').replaceWith($comment.find('.avatar').clone()); + + return false; + }, + + _onClickCloseComment: function(ev) { + ev.preventDefault(); + var $row = $(ev.target).closest('.comment'); + $row.data('commentEl').removeClass('hidden'); + $row.remove(); + return false; + }, + + _onClickDeleteComment: function(ev) { + ev.preventDefault(); + var $comment = $(ev.target).closest('.comment'); + var commentId = $comment.data('id'); + // TODO: undo logic + + $comment.addClass('disabled'); + this.collection.get(commentId).destroy({ + success: function() { + $comment.remove(); + }, + error: function(msg) { + $comment.removeClass('disabled'); + OC.Notification.showTemporary(msg); + } + }); + + + return false; + }, + _onClickShowMore: function(ev) { ev.preventDefault(); this.nextPage(); }, _onSubmitComment: function(e) { + var self = this; var $form = $(e.target); + var commentId = $form.closest('.comment').data('id'); var currentUser = OC.getCurrentUser(); var $submit = $form.find('.submit'); var $loading = $form.find('.submitLoading'); @@ -225,28 +308,56 @@ $submit.addClass('hidden'); $loading.removeClass('hidden'); - this.collection.create({ - actorId: currentUser.uid, - actorDisplayName: currentUser.displayName, - actorType: 'users', - verb: 'comment', - message: $textArea.val(), - creationDateTime: (new Date()).toUTCString() - }, { - at: 0, - success: function() { - $submit.removeClass('hidden'); - $loading.addClass('hidden'); - $textArea.val('').prop('disabled', false); - }, - error: function(msg) { - $submit.removeClass('hidden'); - $loading.addClass('hidden'); - $textArea.prop('disabled', false); - - OC.Notification.showTemporary(msg); - } - }); + if (commentId) { + // edit mode + var comment = this.collection.get(commentId); + comment.save({ + message: $textArea.val() + }, { + success: function(model) { + var $row = $form.closest('.comment'); + $submit.removeClass('hidden'); + $loading.addClass('hidden'); + $row.data('commentEl') + .removeClass('hidden') + .find('.message') + .html(self._formatMessage(model.get('message'))); + $row.remove(); + }, + error: function(msg) { + $submit.removeClass('hidden'); + $loading.addClass('hidden'); + $textArea.prop('disabled', false); + + OC.Notification.showTemporary(msg); + } + }); + } else { + this.collection.create({ + actorId: currentUser.uid, + actorDisplayName: currentUser.displayName, + actorType: 'users', + verb: 'comment', + message: $textArea.val(), + creationDateTime: (new Date()).toUTCString() + }, { + at: 0, + // wait for real creation before adding + wait: true, + success: function() { + $submit.removeClass('hidden'); + $loading.addClass('hidden'); + $textArea.val('').prop('disabled', false); + }, + error: function(msg) { + $submit.removeClass('hidden'); + $loading.addClass('hidden'); + $textArea.prop('disabled', false); + + OC.Notification.showTemporary(msg); + } + }); + } return false; } |