Skip to content
Permalink
Browse files

FEATURE: New route for loading multiple user cards simultaneously (#9078

)

Introduces `/user-cards.json`

Also allows the client-side user model to be passed an existing promise when loading, so that multiple models can share the same AJAX request
  • Loading branch information
davidtaylorhq committed Mar 6, 2020
1 parent 29ccdf5 commit ff62911a89d721ebec1716990c5e407e572d8960
@@ -536,8 +536,12 @@ const User = RestModel.extend({
const user = this;

return PreloadStore.getAndRemove(`user_${user.get("username")}`, () => {
const useCardRoute = options && options.forCard;
if (options && options.existingRequest) {
// Existing ajax request has been passed, use it
return options.existingRequest;
}

const useCardRoute = options && options.forCard;
if (options) delete options.forCard;

const path = useCardRoute
@@ -99,6 +99,30 @@ def show_card
show(for_card: true)
end

def cards
return redirect_to path('/login') if SiteSetting.hide_user_profiles_from_public && !current_user

user_ids = params.require(:user_ids).split(",").map(&:to_i)
raise Discourse::InvalidParameters.new(:user_ids) if user_ids.length > 50

users = User.where(id: user_ids).includes(:user_option,
:user_stat,
:default_featured_user_badges,
:user_profile,
:card_background_upload,
:primary_group,
:primary_email
)

users = users.filter { |u| guardian.can_see_profile?(u) }

preload_fields = User.whitelisted_user_custom_fields(guardian) + UserField.all.pluck(:id).map { |fid| "#{User::USER_FIELD_PREFIX}#{fid}" }
User.preload_custom_fields(users, preload_fields)
User.preload_recent_time_read(users)

render json: users, each_serializer: UserCardSerializer
end

def badges
raise Discourse::NotFound unless SiteSetting.enable_badges?
show
@@ -367,6 +367,8 @@
get "user_preferences" => "users#user_preferences_redirect"
get ".well-known/change-password", to: redirect(relative_url_root + 'my/preferences/account', status: 302)

get "user-cards" => "users#cards", format: :json

%w{users u}.each_with_index do |root_path, index|
get "#{root_path}" => "users#index", constraints: { format: 'html' }

@@ -3052,6 +3052,34 @@ def post_user
end
end

describe "#cards" do
fab!(:user) { Discourse.system_user }
fab!(:user2) { Fabricate(:user) }

it "returns success" do
get "/user-cards.json?user_ids=#{user.id},#{user2.id}"
expect(response.status).to eq(200)
parsed = JSON.parse(response.body)["users"]

expect(parsed.map { |u| u["username"] }).to contain_exactly(user.username, user2.username)
end

it "should redirect to login page for anonymous user when profiles are hidden" do
SiteSetting.hide_user_profiles_from_public = true
get "/user-cards.json?user_ids=#{user.id},#{user2.id}"
expect(response).to redirect_to '/login'
end

it "does not include hidden profiles" do
user2.user_option.update(hide_profile_and_presence: true)
get "/user-cards.json?user_ids=#{user.id},#{user2.id}"
expect(response.status).to eq(200)
parsed = JSON.parse(response.body)["users"]

expect(parsed.map { |u| u["username"] }).to contain_exactly(user.username)
end
end

describe '#badges' do
it "renders fine by default" do
get "/u/#{user.username}/badges"

2 comments on commit ff62911

@discoursebot

This comment has been minimized.

Copy link

@discoursebot discoursebot replied Mar 16, 2020

This commit has been mentioned on Discourse Meta. There might be relevant details there:

https://meta.discourse.org/t/user-card-directory/144479/1

@discoursebot

This comment has been minimized.

Copy link

@discoursebot discoursebot replied Mar 16, 2020

This commit has been mentioned on Discourse Meta. There might be relevant details there:

https://meta.discourse.org/t/adding-user-attributes-to-the-directory-item-serializer/130927/20

Please sign in to comment.
You can’t perform that action at this time.