mirror of
https://github.com/discourse/discourse.git
synced 2025-03-26 17:55:45 +08:00
FEATURE: collapse replies to topics
when you get two replies to a topic they are now collapsed as opposed to getting two notificatons.
This commit is contained in:
parent
854fdae7cd
commit
60c5eb63ce
@ -68,9 +68,7 @@ class PostAlertObserver < ActiveRecord::Observer
|
|||||||
next unless post.reply_to_post.user_id == user.id
|
next unless post.reply_to_post.user_id == user.id
|
||||||
end
|
end
|
||||||
|
|
||||||
destroy_notifications(user, Notification.types[:private_message], post.topic)
|
create_notification(user, Notification.types[:private_message], post)
|
||||||
unread_post = first_unread_post(user,post.topic) || post
|
|
||||||
create_notification(user, Notification.types[:private_message], unread_post)
|
|
||||||
end
|
end
|
||||||
elsif post.post_type != Post.types[:moderator_action]
|
elsif post.post_type != Post.types[:moderator_action]
|
||||||
# If it's not a private message and it's not an automatic post caused by a moderator action, notify the users
|
# If it's not a private message and it's not an automatic post caused by a moderator action, notify the users
|
||||||
@ -84,13 +82,26 @@ class PostAlertObserver < ActiveRecord::Observer
|
|||||||
"#{action}_#{model.class.name.underscore.gsub(/.+\//, '')}"
|
"#{action}_#{model.class.name.underscore.gsub(/.+\//, '')}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def first_unread_post(user, topic)
|
def unread_posts(user, topic)
|
||||||
Post.where('post_number > COALESCE((
|
Post.where('post_number > COALESCE((
|
||||||
SELECT last_read_post_number FROM topic_users tu
|
SELECT last_read_post_number FROM topic_users tu
|
||||||
WHERE tu.user_id = ? AND tu.topic_id = ? ),0)',
|
WHERE tu.user_id = ? AND tu.topic_id = ? ),0)',
|
||||||
user.id, topic.id)
|
user.id, topic.id)
|
||||||
|
.where('reply_to_user_id = ? OR exists(
|
||||||
|
SELECT 1 from topic_users tu
|
||||||
|
WHERE tu.user_id = ? AND
|
||||||
|
tu.topic_id = ? AND
|
||||||
|
notification_level = ?
|
||||||
|
)', user.id, user.id, topic.id, TopicUser.notification_levels[:watching])
|
||||||
.where(topic_id: topic.id)
|
.where(topic_id: topic.id)
|
||||||
.order('post_number').first
|
end
|
||||||
|
|
||||||
|
def first_unread_post(user, topic)
|
||||||
|
unread_posts(user, topic).order('post_number').first
|
||||||
|
end
|
||||||
|
|
||||||
|
def unread_count(user, topic)
|
||||||
|
unread_posts(user, topic).count
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy_notifications(user, type, topic)
|
def destroy_notifications(user, type, topic)
|
||||||
@ -113,6 +124,31 @@ class PostAlertObserver < ActiveRecord::Observer
|
|||||||
# 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
|
||||||
return if user.notifications.exists?(notification_type: type, topic_id: post.topic_id, post_number: post.post_number)
|
return if user.notifications.exists?(notification_type: type, topic_id: post.topic_id, post_number: post.post_number)
|
||||||
|
|
||||||
|
collapsed = false
|
||||||
|
|
||||||
|
if type == Notification.types[:replied] ||
|
||||||
|
type == Notification.types[:posted]
|
||||||
|
|
||||||
|
destroy_notifications(user, Notification.types[:replied] , post.topic)
|
||||||
|
destroy_notifications(user, Notification.types[:posted] , post.topic)
|
||||||
|
collapsed = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if type == Notification.types[:private_message]
|
||||||
|
destroy_notifications(user, type, post.topic)
|
||||||
|
collapsed = true
|
||||||
|
end
|
||||||
|
|
||||||
|
original_post = post
|
||||||
|
|
||||||
|
if collapsed
|
||||||
|
post = first_unread_post(user,post.topic) || post
|
||||||
|
count = unread_count(user, post.topic)
|
||||||
|
opts[:display_username] = I18n.t('embed.replies', count: count) if count > 1
|
||||||
|
end
|
||||||
|
|
||||||
|
UserActionObserver.log_notification(original_post, user, type)
|
||||||
|
|
||||||
# Create the notification
|
# Create the notification
|
||||||
user.notifications.create(notification_type: type,
|
user.notifications.create(notification_type: type,
|
||||||
topic_id: post.topic_id,
|
topic_id: post.topic_id,
|
||||||
@ -150,11 +186,12 @@ class PostAlertObserver < ActiveRecord::Observer
|
|||||||
reply_to_user = post.reply_notification_target
|
reply_to_user = post.reply_notification_target
|
||||||
notify_users(reply_to_user, :replied, post)
|
notify_users(reply_to_user, :replied, post)
|
||||||
|
|
||||||
exclude_user_ids = []
|
exclude_user_ids = [] <<
|
||||||
exclude_user_ids << post.user_id
|
post.user_id <<
|
||||||
|
extract_mentioned_users(post).map(&:id) <<
|
||||||
|
extract_quoted_users(post).map(&:id)
|
||||||
|
|
||||||
exclude_user_ids << reply_to_user.id if reply_to_user.present?
|
exclude_user_ids << reply_to_user.id if reply_to_user.present?
|
||||||
exclude_user_ids << extract_mentioned_users(post).map(&:id)
|
|
||||||
exclude_user_ids << extract_quoted_users(post).map(&:id)
|
|
||||||
exclude_user_ids.flatten!
|
exclude_user_ids.flatten!
|
||||||
TopicUser
|
TopicUser
|
||||||
.where(topic_id: post.topic_id, notification_level: TopicUser.notification_levels[:watching])
|
.where(topic_id: post.topic_id, notification_level: TopicUser.notification_levels[:watching])
|
||||||
|
@ -9,15 +9,11 @@ class UserActionObserver < ActiveRecord::Observer
|
|||||||
log_topic(model)
|
log_topic(model)
|
||||||
when (model.is_a?(Post))
|
when (model.is_a?(Post))
|
||||||
log_post(model)
|
log_post(model)
|
||||||
when (model.is_a?(Notification))
|
|
||||||
log_notification(model)
|
|
||||||
when (model.is_a?(TopicUser))
|
when (model.is_a?(TopicUser))
|
||||||
log_topic_user(model)
|
log_topic_user(model)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def log_topic_user(model)
|
def log_topic_user(model)
|
||||||
action = UserAction::STAR
|
action = UserAction::STAR
|
||||||
|
|
||||||
@ -37,9 +33,9 @@ class UserActionObserver < ActiveRecord::Observer
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def log_notification(model)
|
def self.log_notification(post, user, notification_type)
|
||||||
action =
|
action =
|
||||||
case model.notification_type
|
case notification_type
|
||||||
when Notification.types[:quoted]
|
when Notification.types[:quoted]
|
||||||
UserAction::QUOTE
|
UserAction::QUOTE
|
||||||
when Notification.types[:replied]
|
when Notification.types[:replied]
|
||||||
@ -51,20 +47,14 @@ class UserActionObserver < ActiveRecord::Observer
|
|||||||
end
|
end
|
||||||
|
|
||||||
# like is skipped
|
# like is skipped
|
||||||
return unless action
|
return unless action && post && user
|
||||||
|
|
||||||
post = Post.where(post_number: model.post_number, topic_id: model.topic_id).first
|
|
||||||
|
|
||||||
# stray data
|
|
||||||
return unless post
|
|
||||||
|
|
||||||
row = {
|
row = {
|
||||||
action_type: action,
|
action_type: action,
|
||||||
user_id: model.user_id,
|
user_id: user.id,
|
||||||
acting_user_id: (action == UserAction::EDIT) ? post.last_editor_id : post.user_id,
|
acting_user_id: (action == UserAction::EDIT) ? post.last_editor_id : post.user_id,
|
||||||
target_topic_id: model.topic_id,
|
target_topic_id: post.topic_id,
|
||||||
target_post_id: post.id,
|
target_post_id: post.id
|
||||||
created_at: model.created_at
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if post.deleted_at.nil?
|
if post.deleted_at.nil?
|
||||||
|
Loading…
x
Reference in New Issue
Block a user