summaryrefslogtreecommitdiffstats
path: root/apps/comments
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2016-02-03 18:44:14 +0100
committerVincent Petry <pvince81@owncloud.com>2016-02-03 21:06:55 +0100
commitbbefe1ed64c0b4a9b77dc8d9b06b9f56c6b7f6e8 (patch)
treef304cf2e608a05fdc50f7366046b64e71328155e /apps/comments
parentda0462015507053c4424f62c32a4a182301fae22 (diff)
downloadnextcloud-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.css27
-rw-r--r--apps/comments/js/commentmodel.js13
-rw-r--r--apps/comments/js/commentstabview.js183
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;
}