FEATURE: add small action post when adding/removing users in messages

This commit is contained in:
Régis Hanol 2016-01-11 12:42:06 +01:00
parent 1a8487cf7b
commit 98c0fac461
7 changed files with 61 additions and 17 deletions

View File

@ -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'));
}
}

View File

@ -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

View File

@ -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],

View File

@ -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

View File

@ -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}'

View File

@ -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={})

View File

@ -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