mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 09:26:54 -06:00
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:
parent
e0e1e24c14
commit
ee87d8c93b
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,6 @@
|
||||
.user-badge {
|
||||
display: block;
|
||||
max-width: 185px;
|
||||
margin: 0 0.5em 0 0;
|
||||
}
|
||||
.more-user-badges {
|
||||
max-width: 125px;
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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>."
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user