Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hide user gravatar when email not public. #4104

Merged
merged 1 commit into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 13 additions & 2 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ def gem_info(rubygem)
end
end

def gravatar(size, id = "gravatar", user = current_user, **options)
image_tag user.gravatar_url(size: size, secure: true).html_safe,
def avatar(size, id = "gravatar", user = current_user, theme: :light, **options)
url = user.gravatar_url(size: size, secure: true) || default_avatar(theme: theme)
image_tag url,
id: id,
width: size,
height: size,
Expand Down Expand Up @@ -70,4 +71,14 @@ def flash_message(name, msg)
return sanitize(msg) if name.end_with? "html"
msg
end

private

def default_avatar(theme:)
case theme
when :light then "/images/avatar.svg"
when :dark then "/images/avatar_inverted.svg"
Comment on lines +79 to +80
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've often seen SVGs styled directly in css to change the fill color. Is that worth it here? Something like this with invert() or even inlining the svg so it doesn't take an extra request.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think doing it in the CSS makes sense, then the SVG will change without a page refresh

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not related to dark mode, but I'll try to provide inline SVG with styles, that could be possible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was tired when I wrote this. Don't invert() it unless we want emerald users, haha.

else raise "invalid default avatar theme, only light and dark are suported"
end
end
end
2 changes: 1 addition & 1 deletion app/helpers/rubygems_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def links_to_owners_without_mfa(rubygem)
end

def link_to_user(user)
link_to gravatar(48, "gravatar-#{user.id}", user), profile_path(user.display_id),
link_to avatar(48, "gravatar-#{user.id}", user), profile_path(user.display_id),
alt: user.display_handle, title: user.display_handle
end

Expand Down
4 changes: 4 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ def self.normalize_email(email)
""
end

def gravatar_url(*)
public_email ? super : nil
end

def name
handle || email
end
Expand Down
4 changes: 2 additions & 2 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
<% if signed_in? %>
<a href="<%= profile_path(current_user.display_id) %>" class="header__nav-link mobile__header__nav-link">
<span><%= current_user.name %></span>
<%= gravatar 80, "user_gravatar" %>
<%= avatar 80, "user_gravatar", theme: :dark %>
</a>
<% end %>

Expand All @@ -71,7 +71,7 @@
<% if signed_in? %>
<a href="<%= profile_path(current_user.display_id) %>" class="header__nav-link desktop__header__nav-link">
<span><%= current_user.name %></span>
<%= gravatar 80, "user_gravatar" %>
<%= avatar 80, "user_gravatar", theme: :dark %>
</a>
<a href="#" class="header__popup-link" data-icon="▼">
<span class="t-hidden">More items</span>
Expand Down
8 changes: 6 additions & 2 deletions app/views/profiles/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
<div class="avatar_field">
<%= form.label :avatar, :class => 'form__label' %>
<div class="l-overflow">
<%= gravatar(160) %>
<%= link_to t('.change_avatar'), 'https://www.gravatar.com', :class => 't-text t-link' %>
<%= avatar(160) %>
<% if @user.public_email? %>
<%= link_to t('.change_avatar'), 'https://www.gravatar.com', :class => 't-text t-link' %>
<% else %>
<%= content_tag 'i', t('.disabled_avatar_html'), :class => 't-text' %>
<% end %>
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion app/views/profiles/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<header class="profile__header">
<div class="profile__header__name-wrap">
<div id="avatar-frame">
<%= gravatar(300, 'profile_gravatar', @user, class: 'profile__header__avatar') %>
<%= avatar(300, 'profile_gravatar', @user, class: 'profile__header__avatar') %>
</div>

<% if @user.full_name.present? %>
Expand Down
1 change: 1 addition & 0 deletions config/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ de:
subtitle_html:
edit:
change_avatar:
disabled_avatar_html:
email_awaiting_confirmation:
enter_password:
optional_full_name:
Expand Down
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ en:
subtitle_html: Ask for new maintainers or request ownership <a class="adoption__blog__link" href="https://blog.rubygems.org/2022/01/19/rubygems-adoptions.html">(read more)</a>
edit:
change_avatar: Change Avatar
disabled_avatar_html: "A default avatar is used due to private email settings. To enable a personalized <a href='https://gravatar.com'>Gravatar</a>, turn on 'Show email in public profile'. Notice this will expose your email to the public."
email_awaiting_confirmation: Please confirm your new email address %{unconfirmed_email}
enter_password: Please enter your account's password
optional_full_name: Optional. Will be displayed publicly
Expand Down
1 change: 1 addition & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ es:
subtitle_html:
edit:
change_avatar:
disabled_avatar_html:
email_awaiting_confirmation: Por favor confirma tu nueva dirección de correo
%{unconfirmed_email}
enter_password: Por favor introduce tu contraseña
Expand Down
1 change: 1 addition & 0 deletions config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ fr:
subtitle_html:
edit:
change_avatar:
disabled_avatar_html:
email_awaiting_confirmation: Veuillez confirmer votre nouvelle adresse email
%{unconfirmed_email}
enter_password: Veuillez entrer le mot de passe de votre compte
Expand Down
1 change: 1 addition & 0 deletions config/locales/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ ja:
subtitle_html: 新しい貢献者を募るか所有権を申請してください<a class="adoption__blog__link" href="https://blog.rubygems.org/2022/01/19/rubygems-adoptions.html">(詳細)</a>
edit:
change_avatar: アバターを変更
disabled_avatar_html:
email_awaiting_confirmation: 新しいEメールアドレス%{unconfirmed_email}を確認してください。
enter_password: アカウントのパスワードを入力してください。
optional_full_name: 省略可能です。公開されます。
Expand Down
1 change: 1 addition & 0 deletions config/locales/nl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ nl:
subtitle_html:
edit:
change_avatar:
disabled_avatar_html:
email_awaiting_confirmation:
enter_password:
optional_full_name:
Expand Down
1 change: 1 addition & 0 deletions config/locales/pt-BR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ pt-BR:
subtitle_html:
edit:
change_avatar: Mudar foto de perfil
disabled_avatar_html:
email_awaiting_confirmation:
enter_password:
optional_full_name:
Expand Down
1 change: 1 addition & 0 deletions config/locales/zh-CN.yml
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ zh-CN:
subtitle_html: 寻求新的维护者或申请所有权 <a class="adoption__blog__link" href="https://blog.rubygems.org/2022/01/19/rubygems-adoptions.html">(了解更多)</a>
edit:
change_avatar: 修改头像
disabled_avatar_html:
email_awaiting_confirmation: 请确认您新的邮箱地址 %{unconfirmed_email}
enter_password: 请输入您账户的密码
optional_full_name: 可填。将公开显示
Expand Down
1 change: 1 addition & 0 deletions config/locales/zh-TW.yml
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ zh-TW:
subtitle_html:
edit:
change_avatar:
disabled_avatar_html:
email_awaiting_confirmation: 請驗證你的新 Email %{unconfirmed_email}
enter_password: 輸入密碼
optional_full_name:
Expand Down
1 change: 1 addition & 0 deletions public/images/avatar.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/avatar_inverted.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions test/models/user_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -859,4 +859,14 @@ class UserTest < ActiveSupport::TestCase
assert_equal "", User.normalize_email("\u9999".force_encoding("ascii"))
end
end

context "#gravatar_url" do
should "return gravatar if email is publicly visible" do
assert_includes User.new(public_email: true, email: "text@example.com").gravatar_url, "gravatar.com"
end

should "return nil if email is publicly hidden" do
assert_nil User.new(public_email: false, email: "text@example.com").gravatar_url
end
end
end
47 changes: 47 additions & 0 deletions test/unit/helpers/application_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,51 @@ class ApplicationHelperTest < ActionView::TestCase
assert_instance_of String, flash_message(:notice, @message)
end
end

context "avatar" do
setup do
@user = build(:user, email: "email@example.com")
end

should "raise when invalid theme is requested" do
assert_raises(StandardError) { avatar(160, "id", @user, theme: :unknown) }
end

context "with publicly available email" do
setup do
@user.public_email = true
end

should "return gravatar" do
url = avatar(160, "id", @user)
expected_uri = "https://secure.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e.png?d=retro&amp;r=PG&amp;s=160"

assert_equal "<img id=\"id\" width=\"160\" height=\"160\" src=\"#{expected_uri}\" />", url
end
end

context "with publicly hidden email" do
setup do
@user.public_email = false
end

should "return light themed default avatar" do
url = avatar(160, "id", @user, theme: :light)

assert_equal "<img id=\"id\" width=\"160\" height=\"160\" src=\"/images/avatar.svg\" />", url
end

should "return light themed default avatar by default" do
url = avatar(160, "id", @user)

assert_equal "<img id=\"id\" width=\"160\" height=\"160\" src=\"/images/avatar.svg\" />", url
end

should "return dark themed default avatar" do
url = avatar(160, "id", @user, theme: :dark)

assert_equal "<img id=\"id\" width=\"160\" height=\"160\" src=\"/images/avatar_inverted.svg\" />", url
end
end
end
end
4 changes: 2 additions & 2 deletions test/unit/helpers/rubygems_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class RubygemsHelperTest < ActionView::TestCase
@rubygem = create(:rubygem, owners: users)

expected_links = users.sort_by(&:id).map do |u|
link_to gravatar(48, "gravatar-#{u.id}", u),
link_to avatar(48, "gravatar-#{u.id}", u),
profile_path(u.display_id),
alt: u.display_handle,
title: u.display_handle
Expand All @@ -131,7 +131,7 @@ class RubygemsHelperTest < ActionView::TestCase
rubygem = create(:rubygem, owners: [*without_mfa, with_mfa])

expected_links = without_mfa.sort_by(&:id).map do |u|
link_to gravatar(48, "gravatar-#{u.id}", u),
link_to avatar(48, "gravatar-#{u.id}", u),
profile_path(u.display_id),
alt: u.display_handle,
title: u.display_handle
Expand Down