diff --git a/app/assets/javascripts/discourse/controllers/notification_controller.js b/app/assets/javascripts/discourse/controllers/notification_controller.js index 19db113cad7..765ca1d85a5 100644 --- a/app/assets/javascripts/discourse/controllers/notification_controller.js +++ b/app/assets/javascripts/discourse/controllers/notification_controller.js @@ -8,6 +8,9 @@ Discourse.NotificationController = Discourse.ObjectController.extend({ }.property(), link: function() { + if (this.get('data.badge_id')) { + return '' + this.get('data.badge_name') + ''; + } if (this.blank("data.topic_title")) { return ""; } diff --git a/app/models/notification.rb b/app/models/notification.rb index 77b53b854b1..a1a459e7ebd 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -28,7 +28,7 @@ class Notification < ActiveRecord::Base @types ||= Enum.new( :mentioned, :replied, :quoted, :edited, :liked, :private_message, :invited_to_private_message, :invitee_accepted, :posted, :moved_post, - :linked + :linked, :granted_badge ) end diff --git a/app/services/badge_granter.rb b/app/services/badge_granter.rb index 5511cf9f50f..53b3d1fb965 100644 --- a/app/services/badge_granter.rb +++ b/app/services/badge_granter.rb @@ -23,6 +23,10 @@ class BadgeGranter if @granted_by != Discourse.system_user StaffActionLogger.new(@granted_by).log_badge_grant(user_badge) end + + @user.notifications.create(notification_type: Notification.types[:granted_badge], + data: { badge_id: @badge.id, + badge_name: @badge.name }.to_json) end end @@ -32,10 +36,14 @@ class BadgeGranter def self.revoke(user_badge, options={}) UserBadge.transaction do user_badge.destroy! - Badge.decrement_counter 'grant_count', user_badge.badge.id + Badge.decrement_counter 'grant_count', user_badge.badge_id if options[:revoked_by] StaffActionLogger.new(options[:revoked_by]).log_badge_revoke(user_badge) end + # Revoke badge -- 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 diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index f35abee7636..c493fe74b7e 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -598,6 +598,7 @@ en: moved_post: " {{username}} moved {{link}}" total_flagged: "total flagged posts" linked: " {{username}} {{link}}" + granted_badge: " {{link}}" upload_selector: title: "Add an image" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 37af0e54611..972386d71dc 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -888,6 +888,7 @@ en: invited_to_private_message: "%{display_username} invited you to a private message: %{link}" invitee_accepted: "%{display_username} accepted your invitation" linked: "%{display_username} linked you in %{link}" + granted_badge: "You were granted the badge %{link}" search: within_post: "#%{post_number} by %{username}: %{excerpt}" diff --git a/spec/services/badge_granter_spec.rb b/spec/services/badge_granter_spec.rb index 6801bc969d1..476bc6a4b4a 100644 --- a/spec/services/badge_granter_spec.rb +++ b/spec/services/badge_granter_spec.rb @@ -40,9 +40,10 @@ describe BadgeGranter do user_badge.should_not be_present end - it 'increments grant_count on the badge' do + it 'increments grant_count on the badge and creates a notification' do BadgeGranter.grant(badge, user) badge.reload.grant_count.should eq(1) + user.notifications.where(notification_type: Notification.types[:granted_badge]).first.data_hash["badge_id"].should == badge.id end end @@ -52,12 +53,13 @@ describe BadgeGranter do let(:admin) { Fabricate(:admin) } let!(:user_badge) { BadgeGranter.grant(badge, user) } - it 'revokes the badge and decrements grant_count' do + it 'revokes the badge, deletes the notification and decrements grant_count' do badge.reload.grant_count.should eq(1) StaffActionLogger.any_instance.expects(:log_badge_revoke).with(user_badge) BadgeGranter.revoke(user_badge, revoked_by: admin) UserBadge.where(user: user, badge: badge).first.should_not be_present badge.reload.grant_count.should eq(0) + user.notifications.where(notification_type: Notification.types[:granted_badge]).should be_empty end end