FEATURE: Make max number of favorite configurable (#13480)

It used to be hardcoded to 2 and now it uses max_favorite_badges site
setting. When zero, it disables favorite badges.
This commit is contained in:
Bianca Nenciu 2021-06-22 18:58:03 +03:00 committed by GitHub
parent e0e1e24c14
commit ee87d8c93b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 40 additions and 31 deletions

View File

@ -1,19 +1,18 @@
import Controller, { inject as controller } from "@ember/controller";
import { action, computed } from "@ember/object";
import { action } from "@ember/object";
import { alias, filterBy, sort } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
export default Controller.extend({
user: controller(),
username: alias("user.model.username_lower"),
sortedBadges: sort("model", "badgeSortOrder"),
favoriteBadges: filterBy("model", "is_favorite", true),
canFavoriteMoreBadges: computed(
"favoriteBadges.length",
"model.meta.max_favorites",
function () {
return this.favoriteBadges.length < this.model.meta.max_favorites;
}
),
@discourseComputed("favoriteBadges.length")
canFavoriteMoreBadges(favoriteBadgesCount) {
return favoriteBadgesCount < this.siteSettings.max_favorite_badges;
},
init() {
this._super(...arguments);

View File

@ -7,8 +7,6 @@ import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import discourseComputed from "discourse-common/utils/decorators";
const DEFAULT_USER_BADGES_META = { max_favorites: 2 };
const UserBadge = EmberObject.extend({
@discourseComputed
postUrl: function () {
@ -98,7 +96,6 @@ UserBadge.reopenClass({
userBadges.grant_count = json.user_badge_info.grant_count;
userBadges.username = json.user_badge_info.username;
}
userBadges.meta = json.meta || DEFAULT_USER_BADGES_META;
return userBadges;
}
},

View File

@ -1,6 +1,6 @@
{{#d-section pageClass="user-badges" class="user-content user-badges-list"}}
<p class="favorite-count">
{{i18n "badges.favorite_count" count=this.favoriteBadges.length max=model.meta.max_favorites}}
{{i18n "badges.favorite_count" count=this.favoriteBadges.length max=siteSettings.max_favorite_badges}}
</p>
{{#each sortedBadges as |ub|}}
{{badge-card

View File

@ -7,7 +7,7 @@
display: inline-flex;
align-items: center;
background-color: var(--secondary);
margin: 0 0 3px;
margin: 4px 0 0;
img {
height: 16px;

View File

@ -225,8 +225,7 @@ $avatar_margin: -50px; // negative margin makes avatars extend above cards
// badges
.badge-section {
display: flex;
align-items: flex-start;
line-height: 0;
.user-badge {
@include ellipsis;
background: var(--primary-very-low);
@ -236,11 +235,12 @@ $avatar_margin: -50px; // negative margin makes avatars extend above cards
.user-card-badge-link {
overflow: hidden;
}
.user-card-badge-link,
.more-user-badges {
flex: 0 0 auto; // this is more important than other badges, so don't allow it to shrink
a {
@extend .user-badge;
display: inline-block;
}
.more-user-badges a {
@extend .user-badge;
}
}
}

View File

@ -42,7 +42,6 @@
.user-badge {
display: block;
max-width: 185px;
margin: 0 0.5em 0 0;
}
.more-user-badges {
max-width: 125px;

View File

@ -53,6 +53,8 @@ $avatar_width: 120px;
.user-card {
// badges
.badge-section {
display: flex;
align-items: flex-start;
flex-wrap: wrap;
.user-card-badge-link,
.more-user-badges {
@ -61,8 +63,7 @@ $avatar_width: 120px;
max-width: 50%; // for text ellipsis
padding: 2px 0;
box-sizing: border-box;
&:nth-child(1),
&:nth-child(3) {
&:nth-child(odd) {
padding-right: 4px;
}
a {

View File

@ -1,7 +1,6 @@
# frozen_string_literal: true
class UserBadgesController < ApplicationController
MAX_FAVORITES = 2
MAX_BADGES = 96 # This was limited in PR#2360 to make it divisible by 8
before_action :ensure_badges_enabled
@ -51,7 +50,6 @@ class UserBadgesController < ApplicationController
user_badges,
DetailedUserBadgeSerializer,
root: :user_badges,
meta: { max_favorites: MAX_FAVORITES },
)
end
@ -107,7 +105,7 @@ class UserBadgesController < ApplicationController
return render json: failed_json, status: 403
end
if !user_badge.is_favorite && user_badges.where(is_favorite: true).count >= MAX_FAVORITES
if !user_badge.is_favorite && user_badges.where(is_favorite: true).count >= SiteSetting.max_favorite_badges
return render json: failed_json, status: 400
end

View File

@ -73,9 +73,11 @@ class User < ActiveRecord::Base
}, class_name: "UserSecurityKey"
has_many :badges, through: :user_badges
has_many :default_featured_user_badges,
-> { for_enabled_badges.grouped_with_count.where("featured_rank <= ?", DEFAULT_FEATURED_BADGE_COUNT) },
class_name: "UserBadge"
has_many :default_featured_user_badges, -> {
max_featured_rank = SiteSetting.max_favorite_badges > 0 ? SiteSetting.max_favorite_badges + 1
: DEFAULT_FEATURED_BADGE_COUNT
for_enabled_badges.grouped_with_count.where("featured_rank <= ?", max_featured_rank)
}, class_name: "UserBadge"
has_many :topics_allowed, through: :topic_allowed_users, source: :topic
has_many :groups, through: :group_users
@ -1035,8 +1037,8 @@ class User < ActiveRecord::Base
user_stat&.distinct_badge_count
end
def featured_user_badges(limit = DEFAULT_FEATURED_BADGE_COUNT)
if limit == DEFAULT_FEATURED_BADGE_COUNT
def featured_user_badges(limit = nil)
if limit.nil?
default_featured_user_badges
else
user_badges.grouped_with_count.where("featured_rank <= ?", limit)

View File

@ -25,6 +25,7 @@ class DetailedUserBadgeSerializer < BasicUserBadgeSerializer
end
def can_favorite
SiteSetting.max_favorite_badges > 0 &&
(scope.current_user.present? && object.user_id == scope.current_user.id) &&
!(1..4).include?(object.badge_id)
end

View File

@ -1653,6 +1653,7 @@ en:
email_token_valid_hours: "Forgot password / activate account tokens are valid for (n) hours."
enable_badges: "Enable the badge system"
max_favorite_badges: "Maximum number of badges that user can select"
enable_whispers: "Allow staff private communication within topics."
allow_index_in_robots_txt: "Specify in robots.txt that this site is allowed to be indexed by web search engines. In exceptional cases you can permanently <a href='%{base_path}/admin/customize/robots'>override robots.txt</a>."

View File

@ -307,6 +307,11 @@ basic:
client: true
default: false
hidden: true
max_favorite_badges:
client: true
default: 2
min: 0
max: 5
enable_whispers:
client: true
default: false

View File

@ -277,12 +277,18 @@ describe UserBadgesController do
expect(response.status).to eq(403)
end
it "checks that the user has less than two favorited badges" do
it "checks that the user has less than max_favorites_badges favorited badges" do
sign_in(user)
UserBadge.create(badge: Fabricate(:badge), user: user, granted_by: Discourse.system_user, granted_at: Time.now, is_favorite: true)
UserBadge.create(badge: Fabricate(:badge), user: user, granted_by: Discourse.system_user, granted_at: Time.now, is_favorite: true)
put "/user_badges/#{user_badge.id}/toggle_favorite.json"
expect(response.status).to eq(400)
SiteSetting.max_favorite_badges = 3
put "/user_badges/#{user_badge.id}/toggle_favorite.json"
expect(response.status).to eq(200)
end
it "favorites a badge" do