mirror of
https://github.com/discourse/discourse.git
synced 2025-01-18 18:02:46 +08:00
FEATURE: by default users track a group (as opposed to watch)
FEATURE: a rollup counting number of messages in the group inbox to tracking users
This commit is contained in:
parent
74f22f95da
commit
a764cc3a42
|
@ -42,6 +42,11 @@ export default Ember.Component.extend({
|
|||
if (it.get('notification_type') === INVITED_TYPE) {
|
||||
return Discourse.getURL('/users/' + it.get('data.display_username'));
|
||||
}
|
||||
|
||||
if (it.get('data.group_id')) {
|
||||
return Discourse.getURL('/users/' + it.get('data.username') + '/messages/group/' + it.get('data.group_name'));
|
||||
}
|
||||
|
||||
}.property("notification.data.{badge_id,badge_name,display_username}", "model.slug", "model.topic_id", "model.post_number"),
|
||||
|
||||
description: function() {
|
||||
|
@ -63,7 +68,15 @@ export default Ember.Component.extend({
|
|||
const notification = this.get('notification');
|
||||
const description = this.get('description');
|
||||
const username = notification.get('data.display_username');
|
||||
const text = Discourse.Emoji.unescape(I18n.t(this.get('scope'), {description, username}));
|
||||
var text;
|
||||
if (notification.get('data.inbox_count')) {
|
||||
const count = notification.get('data.inbox_count');
|
||||
const group_name = notification.get('data.group_name');
|
||||
text = I18n.t(this.get('scope'), {count, group_name});
|
||||
} else {
|
||||
text = I18n.t(this.get('scope'), {description, username});
|
||||
}
|
||||
text = Discourse.Emoji.unescape(text);
|
||||
|
||||
const url = this.get('url');
|
||||
if (url) {
|
||||
|
|
|
@ -41,7 +41,9 @@ class Notification < ActiveRecord::Base
|
|||
granted_badge: 12,
|
||||
invited_to_topic: 13,
|
||||
custom: 14,
|
||||
group_mentioned: 15)
|
||||
group_mentioned: 15,
|
||||
group_message_summary: 16
|
||||
)
|
||||
end
|
||||
|
||||
def self.mark_posts_read(user, topic_id, post_numbers)
|
||||
|
|
|
@ -294,8 +294,13 @@ class User < ActiveRecord::Base
|
|||
User.where("id = ? and seen_notification_id < ?", id, notification_id)
|
||||
.update_all ["seen_notification_id = ?", notification_id]
|
||||
|
||||
# mark all "badge granted" and "invite accepted" notifications read
|
||||
Notification.where('user_id = ? AND NOT read AND notification_type IN (?)', id, [Notification.types[:granted_badge], Notification.types[:invitee_accepted]])
|
||||
# some notifications are considered read once seen
|
||||
Notification.where('user_id = ? AND NOT read AND notification_type IN (?)', id, [
|
||||
Notification.types[:granted_badge],
|
||||
Notification.types[:invitee_accepted],
|
||||
Notification.types[:group_message_summary],
|
||||
Notification.types[:liked]
|
||||
])
|
||||
.update_all ["read = ?", true]
|
||||
end
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class PostAlerter
|
|||
allowed_users(post) - allowed_group_users(post)
|
||||
end
|
||||
|
||||
def undirectly_targeted_users(post)
|
||||
def indirectly_targeted_users(post)
|
||||
allowed_group_users(post)
|
||||
end
|
||||
|
||||
|
@ -77,12 +77,16 @@ class PostAlerter
|
|||
end
|
||||
end
|
||||
# users that are part of all mentionned groups
|
||||
undirectly_targeted_users(post).each do |user|
|
||||
indirectly_targeted_users(post).each do |user|
|
||||
if !notified.include?(user)
|
||||
# only create a notification when watching the group
|
||||
if TopicUser.get(post.topic, user).try(:notification_level) == TopicUser.notification_levels[:watching]
|
||||
notification_level = TopicUser.get(post.topic, user).try(:notification_level)
|
||||
if notification_level == TopicUser.notification_levels[:watching]
|
||||
create_notification(user, Notification.types[:private_message], post)
|
||||
notified += [user]
|
||||
elsif notification_level == TopicUser.notification_levels[:tracking]
|
||||
notify_group_summary(user, post)
|
||||
notified += [user]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -141,6 +145,55 @@ class PostAlerter
|
|||
Notification.types[t]
|
||||
}
|
||||
|
||||
def group_stats(topic)
|
||||
topic.allowed_groups.map do |g|
|
||||
{
|
||||
group_id: g.id,
|
||||
group_name: g.name.downcase,
|
||||
inbox_count: Topic.exec_sql(
|
||||
"SELECT COUNT(*) FROM topics t
|
||||
JOIN topic_allowed_groups g ON g.id = :group_id AND g.topic_id = t.id
|
||||
LEFT JOIN group_archived_messages a ON a.topic_id = t.id AND a.group_id = g.id
|
||||
WHERE a.id IS NULL AND t.deleted_at is NULL AND t.archetype = 'private_message'",
|
||||
group_id: g.id).values[0][0].to_i
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def notify_group_summary(user,post)
|
||||
|
||||
@group_stats ||= {}
|
||||
stats = (@group_stats[post.topic_id] ||= group_stats(post.topic))
|
||||
return unless stats
|
||||
|
||||
group_id = post.topic
|
||||
.topic_allowed_groups
|
||||
.where(group_id: user.groups.pluck(:id))
|
||||
.pluck(:group_id).first
|
||||
|
||||
stat = stats.find{|s| s[:group_id] == group_id}
|
||||
return unless stat
|
||||
|
||||
notification_type = Notification.types[:group_message_summary]
|
||||
|
||||
Notification.where(notification_type: notification_type, user_id: user.id).each do |n|
|
||||
n.destroy if n.data_hash[:group_id] == stat[:group_id]
|
||||
end
|
||||
|
||||
Notification.create(
|
||||
notification_type: notification_type,
|
||||
user_id: user.id,
|
||||
data: {
|
||||
group_id: stat[:group_id],
|
||||
group_name: stat[:group_name],
|
||||
inbox_count: stat[:inbox_count],
|
||||
username: user.username_lower
|
||||
}.to_json
|
||||
)
|
||||
|
||||
# TODO decide if it makes sense to also publish a desktop notification
|
||||
end
|
||||
|
||||
def create_notification(user, type, post, opts=nil)
|
||||
return if user.blank?
|
||||
return if user.id == Discourse::SYSTEM_USER_ID
|
||||
|
|
|
@ -1002,6 +1002,10 @@ en:
|
|||
linked: "<i title='linked post' class='fa fa-arrow-left'></i><p><span>{{username}}</span> {{description}}</p>"
|
||||
granted_badge: "<i title='badge granted' class='fa fa-certificate'></i><p>Earned '{{description}}'</p>"
|
||||
|
||||
group_message_summary:
|
||||
one: "<i title='messages in group inbox' class='fa fa-group'></i><p> there is {{count}} message in your {{group_name}} inbox</p>"
|
||||
other: "<i title='messages in group inbox' class='fa fa-group'></i><p> there are {{count}} messages in your {{group_name}} inbox</p>"
|
||||
|
||||
alt:
|
||||
mentioned: "Mentioned by"
|
||||
quoted: "Quoted by"
|
||||
|
@ -1016,6 +1020,7 @@ en:
|
|||
moved_post: "Your post was moved by"
|
||||
linked: "Link to your post"
|
||||
granted_badge: "Badge granted"
|
||||
group_message_summary: "Messages in group inbox"
|
||||
|
||||
popup:
|
||||
mentioned: '{{username}} mentioned you in "{{topic}}" - {{site_title}}'
|
||||
|
|
|
@ -73,10 +73,10 @@ class TopicCreator
|
|||
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[:tracking] then "watch!"
|
||||
when TopicUser.notification_levels[:regular] then "regular!"
|
||||
when TopicUser.notification_levels[:muted] then "mute!"
|
||||
else "watch!"
|
||||
else "track!"
|
||||
end
|
||||
topic.notifier.send(action, gu.user_id)
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ describe "i18n integrity checks" do
|
|||
|
||||
it "needs an i18n key (notification_types) for each Notification type" do
|
||||
Notification.types.each_key do |type|
|
||||
next if type == :custom
|
||||
next if type == :custom || type == :group_message_summary
|
||||
expect(I18n.t("notification_types.#{type}")).not_to match(/translation missing/)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,8 +43,11 @@ describe PostAction do
|
|||
expect(topic_user_ids).to include(codinghorror.id)
|
||||
expect(topic_user_ids).to include(mod.id)
|
||||
|
||||
# Notification level should be "Watching" for everyone
|
||||
expect(topic.topic_users(true).map(&:notification_level).uniq).to eq([TopicUser.notification_levels[:watching]])
|
||||
expect(topic.topic_users.where(user_id: mod.id)
|
||||
.pluck(:notification_level).first).to eq(TopicUser.notification_levels[:tracking])
|
||||
|
||||
expect(topic.topic_users.where(user_id: codinghorror.id)
|
||||
.pluck(:notification_level).first).to eq(TopicUser.notification_levels[:watching])
|
||||
|
||||
# reply to PM should not clear flag
|
||||
PostCreator.new(mod, topic_id: posts[0].topic_id, raw: "This is my test reply to the user, it should clear flags").create
|
||||
|
|
Loading…
Reference in New Issue
Block a user