FEATURE: notification_level on a per-group basis
This commit is contained in:
parent
d0bbf5c9a6
commit
15c229195f
|
@ -0,0 +1,11 @@
|
||||||
|
import NotificationsButton from 'discourse/components/notifications-button';
|
||||||
|
|
||||||
|
export default NotificationsButton.extend({
|
||||||
|
classNames: ['notification-options', 'group-notification-menu'],
|
||||||
|
notificationLevel: Em.computed.alias('group.notification_level'),
|
||||||
|
i18nPrefix: 'groups.notifications',
|
||||||
|
|
||||||
|
clicked(id) {
|
||||||
|
this.get('group').setNotification(id);
|
||||||
|
}
|
||||||
|
});
|
|
@ -133,7 +133,15 @@ const Group = Discourse.Model.extend({
|
||||||
return Em.Object.create(p);
|
return Em.Object.create(p);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
|
setNotification(notification_level) {
|
||||||
|
this.set("notification_level", notification_level);
|
||||||
|
return Discourse.ajax(`/groups/${this.get("name")}/notifications`, {
|
||||||
|
data: { notification_level },
|
||||||
|
type: "POST"
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Group.reopenClass({
|
Group.reopenClass({
|
||||||
|
|
|
@ -1,13 +1,25 @@
|
||||||
|
import Group from 'discourse/models/group';
|
||||||
import createPMRoute from "discourse/routes/build-user-topic-list-route";
|
import createPMRoute from "discourse/routes/build-user-topic-list-route";
|
||||||
|
|
||||||
export default createPMRoute('groups', 'private-messages-groups').extend({
|
export default createPMRoute('groups', 'private-messages-groups').extend({
|
||||||
model(params) {
|
model(params) {
|
||||||
return this.store.findFiltered("topicList", { filter: "topics/private-messages-group/" + this.modelFor("user").get("username_lower") + "/" + params.name });
|
const username = this.modelFor("user").get("username_lower");
|
||||||
|
return this.store.findFiltered("topicList", {
|
||||||
|
filter: `topics/private-messages-group/${username}/${params.name}`
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller,model) {
|
afterModel(model) {
|
||||||
|
const groupName = _.last(model.get("filter").split('/'));
|
||||||
|
Group.findAll().then(groups => {
|
||||||
|
const group = _.first(groups.filterBy("name", groupName));
|
||||||
|
this.controllerFor("user-topics-list").set("group", group)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController(controller, model) {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
const filter = _.last(model.get("filter").split('/'));
|
const group = _.last(model.get("filter").split('/'));
|
||||||
this.controllerFor("user").set("groupFilter", filter);
|
this.controllerFor("user").set("groupFilter", group);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
{{#if showNewPM}}
|
<div class="clearfix">
|
||||||
<div class="clearfix">
|
{{#if group}}
|
||||||
<a class='btn btn-primary pull-right new-private-message' {{action "composePrivateMessage"}}>{{fa-icon "envelope"}}{{i18n 'user.new_private_message'}}</a>
|
{{group-notifications-button group=group}}
|
||||||
</div>
|
{{/if}}
|
||||||
{{/if}}
|
{{#if showNewPM}}
|
||||||
|
{{d-button class="btn-primary pull-right new-private-message" action="composePrivateMessage" icon="envelope" label="user.new_private_message"}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{basic-topic-list topicList=model
|
{{basic-topic-list topicList=model
|
||||||
hideCategory=hideCategory
|
hideCategory=hideCategory
|
||||||
|
|
|
@ -630,6 +630,10 @@
|
||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
.group-notification-menu .dropdown-menu {
|
||||||
|
top: 30px;
|
||||||
|
bottom: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.paginated-topics-list {
|
.paginated-topics-list {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
class GroupsController < ApplicationController
|
class GroupsController < ApplicationController
|
||||||
|
|
||||||
|
before_filter :ensure_logged_in, only: [:set_notifications]
|
||||||
|
|
||||||
def show
|
def show
|
||||||
render_serialized(find_group(:id), BasicGroupSerializer)
|
render_serialized(find_group(:id), BasicGroupSerializer)
|
||||||
end
|
end
|
||||||
|
@ -123,6 +125,17 @@ class GroupsController < ApplicationController
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_notifications
|
||||||
|
group = find_group(:id)
|
||||||
|
notification_level = params.require(:notification_level)
|
||||||
|
|
||||||
|
GroupUser.where(group_id: group.id)
|
||||||
|
.where(user_id: current_user.id)
|
||||||
|
.update_all(notification_level: notification_level)
|
||||||
|
|
||||||
|
render json: success_json
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def find_group(param_name)
|
def find_group(param_name)
|
||||||
|
|
|
@ -19,9 +19,9 @@ class Topic < ActiveRecord::Base
|
||||||
def_delegator :featured_users, :choose, :feature_topic_users
|
def_delegator :featured_users, :choose, :feature_topic_users
|
||||||
|
|
||||||
def_delegator :notifier, :watch!, :notify_watch!
|
def_delegator :notifier, :watch!, :notify_watch!
|
||||||
def_delegator :notifier, :tracking!, :notify_tracking!
|
def_delegator :notifier, :track!, :notify_tracking!
|
||||||
def_delegator :notifier, :regular!, :notify_regular!
|
def_delegator :notifier, :regular!, :notify_regular!
|
||||||
def_delegator :notifier, :muted!, :notify_muted!
|
def_delegator :notifier, :mute!, :notify_muted!
|
||||||
def_delegator :notifier, :toggle_mute, :toggle_mute
|
def_delegator :notifier, :toggle_mute, :toggle_mute
|
||||||
|
|
||||||
attr_accessor :allowed_user_ids
|
attr_accessor :allowed_user_ids
|
||||||
|
|
|
@ -3,10 +3,10 @@ class TopicNotifier
|
||||||
@topic = topic
|
@topic = topic
|
||||||
end
|
end
|
||||||
|
|
||||||
{ :watch! => :watching,
|
{ :watch! => :watching,
|
||||||
:tracking! => :tracking,
|
:track! => :tracking,
|
||||||
:regular! => :regular,
|
:regular! => :regular,
|
||||||
:muted! => :muted }.each_pair do |method_name, level|
|
:mute! => :muted }.each_pair do |method_name, level|
|
||||||
|
|
||||||
define_method method_name do |user_id|
|
define_method method_name do |user_id|
|
||||||
change_level user_id, level
|
change_level user_id, level
|
||||||
|
|
|
@ -103,7 +103,7 @@ class TopicUser < ActiveRecord::Base
|
||||||
|
|
||||||
if rows == 0
|
if rows == 0
|
||||||
now = DateTime.now
|
now = DateTime.now
|
||||||
auto_track_after = User.select(:auto_track_topics_after_msecs).find_by(id: user_id).auto_track_topics_after_msecs
|
auto_track_after = User.select(:auto_track_topics_after_msecs).find_by(id: user_id).try(:auto_track_topics_after_msecs)
|
||||||
auto_track_after ||= SiteSetting.default_other_auto_track_topics_after_msecs
|
auto_track_after ||= SiteSetting.default_other_auto_track_topics_after_msecs
|
||||||
|
|
||||||
if auto_track_after >= 0 && auto_track_after <= (attrs[:total_msecs_viewed].to_i || 0)
|
if auto_track_after >= 0 && auto_track_after <= (attrs[:total_msecs_viewed].to_i || 0)
|
||||||
|
|
|
@ -10,9 +10,20 @@ class BasicGroupSerializer < ApplicationSerializer
|
||||||
:primary_group,
|
:primary_group,
|
||||||
:title,
|
:title,
|
||||||
:grant_trust_level,
|
:grant_trust_level,
|
||||||
:incoming_email
|
:incoming_email,
|
||||||
|
:notification_level
|
||||||
|
|
||||||
def include_incoming_email?
|
def include_incoming_email?
|
||||||
scope.is_staff?
|
scope.is_staff?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def notification_level
|
||||||
|
# TODO: fix this N+1
|
||||||
|
GroupUser.where(group_id: object.id, user_id: scope.user.id).first.try(:notification_level)
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_notification_level?
|
||||||
|
scope.authenticated?
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -64,6 +64,7 @@ class ListableTopicSerializer < BasicTopicSerializer
|
||||||
def notification_level
|
def notification_level
|
||||||
object.user_data.notification_level
|
object.user_data.notification_level
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_notification_level?
|
def include_notification_level?
|
||||||
object.user_data.present?
|
object.user_data.present?
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,22 +15,27 @@ class PostAlerter
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_save_post(post, new_record = false)
|
def after_save_post(post, new_record = false)
|
||||||
|
|
||||||
reply_to_user = post.reply_notification_target
|
|
||||||
|
|
||||||
notified = [post.user].compact
|
notified = [post.user].compact
|
||||||
|
|
||||||
if new_record && post.topic.private_message?
|
if new_record && post.topic.private_message?
|
||||||
# If it's a private message, notify the topic_allowed_users
|
# If it's a private message, notify the topic_allowed_users
|
||||||
allowed_users(post).each do |user|
|
allowed_users(post).each do |user|
|
||||||
if TopicUser.get(post.topic, user).try(:notification_level) == TopicUser.notification_levels[:tracking]
|
case TopicUser.get(post.topic, user).try(:notification_level)
|
||||||
|
when TopicUser.notification_levels[:tracking]
|
||||||
next unless post.reply_to_post_number || post.reply_to_post.try(:user_id) == user.id
|
next unless post.reply_to_post_number || post.reply_to_post.try(:user_id) == user.id
|
||||||
|
when TopicUser.notification_levels[:regular]
|
||||||
|
next unless post.reply_to_post.try(:user_id) == user.id
|
||||||
|
when TopicUser.notification_levels[:muted]
|
||||||
|
notified += [user]
|
||||||
|
next
|
||||||
end
|
end
|
||||||
create_notification(user, Notification.types[:private_message], post)
|
create_notification(user, Notification.types[:private_message], post)
|
||||||
notified += [user]
|
notified += [user]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
reply_to_user = post.reply_notification_target
|
||||||
|
|
||||||
if new_record && reply_to_user && post.post_type == Post.types[:regular]
|
if new_record && reply_to_user && post.post_type == Post.types[:regular]
|
||||||
notify_users(reply_to_user, :replied, post)
|
notify_users(reply_to_user, :replied, post)
|
||||||
end
|
end
|
||||||
|
@ -133,6 +138,11 @@ class PostAlerter
|
||||||
# skip if muted on the topic
|
# skip if muted on the topic
|
||||||
return if TopicUser.get(post.topic, user).try(:notification_level) == TopicUser.notification_levels[:muted]
|
return if TopicUser.get(post.topic, user).try(:notification_level) == TopicUser.notification_levels[:muted]
|
||||||
|
|
||||||
|
# skip if muted on the group
|
||||||
|
if group = opts[:group]
|
||||||
|
return if GroupUser.find_by(group_id: opts[:group_id], user_id: user.id).try(:notification_level) == TopicUser.notification_levels[:muted]
|
||||||
|
end
|
||||||
|
|
||||||
# Don't notify the same user about the same notification on the same post
|
# Don't notify the same user about the same notification on the same post
|
||||||
existing_notification = user.notifications
|
existing_notification = user.notifications
|
||||||
.order("notifications.id desc")
|
.order("notifications.id desc")
|
||||||
|
|
|
@ -355,6 +355,19 @@ en:
|
||||||
trust_levels:
|
trust_levels:
|
||||||
title: "Trust level automatically granted to members when they're added:"
|
title: "Trust level automatically granted to members when they're added:"
|
||||||
none: "None"
|
none: "None"
|
||||||
|
notifications:
|
||||||
|
watching:
|
||||||
|
title: "Watching"
|
||||||
|
description: "You will be notified of every new post in every message, and a count of new replies will be shown."
|
||||||
|
tracking:
|
||||||
|
title: "Tracking"
|
||||||
|
description: "You will be notified if someone mentions your @name or replies to you, and a count of new replies will be shown."
|
||||||
|
regular:
|
||||||
|
title: "Normal"
|
||||||
|
description: "You will be notified if someone mentions your @name or replies to you."
|
||||||
|
muted:
|
||||||
|
title: "Muted"
|
||||||
|
description: "You will never be notified of anything about new topics in this group."
|
||||||
|
|
||||||
user_action_groups:
|
user_action_groups:
|
||||||
"1": "Likes Given"
|
"1": "Likes Given"
|
||||||
|
|
|
@ -351,6 +351,7 @@ Discourse::Application.routes.draw do
|
||||||
member do
|
member do
|
||||||
put "members" => "groups#add_members"
|
put "members" => "groups#add_members"
|
||||||
delete "members" => "groups#remove_member"
|
delete "members" => "groups#remove_member"
|
||||||
|
post "notifications" => "groups#set_notifications"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
class AddNotificationLevelToGroupUsers < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
# defaults to TopicUser.notification_levels[:watching]
|
||||||
|
add_column :group_users, :notification_level, :integer, default: 3, null: false
|
||||||
|
end
|
||||||
|
end
|
|
@ -64,15 +64,28 @@ class TopicCreator
|
||||||
topic.notifier.watch_topic!(topic.user_id)
|
topic.notifier.watch_topic!(topic.user_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
user_ids = topic.topic_allowed_users(true).pluck(:user_id)
|
topic.topic_allowed_users(true).each do |tau|
|
||||||
user_ids += topic.topic_allowed_groups(true).map { |t| t.group.users.pluck(:id) }.flatten
|
next if tau.user_id == -1 || tau.user_id == topic.user_id
|
||||||
|
topic.notifier.watch!(tau.user_id)
|
||||||
user_ids.uniq.reject{ |id| id == topic.user_id }.each do |user_id|
|
|
||||||
topic.notifier.watch_topic!(user_id, nil) unless user_id == -1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
CategoryUser.auto_watch_new_topic(topic)
|
topic.topic_allowed_groups(true).each do |tag|
|
||||||
CategoryUser.auto_track_new_topic(topic)
|
tag.group.group_users.each do |gu|
|
||||||
|
next if gu.user_id == -1 || gu.user_id == topic.user_id
|
||||||
|
action = case gu.notification_level
|
||||||
|
when TopicUser.notification_levels[:tracking] then "track!"
|
||||||
|
when TopicUser.notification_levels[:regular] then "regular!"
|
||||||
|
when TopicUser.notification_levels[:muted] then "mute!"
|
||||||
|
else "watch!"
|
||||||
|
end
|
||||||
|
topic.notifier.send(action, gu.user_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
unless topic.private_message?
|
||||||
|
CategoryUser.auto_watch_new_topic(topic)
|
||||||
|
CategoryUser.auto_track_new_topic(topic)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup_topic_params
|
def setup_topic_params
|
||||||
|
|
|
@ -31,7 +31,8 @@ describe Admin::GroupsController do
|
||||||
"title"=>nil,
|
"title"=>nil,
|
||||||
"primary_group"=>false,
|
"primary_group"=>false,
|
||||||
"grant_trust_level"=>nil,
|
"grant_trust_level"=>nil,
|
||||||
"incoming_email"=>nil
|
"incoming_email"=>nil,
|
||||||
|
"notification_level"=>3,
|
||||||
}])
|
}])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue