diff --git a/app/assets/javascripts/discourse/models/action_summary.js b/app/assets/javascripts/discourse/models/action_summary.js
index ffcc1901117..80517ae147f 100644
--- a/app/assets/javascripts/discourse/models/action_summary.js
+++ b/app/assets/javascripts/discourse/models/action_summary.js
@@ -22,17 +22,22 @@ Discourse.ActionSummary = Discourse.Model.extend({
}
}.property('count', 'acted', 'actionType'),
- canAlsoAction: function() {
- if (this.get('hidden')) return false;
- return this.get('can_act');
- }.property('can_act', 'hidden'),
+ canAlsoAction: Em.computed.and('can_act', 'actionType.notCustomFlag'),
+ usersCollapsed: Em.computed.not('usersExpanded'),
+ usersExpanded: Em.computed.gt('users.length', 0),
// Remove it
removeAction: function() {
- this.set('acted', false);
- this.set('count', this.get('count') - 1);
- this.set('can_act', true);
- return this.set('can_undo', false);
+ this.setProperties({
+ acted: false,
+ count: this.get('count') - 1,
+ can_act: true,
+ can_undo: false
+ });
+
+ if (this.get('usersExpanded')) {
+ this.get('users').removeObject(Discourse.User.current());
+ }
},
// Perform this action
@@ -42,10 +47,12 @@ Discourse.ActionSummary = Discourse.Model.extend({
var action = this.get('actionType.name_key');
// Mark it as acted
- this.set('acted', true);
- this.set('count', this.get('count') + 1);
- this.set('can_act', false);
- this.set('can_undo', true);
+ this.setProperties({
+ acted: true,
+ count: this.get('count') + 1,
+ can_act: false,
+ can_undo: true
+ });
if(action === 'notify_moderators' || action === 'notify_user') {
this.set('can_undo',false);
@@ -53,8 +60,8 @@ Discourse.ActionSummary = Discourse.Model.extend({
}
// Add ourselves to the users who liked it if present
- if (this.present('users')) {
- this.users.pushObject(Discourse.User.current());
+ if (this.get('usersExpanded')) {
+ this.get('users').addObject(Discourse.User.current());
}
// Create our post action
@@ -113,7 +120,11 @@ Discourse.ActionSummary = Discourse.Model.extend({
var users = Em.A();
actionSummary.set('users', users);
_.each(result,function(user) {
- users.pushObject(Discourse.User.create(user));
+ if (user.id === Discourse.User.current('id')) {
+ users.pushObject(Discourse.User.current());
+ } else {
+ users.pushObject(Discourse.User.create(user));
+ }
});
});
}
diff --git a/app/assets/javascripts/discourse/models/post.js b/app/assets/javascripts/discourse/models/post.js
index 551ad65a18f..7ef7de00da6 100644
--- a/app/assets/javascripts/discourse/models/post.js
+++ b/app/assets/javascripts/discourse/models/post.js
@@ -186,6 +186,11 @@ Discourse.Post = Discourse.Model.extend({
},
recover: function() {
+ this.setProperties({
+ deleted_at: null,
+ deleted_by: null
+ });
+
return Discourse.ajax("/posts/" + (this.get('id')) + "/recover", { type: 'PUT', cache: false });
},
diff --git a/app/assets/javascripts/discourse/models/post_action_type.js b/app/assets/javascripts/discourse/models/post_action_type.js
index c3583967b98..b941ae25b2e 100644
--- a/app/assets/javascripts/discourse/models/post_action_type.js
+++ b/app/assets/javascripts/discourse/models/post_action_type.js
@@ -6,7 +6,9 @@
@namespace Discourse
@module Discourse
**/
-Discourse.PostActionType = Discourse.Model.extend({});
+Discourse.PostActionType = Discourse.Model.extend({
+ notCustomFlag: Em.computed.not('is_custom_flag')
+});
Discourse.PostActionType.reopenClass({
MAX_MESSAGE_LENGTH: 500
diff --git a/app/assets/javascripts/discourse/templates/post.js.handlebars b/app/assets/javascripts/discourse/templates/post.js.handlebars
index 57323e820ea..405002912c1 100644
--- a/app/assets/javascripts/discourse/templates/post.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/post.js.handlebars
@@ -55,6 +55,13 @@
{{view Discourse.RepliesView contentBinding="replies" postViewBinding="view"}}
{{view Discourse.ActionsHistoryView contentBinding="actionsHistory"}}
+
+ {{#if deleted_by}}
+
+ {{i18n post.deleted_by}} {{avatar deleted_by imageSize="tiny"}}
+
+ {{/if}}
+
{{view Discourse.TopicSummaryView postBinding="this"}}
diff --git a/app/assets/javascripts/discourse/views/actions_history_view.js b/app/assets/javascripts/discourse/views/actions_history_view.js
index 8ca6aee173e..04ffcae7a9a 100644
--- a/app/assets/javascripts/discourse/views/actions_history_view.js
+++ b/app/assets/javascripts/discourse/views/actions_history_view.js
@@ -10,24 +10,27 @@
Discourse.ActionsHistoryView = Discourse.View.extend({
tagName: 'section',
classNameBindings: [':post-actions', 'hidden'],
-
hidden: Em.computed.empty('content'),
-
- shouldRerender: Discourse.View.renderIfChanged('content.@each', 'content.users.@each'),
+ shouldRerender: Discourse.View.renderIfChanged('content.@each', 'content.users.length'),
// This was creating way too many bound ifs and subviews in the handlebars version.
render: function(buffer) {
if (!this.present('content')) return;
- return this.get('content').forEach(function(c) {
- var actionString, iconsHtml;
+ this.get('content').forEach(function(c) {
buffer.push("");
+ var renderActionIf = function(property, dataAttribute, text) {
+ if (!c.get(property)) { return; }
+ buffer.push("
" + text + ".");
+ };
+
// TODO multi line expansion for flags
- var postUrl;
- if (c.get('users')) {
- iconsHtml = "";
+ var iconsHtml = "";
+ if (c.get('usersExpanded')) {
+ var postUrl;
c.get('users').forEach(function(u) {
+ console.log(u);
iconsHtml += "
";
if (u.post_url) {
postUrl = postUrl || u.post_url;
@@ -42,44 +45,35 @@ Discourse.ActionsHistoryView = Discourse.View.extend({
});
var key = 'post.actions.people.' + c.get('actionType.name_key');
- if(postUrl) {
- key = key + "_with_url";
- }
+ if (postUrl) { key = key + "_with_url"; }
+
buffer.push(" " + I18n.t(key, { icons: iconsHtml, postUrl: postUrl}) + ".");
- } else {
- buffer.push("" + (c.get('description')) + ".");
- }
-
- if (c.get('can_act') && !c.get('actionType.is_custom_flag')) {
- actionString = I18n.t("post.actions.it_too." + c.get('actionType.name_key'));
- buffer.push("
" + actionString + ".");
- }
-
- if (c.get('can_undo')) {
- actionString = I18n.t("post.actions.undo." + c.get('actionType.name_key') );
- buffer.push("
" + actionString + ".");
- }
-
- if (c.get('can_clear_flags')) {
- buffer.push("
" + (I18n.t("post.actions.clear_flags", { count: c.count })) + ".");
}
+ renderActionIf('usersCollapsed', 'who-acted', c.get('description'));
+ renderActionIf('canAlsoAction', 'act', I18n.t("post.actions.it_too." + c.get('actionType.name_key')));
+ renderActionIf('can_undo', 'undo', I18n.t("post.actions.undo." + c.get('actionType.name_key')));
+ renderActionIf('can_clear_flags', 'clear-flags', I18n.t("post.actions.clear_flags", { count: c.count }));
buffer.push("
");
});
},
+ actionTypeById: function(actionTypeId) {
+ return this.get('content').findProperty('id', actionTypeId);
+ },
+
click: function(e) {
- var $target, actionTypeId;
- $target = $(e.target);
+ var $target = $(e.target),
+ actionTypeId;
if (actionTypeId = $target.data('clear-flags')) {
- this.get('controller').clearFlags(this.content.findProperty('id', actionTypeId));
+ this.get('controller').clearFlags(this.actionTypeById(actionTypeId));
return false;
}
// User wants to know who actioned it
if (actionTypeId = $target.data('who-acted')) {
- this.get('controller').whoActed(this.content.findProperty('id', actionTypeId));
+ this.get('controller').whoActed(this.actionTypeById(actionTypeId));
return false;
}
diff --git a/app/serializers/post_serializer.rb b/app/serializers/post_serializer.rb
index c6da600ca95..05a6277cc30 100644
--- a/app/serializers/post_serializer.rb
+++ b/app/serializers/post_serializer.rb
@@ -118,6 +118,14 @@ class PostSerializer < BasicPostSerializer
true
end
+ def deleted_by
+ BasicUserSerializer.new(object.deleted_by, root: false).as_json
+ end
+
+ def include_deleted_by?
+ object.deleted_by.present?
+ end
+
# Summary of the actions taken on this post
def actions_summary
result = []
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 54a351247d0..f8cdc7cac55 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -732,6 +732,7 @@ en:
continue_discussion: "Continuing the discussion from {{postLink}}:"
follow_quote: "go to the quoted post"
deleted_by_author: "(post removed by author)"
+ deleted_by: "deleted by"
expand_collapse: "expand/collapse"
has_replies:
diff --git a/test/javascripts/models/post_test.js b/test/javascripts/models/post_test.js
index cf19235f548..0320e671550 100644
--- a/test/javascripts/models/post_test.js
+++ b/test/javascripts/models/post_test.js
@@ -64,6 +64,11 @@ test('destroy by staff', function() {
present(post.get('deleted_at'), "it has a `deleted_at` field.");
equal(post.get('deleted_by'), user, "it has the user in the `deleted_by` field");
ok(Discourse.ajax.calledOnce, "it made an AJAX call");
+
+ post.recover();
+ blank(post.get('deleted_at'), "it clears `deleted_at` when recovering");
+ blank(post.get('deleted_by'), "it clears `deleted_by` when recovering");
+
});
test('destroy by non-staff', function() {