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 = { const icons = {
'closed.enabled': 'lock', 'closed.enabled': 'lock',
@ -13,16 +14,20 @@ const icons = {
'pinned_globally.disabled': 'thumb-tack unpinned', 'pinned_globally.disabled': 'thumb-tack unpinned',
'visible.enabled': 'eye', 'visible.enabled': 'eye',
'visible.disabled': 'eye-slash', '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() { return function() {
const ac = this.get(actionCode); const ac = this.get(actionCode);
if (ac) { if (ac) {
const dt = new Date(this.get(createdAt)); const dt = new Date(this.get(createdAt));
const when = relativeAge(dt, {format: 'medium-with-ago'}); const when = autoUpdatingRelativeAge(dt, { format: 'medium-with-ago' });
return I18n.t(`action_codes.${ac}`, {when}).htmlSafe(); 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); }.property(actionCode, createdAt);
} }
@ -31,18 +36,19 @@ export default Ember.Component.extend({
layoutName: 'components/small-action', // needed because `time-gap` inherits from this layoutName: 'components/small-action', // needed because `time-gap` inherits from this
classNames: ['small-action'], classNames: ['small-action'],
description: actionDescription('actionCode', 'post.created_at'), description: actionDescription('actionCode', 'post.created_at', 'post.action_code_who'),
icon: function() { @computed("actionCode")
return icons[this.get('actionCode')] || 'exclamation'; icon(actionCode) {
}.property('actionCode'), return icons[actionCode] || 'exclamation';
},
actions: { actions: {
edit: function() { edit() {
this.sendAction('editPost', this.get('post')); this.sendAction('editPost', this.get('post'));
}, },
delete: function() { delete() {
this.sendAction('deletePost', this.get('post')); this.sendAction('deletePost', this.get('post'));
} }
} }

View File

@ -347,7 +347,7 @@ class TopicsController < ApplicationController
topic = Topic.find_by(id: params[:topic_id]) topic = Topic.find_by(id: params[:topic_id])
guardian.ensure_can_remove_allowed_users!(topic) 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 render json: success_json
else else
render json: failed_json, status: 422 render json: failed_json, status: 422

View File

@ -524,7 +524,8 @@ class Topic < ActiveRecord::Base
no_bump: opts[:bump].blank?, no_bump: opts[:bump].blank?,
skip_notifications: opts[:skip_notifications], skip_notifications: opts[:skip_notifications],
topic_id: self.id, topic_id: self.id,
skip_validations: true) skip_validations: true,
custom_fields: opts[:custom_fields])
new_post = creator.create new_post = creator.create
increment!(:moderator_posts_count) if new_post.persisted? increment!(:moderator_posts_count) if new_post.persisted?
@ -557,11 +558,19 @@ class Topic < ActiveRecord::Base
changed_to_category(cat) changed_to_category(cat)
end end
def remove_allowed_user(username) def remove_allowed_user(removed_by, username)
if user = User.find_by(username: username) if user = User.find_by(username: username)
topic_user = topic_allowed_users.find_by(user_id: user.id) topic_user = topic_allowed_users.find_by(user_id: user.id)
if topic_user if topic_user
topic_user.destroy 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 return true
end end
end end
@ -575,6 +584,14 @@ class Topic < ActiveRecord::Base
# If the user exists, add them to the message. # If the user exists, add them to the message.
user = User.find_by_username_or_email(username_or_email) user = User.find_by_username_or_email(username_or_email)
if user && topic_allowed_users.create!(user_id: user.id) 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 # Notify the user they've been invited
user.notifications.create(notification_type: Notification.types[:invited_to_private_message], user.notifications.create(notification_type: Notification.types[:invited_to_private_message],

View File

@ -62,7 +62,8 @@ class PostSerializer < BasicPostSerializer
:user_custom_fields, :user_custom_fields,
:static_doc, :static_doc,
:via_email, :via_email,
:action_code :action_code,
:action_code_who
def initialize(object, opts) def initialize(object, opts)
super(object, opts) super(object, opts)
@ -313,6 +314,14 @@ class PostSerializer < BasicPostSerializer
object.action_code.present? object.action_code.present?
end 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 private
def post_actions def post_actions

View File

@ -121,6 +121,8 @@ en:
action_codes: action_codes:
split_topic: "split this topic %{when}" split_topic: "split this topic %{when}"
invited_user: "invited %{who} %{when}"
removed_user: "removed %{who} %{when}"
autoclosed: autoclosed:
enabled: 'closed %{when}' enabled: 'closed %{when}'
disabled: 'opened %{when}' disabled: 'opened %{when}'

View File

@ -16,6 +16,10 @@ class TopicView
20 20
end end
def self.default_post_custom_fields
@default_post_custom_fields ||= ["action_code_who"]
end
def self.post_custom_fields_whitelisters def self.post_custom_fields_whitelisters
@post_custom_fields_whitelisters ||= Set.new @post_custom_fields_whitelisters ||= Set.new
end end
@ -25,7 +29,8 @@ class TopicView
end end
def self.whitelisted_post_custom_fields(user) 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 end
def initialize(topic_id, user=nil, options={}) 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.invite(topic.user, walter.username)).to eq(true)
expect(topic.allowed_users.include?(walter)).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 topic.reload
expect(topic.allowed_users.include?(walter)).to eq(false) expect(topic.allowed_users.include?(walter)).to eq(false)
end end
@ -386,6 +386,11 @@ describe Topic do
it 'creates a notification' do it 'creates a notification' do
expect { topic.invite(topic.user, walter.username) }.to change(Notification, :count) expect { topic.invite(topic.user, walter.username) }.to change(Notification, :count)
end 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 end
context 'by email' do context 'by email' do