mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 07:53:49 +08:00
FEATURE: live delete / recover
BUGFIX: total post count could be smaller than filtered posts count BUGFIX: filteredPostsCount not correctly defined
This commit is contained in:
@ -265,6 +265,12 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
|
|||||||
return (this.get('progressPosition') < 2);
|
return (this.get('progressPosition') < 2);
|
||||||
}.property('progressPosition'),
|
}.property('progressPosition'),
|
||||||
|
|
||||||
|
filteredPostCountChanged: function(){
|
||||||
|
if(this.get('postStream.filteredPostsCount') < this.get('progressPosition')){
|
||||||
|
this.set('progressPosition', this.get('postStream.filteredPostsCount'));
|
||||||
|
}
|
||||||
|
}.observes('postStream.filteredPostsCount'),
|
||||||
|
|
||||||
jumpBottomDisabled: function() {
|
jumpBottomDisabled: function() {
|
||||||
return this.get('progressPosition') >= this.get('postStream.filteredPostsCount') ||
|
return this.get('progressPosition') >= this.get('postStream.filteredPostsCount') ||
|
||||||
this.get('progressPosition') >= this.get('highest_post_number');
|
this.get('progressPosition') >= this.get('highest_post_number');
|
||||||
@ -410,6 +416,16 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.type === "deleted"){
|
||||||
|
postStream.triggerDeletedPost(data.id, data.post_number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === "recovered"){
|
||||||
|
postStream.triggerRecoveredPost(data.id, data.post_number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Add the new post into the stream
|
// Add the new post into the stream
|
||||||
postStream.triggerNewPostInStream(data.id);
|
postStream.triggerNewPostInStream(data.id);
|
||||||
});
|
});
|
||||||
|
@ -17,14 +17,18 @@ Discourse.PostStream = Em.Object.extend({
|
|||||||
|
|
||||||
notLoading: Em.computed.not('loading'),
|
notLoading: Em.computed.not('loading'),
|
||||||
|
|
||||||
filteredPostsCount: Em.computed.alias('stream.length'),
|
filteredPostsCount: function(){
|
||||||
|
return this.get("stream").length;
|
||||||
|
}.property("stream.@each"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Have we loaded any posts?
|
Have we loaded any posts?
|
||||||
|
|
||||||
@property hasPosts
|
@property hasPosts
|
||||||
**/
|
**/
|
||||||
hasPosts: Em.computed.gt('posts.length', 0),
|
hasPosts: function(){
|
||||||
|
return this.get('posts.length') > 0;
|
||||||
|
}.property("posts.@each"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Do we have a stream list of post ids?
|
Do we have a stream list of post ids?
|
||||||
@ -55,7 +59,7 @@ Discourse.PostStream = Em.Object.extend({
|
|||||||
firstPostPresent: function() {
|
firstPostPresent: function() {
|
||||||
if (!this.get('hasLoadedData')) { return false; }
|
if (!this.get('hasLoadedData')) { return false; }
|
||||||
return !!this.get('posts').findProperty('id', this.get('firstPostId'));
|
return !!this.get('posts').findProperty('id', this.get('firstPostId'));
|
||||||
}.property('hasLoadedData', 'posts.[]', 'firstPostId'),
|
}.property('hasLoadedData', 'posts.@each', 'firstPostId'),
|
||||||
|
|
||||||
firstPostNotLoaded: Em.computed.not('firstPostPresent'),
|
firstPostNotLoaded: Em.computed.not('firstPostPresent'),
|
||||||
|
|
||||||
@ -480,9 +484,13 @@ Discourse.PostStream = Em.Object.extend({
|
|||||||
if (Em.isEmpty(posts)) { return; }
|
if (Em.isEmpty(posts)) { return; }
|
||||||
|
|
||||||
var postIds = posts.map(function (p) { return p.get('id'); });
|
var postIds = posts.map(function (p) { return p.get('id'); });
|
||||||
|
var identityMap = this.get('postIdentityMap');
|
||||||
|
|
||||||
this.get('stream').removeObjects(postIds);
|
this.get('stream').removeObjects(postIds);
|
||||||
this.get('posts').removeObjects(posts);
|
this.get('posts').removeObjects(posts);
|
||||||
|
postIds.forEach(function(id){
|
||||||
|
identityMap.remove(id);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -518,17 +526,78 @@ Discourse.PostStream = Em.Object.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
triggerRecoveredPost: function(postId){
|
||||||
|
var self = this,
|
||||||
|
postIdentityMap = this.get('postIdentityMap'),
|
||||||
|
existing = postIdentityMap.get(postId);
|
||||||
|
|
||||||
|
if(existing){
|
||||||
|
this.triggerChangedPost(postId, new Date());
|
||||||
|
} else {
|
||||||
|
// need to insert into stream
|
||||||
|
var url = "/posts/" + postId;
|
||||||
|
Discourse.ajax(url).then(function(p){
|
||||||
|
var post = Discourse.Post.create(p);
|
||||||
|
var stream = self.get("stream");
|
||||||
|
var posts = self.get("posts");
|
||||||
|
self.storePost(post);
|
||||||
|
|
||||||
|
// we need to zip this into the stream
|
||||||
|
var index = 0;
|
||||||
|
stream.forEach(function(postId){
|
||||||
|
if(postId < p.id){
|
||||||
|
index+= 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.insertAt(index, p.id);
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
posts.forEach(function(_post){
|
||||||
|
if(_post.id < p.id){
|
||||||
|
index+= 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(index < posts.length){
|
||||||
|
posts.insertAt(index, post);
|
||||||
|
} else {
|
||||||
|
if(post.post_number < posts[posts.length-1].post_number + 5){
|
||||||
|
self.appendMore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
triggerDeletedPost: function(postId){
|
||||||
|
var self = this,
|
||||||
|
postIdentityMap = this.get('postIdentityMap'),
|
||||||
|
existing = postIdentityMap.get(postId);
|
||||||
|
|
||||||
|
if(existing){
|
||||||
|
var url = "/posts/" + postId;
|
||||||
|
Discourse.ajax(url).then(
|
||||||
|
function(p){
|
||||||
|
self.storePost(Discourse.Post.create(p));
|
||||||
|
},
|
||||||
|
function(){
|
||||||
|
self.removePosts([existing]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
triggerChangedPost: function(postId, updatedAt) {
|
triggerChangedPost: function(postId, updatedAt) {
|
||||||
if (!postId) { return; }
|
if (!postId) { return; }
|
||||||
|
|
||||||
var postIdentityMap = this.get('postIdentityMap'),
|
var postIdentityMap = this.get('postIdentityMap'),
|
||||||
existing = postIdentityMap.get(postId),
|
existing = postIdentityMap.get(postId),
|
||||||
postStream = this;
|
self = this;
|
||||||
|
|
||||||
if (existing && existing.updated_at !== updatedAt) {
|
if (existing && existing.updated_at !== updatedAt) {
|
||||||
var url = "/posts/" + postId;
|
var url = "/posts/" + postId;
|
||||||
Discourse.ajax(url).then(function(p){
|
Discourse.ajax(url).then(function(p){
|
||||||
postStream.storePost(Discourse.Post.create(p));
|
self.storePost(Discourse.Post.create(p));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -25,7 +25,7 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
|
|||||||
|
|
||||||
updateBar: function() {
|
updateBar: function() {
|
||||||
Em.run.scheduleOnce('afterRender', this, '_updateProgressBar');
|
Em.run.scheduleOnce('afterRender', this, '_updateProgressBar');
|
||||||
}.observes('controller.streamPercentage'),
|
}.observes('controller.streamPercentage', 'postStream.stream.@each'),
|
||||||
|
|
||||||
_updateProgressBar: function() {
|
_updateProgressBar: function() {
|
||||||
var $topicProgress = this._topicProgress;
|
var $topicProgress = this._topicProgress;
|
||||||
|
@ -48,6 +48,7 @@ class PostDestroyer
|
|||||||
|
|
||||||
def staff_recovered
|
def staff_recovered
|
||||||
@post.recover!
|
@post.recover!
|
||||||
|
publish("recovered")
|
||||||
end
|
end
|
||||||
|
|
||||||
# When a post is properly deleted. Well, it's still soft deleted, but it will no longer
|
# When a post is properly deleted. Well, it's still soft deleted, but it will no longer
|
||||||
@ -68,6 +69,21 @@ class PostDestroyer
|
|||||||
@post.topic.trash!(@user) if @post.topic and @post.post_number == 1
|
@post.topic.trash!(@user) if @post.topic and @post.post_number == 1
|
||||||
update_associated_category_latest_topic
|
update_associated_category_latest_topic
|
||||||
end
|
end
|
||||||
|
publish("deleted")
|
||||||
|
end
|
||||||
|
|
||||||
|
def publish(message)
|
||||||
|
# edge case, topic is already destroyed
|
||||||
|
return unless @post.topic
|
||||||
|
|
||||||
|
MessageBus.publish("/topic/#{@post.topic_id}",{
|
||||||
|
id: @post.id,
|
||||||
|
post_number: @post.post_number,
|
||||||
|
updated_at: @post.updated_at,
|
||||||
|
type: message
|
||||||
|
},
|
||||||
|
group_ids: @post.topic.secure_group_ids
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# When a user 'deletes' their own post. We just change the text.
|
# When a user 'deletes' their own post. We just change the text.
|
||||||
|
Reference in New Issue
Block a user