This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/models/topic_tracking_state.js
2013-06-03 14:54:51 +10:00

194 lines
4.9 KiB
JavaScript

Discourse.TopicTrackingState = Discourse.Model.extend({
messageCount: 0,
init: function(){
this._super();
this.unreadSequence = [];
this.newSequence = [];
this.states = {};
},
establishChannels: function() {
var tracker = this;
var process = function(data){
if (data.message_type === "delete") {
tracker.removeTopic(data.topic_id);
}
if (data.message_type === "new_topic" || data.message_type === "unread" || data.message_type === "read") {
tracker.notify(data);
tracker.states["t" + data.topic_id] = data.payload;
}
tracker.incrementMessageCount();
};
Discourse.MessageBus.subscribe("/new", process);
var currentUser = Discourse.User.current();
if(currentUser) {
Discourse.MessageBus.subscribe("/unread/" + currentUser.id, process);
}
},
notify: function(data){
if (!this.newIncoming) { return; }
if ((this.filter === "all" ||this.filter === "latest" || this.filter === "new") && data.message_type === "new_topic" ) {
this.newIncoming.push(data.topic_id);
}
if ((this.filter === "all" || this.filter === "unread") && data.message_type === "unread") {
var old = this.states["t" + data.topic_id];
if(!old) {
this.newIncoming.push(data.topic_id);
}
}
this.set("incomingCount", this.newIncoming.length);
},
resetTracking: function(){
this.newIncoming = [];
this.set("incomingCount", 0);
},
// track how many new topics came for this filter
trackIncoming: function(filter) {
this.newIncoming = [];
this.filter = filter;
this.set("incomingCount", 0);
},
hasIncoming: function(){
var count = this.get('incomingCount');
return count && count > 0;
}.property('incomingCount'),
removeTopic: function(topic_id) {
delete this.states["t" + topic_id];
},
sync: function(list, filter){
var tracker = this;
if(!list || !list.topics) { return; }
if(filter === "new" && !list.more_topics_url){
// scrub all new rows and reload from list
$.each(this.states, function(){
if(this.last_read_post_number === null) {
tracker.removeTopic(this.topic_id);
}
});
}
if(filter === "unread" && !list.more_topics_url){
// scrub all new rows and reload from list
$.each(this.states, function(){
if(this.last_read_post_number !== null) {
tracker.removeTopic(this.topic_id);
}
});
}
$.each(list.topics, function(){
var row = {};
var topic = this;
row.topic_id = topic.id;
if(topic.unseen) {
row.last_read_post_number = null;
} else if (topic.unread || topic.new_posts){
// subtle issue here
row.last_read_post_number = topic.highest_post_number - ((topic.unread||0) + (topic.new_posts||0));
} else {
delete tracker.states["t" + topic.id];
return;
}
row.highest_post_number = topic.highest_post_number;
if (topic.category) {
row.category_name = topic.category.name;
}
tracker.states["t" + topic.id] = row;
});
this.incrementMessageCount();
},
incrementMessageCount: function() {
this.set("messageCount", this.get("messageCount") + 1);
},
countNew: function(){
var count = 0;
$.each(this.states, function(){
count += this.last_read_post_number === null ? 1 : 0;
});
return count;
},
countUnread: function(){
var count = 0;
$.each(this.states, function(){
count += (this.last_read_post_number !== null &&
this.last_read_post_number < this.highest_post_number) ? 1 : 0;
});
return count;
},
countCategory: function(category) {
var count = 0;
$.each(this.states, function(){
if (this.category_name === category) {
count += (this.last_read_post_number === null ||
this.last_read_post_number < this.highest_post_number) ? 1 : 0;
}
});
return count;
},
lookupCount: function(name){
if(name==="new") {
return this.countNew();
} else if(name==="unread") {
return this.countUnread();
} else {
var category = name.split("/")[1];
if(category) {
return this.countCategory(category);
}
}
},
loadStates: function (data) {
// not exposed
var states = this.states;
if(data) {
data.each(function(row){
states["t" + row.topic_id] = row;
});
}
}
});
Discourse.TopicTrackingState.reopenClass({
createFromStates: function(data){
var instance = Discourse.TopicTrackingState.create();
instance.loadStates(data);
instance.establishChannels();
return instance;
},
current: function(){
if (!this.tracker) {
var data = PreloadStore.get('topicTrackingStates');
this.tracker = this.createFromStates(data);
PreloadStore.remove('topicTrackingStates');
}
return this.tracker;
}
});