Skip to content

Commit

Permalink
Add more badges (#4089)
Browse files Browse the repository at this point in the history
* Add commented debates badge

* Ad followers badge

* Fix debates locales

* Normalize locales

* Improve badge display

* Fix changelog

* Fix rubocop issues

* Fix rubocop issues

* Lint erb
  • Loading branch information
josepjaume authored and mrcasals committed Sep 12, 2018
1 parent b69d0e9 commit 83b96d2
Show file tree
Hide file tree
Showing 18 changed files with 434 additions and 3 deletions.
1 change: 1 addition & 0 deletions .rubocop.yml
Expand Up @@ -1213,6 +1213,7 @@ RSpec/DescribeClass:
- spec/gemfiles_spec.rb
- spec/js_bundles_spec.rb
- spec/i18n_spec.rb
- "**/*/spec/**/*_badge_spec.rb"
- decidim-core/spec/lib/global_engines_spec.rb
- "**/tasks/**/*"

Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,8 @@
**Added**:

- **decidim-assemblies**: Add organizational chart to assemblies home. [\#4045](https://github.com/decidim/decidim/pull/4045)
- **decidim-core**: Adds the *followers* badge. [\#4089](https://github.com/decidim/decidim/pull/4089)
- **decidim-debates**: Adds the *commented debates* badge. [\#4089](https://github.com/decidim/decidim/pull/4089)
- **decidim-meetings**: Add upcoming events content block and page. [\#3987](https://github.com/decidim/decidim/pull/3987)

**Changed**:
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions decidim-core/app/cells/decidim/badge/show.erb
Expand Up @@ -6,7 +6,7 @@
</div>
</div>
<div class="card__content">
<div class="card__header">
<div class="card__header" style="opacity: <%= opacity %>;">
<div class="badge-container">
<%= image_tag badge.image, class: "badge__logo" %>
</div>
Expand All @@ -22,7 +22,7 @@
<div class="p-xs">
<div class="flex--sbc">
<strong class="text-uppercase muted">
<%= t "decidim.gamification.level", level: status.level %>
<%= level_title %>
</strong>
<div class="badge-level">
<% badge.levels.each_with_index do |_threshold, level| %>
Expand Down
5 changes: 5 additions & 0 deletions decidim-core/app/cells/decidim/badge/small.erb
@@ -0,0 +1,5 @@
<%=
image_tag badge.image,
class: "badge__logo--small external-icon",
title: "#{badge_name} (#{level_title}): #{description}"
%>
14 changes: 13 additions & 1 deletion decidim-core/app/cells/decidim/badge_cell.rb
Expand Up @@ -8,6 +8,10 @@ class BadgeCell < Decidim::ViewModel

delegate :current_user, to: :controller

def small
render "small"
end

def badge
@options[:badge]
end
Expand All @@ -16,6 +20,10 @@ def user
model
end

def level_title
t "decidim.gamification.level", level: status.level
end

def description
if user == current_user && status.level.zero?
t "decidim.gamification.badges.#{badge.name}.unearned_own"
Expand Down Expand Up @@ -44,10 +52,14 @@ def badge_name
t "decidim.gamification.badges.#{badge.name}.name"
end

def opacity
status.level < 1 ? 0.2 : 1
end

private

def status
@status ||= Decidim::Gamification.status_for(user, badge.name)
@status ||= options[:status] || Decidim::Gamification.status_for(user, badge.name)
end
end
end
25 changes: 25 additions & 0 deletions decidim-core/app/cells/decidim/profile_sidebar/show.erb
Expand Up @@ -42,6 +42,31 @@
</div>
</div>
</div>

<div class="card__footer card__footer--transparent">
<div class="card__support">
<div class="row column mb-s">
<strong class="muted"><%= t("decidim.profiles.sidebar.badges.title") %></strong>
<div class="badge-tip badge-tip--inline">
<div data-tooltip data-position="top" title="<%= t("decidim.profiles.sidebar.badges.info") %>" aria-describedby="badges-tooltip" data-yeti-box="badges-tooltip" data-toggle="badges-tooltip" data-resize="badges-tooltip" class="has-tip" data-events="resize">
<%= icon "info", class: "icon--small" %>
</div>
</div>
</div>
<div class="collapsible-list is-filtered row small-up-2 medium-up-4 collapse">
<% Decidim::Gamification.badges.sort_by(&:name).each do |badge| %>
<% status = Decidim::Gamification.status_for(user, badge.name) %>
<% if status.level > 0 %>
<div class="column">
<div class="badge-container pr-xs">
<%= cell("decidim/badge", user, badge: badge, status: status).(:small) %>
</div>
</div>
<% end %>
<% end %>
</div>
</div>
</div>
</div>

<% if own_profile? %>
Expand Down
6 changes: 6 additions & 0 deletions decidim-core/app/commands/decidim/create_follow.rb
Expand Up @@ -22,6 +22,7 @@ def call
return broadcast(:invalid) if form.invalid?

create_follow!
increment_score

broadcast(:ok, follow)
end
Expand All @@ -36,5 +37,10 @@ def create_follow!
user: current_user
)
end

def increment_score
return unless form.followable.is_a? Decidim::User
Decidim::Gamification.increment_score(form.followable, :followers)
end
end
end
7 changes: 7 additions & 0 deletions decidim-core/app/commands/decidim/delete_follow.rb
Expand Up @@ -22,6 +22,7 @@ def call
return broadcast(:invalid) if form.invalid?

delete_follow!
decrement_score

broadcast(:ok)
end
Expand All @@ -33,5 +34,11 @@ def call
def delete_follow!
form.follow.destroy!
end

def decrement_score
followable = form.follow.followable
return unless followable.is_a? Decidim::User
Decidim::Gamification.decrement_score(followable, :followers)
end
end
end
12 changes: 12 additions & 0 deletions decidim-core/config/locales/en.yml
Expand Up @@ -386,6 +386,14 @@ en:
remove_this_file: Remove this file
gamification:
badges:
followers:
description_another: This user has %{score} followers.
description_own: "%{score} users are following you."
explanation: Users get this badge by getting followed by other users.
name: Followers
next_level_in: Get %{score} more users to follow you to reach the next level!
unearned_another: This user doesn't have any followers yet.
unearned_own: You've got no followers yet.
invitations:
description_another: This user has invited %{score} users.
description_own: You have invited %{score} users.
Expand Down Expand Up @@ -573,6 +581,10 @@ en:
followers: Followers
following: Follows
notifications: Notifications
sidebar:
badges:
info: Badges are earned by performing specific activity in the platform.
title: Badges
user:
edit_profile: Edit profile
reported_mailer:
Expand Down
5 changes: 5 additions & 0 deletions decidim-core/lib/decidim/core/engine.rb
Expand Up @@ -332,6 +332,11 @@ class Engine < ::Rails::Engine
badge.levels = [1, 5, 10, 30, 50]
badge.reset = ->(user) { Decidim::User.where(invited_by: user.id).count }
end

Decidim::Gamification.register_badge(:followers) do |badge|
badge.levels = [1, 15, 30, 60, 100]
badge.reset = ->(user) { user.followers.count }
end
end
end
end
Expand Down
25 changes: 25 additions & 0 deletions decidim-core/spec/commands/decidim/create_follow_spec.rb
@@ -0,0 +1,25 @@
# frozen_string_literal: true

require "spec_helper"

module Decidim
describe CreateFollow do
let!(:organization) { create(:organization) }
let!(:user1) { create(:user, organization: organization) }
let!(:user2) { create(:user, organization: organization) }

let(:form) { double(followable: user2, invalid?: false) }

it "creates a follow" do
expect { described_class.new(form, user1).call }.to broadcast(:ok)
expect(user2.reload.followers).to include(user1)
end

it "increments the user's score" do
described_class.new(form, user1).call

expect(Decidim::Gamification.status_for(user1, :followers).score).to eq(0)
expect(Decidim::Gamification.status_for(user2, :followers).score).to eq(1)
end
end
end
34 changes: 34 additions & 0 deletions decidim-core/spec/commands/decidim/delete_follow_spec.rb
@@ -0,0 +1,34 @@
# frozen_string_literal: true

require "spec_helper"

module Decidim
describe DeleteFollow do
let!(:organization) { create(:organization) }
let!(:user1) { create(:user, organization: organization) }
let!(:user2) { create(:user, organization: organization) }
let!(:follow) { create(:follow, user: user1, followable: user2) }

let(:form) { double(follow: follow, invalid?: false) }

it "destroys a follow" do
expect { described_class.new(form, user1).call }.to broadcast(:ok)

expect(user2.reload.followers).not_to include(user1)
end

describe "gamification" do
before do
Decidim::Gamification.set_score(user1, :followers, 10)
Decidim::Gamification.set_score(user2, :followers, 10)
end

it "decrements the user's score" do
described_class.new(form, user1).call

expect(Decidim::Gamification.status_for(user1, :followers).score).to eq(10)
expect(Decidim::Gamification.status_for(user2, :followers).score).to eq(9)
end
end
end
end
21 changes: 21 additions & 0 deletions decidim-core/spec/lib/followers_badge_spec.rb
@@ -0,0 +1,21 @@
# frozen_string_literal: true

require "spec_helper"

describe "followers badge" do
let(:organization) { create(:organization) }

describe "reset" do
it "resets the score to the amount of followers of a user" do
user = create(:user, organization: organization)
users = create_list(:user, 5, organization: organization)

users.each do |follower|
create(:follow, user: follower, followable: user)
end

Decidim::Gamification.reset_badges(Decidim::User.where(id: user.id))
expect(Decidim::Gamification.status_for(user, :followers).score).to eq(5)
end
end
end

0 comments on commit 83b96d2

Please sign in to comment.