FIX: more reliable topic list counts

- unread was not incrementing when you read last post on topic
- new notifications were being inserted even if they existed in list
- terminology was all mixed up "1 new posts", split to 3 messages
- latest behaves as expected, updating count of new and updated topics
This commit is contained in:
Sam 2014-08-05 13:27:34 +10:00
parent 1958b0205e
commit 4536f772c1
9 changed files with 64 additions and 12 deletions

View file

@ -54,7 +54,7 @@ Ember.Handlebars.registerHelper('countI18n', function(key, options) {
shouldRerender: Discourse.View.renderIfChanged('count'), shouldRerender: Discourse.View.renderIfChanged('count'),
render: function(buffer) { render: function(buffer) {
buffer.push(I18n.t(key, { count: this.get('count') })); buffer.push(I18n.t(key + (this.get('suffix') || ""), { count: this.get('count') }));
} }
}); });

View file

@ -17,13 +17,17 @@ Discourse.TopicTrackingState = Discourse.Model.extend({
tracker.incrementMessageCount(); tracker.incrementMessageCount();
} }
if (data.message_type === "new_topic"){ if (data.message_type === "new_topic" || data.message_type === "latest") {
var ignored_categories = Discourse.User.currentProp("muted_category_ids"); var ignored_categories = Discourse.User.currentProp("muted_category_ids");
if(_.include(ignored_categories, data.payload.category_id)){ if(_.include(ignored_categories, data.payload.category_id)){
return; return;
} }
} }
if (data.message_type === "latest"){
tracker.notify(data);
}
if (data.message_type === "new_topic" || data.message_type === "unread" || data.message_type === "read") { if (data.message_type === "new_topic" || data.message_type === "unread" || data.message_type === "read") {
tracker.notify(data); tracker.notify(data);
var old = tracker.states["t" + data.topic_id]; var old = tracker.states["t" + data.topic_id];
@ -36,6 +40,7 @@ Discourse.TopicTrackingState = Discourse.Model.extend({
}; };
Discourse.MessageBus.subscribe("/new", process); Discourse.MessageBus.subscribe("/new", process);
Discourse.MessageBus.subscribe("/latest", process);
var currentUser = Discourse.User.current(); var currentUser = Discourse.User.current();
if(currentUser) { if(currentUser) {
Discourse.MessageBus.subscribe("/unread/" + currentUser.id, process); Discourse.MessageBus.subscribe("/unread/" + currentUser.id, process);
@ -55,17 +60,29 @@ Discourse.TopicTrackingState = Discourse.Model.extend({
if (!this.newIncoming) { return; } if (!this.newIncoming) { return; }
if ((this.filter === "all" ||this.filter === "latest" || this.filter === "new") && data.message_type === "new_topic" ) { if ((this.filter === "all" ||this.filter === "latest" || this.filter === "new") && data.message_type === "new_topic" ) {
this.newIncoming.push(data.topic_id); this.addIncoming(data.topic_id);
} }
if ((this.filter === "all" ||this.filter === "latest" || this.filter === "unread") && data.message_type === "unread") {
if ((this.filter === "all" || this.filter === "unread") && data.message_type === "unread") {
var old = this.states["t" + data.topic_id]; var old = this.states["t" + data.topic_id];
if(!old) { if(!old || old.highest_post_number === old.last_read_post_number) {
this.newIncoming.push(data.topic_id); this.addIncoming(data.topic_id);
} }
} }
if(this.filter === "latest" && data.message_type === "latest") {
this.addIncoming(data.topic_id);
}
this.set("incomingCount", this.newIncoming.length); this.set("incomingCount", this.newIncoming.length);
}, },
addIncoming: function(topicId) {
if(this.newIncoming.indexOf(topicId) === -1){
this.newIncoming.push(topicId);
}
},
resetTracking: function(){ resetTracking: function(){
this.newIncoming = []; this.newIncoming = [];
this.set("incomingCount", 0); this.set("incomingCount", 0);

View file

@ -67,8 +67,8 @@
<tr> <tr>
<td colspan="9"> <td colspan="9">
<div class='alert alert-info clickable' {{action showInserted}}> <div class='alert alert-info clickable' {{action showInserted}}>
{{countI18n new_topics_inserted count=topicTrackingState.incomingCount}} {{countI18n topic_count_ suffix=topicTrackingState.filter count=topicTrackingState.incomingCount}}
{{i18n show_new_topics}} {{i18n click_to_show}}
</div> </div>
</td> </td>
</tr> </tr>

View file

@ -12,8 +12,8 @@
<tr> <tr>
<td> <td>
<div class='alert alert-info' {{action showInserted}}> <div class='alert alert-info' {{action showInserted}}>
{{countI18n new_topics_inserted countBinding="topicTrackingState.incomingCount"}} {{countI18n topic_count_ suffix=topicTrackingState.filter count=topicTrackingState.incomingCount}}
{{i18n show_new_topics}} {{i18n click_to_show}}
</div> </div>
</td> </td>
</tr> </tr>

View file

@ -117,6 +117,11 @@ export default Discourse.View.extend(AddCategoryClass, Discourse.Scrolling, {
@method scrolled @method scrolled
**/ **/
scrolled: function(){ scrolled: function(){
if(this.isDestroyed || this.isDestroying) {
return;
}
var offset = window.pageYOffset || $('html').scrollTop(); var offset = window.pageYOffset || $('html').scrollTop();
if (!this.get('docAt')) { if (!this.get('docAt')) {
var title = $('#topic-title'); var title = $('#topic-title');

View file

@ -37,6 +37,23 @@ class TopicTrackingState
publish_read(topic.id, 1, topic.user_id) publish_read(topic.id, 1, topic.user_id)
end end
def self.publish_latest(topic)
return unless topic.archetype == "regular"
message = {
topic_id: topic.id,
message_type: "latest",
payload: {
bumped_at: topic.bumped_at,
topic_id: topic.id,
category_id: topic.category_id
}
}
group_ids = topic.category && topic.category.secure_group_ids
MessageBus.publish("/latest", message.as_json, group_ids: group_ids)
end
def self.publish_unread(post) def self.publish_unread(post)
# TODO at high scale we are going to have to defer this, # TODO at high scale we are going to have to defer this,
# perhaps cut down to users that are around in the last 7 days as well # perhaps cut down to users that are around in the last 7 days as well

View file

@ -150,8 +150,19 @@ en:
last_read: "this is the last post you've read; click to bookmark it" last_read: "this is the last post you've read; click to bookmark it"
remove: "Remove Bookmark" remove: "Remove Bookmark"
new_topics_inserted: "{{count}} new posts." topic_count_latest:
show_new_topics: "Click to show." one: "{{count}} new or updated topic."
other: "{{count}} new or updated topics."
topic_count_unread:
one: "{{count}} unread topic."
other: "{{count}} unread topics."
topic_count_new:
one: "{{count}} new topic."
other: "{{count}} new topics."
click_to_show: "Click to show."
preview: "preview" preview: "preview"
cancel: "cancel" cancel: "cancel"

View file

@ -30,6 +30,7 @@ class PostJobsEnqueuer
def after_post_create def after_post_create
TopicTrackingState.publish_unread(@post) if @post.post_number > 1 TopicTrackingState.publish_unread(@post) if @post.post_number > 1
TopicTrackingState.publish_latest(@topic)
Jobs.enqueue_in( Jobs.enqueue_in(
SiteSetting.email_time_window_mins.minutes, SiteSetting.email_time_window_mins.minutes,

View file

@ -82,6 +82,7 @@ class PostRevisor
def bump_topic def bump_topic
unless Post.where('post_number > ? and topic_id = ?', @post.post_number, @post.topic_id).exists? unless Post.where('post_number > ? and topic_id = ?', @post.post_number, @post.topic_id).exists?
@post.topic.update_column(:bumped_at, Time.now) @post.topic.update_column(:bumped_at, Time.now)
TopicTrackingState.publish_latest(@post.topic)
end end
end end