mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 22:43:33 +08:00
FIX: Select+below will ask server for post ids on megatopics.
This commit is contained in:
@ -152,6 +152,35 @@ export default Ember.Controller.extend(BufferedContent, {
|
|||||||
this.appEvents.trigger("post-stream:refresh", { force: true });
|
this.appEvents.trigger("post-stream:refresh", { force: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateSelectedPostIds(postIds) {
|
||||||
|
this.get("selectedPostIds").pushObjects(postIds);
|
||||||
|
this.set("selectedPostIds", [...new Set(this.get("selectedPostIds"))]);
|
||||||
|
this._forceRefreshPostStream();
|
||||||
|
},
|
||||||
|
|
||||||
|
_loadPostIds(post) {
|
||||||
|
if (this.get("loadingPostIds")) return;
|
||||||
|
|
||||||
|
const postStream = this.get("model.postStream");
|
||||||
|
const url = `/t/${this.get("model.id")}/post_ids.json`;
|
||||||
|
|
||||||
|
this.set("loadingPostIds", true);
|
||||||
|
|
||||||
|
return ajax(url, {
|
||||||
|
data: _.merge(
|
||||||
|
{ post_number: post.get("post_number") },
|
||||||
|
postStream.get("streamFilters")
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
result.post_ids.pushObject(post.get("id"));
|
||||||
|
this._updateSelectedPostIds(result.post_ids);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.set("loadingPostIds", false);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
showPostFlags(post) {
|
showPostFlags(post) {
|
||||||
return this.send("showFlags", post);
|
return this.send("showFlags", post);
|
||||||
@ -627,10 +656,13 @@ export default Ember.Controller.extend(BufferedContent, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
selectBelow(post) {
|
selectBelow(post) {
|
||||||
const stream = [...this.get("model.postStream.stream")];
|
if (this.get("model.postStream.isMegaTopic")) {
|
||||||
const below = stream.slice(stream.indexOf(post.id));
|
this._loadPostIds(post);
|
||||||
this.get("selectedPostIds").pushObjects(below);
|
} else {
|
||||||
this._forceRefreshPostStream();
|
const stream = [...this.get("model.postStream.stream")];
|
||||||
|
const below = stream.slice(stream.indexOf(post.id));
|
||||||
|
this._updateSelectedPostIds(below);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteSelected() {
|
deleteSelected() {
|
||||||
|
@ -175,22 +175,34 @@ class TopicsController < ApplicationController
|
|||||||
render_json_dump(wordpress_serializer)
|
render_json_dump(wordpress_serializer)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def post_ids
|
||||||
|
params.require(:topic_id)
|
||||||
|
params.permit(:post_number, :username_filters, :filter)
|
||||||
|
|
||||||
|
options = {
|
||||||
|
filter_post_number: params[:post_number],
|
||||||
|
filter: params[:filter],
|
||||||
|
skip_limit: true,
|
||||||
|
asc: true,
|
||||||
|
skip_custom_fields: true
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch_topic_view(options)
|
||||||
|
render_json_dump(post_ids: @topic_view.posts.pluck(:id))
|
||||||
|
end
|
||||||
|
|
||||||
def posts
|
def posts
|
||||||
params.require(:topic_id)
|
params.require(:topic_id)
|
||||||
params.permit(:post_ids, :post_number, :username_filters, :filter)
|
params.permit(:post_ids, :post_number, :username_filters, :filter)
|
||||||
|
|
||||||
default_options = {
|
options = {
|
||||||
filter_post_number: params[:post_number],
|
filter_post_number: params[:post_number],
|
||||||
post_ids: params[:post_ids],
|
post_ids: params[:post_ids],
|
||||||
asc: ActiveRecord::Type::Boolean.new.deserialize(params[:asc]),
|
asc: ActiveRecord::Type::Boolean.new.deserialize(params[:asc]),
|
||||||
filter: params[:filter]
|
filter: params[:filter]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (username_filters = params[:username_filters]).present?
|
fetch_topic_view(options)
|
||||||
default_options[:username_filters] = username_filters.split(',')
|
|
||||||
end
|
|
||||||
|
|
||||||
@topic_view = TopicView.new(params[:topic_id], current_user, default_options)
|
|
||||||
|
|
||||||
render_json_dump(TopicViewPostsSerializer.new(@topic_view,
|
render_json_dump(TopicViewPostsSerializer.new(@topic_view,
|
||||||
scope: guardian,
|
scope: guardian,
|
||||||
@ -714,6 +726,17 @@ class TopicsController < ApplicationController
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fetch_topic_view(options)
|
||||||
|
check_username_filters { |usernames| options[:username_filters] = usernames }
|
||||||
|
@topic_view = TopicView.new(params[:topic_id], current_user, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_username_filters
|
||||||
|
if (username_filters = params[:username_filters]).present?
|
||||||
|
yield(username_filters.split(',')) if block_given?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def toggle_mute
|
def toggle_mute
|
||||||
@topic = Topic.find_by(id: params[:topic_id].to_i)
|
@topic = Topic.find_by(id: params[:topic_id].to_i)
|
||||||
guardian.ensure_can_see!(@topic)
|
guardian.ensure_can_see!(@topic)
|
||||||
|
@ -680,6 +680,7 @@ Discourse::Application.routes.draw do
|
|||||||
get "t/:slug/:topic_id/:post_number" => "topics#show", constraints: { topic_id: /\d+/, post_number: /\d+/ }
|
get "t/:slug/:topic_id/:post_number" => "topics#show", constraints: { topic_id: /\d+/, post_number: /\d+/ }
|
||||||
get "t/:slug/:topic_id/last" => "topics#show", post_number: 99999999, constraints: { topic_id: /\d+/ }
|
get "t/:slug/:topic_id/last" => "topics#show", post_number: 99999999, constraints: { topic_id: /\d+/ }
|
||||||
get "t/:topic_id/posts" => "topics#posts", constraints: { topic_id: /\d+/ }, format: :json
|
get "t/:topic_id/posts" => "topics#posts", constraints: { topic_id: /\d+/ }, format: :json
|
||||||
|
get "t/:topic_id/post_ids" => "topics#post_ids", constraints: { topic_id: /\d+/ }, format: :json
|
||||||
get "t/:topic_id/excerpts" => "topics#excerpts", constraints: { topic_id: /\d+/ }, format: :json
|
get "t/:topic_id/excerpts" => "topics#excerpts", constraints: { topic_id: /\d+/ }, format: :json
|
||||||
post "t/:topic_id/timings" => "topics#timings", constraints: { topic_id: /\d+/ }
|
post "t/:topic_id/timings" => "topics#timings", constraints: { topic_id: /\d+/ }
|
||||||
post "t/:topic_id/invite" => "topics#invite", constraints: { topic_id: /\d+/ }
|
post "t/:topic_id/invite" => "topics#invite", constraints: { topic_id: /\d+/ }
|
||||||
|
@ -71,7 +71,7 @@ class TopicView
|
|||||||
|
|
||||||
filter_posts(options)
|
filter_posts(options)
|
||||||
|
|
||||||
if @posts
|
if @posts && !@skip_custom_fields
|
||||||
if (added_fields = User.whitelisted_user_custom_fields(@guardian)).present?
|
if (added_fields = User.whitelisted_user_custom_fields(@guardian)).present?
|
||||||
@user_custom_fields = User.custom_fields_for_ids(@posts.pluck(:user_id), added_fields)
|
@user_custom_fields = User.custom_fields_for_ids(@posts.pluck(:user_id), added_fields)
|
||||||
end
|
end
|
||||||
@ -534,7 +534,7 @@ class TopicView
|
|||||||
.order(sort_order: :desc)
|
.order(sort_order: :desc)
|
||||||
end
|
end
|
||||||
|
|
||||||
posts = posts.limit(@limit)
|
posts = posts.limit(@limit) if !@skip_limit
|
||||||
filter_posts_by_ids(posts.pluck(:id))
|
filter_posts_by_ids(posts.pluck(:id))
|
||||||
|
|
||||||
@posts = @posts.unscope(:order).order(sort_order: :desc) if !asc
|
@posts = @posts.unscope(:order).order(sort_order: :desc) if !asc
|
||||||
|
@ -1451,6 +1451,70 @@ RSpec.describe TopicsController do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#post_ids' do
|
||||||
|
let(:post) { Fabricate(:post) }
|
||||||
|
let(:topic) { post.topic }
|
||||||
|
|
||||||
|
before do
|
||||||
|
TopicView.stubs(:chunk_size).returns(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the right post ids' do
|
||||||
|
post2 = Fabricate(:post, topic: topic)
|
||||||
|
post3 = Fabricate(:post, topic: topic)
|
||||||
|
|
||||||
|
get "/t/#{topic.id}/post_ids.json", params: {
|
||||||
|
post_number: post.post_number
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
body = JSON.parse(response.body)
|
||||||
|
|
||||||
|
expect(body["post_ids"]).to eq([post2.id, post3.id])
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'filtering by post number with filters' do
|
||||||
|
describe 'username filters' do
|
||||||
|
let(:user) { Fabricate(:user) }
|
||||||
|
let(:post) { Fabricate(:post, user: user) }
|
||||||
|
let!(:post2) { Fabricate(:post, topic: topic, user: user) }
|
||||||
|
let!(:post3) { Fabricate(:post, topic: topic) }
|
||||||
|
|
||||||
|
it 'should return the right posts' do
|
||||||
|
get "/t/#{topic.id}/post_ids.json", params: {
|
||||||
|
post_number: post.post_number,
|
||||||
|
username_filters: post2.user.username
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
body = JSON.parse(response.body)
|
||||||
|
|
||||||
|
expect(body["post_ids"]).to eq([post2.id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'summary filter' do
|
||||||
|
let!(:post2) { Fabricate(:post, topic: topic, percent_rank: 0.2) }
|
||||||
|
let!(:post3) { Fabricate(:post, topic: topic) }
|
||||||
|
|
||||||
|
it 'should return the right posts' do
|
||||||
|
get "/t/#{topic.id}/post_ids.json", params: {
|
||||||
|
post_number: post.post_number,
|
||||||
|
filter: 'summary'
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
body = JSON.parse(response.body)
|
||||||
|
|
||||||
|
expect(body["post_ids"]).to eq([post2.id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#posts' do
|
describe '#posts' do
|
||||||
let(:post) { Fabricate(:post) }
|
let(:post) { Fabricate(:post) }
|
||||||
let(:topic) { post.topic }
|
let(:topic) { post.topic }
|
||||||
|
@ -264,3 +264,26 @@ QUnit.test("selecting posts", async assert => {
|
|||||||
"it should hide the multi select menu"
|
"it should hide the multi select menu"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test("select below", async assert => {
|
||||||
|
await visit("/t/internationalization-localization/280");
|
||||||
|
await click(".toggle-admin-menu");
|
||||||
|
await click(".topic-admin-multi-select .btn");
|
||||||
|
await click("#post_3 .select-below");
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
find(".selected-posts")
|
||||||
|
.html()
|
||||||
|
.includes(I18n.t("topic.multi_select.description", { count: 18 })),
|
||||||
|
"it should select the right number of posts"
|
||||||
|
);
|
||||||
|
|
||||||
|
await click("#post_2 .select-below");
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
find(".selected-posts")
|
||||||
|
.html()
|
||||||
|
.includes(I18n.t("topic.multi_select.description", { count: 19 })),
|
||||||
|
"it should select the right number of posts"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
Reference in New Issue
Block a user