mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
commit
56a04366ec
@ -8,6 +8,8 @@
|
|||||||
@module Discourse
|
@module Discourse
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
var RESERVED_BADGE_COUNT = 100;
|
||||||
|
|
||||||
Discourse.AdminBadgeController = Discourse.ObjectController.extend({
|
Discourse.AdminBadgeController = Discourse.ObjectController.extend({
|
||||||
/**
|
/**
|
||||||
Whether this badge has been selected.
|
Whether this badge has been selected.
|
||||||
@ -31,5 +33,5 @@ Discourse.AdminBadgeController = Discourse.ObjectController.extend({
|
|||||||
@property readOnly
|
@property readOnly
|
||||||
@type {Boolean}
|
@type {Boolean}
|
||||||
**/
|
**/
|
||||||
readOnly: Ember.computed.lt('model.id', 100)
|
readOnly: Ember.computed.lt('model.id', RESERVED_BADGE_COUNT)
|
||||||
});
|
});
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div>
|
<div>
|
||||||
<label for="name">{{i18n admin.badges.name}}</label>
|
<label for="name">{{i18n admin.badges.name}}</label>
|
||||||
{{input type="text" name="name" value=name disabled=readOnly}}
|
{{input type="text" name="name" value=name disabled=readonly}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if showDisplayName}}
|
{{#if showDisplayName}}
|
||||||
@ -33,6 +33,11 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="name">{{i18n admin.badges.icon}}</label>
|
||||||
|
{{input type="text" name="name" value=icon disabled=readonly}}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="badge_type_id">{{i18n admin.badges.badge_type}}</label>
|
<label for="badge_type_id">{{i18n admin.badges.badge_type}}</label>
|
||||||
{{view Ember.Select name="badge_type_id" value=badge_type_id
|
{{view Ember.Select name="badge_type_id" value=badge_type_id
|
||||||
|
@ -7,5 +7,7 @@ export default Ember.Component.extend({
|
|||||||
|
|
||||||
showGrantCount: function() {
|
showGrantCount: function() {
|
||||||
return this.get('count') && this.get('count') > 1;
|
return this.get('count') && this.get('count') > 1;
|
||||||
}.property('count')
|
}.property('count'),
|
||||||
|
|
||||||
|
isIcon: Em.computed.match('badge.icon', /^fa-/)
|
||||||
});
|
});
|
||||||
|
@ -116,7 +116,8 @@ Discourse.Badge = Discourse.Model.extend({
|
|||||||
description: this.get('description'),
|
description: this.get('description'),
|
||||||
badge_type_id: this.get('badge_type_id'),
|
badge_type_id: this.get('badge_type_id'),
|
||||||
allow_title: !!this.get('allow_title'),
|
allow_title: !!this.get('allow_title'),
|
||||||
multiple_grant: !!this.get('multiple_grant')
|
multiple_grant: !!this.get('multiple_grant'),
|
||||||
|
icon: this.get('icon')
|
||||||
}
|
}
|
||||||
}).then(function(json) {
|
}).then(function(json) {
|
||||||
self.updateFromJson(json);
|
self.updateFromJson(json);
|
||||||
|
@ -84,8 +84,8 @@ Discourse.UserBadge.reopenClass({
|
|||||||
**/
|
**/
|
||||||
findByUsername: function(username, options) {
|
findByUsername: function(username, options) {
|
||||||
var url = "/user_badges.json?username=" + username;
|
var url = "/user_badges.json?username=" + username;
|
||||||
if (options && options.aggregated) {
|
if (options && options.grouped) {
|
||||||
url += "&aggregated=true";
|
url += "&grouped=true";
|
||||||
}
|
}
|
||||||
return Discourse.ajax(url).then(function(json) {
|
return Discourse.ajax(url).then(function(json) {
|
||||||
return Discourse.UserBadge.createFromJson(json);
|
return Discourse.UserBadge.createFromJson(json);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
**/
|
**/
|
||||||
Discourse.UserBadgesRoute = Discourse.Route.extend({
|
Discourse.UserBadgesRoute = Discourse.Route.extend({
|
||||||
model: function() {
|
model: function() {
|
||||||
return Discourse.UserBadge.findByUsername(this.modelFor('user').get('username_lower'), {aggregated: true});
|
return Discourse.UserBadge.findByUsername(this.modelFor('user').get('username_lower'), {grouped: true});
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController: function(controller, model) {
|
setupController: function(controller, model) {
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
<h1>{{i18n badges.title}}</h1>
|
<h1>{{i18n badges.title}}</h1>
|
||||||
|
|
||||||
<table class='badges-listing'>
|
<table class='badges-listing'>
|
||||||
{{#each}}
|
<tbody>
|
||||||
<tr>
|
{{#each}}
|
||||||
<td class='badge'>{{user-badge badge=this}}</td>
|
<tr>
|
||||||
<td class='description'>{{displayDescription}}</td>
|
<td class='badge'>{{user-badge badge=this}}</td>
|
||||||
<td class='grant-count'>{{i18n badges.granted count=grant_count}}</td>
|
<td class='description'>{{displayDescription}}</td>
|
||||||
</tr>
|
<td class='grant-count'>{{i18n badges.granted count=grant_count}}</td>
|
||||||
{{/each}}
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,11 +6,13 @@
|
|||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<table class='badges-listing'>
|
<table class='badges-listing'>
|
||||||
<tr>
|
<tbody>
|
||||||
<td class='badge'>{{user-badge badge=this}}</td>
|
<tr>
|
||||||
<td class='description'>{{displayDescription}}</td>
|
<td class='badge'>{{user-badge badge=this}}</td>
|
||||||
<td class='grant-count'>{{i18n badges.granted count=grant_count}}</td>
|
<td class='description'>{{displayDescription}}</td>
|
||||||
</tr>
|
<td class='grant-count'>{{i18n badges.granted count=grant_count}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
{{#if userBadges}}
|
{{#if userBadges}}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
{{#link-to 'badges.show' badge}}
|
{{#link-to 'badges.show' badge}}
|
||||||
<span {{bind-attr class=":user-badge badgeTypeClassName" data-badge-name="badge.name" title="badge.displayDescription"}}>
|
<span {{bind-attr class=":user-badge badgeTypeClassName" data-badge-name="badge.name" title="badge.displayDescription"}}>
|
||||||
<i class='fa fa-certificate'></i>
|
{{#if isIcon}}
|
||||||
|
<i {{bind-attr class=":fa badge.icon"}}></i>
|
||||||
|
{{else}}
|
||||||
|
<img {{bind-attr src="badge.icon"}}>
|
||||||
|
{{/if}}
|
||||||
{{badge.displayName}}
|
{{badge.displayName}}
|
||||||
{{#if showGrantCount}}
|
{{#if showGrantCount}}
|
||||||
<span class="count">(× {{count}})</span>
|
<span class="count">(× {{count}})</span>
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
&.badge-type-gold .fa {
|
&.badge-type-gold .fa {
|
||||||
color: #ffd700;
|
color: #ffd700;
|
||||||
}
|
}
|
||||||
@ -46,6 +51,12 @@
|
|||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: inline-block;
|
||||||
|
width: 55px;
|
||||||
|
height: 55px;
|
||||||
|
}
|
||||||
|
|
||||||
.count {
|
.count {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
|
@ -36,6 +36,7 @@ class Admin::BadgesController < Admin::AdminController
|
|||||||
badge.badge_type = BadgeType.find(params[:badge_type_id])
|
badge.badge_type = BadgeType.find(params[:badge_type_id])
|
||||||
badge.allow_title = params[:allow_title]
|
badge.allow_title = params[:allow_title]
|
||||||
badge.multiple_grant = params[:multiple_grant]
|
badge.multiple_grant = params[:multiple_grant]
|
||||||
|
badge.icon = params[:icon]
|
||||||
badge
|
badge
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -16,6 +16,14 @@ class BadgesController < ApplicationController
|
|||||||
def show
|
def show
|
||||||
params.require(:id)
|
params.require(:id)
|
||||||
badge = Badge.find(params[:id])
|
badge = Badge.find(params[:id])
|
||||||
|
|
||||||
|
if current_user
|
||||||
|
user_badge = UserBadge.find_by(user_id: current_user.id, badge_id: badge.id)
|
||||||
|
if user_badge && user_badge.notification
|
||||||
|
user_badge.notification.update_attributes read: true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
serialized = MultiJson.dump(serialize_data(badge, BadgeSerializer, root: "badge"))
|
serialized = MultiJson.dump(serialize_data(badge, BadgeSerializer, root: "badge"))
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
|
@ -16,7 +16,7 @@ class UserBadgesController < ApplicationController
|
|||||||
|
|
||||||
user_badges = user_badges.includes(:user, :granted_by, badge: :badge_type)
|
user_badges = user_badges.includes(:user, :granted_by, badge: :badge_type)
|
||||||
|
|
||||||
if params[:aggregated]
|
if params[:grouped]
|
||||||
user_badges = user_badges.group(:badge_id).select(UserBadge.attribute_names.map {|x| "MAX(#{x}) as #{x}" }, 'COUNT(*) as count')
|
user_badges = user_badges.group(:badge_id).select(UserBadge.attribute_names.map {|x| "MAX(#{x}) as #{x}" }, 'COUNT(*) as count')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
42
app/jobs/regular/update_badges.rb
Normal file
42
app/jobs/regular/update_badges.rb
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
module Jobs
|
||||||
|
class UpdateBadges < Jobs::Base
|
||||||
|
|
||||||
|
def execute(args)
|
||||||
|
self.send(args[:action], args)
|
||||||
|
end
|
||||||
|
|
||||||
|
def trust_level_change(args)
|
||||||
|
user = User.find(args[:user_id])
|
||||||
|
trust_level = user.trust_level
|
||||||
|
Badge.trust_level_badge_ids.each do |badge_id|
|
||||||
|
user_badge = UserBadge.find_by(user_id: user.id, badge_id: badge_id)
|
||||||
|
if user_badge
|
||||||
|
# Revoke the badge if trust level was lowered.
|
||||||
|
BadgeGranter.revoke(user_badge) if trust_level < badge_id
|
||||||
|
else
|
||||||
|
# Grant the badge if trust level was increased.
|
||||||
|
badge = Badge.find(badge_id)
|
||||||
|
BadgeGranter.grant(badge, user) if trust_level >= badge_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def post_like(args)
|
||||||
|
post = Post.find(args[:post_id])
|
||||||
|
user = post.user
|
||||||
|
|
||||||
|
# Grant "Welcome" badge to the user if they do not already have it.
|
||||||
|
BadgeGranter.grant(Badge.find(5), user)
|
||||||
|
|
||||||
|
[{id: 6, count: 10}, {id: 7, count: 25}, {id: 8, count: 100}].each do |b|
|
||||||
|
if post.like_count >= b[:count]
|
||||||
|
BadgeGranter.grant(Badge.find(b[:id]), user, post_id: post.id)
|
||||||
|
else
|
||||||
|
user_badge = UserBadge.find_by(badge_id: b[:id], user_id: user.id, post_id: post.id)
|
||||||
|
user_badge && BadgeGranter.revoke(user_badge)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
@ -35,6 +35,7 @@ end
|
|||||||
# updated_at :datetime
|
# updated_at :datetime
|
||||||
# allow_title :boolean default(FALSE), not null
|
# allow_title :boolean default(FALSE), not null
|
||||||
# multiple_grant :boolean default(FALSE), not null
|
# multiple_grant :boolean default(FALSE), not null
|
||||||
|
# icon :string(255) default("fa-certificate")
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
|
@ -131,13 +131,19 @@ class PostAction < ActiveRecord::Base
|
|||||||
post.topic.posts_count != 1
|
post.topic.posts_count != 1
|
||||||
end
|
end
|
||||||
|
|
||||||
create( post_id: post.id,
|
post_action = create( post_id: post.id,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
post_action_type_id: post_action_type_id,
|
post_action_type_id: post_action_type_id,
|
||||||
message: opts[:message],
|
message: opts[:message],
|
||||||
staff_took_action: opts[:take_action] || false,
|
staff_took_action: opts[:take_action] || false,
|
||||||
related_post_id: related_post_id,
|
related_post_id: related_post_id,
|
||||||
targets_topic: !!targets_topic )
|
targets_topic: !!targets_topic )
|
||||||
|
|
||||||
|
if post_action && post_action.is_like?
|
||||||
|
BadgeGranter.update_badges(action: :post_like, post_id: post.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
post_action
|
||||||
|
|
||||||
rescue ActiveRecord::RecordNotUnique
|
rescue ActiveRecord::RecordNotUnique
|
||||||
# can happen despite being .create
|
# can happen despite being .create
|
||||||
|
@ -2,22 +2,33 @@ class UserBadge < ActiveRecord::Base
|
|||||||
belongs_to :badge
|
belongs_to :badge
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :granted_by, class_name: 'User'
|
belongs_to :granted_by, class_name: 'User'
|
||||||
|
belongs_to :notification, dependent: :destroy
|
||||||
|
|
||||||
validates :badge_id, presence: true, uniqueness: {scope: :user_id}, if: 'badge.single_grant?'
|
validates :badge_id, presence: true, uniqueness: {scope: :user_id}, if: 'badge.single_grant?'
|
||||||
validates :user_id, presence: true
|
validates :user_id, presence: true
|
||||||
validates :granted_at, presence: true
|
validates :granted_at, presence: true
|
||||||
validates :granted_by, presence: true
|
validates :granted_by, presence: true
|
||||||
|
|
||||||
|
after_create do
|
||||||
|
Badge.increment_counter 'grant_count', self.badge_id
|
||||||
|
end
|
||||||
|
|
||||||
|
after_destroy do
|
||||||
|
Badge.decrement_counter 'grant_count', self.badge_id
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
#
|
#
|
||||||
# Table name: user_badges
|
# Table name: user_badges
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# badge_id :integer not null
|
# badge_id :integer not null
|
||||||
# user_id :integer not null
|
# user_id :integer not null
|
||||||
# granted_at :datetime not null
|
# granted_at :datetime not null
|
||||||
# granted_by_id :integer not null
|
# granted_by_id :integer not null
|
||||||
|
# post_id :integer
|
||||||
|
# notification_id :integer
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
class BadgeSerializer < ApplicationSerializer
|
class BadgeSerializer < ApplicationSerializer
|
||||||
attributes :id, :name, :description, :grant_count, :allow_title, :multiple_grant
|
attributes :id, :name, :description, :grant_count, :allow_title, :multiple_grant, :icon
|
||||||
|
|
||||||
has_one :badge_type
|
has_one :badge_type
|
||||||
end
|
end
|
||||||
|
@ -3,6 +3,7 @@ class BadgeGranter
|
|||||||
def initialize(badge, user, opts={})
|
def initialize(badge, user, opts={})
|
||||||
@badge, @user, @opts = badge, user, opts
|
@badge, @user, @opts = badge, user, opts
|
||||||
@granted_by = opts[:granted_by] || Discourse.system_user
|
@granted_by = opts[:granted_by] || Discourse.system_user
|
||||||
|
@post_id = opts[:post_id]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.grant(badge, user, opts={})
|
def self.grant(badge, user, opts={})
|
||||||
@ -12,22 +13,22 @@ class BadgeGranter
|
|||||||
def grant
|
def grant
|
||||||
return if @granted_by and !Guardian.new(@granted_by).can_grant_badges?(@user)
|
return if @granted_by and !Guardian.new(@granted_by).can_grant_badges?(@user)
|
||||||
|
|
||||||
user_badge = UserBadge.find_by(badge_id: @badge.id, user_id: @user.id)
|
user_badge = UserBadge.find_by(badge_id: @badge.id, user_id: @user.id, post_id: @post_id)
|
||||||
|
|
||||||
if user_badge.nil? || @badge.multiple_grant?
|
if user_badge.nil? || @badge.multiple_grant?
|
||||||
UserBadge.transaction do
|
UserBadge.transaction do
|
||||||
user_badge = UserBadge.create!(badge: @badge, user: @user,
|
user_badge = UserBadge.create!(badge: @badge, user: @user,
|
||||||
granted_by: @granted_by, granted_at: Time.now)
|
granted_by: @granted_by,
|
||||||
|
granted_at: Time.now,
|
||||||
|
post_id: @post_id)
|
||||||
|
|
||||||
Badge.increment_counter 'grant_count', @badge.id
|
|
||||||
if @granted_by != Discourse.system_user
|
if @granted_by != Discourse.system_user
|
||||||
StaffActionLogger.new(@granted_by).log_badge_grant(user_badge)
|
StaffActionLogger.new(@granted_by).log_badge_grant(user_badge)
|
||||||
end
|
end
|
||||||
|
|
||||||
if SiteSetting.enable_badges?
|
if SiteSetting.enable_badges?
|
||||||
@user.notifications.create(notification_type: Notification.types[:granted_badge],
|
notification = @user.notifications.create(notification_type: Notification.types[:granted_badge], data: { badge_id: @badge.id, badge_name: @badge.name }.to_json)
|
||||||
data: { badge_id: @badge.id,
|
user_badge.update_attributes notification_id: notification.id
|
||||||
badge_name: @badge.name }.to_json)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -38,7 +39,6 @@ class BadgeGranter
|
|||||||
def self.revoke(user_badge, options={})
|
def self.revoke(user_badge, options={})
|
||||||
UserBadge.transaction do
|
UserBadge.transaction do
|
||||||
user_badge.destroy!
|
user_badge.destroy!
|
||||||
Badge.decrement_counter 'grant_count', user_badge.badge_id
|
|
||||||
if options[:revoked_by]
|
if options[:revoked_by]
|
||||||
StaffActionLogger.new(options[:revoked_by]).log_badge_revoke(user_badge)
|
StaffActionLogger.new(options[:revoked_by]).log_badge_revoke(user_badge)
|
||||||
end
|
end
|
||||||
@ -48,30 +48,11 @@ class BadgeGranter
|
|||||||
user_badge.user.title = nil
|
user_badge.user.title = nil
|
||||||
user_badge.user.save!
|
user_badge.user.save!
|
||||||
end
|
end
|
||||||
|
|
||||||
# Delete notification -- This is inefficient, but not very easy to optimize
|
|
||||||
# unless the data hash is converted into a hstore.
|
|
||||||
notification = user_badge.user.notifications.where(notification_type: Notification.types[:granted_badge]).where("data LIKE ?", "%" + user_badge.badge_id.to_s + "%").select {|n| n.data_hash["badge_id"] == user_badge.badge_id }.first
|
|
||||||
notification && notification.destroy
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.update_badges(user, opts={})
|
def self.update_badges(args)
|
||||||
if opts.has_key?(:trust_level)
|
Jobs.enqueue(:update_badges, args)
|
||||||
# Update trust level badges.
|
|
||||||
trust_level = opts[:trust_level]
|
|
||||||
Badge.trust_level_badge_ids.each do |badge_id|
|
|
||||||
user_badge = UserBadge.find_by(user_id: user.id, badge_id: badge_id)
|
|
||||||
if user_badge
|
|
||||||
# Revoke the badge if trust level was lowered.
|
|
||||||
BadgeGranter.revoke(user_badge) if trust_level < badge_id
|
|
||||||
else
|
|
||||||
# Grant the badge if trust level was increased.
|
|
||||||
badge = Badge.find(badge_id)
|
|
||||||
BadgeGranter.grant(badge, user) if trust_level >= badge_id
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1856,6 +1856,7 @@ en:
|
|||||||
no_badges: There are no badges that can be granted.
|
no_badges: There are no badges that can be granted.
|
||||||
allow_title: Allow badge to be used as a title
|
allow_title: Allow badge to be used as a title
|
||||||
multiple_grant: Can be granted multiple times
|
multiple_grant: Can be granted multiple times
|
||||||
|
icon: Icon
|
||||||
|
|
||||||
lightbox:
|
lightbox:
|
||||||
download: "download"
|
download: "download"
|
||||||
@ -1926,3 +1927,15 @@ en:
|
|||||||
elder:
|
elder:
|
||||||
name: Elder
|
name: Elder
|
||||||
description: Granted global edit, pin, close, archive, split and merge.
|
description: Granted global edit, pin, close, archive, split and merge.
|
||||||
|
welcome:
|
||||||
|
name: Welcome
|
||||||
|
description: Received a like.
|
||||||
|
nice_post:
|
||||||
|
name: Nice Post
|
||||||
|
description: Received 10 likes on a post.
|
||||||
|
good_post:
|
||||||
|
name: Good Post
|
||||||
|
description: Received 25 likes on a post.
|
||||||
|
great_post:
|
||||||
|
name: Great Post
|
||||||
|
description: Received 100 likes on a post.
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
# Trust level system badges.
|
||||||
trust_level_badges = [
|
trust_level_badges = [
|
||||||
{id: 1, name: "Basic User", type: 3},
|
{id: 1, name: "Basic User", type: 3},
|
||||||
{id: 2, name: "Regular User", type: 3},
|
{id: 2, name: "Regular User", type: 3},
|
||||||
@ -44,3 +45,29 @@ SQL
|
|||||||
|
|
||||||
Badge.where(id: Badge.trust_level_badge_ids).each {|badge| badge.reset_grant_count! }
|
Badge.where(id: Badge.trust_level_badge_ids).each {|badge| badge.reset_grant_count! }
|
||||||
end
|
end
|
||||||
|
#
|
||||||
|
# Like system badges.
|
||||||
|
like_badges = [
|
||||||
|
{id: 5, name: "Welcome", type: 3, multiple: false},
|
||||||
|
{id: 6, name: "Nice Post", type: 3, multiple: true},
|
||||||
|
{id: 7, name: "Good Post", type: 2, multiple: true},
|
||||||
|
{id: 8, name: "Great Post", type: 1, multiple: true}
|
||||||
|
]
|
||||||
|
|
||||||
|
like_badges.each do |spec|
|
||||||
|
Badge.seed do |b|
|
||||||
|
b.id = spec[:id]
|
||||||
|
b.name = spec[:name]
|
||||||
|
b.badge_type_id = spec[:type]
|
||||||
|
b.multiple_grant = spec[:multiple]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create an example badge if one does not already exist.
|
||||||
|
if Badge.find_by(id: 101).nil?
|
||||||
|
Badge.seed do |b|
|
||||||
|
b.id = 101
|
||||||
|
b.name = "Example Badge"
|
||||||
|
b.badge_type_id = 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
5
db/migrate/20140610012414_add_post_id_to_user_badges.rb
Normal file
5
db/migrate/20140610012414_add_post_id_to_user_badges.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
class AddPostIdToUserBadges < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :user_badges, :post_id, :integer
|
||||||
|
end
|
||||||
|
end
|
5
db/migrate/20140610012833_add_icon_to_badges.rb
Normal file
5
db/migrate/20140610012833_add_icon_to_badges.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
class AddIconToBadges < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :badges, :icon, :string, default: "fa-certificate"
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddNotificationIdToUserBadge < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :user_badges, :notification_id, :integer
|
||||||
|
end
|
||||||
|
end
|
@ -60,7 +60,7 @@ class Promotion
|
|||||||
@user.user_profile.recook_bio
|
@user.user_profile.recook_bio
|
||||||
@user.user_profile.save!
|
@user.user_profile.save!
|
||||||
Group.user_trust_level_change!(@user.id, @user.trust_level)
|
Group.user_trust_level_change!(@user.id, @user.trust_level)
|
||||||
BadgeGranter.update_badges(@user, trust_level: @user.trust_level)
|
BadgeGranter.update_badges(action: :trust_level_change, user_id: @user.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
true
|
true
|
||||||
|
@ -2,6 +2,11 @@ require 'spec_helper'
|
|||||||
|
|
||||||
describe BadgesController do
|
describe BadgesController do
|
||||||
let!(:badge) { Fabricate(:badge) }
|
let!(:badge) { Fabricate(:badge) }
|
||||||
|
let(:user) { Fabricate(:user) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
SiteSetting.enable_badges = true
|
||||||
|
end
|
||||||
|
|
||||||
context 'index' do
|
context 'index' do
|
||||||
it 'should return a list of all badges' do
|
it 'should return a list of all badges' do
|
||||||
@ -20,5 +25,13 @@ describe BadgesController do
|
|||||||
parsed = JSON.parse(response.body)
|
parsed = JSON.parse(response.body)
|
||||||
parsed["badge"].should be_present
|
parsed["badge"].should be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should mark the notification as viewed" do
|
||||||
|
log_in_user(user)
|
||||||
|
user_badge = BadgeGranter.grant(badge, user)
|
||||||
|
user_badge.notification.read.should == false
|
||||||
|
get :show, id: badge.id, format: :json
|
||||||
|
user_badge.notification.reload.read.should == true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -28,7 +28,7 @@ describe UserBadgesController do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'includes counts when passed the aggregate argument' do
|
it 'includes counts when passed the aggregate argument' do
|
||||||
xhr :get, :index, username: user.username, aggregated: true
|
xhr :get, :index, username: user.username, grouped: true
|
||||||
|
|
||||||
response.status.should == 200
|
response.status.should == 200
|
||||||
parsed = JSON.parse(response.body)
|
parsed = JSON.parse(response.body)
|
||||||
|
@ -72,6 +72,7 @@ describe BadgeGranter do
|
|||||||
|
|
||||||
context "update_badges" do
|
context "update_badges" do
|
||||||
let(:user) { Fabricate(:user) }
|
let(:user) { Fabricate(:user) }
|
||||||
|
let(:liker) { Fabricate(:user) }
|
||||||
|
|
||||||
it "grants and revokes trust level badges" do
|
it "grants and revokes trust level badges" do
|
||||||
user.change_trust_level!(:elder)
|
user.change_trust_level!(:elder)
|
||||||
@ -80,6 +81,29 @@ describe BadgeGranter do
|
|||||||
UserBadge.where(user_id: user.id, badge_id: 1).first.should_not be_nil
|
UserBadge.where(user_id: user.id, badge_id: 1).first.should_not be_nil
|
||||||
UserBadge.where(user_id: user.id, badge_id: 2).first.should be_nil
|
UserBadge.where(user_id: user.id, badge_id: 2).first.should be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "grants system like badges" do
|
||||||
|
post = create_post(user: user)
|
||||||
|
# Welcome badge
|
||||||
|
PostAction.act(liker, post, PostActionType.types[:like])
|
||||||
|
UserBadge.find_by(user_id: user.id, badge_id: 5).should_not be_nil
|
||||||
|
# Nice post badge
|
||||||
|
post.update_attributes like_count: 10
|
||||||
|
BadgeGranter.update_badges(action: :post_like, post_id: post.id)
|
||||||
|
UserBadge.find_by(user_id: user.id, badge_id: 6).should_not be_nil
|
||||||
|
# Good post badge
|
||||||
|
post.update_attributes like_count: 25
|
||||||
|
BadgeGranter.update_badges(action: :post_like, post_id: post.id)
|
||||||
|
UserBadge.find_by(user_id: user.id, badge_id: 7).should_not be_nil
|
||||||
|
# Great post badge
|
||||||
|
post.update_attributes like_count: 100
|
||||||
|
BadgeGranter.update_badges(action: :post_like, post_id: post.id)
|
||||||
|
UserBadge.find_by(user_id: user.id, badge_id: 8).should_not be_nil
|
||||||
|
# Revoke badges on unlike
|
||||||
|
post.update_attributes like_count: 99
|
||||||
|
BadgeGranter.update_badges(action: :post_like, post_id: post.id)
|
||||||
|
UserBadge.find_by(user_id: user.id, badge_id: 8).should be_nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user