diff --git a/app/assets/javascripts/discourse/components/group-notifications-button.js.es6 b/app/assets/javascripts/discourse/components/group-notifications-button.js.es6
new file mode 100644
index 000000000..6010cf02a
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/group-notifications-button.js.es6
@@ -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);
+ }
+});
diff --git a/app/assets/javascripts/discourse/models/group.js.es6 b/app/assets/javascripts/discourse/models/group.js.es6
index 61744e0c6..d0048cc95 100644
--- a/app/assets/javascripts/discourse/models/group.js.es6
+++ b/app/assets/javascripts/discourse/models/group.js.es6
@@ -133,7 +133,15 @@ const Group = Discourse.Model.extend({
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({
diff --git a/app/assets/javascripts/discourse/routes/user-private-messages-group.js.es6 b/app/assets/javascripts/discourse/routes/user-private-messages-group.js.es6
index 80f498273..933a43904 100644
--- a/app/assets/javascripts/discourse/routes/user-private-messages-group.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-private-messages-group.js.es6
@@ -1,13 +1,25 @@
+import Group from 'discourse/models/group';
import createPMRoute from "discourse/routes/build-user-topic-list-route";
export default createPMRoute('groups', 'private-messages-groups').extend({
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);
- const filter = _.last(model.get("filter").split('/'));
- this.controllerFor("user").set("groupFilter", filter);
+ const group = _.last(model.get("filter").split('/'));
+ this.controllerFor("user").set("groupFilter", group);
}
});
diff --git a/app/assets/javascripts/discourse/templates/user-topics-list.hbs b/app/assets/javascripts/discourse/templates/user-topics-list.hbs
index a63fc87f9..a2aae2de1 100644
--- a/app/assets/javascripts/discourse/templates/user-topics-list.hbs
+++ b/app/assets/javascripts/discourse/templates/user-topics-list.hbs
@@ -1,8 +1,11 @@
-{{#if showNewPM}}
-
-{{/if}}
+
+ {{#if group}}
+ {{group-notifications-button group=group}}
+ {{/if}}
+ {{#if showNewPM}}
+ {{d-button class="btn-primary pull-right new-private-message" action="composePrivateMessage" icon="envelope" label="user.new_private_message"}}
+ {{/if}}
+
{{basic-topic-list topicList=model
hideCategory=hideCategory
diff --git a/app/assets/stylesheets/desktop/user.scss b/app/assets/stylesheets/desktop/user.scss
index 71d148119..1cfdfab7e 100644
--- a/app/assets/stylesheets/desktop/user.scss
+++ b/app/assets/stylesheets/desktop/user.scss
@@ -630,6 +630,10 @@
clear: both;
margin-bottom: 10px;
}
+ .group-notification-menu .dropdown-menu {
+ top: 30px;
+ bottom: auto;
+ }
}
.paginated-topics-list {
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 68849d03d..e33dfa449 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -1,5 +1,7 @@
class GroupsController < ApplicationController
+ before_filter :ensure_logged_in, only: [:set_notifications]
+
def show
render_serialized(find_group(:id), BasicGroupSerializer)
end
@@ -123,6 +125,17 @@ class GroupsController < ApplicationController
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
def find_group(param_name)
diff --git a/app/models/topic.rb b/app/models/topic.rb
index 9e4bd7d4c..ace0481d2 100644
--- a/app/models/topic.rb
+++ b/app/models/topic.rb
@@ -19,9 +19,9 @@ class Topic < ActiveRecord::Base
def_delegator :featured_users, :choose, :feature_topic_users
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, :muted!, :notify_muted!
+ def_delegator :notifier, :mute!, :notify_muted!
def_delegator :notifier, :toggle_mute, :toggle_mute
attr_accessor :allowed_user_ids
diff --git a/app/models/topic_notifier.rb b/app/models/topic_notifier.rb
index ee25a1592..db30a8e47 100644
--- a/app/models/topic_notifier.rb
+++ b/app/models/topic_notifier.rb
@@ -3,10 +3,10 @@ class TopicNotifier
@topic = topic
end
- { :watch! => :watching,
- :tracking! => :tracking,
- :regular! => :regular,
- :muted! => :muted }.each_pair do |method_name, level|
+ { :watch! => :watching,
+ :track! => :tracking,
+ :regular! => :regular,
+ :mute! => :muted }.each_pair do |method_name, level|
define_method method_name do |user_id|
change_level user_id, level
diff --git a/app/models/topic_user.rb b/app/models/topic_user.rb
index 89c452146..c49f13a43 100644
--- a/app/models/topic_user.rb
+++ b/app/models/topic_user.rb
@@ -103,7 +103,7 @@ class TopicUser < ActiveRecord::Base
if rows == 0
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
if auto_track_after >= 0 && auto_track_after <= (attrs[:total_msecs_viewed].to_i || 0)
diff --git a/app/serializers/basic_group_serializer.rb b/app/serializers/basic_group_serializer.rb
index cc7ea1a22..925ac2365 100644
--- a/app/serializers/basic_group_serializer.rb
+++ b/app/serializers/basic_group_serializer.rb
@@ -10,9 +10,20 @@ class BasicGroupSerializer < ApplicationSerializer
:primary_group,
:title,
:grant_trust_level,
- :incoming_email
+ :incoming_email,
+ :notification_level
def include_incoming_email?
scope.is_staff?
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
diff --git a/app/serializers/listable_topic_serializer.rb b/app/serializers/listable_topic_serializer.rb
index 94963913e..609bf1d72 100644
--- a/app/serializers/listable_topic_serializer.rb
+++ b/app/serializers/listable_topic_serializer.rb
@@ -64,6 +64,7 @@ class ListableTopicSerializer < BasicTopicSerializer
def notification_level
object.user_data.notification_level
end
+
def include_notification_level?
object.user_data.present?
end
diff --git a/app/services/post_alerter.rb b/app/services/post_alerter.rb
index 4f5c0d58c..2a1bd9cd1 100644
--- a/app/services/post_alerter.rb
+++ b/app/services/post_alerter.rb
@@ -15,22 +15,27 @@ class PostAlerter
end
def after_save_post(post, new_record = false)
-
- reply_to_user = post.reply_notification_target
-
notified = [post.user].compact
if new_record && post.topic.private_message?
# If it's a private message, notify the topic_allowed_users
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
+ 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
create_notification(user, Notification.types[:private_message], post)
notified += [user]
end
end
+ reply_to_user = post.reply_notification_target
+
if new_record && reply_to_user && post.post_type == Post.types[:regular]
notify_users(reply_to_user, :replied, post)
end
@@ -133,6 +138,11 @@ class PostAlerter
# skip if muted on the topic
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
existing_notification = user.notifications
.order("notifications.id desc")
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 1b37af813..b44e809b7 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -355,6 +355,19 @@ en:
trust_levels:
title: "Trust level automatically granted to members when they're added:"
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:
"1": "Likes Given"
diff --git a/config/routes.rb b/config/routes.rb
index e28edf8e5..c74d77404 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -351,6 +351,7 @@ Discourse::Application.routes.draw do
member do
put "members" => "groups#add_members"
delete "members" => "groups#remove_member"
+ post "notifications" => "groups#set_notifications"
end
end
diff --git a/db/migrate/20151214165852_add_notification_level_to_group_users.rb b/db/migrate/20151214165852_add_notification_level_to_group_users.rb
new file mode 100644
index 000000000..a1f2a5d81
--- /dev/null
+++ b/db/migrate/20151214165852_add_notification_level_to_group_users.rb
@@ -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
diff --git a/lib/topic_creator.rb b/lib/topic_creator.rb
index a69f17938..79a2a92ef 100644
--- a/lib/topic_creator.rb
+++ b/lib/topic_creator.rb
@@ -64,15 +64,28 @@ class TopicCreator
topic.notifier.watch_topic!(topic.user_id)
end
- user_ids = topic.topic_allowed_users(true).pluck(:user_id)
- user_ids += topic.topic_allowed_groups(true).map { |t| t.group.users.pluck(:id) }.flatten
-
- user_ids.uniq.reject{ |id| id == topic.user_id }.each do |user_id|
- topic.notifier.watch_topic!(user_id, nil) unless user_id == -1
+ topic.topic_allowed_users(true).each do |tau|
+ next if tau.user_id == -1 || tau.user_id == topic.user_id
+ topic.notifier.watch!(tau.user_id)
end
- CategoryUser.auto_watch_new_topic(topic)
- CategoryUser.auto_track_new_topic(topic)
+ topic.topic_allowed_groups(true).each do |tag|
+ 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
def setup_topic_params
diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb
index 677bc0789..35c9420be 100644
--- a/spec/controllers/admin/groups_controller_spec.rb
+++ b/spec/controllers/admin/groups_controller_spec.rb
@@ -31,7 +31,8 @@ describe Admin::GroupsController do
"title"=>nil,
"primary_group"=>false,
"grant_trust_level"=>nil,
- "incoming_email"=>nil
+ "incoming_email"=>nil,
+ "notification_level"=>3,
}])
end