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:
Sam 2018-11-12 13:04:30 +11:00
parent e50d0ba477
commit e17a13ce19
16 changed files with 151 additions and 77 deletions

View File

@ -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");
}
});

View File

@ -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) {

View File

@ -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) {

View File

@ -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>

View File

@ -1,5 +1,4 @@
<h3 class="suggested-topics-title">{{{suggestedTitle}}}</h3>
<div class="topics">
{{#if topic.isPrivateMessage}}
{{basic-topic-list

View File

@ -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}}

View File

@ -726,7 +726,7 @@ a.mention-group {
}
}
#suggested-topics {
.suggested-topics {
.topics {
padding-bottom: 15px;
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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;

View File

@ -259,7 +259,7 @@ a.reply-to-tab {
margin: 0 auto;
}
#suggested-topics {
.suggested-topics {
clear: left;
padding: 20px 0 15px 0;
th.views,

View File

@ -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)

View File

@ -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"

View File

@ -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?

View File

@ -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

View File

@ -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