Skip to content

Commit

Permalink
New badge display logic on user's profile (#20936)
Browse files Browse the repository at this point in the history
* new badge display

* fix cypress

* fix cypress

* Fit grid to exact number

* change point at which badges shown on profile header to 7

---------

Co-authored-by: Ben Halpern <bendhalpern@gmail.com>
  • Loading branch information
PhilipHow and benhalpern committed May 9, 2024
1 parent f77e348 commit 149ae12
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 50 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"rubyLsp.rubyVersionManager": "auto",
"rubyLsp.rubyVersionManager": {
"identifier": "auto"
},
"rubyLsp.formatter": "rubocop",
}
Empty file removed app/assets/builds/.keep
Empty file.
8 changes: 7 additions & 1 deletion app/assets/stylesheets/config/_generator.scss
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,13 @@
'3': repeat(3, minmax(0, 1fr)),
'4': repeat(4, minmax(0, 1fr)),
'5': repeat(5, minmax(0, 1fr)),
'6': repeat(6, minmax(0, 1fr))
'6': repeat(6, minmax(0, 1fr)),
'7': repeat(7, minmax(0, 1fr)),
'8': repeat(8, minmax(0, 1fr)),
'9': repeat(9, minmax(0, 1fr)),
'10': repeat(10, minmax(0, 1fr)),
'11': repeat(11, minmax(0, 1fr)),
'12': repeat(12, minmax(0, 1fr))
),
(),
true
Expand Down
11 changes: 1 addition & 10 deletions app/controllers/stories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -207,16 +207,7 @@ def handle_user_index

assign_user_github_repositories

# @badges_limit is here and is set to 6 because it determines how many badges we will display
# on Profile sidebar widget. If user has more badges, we hide them and let them be revealed
# by clicking "See more" button (because we want to save space etc..). But why 6 exactly?
# To make that widget look good:
# - On desktop it will have 3 rows, each row with 2 badges.
# - On mobile it will have 2 rows, each row with 3 badges.
# So it's always 6. If we make it higher or lower number, we would have to sacrifice UI:
# - Let's say it's `4`. On mobile it would display two rows: 1st with 3 badges and
# 2nd with 1 badge (!) <-- and that would look off.
@badges_limit = 6
@grouped_badges = @user.badge_achievements.order(id: :desc).includes(:badge).group_by(&:badge_id)
@profile = @user.profile.decorate
@is_user_flagged = Reaction.where(user_id: session_current_user_id, reactable: @user).any?

Expand Down
21 changes: 12 additions & 9 deletions app/views/users/_badges_area.html.erb
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
<div class="crayons-card crayons-card--secondary">
<header class="crayons-card__header">
<h3 class="crayons-subtitle-3"><%= t("views.badges.heading") %></h3>
</header>
<% if defined?(show_heading) ? show_heading : true %>
<header class="crayons-card__header">
<h3 class="crayons-subtitle-3"><%= t("views.badges.heading") %></h3>
</header>
<% end %>

<div class="crayons-card__body">
<div class="grid gap-4 grid-cols-3 s:grid-cols-4 m:grid-cols-2 align-center items-center js-profile-badges">
<% achievements.group_by(&:badge_id).each_with_index do |(badge_id, badge_achievements), i| %>
<% grid_class ||= "grid-cols-3 s:grid-cols-4 m:grid-cols-2" %>
<div class="grid gap-4 <%= grid_class %> align-center items-center js-profile-badges">
<% grouped_badges.each_with_index do |(badge_id, badge_achievements), i| %>
<% achievement = badge_achievements.first %>
<div role="button" onclick="window.Forem.showModal({size: 'medium', showHeader: false, contentSelector: '#badge-<%= achievement.badge_id %>', overlay: true})"
title="<%= achievement.badge_title %>"
class="js-profile-badge <% if i >= limit %>hidden<% end %> relative">
<img src="<%= optimized_image_url(achievement.badge_image_url, width: 180) %>"
alt="<%= achievement.badge_title %>"
class="mx-auto max-w-75 h-auto align-middle"
style="object-fit: contain; cursor: pointer; width: 100%; aspect-ratio: 1 / 1;"
class="mx-auto w-75 h-auto align-middle"
style="object-fit: contain; cursor: pointer; width: 100%; aspect-ratio: 1 / 1; max-width: 80px;"
loading="lazy" />
<% if badge_achievements.length > 1 %><div class="badge-indicator" title="<%= t("views.badges.indicator", user: @user.name, number: badge_achievements.length) %>"><%= badge_achievements.length %></div><% end %>
</div>
Expand All @@ -24,9 +27,9 @@
<% end %>
</div>

<% if limit > 1 && count > limit %>
<% if limit > 1 && grouped_badges.size > limit %>
<button type="button"
class="crayons-btn crayons-btn--ghost-brand crayons-btn--s w-100 js-profile-badges-trigger">
class="crayons-btn crayons-btn--ghost-brand crayons-btn--s w-100 mt-3 js-profile-badges-trigger">
<%= t("views.badges.all", count: count) %>
</button>
<% end %>
Expand Down
16 changes: 9 additions & 7 deletions app/views/users/_sidebar.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
<div class="m:gap-4 hidden m:grid js-user-info">
<% cache "user-profile-sidebar-additional-#{@user.id}-#{@user.github_repos_updated_at}-#{@user.badge_achievements_count}-#{@user.organization_info_updated_at}", expires_in: 2.days do %>
<% if @user.badge_achievements_count.positive? && @user.badge_achievements_count <= 6 %>
<%= render partial: "users/badges_area", locals: {
grouped_badges: @grouped_badges,
count: @user.badge_achievements_count,
limit: 6,
show_heading: true,
grid_class: "grid-cols-3 s:grid-cols-4 m:grid-cols-2"
} %>
<% end %>
<% if @user.organizations.present? %>
<div class="crayons-card crayons-card--secondary crayons-layout__content">
<header class="crayons-card__header">
Expand All @@ -22,13 +31,6 @@
<%= render partial: "users/github_repositories_area", locals: { repositories: repositories } %>
<% if @user.badge_achievements_count.positive? %>
<%= render partial: "users/badges_area", locals: {
achievements: @user.badge_achievements.order(id: :desc).includes(:badge),
count: @user.badge_achievements_count,
limit: @badges_limit
} %>
<% end %>
<% end %>
<% cache "user-profile-sidebar-profile-details-#{@user.id}-#{@user.profile_updated_at}", expires_in: 10.days do %>
Expand Down
15 changes: 13 additions & 2 deletions app/views/users/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,20 @@

<%= render "users/metadata" %>
<div class="p-3 pt-0 block m:hidden js-user-info-trigger-wrapper">
<button type="button" class="crayons-btn crayons-btn--outlined w-100 js-user-info-trigger"><%= t("views.users.more", user: @user.username) %></button>
<% if @user.badge_achievements_count >= 7 %>
<%= render partial: "users/badges_area", locals: {
grouped_badges: @grouped_badges,
count: @user.badge_achievements_count,
limit: 12,
show_heading: false,
grid_class: "grid-cols-#{[@user.badge_achievements_count, 6].min} s:grid-cols-#{[@user.badge_achievements_count, 8].min} m:grid-cols-#{[@user.badge_achievements_count, 12].min}"
} %>
<% end %>

<div class="p-3 block m:hidden js-user-info-trigger-wrapper">
<button type="button" class="m-3 crayons-btn crayons-btn--outlined w-100 js-user-info-trigger"><%= t("views.users.more", user: @user.username) %></button>
</div>

</header>
</div>
</div>
Expand Down
14 changes: 7 additions & 7 deletions cypress/e2e/seededFlows/profileFlows/userProfile.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('User Profile', () => {

cy.get('.js-user-info').contains('Organizations').should('be.visible');

cy.get('.js-user-info').contains('Badges').should('be.visible');
cy.get('.js-profile-badges').should('be.visible');

cy.get('.js-user-info')
.contains('posts published')
Expand All @@ -35,25 +35,25 @@ describe('User Profile', () => {
});

describe('toggle profile badges', () => {
it('should show 6 badges by default if there are more than 6', () => {
it('should show 12 badges by default if there are more than 12', () => {
cy.get('.js-profile-badges')
.findAllByRole('button')
.should('have.length', 6);
.should('have.length', 12);
});

it('should show a button to show all the badges if there are more than 6', () => {
cy.findByRole('button', {
name: 'Show all 7 badges',
name: 'Show all 13 badges',
}).should('be.visible');
});

it('should show 7 badges when the button is clicked', () => {
it('should show 13 badges when the button is clicked', () => {
cy.findByRole('button', {
name: 'Show all 7 badges',
name: 'Show all 13 badges',
}).click();
cy.get('.js-profile-badges')
.findAllByRole('button')
.should('have.length', 7);
.should('have.length', 13);
});
});
});
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@
"lint-staged": "^13.3.0",
"markdown-loader": "^7.0.0",
"mocha-junit-reporter": "^2.2.1",
"prettier": "^2.8.8",
"sass": "1.54.0",
"sass-loader": "^13.3.3",
"storybook-addon-jsx": "^7.3.14",
Expand Down
2 changes: 1 addition & 1 deletion spec/support/seeds/seeds_e2e.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,7 @@
##############################################################################

seeder.create_if_none(Badge) do
7.times do |t|
13.times do |t|
Badge.create!(
title: "#{Faker::Lorem.word} #{rand(100)} #{t}",
description: "#{Faker::Lorem.sentence} #{rand(100)}",
Expand Down
1 change: 0 additions & 1 deletion spec/views/users/main_feed_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
allow(view).to receive(:feed_style_preference).and_return("basic")
end
assign(:user, user)
assign(:badges_limit, 6)
assign(:stories, [])
assign(:comments, [])
assign(:pinned_stories, [])
Expand Down
10 changes: 0 additions & 10 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9290,7 +9290,6 @@ __metadata:
postcss-preset-env: "npm:^7.8.2"
postscribe: "npm:^2.0.8"
preact: "npm:^10.20.2"
prettier: "npm:^2.8.8"
prop-types: "npm:^15.8.1"
rails-erb-loader: "npm:^5.5.2"
react-colorful: "npm:^5.6.1"
Expand Down Expand Up @@ -17617,15 +17616,6 @@ __metadata:
languageName: node
linkType: hard

"prettier@npm:^2.8.8":
version: 2.8.8
resolution: "prettier@npm:2.8.8"
bin:
prettier: bin-prettier.js
checksum: 10c0/463ea8f9a0946cd5b828d8cf27bd8b567345cf02f56562d5ecde198b91f47a76b7ac9eae0facd247ace70e927143af6135e8cf411986b8cb8478784a4d6d724a
languageName: node
linkType: hard

"pretty-bytes@npm:^5.6.0":
version: 5.6.0
resolution: "pretty-bytes@npm:5.6.0"
Expand Down

0 comments on commit 149ae12

Please sign in to comment.