mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 11:44:49 +08:00
FEATURE: additional "related messages" section
This splits out previous message correspondence from suggeted and instead has a dedicated section called "related messages"
This commit is contained in:
parent
e50d0ba477
commit
e17a13ce19
|
@ -0,0 +1,17 @@
|
|||
import computed from "ember-addons/ember-computed-decorators";
|
||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||
|
||||
export default Ember.Component.extend({
|
||||
elementId: "related-messages",
|
||||
classNames: ["suggested-topics"],
|
||||
|
||||
@computed("topic")
|
||||
relatedTitle(topic) {
|
||||
const href = this.currentUser && this.currentUser.pmPath(topic);
|
||||
return href
|
||||
? `<a href="${href}">${iconHTML("envelope", {
|
||||
class: "private-message-glyph"
|
||||
})}</a><span>${I18n.t("related_messages.title")}</span>`
|
||||
: I18n.t("related_messages.title");
|
||||
}
|
||||
});
|
|
@ -4,6 +4,7 @@ import { iconHTML } from "discourse-common/lib/icon-library";
|
|||
|
||||
export default Ember.Component.extend({
|
||||
elementId: "suggested-topics",
|
||||
classNames: ["suggested-topics"],
|
||||
|
||||
@computed("topic")
|
||||
suggestedTitle(topic) {
|
||||
|
|
|
@ -124,6 +124,20 @@ const Topic = RestModel.extend({
|
|||
return newTags;
|
||||
},
|
||||
|
||||
@computed("related_messages")
|
||||
relatedMessages(relatedMessages) {
|
||||
if (relatedMessages) {
|
||||
const store = this.store;
|
||||
|
||||
return this.set(
|
||||
"related_messages",
|
||||
relatedMessages.map(st => {
|
||||
return store.createRecord("topic", st);
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@computed("suggested_topics")
|
||||
suggestedTopics(suggestedTopics) {
|
||||
if (suggestedTopics) {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<h3 class="suggested-topics-title">{{{relatedTitle}}}</h3>
|
||||
<div class="topics">
|
||||
{{basic-topic-list
|
||||
hideCategory="true"
|
||||
showPosters="true"
|
||||
topics=topic.relatedMessages}}
|
||||
</div>
|
|
@ -1,5 +1,4 @@
|
|||
<h3 class="suggested-topics-title">{{{suggestedTitle}}}</h3>
|
||||
|
||||
<div class="topics">
|
||||
{{#if topic.isPrivateMessage}}
|
||||
{{basic-topic-list
|
||||
|
|
|
@ -284,6 +284,9 @@
|
|||
|
||||
{{plugin-outlet name="topic-above-suggested" args=(hash model=model)}}
|
||||
|
||||
{{#if model.relatedMessages.length}}
|
||||
{{related-messages topic=model}}
|
||||
{{/if}}
|
||||
{{#if model.suggestedTopics.length}}
|
||||
{{suggested-topics topic=model}}
|
||||
{{/if}}
|
||||
|
|
|
@ -726,7 +726,7 @@ a.mention-group {
|
|||
}
|
||||
}
|
||||
|
||||
#suggested-topics {
|
||||
.suggested-topics {
|
||||
.topics {
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
|
|
@ -168,31 +168,31 @@ a.badge-category {
|
|||
}
|
||||
|
||||
// Target the .badge-category text, the bullet icon needs to maintain `display: block`
|
||||
#suggested-topics h3 .badge-wrapper.bullet span.badge-category,
|
||||
#suggested-topics h3 .badge-wrapper.box span,
|
||||
#suggested-topics h3 .badge-wrapper.bar span {
|
||||
.suggested-topics h3 .badge-wrapper.bullet span.badge-category,
|
||||
.suggested-topics h3 .badge-wrapper.box span,
|
||||
.suggested-topics h3 .badge-wrapper.bar span {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#suggested-topics h3 .badge-wrapper.bullet span.badge-category {
|
||||
.suggested-topics h3 .badge-wrapper.bullet span.badge-category {
|
||||
// Override vertical-align: text-top from `badges.css.scss`
|
||||
vertical-align: baseline;
|
||||
line-height: $line-height-medium;
|
||||
}
|
||||
|
||||
#suggested-topics h3 .badge-wrapper.bullet,
|
||||
#suggested-topics h3 .badge-wrapper.bullet span.badge-category-parent-bg,
|
||||
#suggested-topics h3 .badge-wrapper.bullet span.badge-category-bg {
|
||||
.suggested-topics h3 .badge-wrapper.bullet,
|
||||
.suggested-topics h3 .badge-wrapper.bullet span.badge-category-parent-bg,
|
||||
.suggested-topics h3 .badge-wrapper.bullet span.badge-category-bg {
|
||||
// Top of bullet aligns with top of line - adjust line height to vertically align bullet.
|
||||
line-height: 0.8;
|
||||
}
|
||||
|
||||
#suggested-topics .badge-wrapper.bullet span.badge-category,
|
||||
#suggested-topics .badge-wrapper.bar span.badge-category {
|
||||
.suggested-topics .badge-wrapper.bullet span.badge-category,
|
||||
.suggested-topics .badge-wrapper.bar span.badge-category {
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
#suggested-topics .suggested-topics-title {
|
||||
.suggested-topics .suggested-topics-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
.topic-map,
|
||||
.post-menu-area.clearfix,
|
||||
div#topic-footer-buttons,
|
||||
div#suggested-topics,
|
||||
div.suggested-topics,
|
||||
div#progress-topic-wrapper,
|
||||
#topic-progress-wrapper,
|
||||
div.nums,
|
||||
|
|
|
@ -447,7 +447,7 @@ nav.post-controls {
|
|||
width: 757px;
|
||||
}
|
||||
|
||||
#suggested-topics {
|
||||
.suggested-topics {
|
||||
clear: left;
|
||||
padding: 20px 0 15px 0;
|
||||
table {
|
||||
|
@ -459,7 +459,7 @@ nav.post-controls {
|
|||
}
|
||||
}
|
||||
|
||||
#suggested-topics .topic-statuses .topic-status {
|
||||
.suggested-topics .topic-statuses .topic-status {
|
||||
padding: 0;
|
||||
i {
|
||||
font-size: 1em;
|
||||
|
|
|
@ -259,7 +259,7 @@ a.reply-to-tab {
|
|||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#suggested-topics {
|
||||
.suggested-topics {
|
||||
clear: left;
|
||||
padding: 20px 0 15px 0;
|
||||
th.views,
|
||||
|
|
|
@ -1,12 +1,23 @@
|
|||
module SuggestedTopicsMixin
|
||||
def self.included(klass)
|
||||
klass.attributes :related_messages
|
||||
klass.attributes :suggested_topics
|
||||
end
|
||||
|
||||
def include_related_messages?
|
||||
object.next_page.nil? && object.related_messages&.topics.present?
|
||||
end
|
||||
|
||||
def include_suggested_topics?
|
||||
object.next_page.nil? && object.suggested_topics&.topics.present?
|
||||
end
|
||||
|
||||
def related_messages
|
||||
object.related_messages.topics.map do |t|
|
||||
SuggestedTopicSerializer.new(t, scope: scope, root: false)
|
||||
end
|
||||
end
|
||||
|
||||
def suggested_topics
|
||||
object.suggested_topics.topics.map do |t|
|
||||
SuggestedTopicSerializer.new(t, scope: scope, root: false)
|
||||
|
|
|
@ -252,6 +252,9 @@ en:
|
|||
one: "{{count}} character"
|
||||
other: "{{count}} characters"
|
||||
|
||||
related_messages:
|
||||
title: "Related Messages"
|
||||
|
||||
suggested_topics:
|
||||
title: "Suggested Topics"
|
||||
pm_title: "Suggested Messages"
|
||||
|
|
|
@ -135,8 +135,71 @@ class TopicQuery
|
|||
(list || Topic).joins("LEFT OUTER JOIN topic_users AS tu ON (topics.id = tu.topic_id AND tu.user_id = #{@user.id.to_i})")
|
||||
end
|
||||
|
||||
def get_pm_params(topic)
|
||||
if topic.private_message?
|
||||
|
||||
my_group_ids = topic.topic_allowed_groups
|
||||
.joins("
|
||||
LEFT JOIN group_users gu
|
||||
ON topic_allowed_groups.group_id = gu.group_id
|
||||
AND gu.user_id = #{@user.id.to_i}
|
||||
")
|
||||
.where("gu.group_id IS NOT NULL")
|
||||
.pluck(:group_id)
|
||||
|
||||
target_group_ids = topic.topic_allowed_groups.pluck(:group_id)
|
||||
|
||||
target_users = topic
|
||||
.topic_allowed_users
|
||||
|
||||
if my_group_ids.present?
|
||||
|
||||
# strip out users in groups you already belong to
|
||||
target_users = target_users
|
||||
.joins("LEFT JOIN group_users gu ON gu.user_id = topic_allowed_users.user_id AND gu.group_id IN (#{sanitize_sql_array(my_group_ids)})")
|
||||
.where('gu.group_id IS NULL')
|
||||
end
|
||||
|
||||
target_user_ids = target_users
|
||||
.where('NOT topic_allowed_users.user_id = ?', @user.id)
|
||||
.pluck(:user_id)
|
||||
|
||||
{
|
||||
topic: topic,
|
||||
my_group_ids: my_group_ids,
|
||||
target_group_ids: target_group_ids,
|
||||
target_user_ids: target_user_ids
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def list_related_for(topic, pm_params: nil)
|
||||
return if !topic.private_message?
|
||||
return if @user.blank?
|
||||
return if !SiteSetting.enable_personal_messages?
|
||||
|
||||
builder = SuggestedTopicsBuilder.new(topic)
|
||||
pm_params = pm_params || get_pm_params(topic)
|
||||
|
||||
if pm_params[:my_group_ids].present?
|
||||
builder.add_results(related_messages_group(
|
||||
pm_params.merge(count: [6, builder.results_left].max,
|
||||
exclude: builder.excluded_topic_ids)
|
||||
))
|
||||
else
|
||||
builder.add_results(related_messages_user(
|
||||
pm_params.merge(count: [6, builder.results_left].max,
|
||||
exclude: builder.excluded_topic_ids)
|
||||
))
|
||||
end
|
||||
|
||||
params = { unordered: true }
|
||||
params[:preload_posters] = true
|
||||
create_list(:suggested, params, builder.results)
|
||||
end
|
||||
|
||||
# Return a list of suggested topics for a topic
|
||||
def list_suggested_for(topic)
|
||||
def list_suggested_for(topic, pm_params: nil)
|
||||
|
||||
# Don't suggest messages unless we have a user, and private messages are
|
||||
# enabled.
|
||||
|
@ -145,42 +208,7 @@ class TopicQuery
|
|||
|
||||
builder = SuggestedTopicsBuilder.new(topic)
|
||||
|
||||
pm_params =
|
||||
if topic.private_message?
|
||||
|
||||
my_group_ids = topic.topic_allowed_groups
|
||||
.joins("
|
||||
LEFT JOIN group_users gu
|
||||
ON topic_allowed_groups.group_id = gu.group_id
|
||||
AND gu.user_id = #{@user.id.to_i}
|
||||
")
|
||||
.where("gu.group_id IS NOT NULL")
|
||||
.pluck(:group_id)
|
||||
|
||||
target_group_ids = topic.topic_allowed_groups.pluck(:group_id)
|
||||
|
||||
target_users = topic
|
||||
.topic_allowed_users
|
||||
|
||||
if my_group_ids.present?
|
||||
|
||||
# strip out users in groups you already belong to
|
||||
target_users = target_users
|
||||
.joins("LEFT JOIN group_users gu ON gu.user_id = topic_allowed_users.user_id AND gu.group_id IN (#{sanitize_sql_array(my_group_ids)})")
|
||||
.where('gu.group_id IS NULL')
|
||||
end
|
||||
|
||||
target_user_ids = target_users
|
||||
.where('NOT topic_allowed_users.user_id = ?', @user.id)
|
||||
.pluck(:user_id)
|
||||
|
||||
{
|
||||
topic: topic,
|
||||
my_group_ids: my_group_ids,
|
||||
target_group_ids: target_group_ids,
|
||||
target_user_ids: target_user_ids
|
||||
}
|
||||
end
|
||||
pm_params = pm_params || get_pm_params(topic)
|
||||
|
||||
# When logged in we start with different results
|
||||
if @user
|
||||
|
@ -194,18 +222,6 @@ class TopicQuery
|
|||
pm_params.merge(count: builder.results_left)
|
||||
)) unless builder.full?
|
||||
|
||||
if pm_params[:my_group_ids].present?
|
||||
builder.add_results(related_messages_group(
|
||||
pm_params.merge(count: [3, builder.results_left].max,
|
||||
exclude: builder.excluded_topic_ids)
|
||||
), :ultra_high)
|
||||
else
|
||||
builder.add_results(related_messages_user(
|
||||
pm_params.merge(count: [3, builder.results_left].max,
|
||||
exclude: builder.excluded_topic_ids)
|
||||
), :ultra_high)
|
||||
end
|
||||
|
||||
else
|
||||
builder.add_results(unread_results(topic: topic, per_page: builder.results_left), :high)
|
||||
builder.add_results(new_results(topic: topic, per_page: builder.category_results_left)) unless builder.full?
|
||||
|
|
|
@ -402,8 +402,16 @@ class TopicView
|
|||
@initial_load
|
||||
end
|
||||
|
||||
def pm_params
|
||||
@pm_params ||= TopicQuery.new(@user).get_pm_params(topic)
|
||||
end
|
||||
|
||||
def suggested_topics
|
||||
@suggested_topics ||= TopicQuery.new(@user).list_suggested_for(topic)
|
||||
@suggested_topics ||= TopicQuery.new(@user).list_suggested_for(topic, pm_params: pm_params)
|
||||
end
|
||||
|
||||
def related_messages
|
||||
@related_messages ||= TopicQuery.new(@user).list_related_for(topic, pm_params: pm_params)
|
||||
end
|
||||
|
||||
# This is pending a larger refactor, that allows custom orders
|
||||
|
|
|
@ -644,7 +644,7 @@ describe TopicQuery do
|
|||
end
|
||||
end
|
||||
|
||||
context 'suggested_for message do' do
|
||||
context 'list_related_for do' do
|
||||
|
||||
let(:user) do
|
||||
Fabricate(:admin)
|
||||
|
@ -679,11 +679,6 @@ describe TopicQuery do
|
|||
pm_to_group = create_pm(sender, target_group_names: [group_with_user.name])
|
||||
pm_to_user = create_pm(sender, target_usernames: [user.username])
|
||||
|
||||
new_pm = create_pm(target_usernames: [user.username])
|
||||
|
||||
unread_pm = create_pm(target_usernames: [user.username])
|
||||
read(user, unread_pm, 0)
|
||||
|
||||
old_unrelated_pm = create_pm(target_usernames: [user.username])
|
||||
read(user, old_unrelated_pm, 1)
|
||||
|
||||
|
@ -693,17 +688,17 @@ describe TopicQuery do
|
|||
related_by_group_pm = create_pm(sender, target_group_names: [group_with_user.name])
|
||||
read(user, related_by_group_pm, 1)
|
||||
|
||||
expect(TopicQuery.new(user).list_suggested_for(pm_to_group).topics.map(&:id)).to(
|
||||
expect(TopicQuery.new(user).list_related_for(pm_to_group).topics.map(&:id)).to(
|
||||
eq([related_by_group_pm.id])
|
||||
)
|
||||
|
||||
expect(TopicQuery.new(user).list_suggested_for(pm_to_user).topics.map(&:id)).to(
|
||||
eq([related_by_user_pm.id, new_pm.id, unread_pm.id])
|
||||
expect(TopicQuery.new(user).list_related_for(pm_to_user).topics.map(&:id)).to(
|
||||
eq([related_by_user_pm.id])
|
||||
)
|
||||
|
||||
SiteSetting.enable_personal_messages = false
|
||||
expect(TopicQuery.new(user).list_suggested_for(pm_to_group)).to be_blank
|
||||
expect(TopicQuery.new(user).list_suggested_for(pm_to_user)).to be_blank
|
||||
expect(TopicQuery.new(user).list_related_for(pm_to_group)).to be_blank
|
||||
expect(TopicQuery.new(user).list_related_for(pm_to_user)).to be_blank
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user