FEATURE: Introduce a staff only override key for discourse-presence.

Merge remote-tracking branch 'origin/coding-standards'
This uses the composer as a bridge for other plugins.
This commit is contained in:
Guo Xiang Tan 2020-05-13 14:07:54 +08:00
parent 7f841dc21f
commit 623920f13d
No known key found for this signature in database
GPG Key ID: FBD110179AAC1F20
6 changed files with 103 additions and 79 deletions

View File

@ -17,36 +17,30 @@ import { REPLY, EDIT } from "discourse/models/composer";
export default Component.extend({ export default Component.extend({
// Passed in variables // Passed in variables
action: null,
post: null,
topic: null,
reply: null,
title: null,
isWhispering: null,
presenceManager: service(), presenceManager: service(),
@discourseComputed("topic.id") @discourseComputed("model.topic.id")
users(topicId) { users(topicId) {
return this.presenceManager.users(topicId); return this.presenceManager.users(topicId);
}, },
@discourseComputed("topic.id") @discourseComputed("model.topic.id")
editingUsers(topicId) { editingUsers(topicId) {
return this.presenceManager.editingUsers(topicId); return this.presenceManager.editingUsers(topicId);
}, },
isReply: equal("action", REPLY), isReply: equal("model.action", REPLY),
@on("didInsertElement") @on("didInsertElement")
subscribe() { subscribe() {
this.presenceManager.subscribe(this.get("topic.id"), COMPOSER_TYPE); this.presenceManager.subscribe(this.get("model.topic.id"), COMPOSER_TYPE);
}, },
@discourseComputed( @discourseComputed(
"post.id", "model.post.id",
"editingUsers.@each.last_seen", "editingUsers.@each.last_seen",
"users.@each.last_seen", "users.@each.last_seen",
"action" "model.action"
) )
presenceUsers(postId, editingUsers, users, action) { presenceUsers(postId, editingUsers, users, action) {
if (action === EDIT) { if (action === EDIT) {
@ -59,23 +53,24 @@ export default Component.extend({
shouldDisplay: gt("presenceUsers.length", 0), shouldDisplay: gt("presenceUsers.length", 0),
@observes("reply", "title") @observes("model.reply", "model.title")
typing() { typing() {
throttle(this, this._typing, KEEP_ALIVE_DURATION_SECONDS * 1000); throttle(this, this._typing, KEEP_ALIVE_DURATION_SECONDS * 1000);
}, },
_typing() { _typing() {
const action = this.action; const action = this.get("model.action");
if (action !== REPLY && action !== EDIT) { if (action !== REPLY && action !== EDIT) {
return; return;
} }
let data = { let data = {
topicId: this.get("topic.id"), topicId: this.get("model.topic.id"),
state: action === EDIT ? EDITING : REPLYING, state: action === EDIT ? EDITING : REPLYING,
whisper: this.whisper, whisper: this.get("model.whisper"),
postId: this.get("post.id") postId: this.get("model.post.id"),
presenceStaffOnly: this.get("model._presenceStaffOnly")
}; };
this._prevPublishData = data; this._prevPublishData = data;
@ -84,16 +79,17 @@ export default Component.extend({
data.topicId, data.topicId,
data.state, data.state,
data.whisper, data.whisper,
data.postId data.postId,
data.presenceStaffOnly
); );
}, },
@observes("whisper") @observes("model.whisper")
cancelThrottle() { cancelThrottle() {
this._cancelThrottle(); this._cancelThrottle();
}, },
@observes("action", "topic.id") @observes("model.action", "model.topic.id")
composerState() { composerState() {
if (this._prevPublishData) { if (this._prevPublishData) {
this.presenceManager.publish( this.presenceManager.publish(

View File

@ -99,7 +99,7 @@ const Presence = EmberObject.extend({
return `/presence/${topicId}`; return `/presence/${topicId}`;
}, },
publish(state, whisper, postId) { publish(state, whisper, postId, staffOnly) {
if (this.get("currentUser.hide_profile_and_presence")) return; if (this.get("currentUser.hide_profile_and_presence")) return;
const data = { const data = {
@ -108,13 +108,17 @@ const Presence = EmberObject.extend({
}; };
if (whisper) { if (whisper) {
data.is_whisper = 1; data.is_whisper = true;
} }
if (postId && state === EDITING) { if (postId && state === EDITING) {
data.post_id = postId; data.post_id = postId;
} }
if (staffOnly) {
data.staff_only = true;
}
return ajax("/presence/publish", { return ajax("/presence/publish", {
type: "POST", type: "POST",
data data

View File

@ -36,9 +36,14 @@ const PresenceManager = Service.extend({
return this._getPresence(topicId).editingUsers; return this._getPresence(topicId).editingUsers;
}, },
publish(topicId, state, whisper, postId) { publish(topicId, state, whisper, postId, staffOnly) {
if (!topicId) return; if (!topicId) return;
return this._getPresence(topicId).publish(state, whisper, postId); return this._getPresence(topicId).publish(
state,
whisper,
postId,
staffOnly
);
}, },
cleanUpPresence(type) { cleanUpPresence(type) {

View File

@ -1,8 +1 @@
{{composer-presence-display {{composer-presence-display model=model}}
action=model.action
post=model.post
topic=model.topic
reply=model.reply
title=model.title
whisper=model.whisper
}}

View File

@ -73,61 +73,65 @@ after_initialize do
max_backlog_age: Presence::MAX_BACKLOG_AGE_SECONDS max_backlog_age: Presence::MAX_BACKLOG_AGE_SECONDS
} }
case permitted_params[:state] if permitted_params[:staff_only]
when EDITING_STATE
opts[:group_ids] = [Group::AUTO_GROUPS[:staff]] opts[:group_ids] = [Group::AUTO_GROUPS[:staff]]
else
case permitted_params[:state]
when EDITING_STATE
opts[:group_ids] = [Group::AUTO_GROUPS[:staff]]
if !post.locked? && !permitted_params[:is_whisper] if !post.locked? && !permitted_params[:is_whisper]
opts[:user_ids] = [post.user_id] opts[:user_ids] = [post.user_id]
if topic.private_message? if topic.private_message?
if post.wiki if post.wiki
opts[:user_ids] = opts[:user_ids].concat( opts[:user_ids] = opts[:user_ids].concat(
topic.allowed_users.where( topic.allowed_users.where(
"trust_level >= ? AND NOT admin OR moderator", "trust_level >= ? AND NOT admin OR moderator",
SiteSetting.min_trust_to_edit_wiki_post SiteSetting.min_trust_to_edit_wiki_post
).pluck(:id) ).pluck(:id)
) )
opts[:user_ids].uniq! opts[:user_ids].uniq!
# Ignore trust level and just publish to all allowed groups since # Ignore trust level and just publish to all allowed groups since
# trying to figure out which users in the allowed groups have # trying to figure out which users in the allowed groups have
# the necessary trust levels can lead to a large array of user ids # the necessary trust levels can lead to a large array of user ids
# if the groups are big. # if the groups are big.
opts[:group_ids] = opts[:group_ids].concat( opts[:group_ids] = opts[:group_ids].concat(
topic.allowed_groups.pluck(:id) topic.allowed_groups.pluck(:id)
) )
end end
else else
if post.wiki if post.wiki
opts[:group_ids] << Group::AUTO_GROUPS[:"trust_level_#{SiteSetting.min_trust_to_edit_wiki_post}"] opts[:group_ids] << Group::AUTO_GROUPS[:"trust_level_#{SiteSetting.min_trust_to_edit_wiki_post}"]
elsif SiteSetting.trusted_users_can_edit_others? elsif SiteSetting.trusted_users_can_edit_others?
opts[:group_ids] << Group::AUTO_GROUPS[:trust_level_4] opts[:group_ids] << Group::AUTO_GROUPS[:trust_level_4]
end
end end
end end
end when REPLYING_STATE
when REPLYING_STATE if permitted_params[:is_whisper]
if permitted_params[:is_whisper] opts[:group_ids] = [Group::AUTO_GROUPS[:staff]]
opts[:group_ids] = [Group::AUTO_GROUPS[:staff]] elsif topic.private_message?
elsif topic.private_message? opts[:user_ids] = topic.allowed_users.pluck(:id)
opts[:user_ids] = topic.allowed_users.pluck(:id)
opts[:group_ids] = [Group::AUTO_GROUPS[:staff]].concat( opts[:group_ids] = [Group::AUTO_GROUPS[:staff]].concat(
topic.allowed_groups.pluck(:id) topic.allowed_groups.pluck(:id)
) )
else else
opts[:group_ids] = topic.secure_group_ids opts[:group_ids] = topic.secure_group_ids
end end
when CLOSED_STATE when CLOSED_STATE
if topic.private_message? if topic.private_message?
opts[:user_ids] = topic.allowed_users.pluck(:id) opts[:user_ids] = topic.allowed_users.pluck(:id)
opts[:group_ids] = [Group::AUTO_GROUPS[:staff]].concat( opts[:group_ids] = [Group::AUTO_GROUPS[:staff]].concat(
topic.allowed_groups.pluck(:id) topic.allowed_groups.pluck(:id)
) )
else else
opts[:group_ids] = topic.secure_group_ids opts[:group_ids] = topic.secure_group_ids
end
end end
end end
@ -158,7 +162,7 @@ after_initialize do
end end
def permitted_params def permitted_params
params.permit(:state, :topic_id, :post_id, :is_whisper) params.permit(:state, :topic_id, :post_id, :is_whisper, :staff_only)
end end
end end

View File

@ -193,6 +193,28 @@ describe ::Presence::PresencesController do
expect(message.user_ids).to eq(nil) expect(message.user_ids).to eq(nil)
end end
it 'publishes the message to staff group when staff_only param override is present' do
messages = MessageBus.track_publish do
post '/presence/publish.json', params: {
topic_id: public_topic.id,
state: 'replying',
staff_only: true
}
expect(response.status).to eq(200)
end
expect(messages.length).to eq(1)
message = messages.first
expect(message.channel).to eq("/presence/#{public_topic.id}")
expect(message.data.dig(:user, :id)).to eq(user.id)
expect(message.data[:published_at]).to eq(Time.zone.now.to_i)
expect(message.group_ids).to contain_exactly(Group::AUTO_GROUPS[:staff])
expect(message.user_ids).to eq(nil)
end
it 'publishes the message to staff group when a staff is editing a whisper' do it 'publishes the message to staff group when a staff is editing a whisper' do
SiteSetting.enable_whispers = true SiteSetting.enable_whispers = true
sign_in(admin) sign_in(admin)