diff --git a/app/assets/javascripts/discourse/components/small-action.js.es6 b/app/assets/javascripts/discourse/components/small-action.js.es6 index 54ef41b9f..567436348 100644 --- a/app/assets/javascripts/discourse/components/small-action.js.es6 +++ b/app/assets/javascripts/discourse/components/small-action.js.es6 @@ -1,4 +1,5 @@ -import { relativeAge } from 'discourse/lib/formatter'; +import { autoUpdatingRelativeAge } from 'discourse/lib/formatter'; +import computed from 'ember-addons/ember-computed-decorators'; const icons = { 'closed.enabled': 'lock', @@ -13,16 +14,20 @@ const icons = { 'pinned_globally.disabled': 'thumb-tack unpinned', 'visible.enabled': 'eye', 'visible.disabled': 'eye-slash', - 'split_topic': 'sign-out' + 'split_topic': 'sign-out', + 'invited_user': 'plus-circle', + 'removed_user': 'minus-circle' }; -export function actionDescription(actionCode, createdAt) { +export function actionDescription(actionCode, createdAt, username) { return function() { const ac = this.get(actionCode); if (ac) { const dt = new Date(this.get(createdAt)); - const when = relativeAge(dt, {format: 'medium-with-ago'}); - return I18n.t(`action_codes.${ac}`, {when}).htmlSafe(); + const when = autoUpdatingRelativeAge(dt, { format: 'medium-with-ago' }); + const u = this.get(username); + const who = u ? `<a class="mention" href="/users/${u}">@${u}</a>` : ""; + return I18n.t(`action_codes.${ac}`, { who, when }).htmlSafe(); } }.property(actionCode, createdAt); } @@ -31,18 +36,19 @@ export default Ember.Component.extend({ layoutName: 'components/small-action', // needed because `time-gap` inherits from this classNames: ['small-action'], - description: actionDescription('actionCode', 'post.created_at'), + description: actionDescription('actionCode', 'post.created_at', 'post.action_code_who'), - icon: function() { - return icons[this.get('actionCode')] || 'exclamation'; - }.property('actionCode'), + @computed("actionCode") + icon(actionCode) { + return icons[actionCode] || 'exclamation'; + }, actions: { - edit: function() { + edit() { this.sendAction('editPost', this.get('post')); }, - delete: function() { + delete() { this.sendAction('deletePost', this.get('post')); } } diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index b049438b6..4a9c0fec3 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -347,7 +347,7 @@ class TopicsController < ApplicationController topic = Topic.find_by(id: params[:topic_id]) guardian.ensure_can_remove_allowed_users!(topic) - if topic.remove_allowed_user(params[:username]) + if topic.remove_allowed_user(current_user, params[:username]) render json: success_json else render json: failed_json, status: 422 diff --git a/app/models/topic.rb b/app/models/topic.rb index 5f470c509..022efc498 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -524,7 +524,8 @@ class Topic < ActiveRecord::Base no_bump: opts[:bump].blank?, skip_notifications: opts[:skip_notifications], topic_id: self.id, - skip_validations: true) + skip_validations: true, + custom_fields: opts[:custom_fields]) new_post = creator.create increment!(:moderator_posts_count) if new_post.persisted? @@ -557,11 +558,19 @@ class Topic < ActiveRecord::Base changed_to_category(cat) end - def remove_allowed_user(username) + def remove_allowed_user(removed_by, username) if user = User.find_by(username: username) topic_user = topic_allowed_users.find_by(user_id: user.id) if topic_user topic_user.destroy + # add small action + self.add_moderator_post( + removed_by, + nil, + post_type: Post.types[:small_action], + action_code: "removed_user", + custom_fields: { action_code_who: user.username } + ) return true end end @@ -575,6 +584,14 @@ class Topic < ActiveRecord::Base # If the user exists, add them to the message. user = User.find_by_username_or_email(username_or_email) if user && topic_allowed_users.create!(user_id: user.id) + # Create a small action message + self.add_moderator_post( + invited_by, + nil, + post_type: Post.types[:small_action], + action_code: "invited_user", + custom_fields: { action_code_who: user.username } + ) # Notify the user they've been invited user.notifications.create(notification_type: Notification.types[:invited_to_private_message], diff --git a/app/serializers/post_serializer.rb b/app/serializers/post_serializer.rb index 259c781d2..2fd245c45 100644 --- a/app/serializers/post_serializer.rb +++ b/app/serializers/post_serializer.rb @@ -62,7 +62,8 @@ class PostSerializer < BasicPostSerializer :user_custom_fields, :static_doc, :via_email, - :action_code + :action_code, + :action_code_who def initialize(object, opts) super(object, opts) @@ -313,6 +314,14 @@ class PostSerializer < BasicPostSerializer object.action_code.present? end + def action_code_who + post_custom_fields["action_code_who"] + end + + def include_action_code_who? + include_action_code? && action_code_who.present? + end + private def post_actions diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 80f7a596f..f8df19ae1 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -121,6 +121,8 @@ en: action_codes: split_topic: "split this topic %{when}" + invited_user: "invited %{who} %{when}" + removed_user: "removed %{who} %{when}" autoclosed: enabled: 'closed %{when}' disabled: 'opened %{when}' diff --git a/lib/topic_view.rb b/lib/topic_view.rb index 7db989d45..9072610f5 100644 --- a/lib/topic_view.rb +++ b/lib/topic_view.rb @@ -16,6 +16,10 @@ class TopicView 20 end + def self.default_post_custom_fields + @default_post_custom_fields ||= ["action_code_who"] + end + def self.post_custom_fields_whitelisters @post_custom_fields_whitelisters ||= Set.new end @@ -25,7 +29,8 @@ class TopicView end def self.whitelisted_post_custom_fields(user) - post_custom_fields_whitelisters.map { |w| w.call(user) }.flatten.uniq + wpcf = default_post_custom_fields + post_custom_fields_whitelisters.map { |w| w.call(user) } + wpcf.flatten.uniq end def initialize(topic_id, user=nil, options={}) diff --git a/spec/models/topic_spec.rb b/spec/models/topic_spec.rb index 6a8eb9d76..b5d15f36e 100644 --- a/spec/models/topic_spec.rb +++ b/spec/models/topic_spec.rb @@ -378,7 +378,7 @@ describe Topic do expect(topic.invite(topic.user, walter.username)).to eq(true) expect(topic.allowed_users.include?(walter)).to eq(true) - expect(topic.remove_allowed_user(walter.username)).to eq(true) + expect(topic.remove_allowed_user(topic.user, walter.username)).to eq(true) topic.reload expect(topic.allowed_users.include?(walter)).to eq(false) end @@ -386,6 +386,11 @@ describe Topic do it 'creates a notification' do expect { topic.invite(topic.user, walter.username) }.to change(Notification, :count) end + + it 'creates a small action post' do + expect { topic.invite(topic.user, walter.username) }.to change(Post, :count) + expect { topic.remove_allowed_user(topic.user, walter.username) }.to change(Post, :count) + end end context 'by email' do