Commit 2e8d366d authored by Yorick Peterse's avatar Yorick Peterse

Merge branch '42800-change-usage-of-avatar_icon' into 'master'

Change all occurrences of ApplicationHelper#avatar_icon to use a User object where possible

Closes #42800

See merge request gitlab-org/gitlab-ce!16976
parents 48c505eb dd1d13b8
...@@ -21,7 +21,7 @@ class IssuesFinder < IssuableFinder ...@@ -21,7 +21,7 @@ class IssuesFinder < IssuableFinder
CONFIDENTIAL_ACCESS_LEVEL = Gitlab::Access::REPORTER CONFIDENTIAL_ACCESS_LEVEL = Gitlab::Access::REPORTER
def klass def klass
Issue Issue.includes(:author)
end end
def with_confidentiality_access_check def with_confidentiality_access_check
......
...@@ -57,7 +57,7 @@ class NotesFinder ...@@ -57,7 +57,7 @@ class NotesFinder
types = %w(commit issue merge_request snippet) types = %w(commit issue merge_request snippet)
note_relations = types.map { |t| notes_for_type(t) } note_relations = types.map { |t| notes_for_type(t) }
note_relations.map! { |notes| search(notes) } note_relations.map! { |notes| search(notes) }
UnionFinder.new.find_union(note_relations, Note) UnionFinder.new.find_union(note_relations, Note.includes(:author))
end end
def noteables_for_type(noteable_type) def noteables_for_type(noteable_type)
......
...@@ -68,18 +68,32 @@ module ApplicationHelper ...@@ -68,18 +68,32 @@ module ApplicationHelper
end end
end end
def avatar_icon(user_or_email = nil, size = nil, scale = 2, only_path: true) # Takes both user and email and returns the avatar_icon by
user = # user (preferred) or email.
if user_or_email.is_a?(User) def avatar_icon_for(user = nil, email = nil, size = nil, scale = 2, only_path: true)
user_or_email if user
else avatar_icon_for_user(user, size, scale, only_path: only_path)
User.find_by_any_email(user_or_email.try(:downcase)) elsif email
end avatar_icon_for_email(email, size, scale, only_path: only_path)
else
default_avatar
end
end
def avatar_icon_for_email(email = nil, size = nil, scale = 2, only_path: true)
user = User.find_by_any_email(email.try(:downcase))
if user
avatar_icon_for_user(user, size, scale, only_path: only_path)
else
gravatar_icon(email, size, scale)
end
end
def avatar_icon_for_user(user = nil, size = nil, scale = 2, only_path: true)
if user if user
user.avatar_url(size: size, only_path: only_path) || default_avatar user.avatar_url(size: size, only_path: only_path) || default_avatar
else else
gravatar_icon(user_or_email, size, scale) gravatar_icon(nil, size, scale)
end end
end end
......
...@@ -8,10 +8,22 @@ module AvatarsHelper ...@@ -8,10 +8,22 @@ module AvatarsHelper
})) }))
end end
def user_avatar_url_for(options = {})
if options[:url]
options[:url]
elsif options[:user]
avatar_icon_for_user(options[:user], options[:size])
else
avatar_icon_for_email(options[:user_email], options[:size])
end
end
def user_avatar_without_link(options = {}) def user_avatar_without_link(options = {})
avatar_size = options[:size] || 16 avatar_size = options[:size] || 16
user_name = options[:user].try(:name) || options[:user_name] user_name = options[:user].try(:name) || options[:user_name]
avatar_url = options[:url] || avatar_icon(options[:user] || options[:user_email], avatar_size)
avatar_url = user_avatar_url_for(options.merge(size: avatar_size))
has_tooltip = options[:has_tooltip].nil? ? true : options[:has_tooltip] has_tooltip = options[:has_tooltip].nil? ? true : options[:has_tooltip]
data_attributes = options[:data] || {} data_attributes = options[:data] || {}
css_class = %W[avatar s#{avatar_size}].push(*options[:css_class]) css_class = %W[avatar s#{avatar_size}].push(*options[:css_class])
......
...@@ -33,7 +33,7 @@ module NamespacesHelper ...@@ -33,7 +33,7 @@ module NamespacesHelper
if namespace.is_a?(Group) if namespace.is_a?(Group)
group_icon(namespace) group_icon(namespace)
else else
avatar_icon(namespace.owner.email, size) avatar_icon_for_user(namespace.owner, size)
end end
end end
......
...@@ -19,7 +19,7 @@ module ProjectsHelper ...@@ -19,7 +19,7 @@ module ProjectsHelper
classes = %W[avatar avatar-inline s#{opts[:size]}] classes = %W[avatar avatar-inline s#{opts[:size]}]
classes << opts[:avatar_class] if opts[:avatar_class] classes << opts[:avatar_class] if opts[:avatar_class]
avatar = avatar_icon(author, opts[:size]) avatar = avatar_icon_for_user(author, opts[:size])
src = opts[:lazy_load] ? nil : avatar src = opts[:lazy_load] ? nil : avatar
image_tag(src, width: opts[:size], class: classes, alt: '', "data-src" => avatar) image_tag(src, width: opts[:size], class: classes, alt: '', "data-src" => avatar)
......
%li.flex-row %li.flex-row
.user-avatar .user-avatar
= image_tag avatar_icon(user), class: "avatar", alt: '' = image_tag avatar_icon_for_user(user), class: "avatar", alt: ''
.row-main-content .row-main-content
.user-name.row-title.str-truncated-100 .user-name.row-title.str-truncated-100
= link_to user.name, [:admin, user] = link_to user.name, [:admin, user]
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= @user.name = @user.name
%ul.well-list %ul.well-list
%li %li
= image_tag avatar_icon(@user, 60), class: "avatar s60" = image_tag avatar_icon_for_user(@user, 60), class: "avatar s60"
%li %li
%span.light Profile page: %span.light Profile page:
%strong %strong
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.timeline-entry-inner .timeline-entry-inner
.timeline-icon .timeline-icon
= link_to user_path(discussion.author) do = link_to user_path(discussion.author) do
= image_tag avatar_icon(discussion.author), class: "avatar s40" = image_tag avatar_icon_for_user(discussion.author), class: "avatar s40"
.timeline-content .timeline-content
.discussion.js-toggle-container{ data: { discussion_id: discussion.id } } .discussion.js-toggle-container{ data: { discussion_id: discussion.id } }
.discussion-header .discussion-header
......
...@@ -10,7 +10,7 @@ xml.entry do ...@@ -10,7 +10,7 @@ xml.entry do
# eager-loaded. This allows us to re-use the user object's Email address, # eager-loaded. This allows us to re-use the user object's Email address,
# instead of having to run additional queries to figure out what Email to use # instead of having to run additional queries to figure out what Email to use
# for the avatar. # for the avatar.
xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(event.author)) xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon_for_user(event.author))
xml.author do xml.author do
xml.username event.author_username xml.username event.author_username
......
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
.example .example
.cover-block .cover-block
.avatar-holder .avatar-holder
= image_tag avatar_icon('admin@example.com', 90), class: "avatar s90", alt: '' = image_tag avatar_icon_for_email('admin@example.com', 90), class: "avatar s90", alt: ''
.cover-title .cover-title
John Smith John Smith
......
...@@ -3,7 +3,7 @@ xml.entry do ...@@ -3,7 +3,7 @@ xml.entry do
xml.link href: project_issue_url(issue.project, issue) xml.link href: project_issue_url(issue.project, issue)
xml.title truncate(issue.title, length: 80) xml.title truncate(issue.title, length: 80)
xml.updated issue.updated_at.xmlschema xml.updated issue.updated_at.xmlschema
xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(issue.author_email)) xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon_for_user(issue.author))
xml.author do xml.author do
xml.name issue.author_name xml.name issue.author_name
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
= todos_count_format(todos_pending_count) = todos_count_format(todos_pending_count)
%li.header-user.dropdown %li.header-user.dropdown
= link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown" } do = link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown" } do
= image_tag avatar_icon(current_user, 23), width: 23, height: 23, class: "header-user-avatar qa-user-avatar" = image_tag avatar_icon_for_user(current_user, 23), width: 23, height: 23, class: "header-user-avatar qa-user-avatar"
= sprite_icon('angle-down', css_class: 'caret-down') = sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu-nav.dropdown-menu-align-right .dropdown-menu-nav.dropdown-menu-align-right
%ul %ul
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
%tbody %tbody
%tr %tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" }
%img.avatar{ height: "24", src: avatar_icon(commit.author || commit.author_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/ %img.avatar{ height: "24", src: avatar_icon_for(commit.author, commit.author_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" }
- if commit.author - if commit.author
%a.muted{ href: user_url(commit.author), style: "color:#333333;text-decoration:none;" } %a.muted{ href: user_url(commit.author), style: "color:#333333;text-decoration:none;" }
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
%tbody %tbody
%tr %tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" }
%img.avatar{ height: "24", src: avatar_icon(commit.committer || commit.committer_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/ %img.avatar{ height: "24", src: avatar_icon_for(commit.committer, commit.committer_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" }
- if commit.committer - if commit.committer
%a.muted{ href: user_url(commit.committer), style: "color:#333333;text-decoration:none;" } %a.muted{ href: user_url(commit.committer), style: "color:#333333;text-decoration:none;" }
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
triggered by triggered by
- if @pipeline.user - if @pipeline.user
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;padding-left:5px", width: "24" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;padding-left:5px", width: "24" }
%img.avatar{ height: "24", src: avatar_icon(@pipeline.user, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/ %img.avatar{ height: "24", src: avatar_icon_for_user(@pipeline.user, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;font-weight:500;line-height:1.4;vertical-align:baseline;" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;font-weight:500;line-height:1.4;vertical-align:baseline;" }
%a.muted{ href: user_url(@pipeline.user), style: "color:#333333;text-decoration:none;" } %a.muted{ href: user_url(@pipeline.user), style: "color:#333333;text-decoration:none;" }
= @pipeline.user.name = @pipeline.user.name
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
%tbody %tbody
%tr %tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" }
%img.avatar{ height: "24", src: avatar_icon(commit.author || commit.author_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/ %img.avatar{ height: "24", src: avatar_icon_for(commit.author, commit.author_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" }
- if commit.author - if commit.author
%a.muted{ href: user_url(commit.author), style: "color:#333333;text-decoration:none;" } %a.muted{ href: user_url(commit.author), style: "color:#333333;text-decoration:none;" }
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
%tbody %tbody
%tr %tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" }
%img.avatar{ height: "24", src: avatar_icon(commit.committer || commit.committer_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/ %img.avatar{ height: "24", src: avatar_icon_for(commit.committer, commit.committer_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" }
- if commit.committer - if commit.committer
%a.muted{ href: user_url(commit.committer), style: "color:#333333;text-decoration:none;" } %a.muted{ href: user_url(commit.committer), style: "color:#333333;text-decoration:none;" }
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
triggered by triggered by
- if @pipeline.user - if @pipeline.user
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;padding-left:5px", width: "24" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;padding-left:5px", width: "24" }
%img.avatar{ height: "24", src: avatar_icon(@pipeline.user, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/ %img.avatar{ height: "24", src: avatar_icon_for_user(@pipeline.user, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;font-weight:500;line-height:1.4;vertical-align:baseline;" } %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;font-weight:500;line-height:1.4;vertical-align:baseline;" }
%a.muted{ href: user_url(@pipeline.user), style: "color:#333333;text-decoration:none;" } %a.muted{ href: user_url(@pipeline.user), style: "color:#333333;text-decoration:none;" }
= @pipeline.user.name = @pipeline.user.name
......
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
or change it at #{link_to Gitlab.config.gravatar.host, 'https://' + Gitlab.config.gravatar.host} or change it at #{link_to Gitlab.config.gravatar.host, 'https://' + Gitlab.config.gravatar.host}
.col-lg-8 .col-lg-8
.clearfix.avatar-image.append-bottom-default .clearfix.avatar-image.append-bottom-default
= link_to avatar_icon(@user, 400), target: '_blank', rel: 'noopener noreferrer' do = link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do
= image_tag avatar_icon(@user, 160), alt: '', class: 'avatar s160' = image_tag avatar_icon_for_user(@user, 160), alt: '', class: 'avatar s160'
%h5.prepend-top-0= _("Upload new avatar") %h5.prepend-top-0= _("Upload new avatar")
.prepend-top-5.append-bottom-10 .prepend-top-5.append-bottom-10
%button.btn.js-choose-user-avatar-button{ type: 'button' }= _("Choose file...") %button.btn.js-choose-user-avatar-button{ type: 'button' }= _("Choose file...")
......
...@@ -3,7 +3,7 @@ xml.entry do ...@@ -3,7 +3,7 @@ xml.entry do
xml.link href: project_commit_url(@project, id: commit.id) xml.link href: project_commit_url(@project, id: commit.id)
xml.title truncate(commit.title, length: 80, escape: false) xml.title truncate(commit.title, length: 80, escape: false)
xml.updated commit.committed_date.xmlschema xml.updated commit.committed_date.xmlschema
xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(commit.author_email)) xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon_for_email(commit.author_email))
xml.author do |author| xml.author do |author|
xml.name commit.author_name xml.name commit.author_name
......
by by
%a{ href: user_path(@build.user) } %a{ href: user_path(@build.user) }
%span.hidden-xs %span.hidden-xs
= image_tag avatar_icon(@build.user, 24), class: "avatar s24" = image_tag avatar_icon_for_user(@build.user, 24), class: "avatar s24"
%strong{ data: { toggle: 'tooltip', placement: 'top', title: @build.user.to_reference } } %strong{ data: { toggle: 'tooltip', placement: 'top', title: @build.user.to_reference } }
= @build.user.name = @build.user.name
%strong.visible-xs-inline= @build.user.to_reference %strong.visible-xs-inline= @build.user.to_reference
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
author: { author: {
name: c.author_name, name: c.author_name,
email: c.author_email, email: c.author_email,
icon: image_path(avatar_icon(c.author_email, 20)) icon: image_path(avatar_icon_for_email(c.author_email, 20))
}, },
time: c.time, time: c.time,
space: c.spaces.first, space: c.spaces.first,
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
= s_("PipelineSchedules|Inactive") = s_("PipelineSchedules|Inactive")
%td %td
- if pipeline_schedule.owner - if pipeline_schedule.owner
= image_tag avatar_icon(pipeline_schedule.owner, 20), class: "avatar s20" = image_tag avatar_icon_for_user(pipeline_schedule.owner, 20), class: "avatar s20"
= link_to user_path(pipeline_schedule.owner) do = link_to user_path(pipeline_schedule.owner) do
= pipeline_schedule.owner&.name = pipeline_schedule.owner&.name
%td %td
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
%div %div
= link_to project_commits_path(@project, commit.id) do = link_to project_commits_path(@project, commit.id) do
%code= commit.short_id %code= commit.short_id
= image_tag avatar_icon(commit.author_email), class: "", width: 16, alt: '' = image_tag avatar_icon_for_email(commit.author_email), class: "", width: 16, alt: ''
= markdown(truncate(commit.title, length: 40), pipeline: :single_line, author: commit.author) = markdown(truncate(commit.title, length: 40), pipeline: :single_line, author: commit.author)
%td %td
%span.pull-right.cgray %span.pull-right.cgray
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
= snippet.title = snippet.title
by by
= link_to user_snippets_path(snippet.author) do = link_to user_snippets_path(snippet.author) do
= image_tag avatar_icon(snippet.author), class: "avatar avatar-inline s16", alt: '' = image_tag avatar_icon_for_user(snippet.author), class: "avatar avatar-inline s16", alt: ''
= snippet.author_name = snippet.author_name
%span.light= time_ago_with_tooltip(snippet.created_at) %span.light= time_ago_with_tooltip(snippet.created_at)
%h4.snippet-title %h4.snippet-title
......
...@@ -18,6 +18,6 @@ ...@@ -18,6 +18,6 @@
%span %span
by by
= link_to user_snippets_path(snippet_title.author) do = link_to user_snippets_path(snippet_title.author) do
= image_tag avatar_icon(snippet_title.author), class: "avatar avatar-inline s16", alt: '' = image_tag avatar_icon_for_user(snippet_title.author), class: "avatar avatar-inline s16", alt: ''
= snippet_title.author_name = snippet_title.author_name
%span.light= time_ago_with_tooltip(snippet_title.created_at) %span.light= time_ago_with_tooltip(snippet_title.created_at)
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
%li.member{ class: dom_class(member), id: dom_id(member) } %li.member{ class: dom_class(member), id: dom_id(member) }
%span.list-item-name %span.list-item-name
- if user - if user
= image_tag avatar_icon(user, 40), class: "avatar s40", alt: '' = image_tag avatar_icon_for_user(user, 40), class: "avatar s40", alt: ''
.user-info .user-info
= link_to user.name, user_path(user), class: 'member' = link_to user.name, user_path(user), class: 'member'
%span.cgray= user.to_reference %span.cgray= user.to_reference
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
Expires in #{distance_of_time_in_words_to_now(member.expires_at)} Expires in #{distance_of_time_in_words_to_now(member.expires_at)}
- else - else
= image_tag avatar_icon(member.invite_email, 40), class: "avatar s40", alt: '' = image_tag avatar_icon_for_email(member.invite_email, 40), class: "avatar s40", alt: ''
.user-info .user-info
.member= member.invite_email .member= member.invite_email
.cgray .cgray
......
...@@ -28,4 +28,4 @@ ...@@ -28,4 +28,4 @@
- assignees.each do |assignee| - assignees.each do |assignee|
= link_to polymorphic_path(issuable_type_args, { milestone_title: @milestone.title, assignee_id: assignee.id, state: 'all' }), = link_to polymorphic_path(issuable_type_args, { milestone_title: @milestone.title, assignee_id: assignee.id, state: 'all' }),
class: 'has-tooltip', title: "Assigned to #{assignee.name}", data: { container: 'body' } do class: 'has-tooltip', title: "Assigned to #{assignee.name}", data: { container: 'body' } do
- image_tag(avatar_icon(assignee, 16), class: "avatar s16", alt: '') - image_tag(avatar_icon_for_user(assignee, 16), class: "avatar s16", alt: '')
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
- users.each do |user| - users.each do |user|
%li %li
= link_to user, title: user.name, class: "darken" do = link_to user, title: user.name, class: "darken" do
= image_tag avatar_icon(user, 32), class: "avatar s32" = image_tag avatar_icon_for_user(user, 32), class: "avatar s32"
%strong= truncate(user.name, length: 40) %strong= truncate(user.name, length: 40)
%div %div
%small.cgray= user.username %small.cgray= user.username
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
= icon_for_system_note(note) = icon_for_system_note(note)
- else - else
%a.image-diff-avatar-link{ href: user_path(note.author) } %a.image-diff-avatar-link{ href: user_path(note.author) }
= image_tag avatar_icon(note.author), alt: '', class: 'avatar s40' = image_tag avatar_icon_for_user(note.author), alt: '', class: 'avatar s40'
- if note.is_a?(DiffNote) && note.on_image? - if note.is_a?(DiffNote) && note.on_image?
- if show_image_comment_badge && note_counter == 0 - if show_image_comment_badge && note_counter == 0
-# Only show this for the first comment in the discussion -# Only show this for the first comment in the discussion
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
.timeline-icon.hidden-xs.hidden-sm .timeline-icon.hidden-xs.hidden-sm
%a.author_link{ href: user_path(current_user) } %a.author_link{ href: user_path(current_user) }
= image_tag avatar_icon(current_user), alt: current_user.to_reference, class: 'avatar s40' = image_tag avatar_icon_for_user(current_user), alt: current_user.to_reference, class: 'avatar s40'
.timeline-content.timeline-content-form .timeline-content.timeline-content-form
= render "shared/notes/form", view: diff_view, supports_autocomplete: autocomplete = render "shared/notes/form", view: diff_view, supports_autocomplete: autocomplete
- elsif !current_user - elsif !current_user
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
.avatar-container.s40 .avatar-container.s40
= link_to project_path(project), class: dom_class(project) do = link_to project_path(project), class: dom_class(project) do
- if project.creator && use_creator_avatar - if project.creator && use_creator_avatar
= image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:'' = image_tag avatar_icon_for_user(project.creator, 40), class: "avatar s40", alt:''
- else - else
= project_icon(project, alt: '', class: 'avatar project-avatar s40') = project_icon(project, alt: '', class: 'avatar project-avatar s40')
.project-details .project-details
......
- link_project = local_assigns.fetch(:link_project, false) - link_project = local_assigns.fetch(:link_project, false)
%li.snippet-row %li.snippet-row
= image_tag avatar_icon(snippet.author), class: "avatar s40 hidden-xs", alt: '' = image_tag avatar_icon_for_user(snippet.author), class: "avatar s40 hidden-xs", alt: ''
.title .title
= link_to reliable_snippet_path(snippet) do = link_to reliable_snippet_path(snippet) do
......
...@@ -35,8 +35,8 @@ ...@@ -35,8 +35,8 @@
.profile-header .profile-header
.avatar-holder .avatar-holder
= link_to avatar_icon(@user, 400), target: '_blank', rel: 'noopener noreferrer' do = link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do
= image_tag avatar_icon(@user, 90), class: "avatar s90", alt: '' = image_tag avatar_icon_for_user(@user, 90), class: "avatar s90", alt: ''
.user-info .user-info
.cover-title .cover-title
......
---
title: Use a user object in ApplicationHelper#avatar_icon where possible to avoid
N+1 queries.
merge_request: 42800
author:
type: performance
...@@ -63,13 +63,29 @@ describe ApplicationHelper do ...@@ -63,13 +63,29 @@ describe ApplicationHelper do
end end
end end
describe 'avatar_icon' do describe 'avatar_icon_for' do
let!(:user) { create(:user, avatar: File.open(uploaded_image_temp_path), email: 'bar@example.com') }
let(:email) { 'foo@example.com' }
let!(:another_user) { create(:user, avatar: File.open(uploaded_image_temp_path), email: email) }
it 'prefers the user to retrieve the avatar_url' do
expect(helper.avatar_icon_for(user, email).to_s)
.to eq(user.avatar.url)
end
it 'falls back to email lookup if no user given' do
expect(helper.avatar_icon_for(nil, email).to_s)
.to eq(another_user.avatar.url)
end
end
describe 'avatar_icon_for_email' do
let(:user) { create(:user, avatar: File.open(uploaded_image_temp_path)) } let(:user) { create(:user, avatar: File.open(uploaded_image_temp_path)) }
context 'using an email' do context 'using an email' do
context 'when there is a matching user' do context 'when there is a matching user' do
it 'returns a relative URL for the avatar' do it 'returns a relative URL for the avatar' do
expect(helper.avatar_icon(user.email).to_s) expect(helper.avatar_icon_for_email(user.email).to_s)
.to eq(user.avatar.url) .to eq(user.avatar.url)
end end
end end
...@@ -78,17 +94,37 @@ describe ApplicationHelper do ...@@ -78,17 +94,37 @@ describe ApplicationHelper do
it 'calls gravatar_icon' do it 'calls gravatar_icon' do
expect(helper).to receive(:gravatar_icon).with('foo@example.com', 20, 2) expect(helper).to receive(:gravatar_icon).with('foo@example.com', 20, 2)
helper.avatar_icon('foo@example.com', 20, 2) helper.avatar_icon_for_email('foo@example.com', 20, 2)
end
end
context 'without an email passed' do
it 'calls gravatar_icon' do
expect(helper).to receive(:gravatar_icon).with(nil, 20, 2)
helper.avatar_icon_for_email(nil, 20, 2)
end end
end end
end end
end
describe 'avatar_icon_for_user' do
let(:user) { create(:user, avatar: File.open(uploaded_image_temp_path)) }
describe 'using a user' do context 'with a user object passed' do
it 'returns a relative URL for the avatar' do it 'returns a relative URL for the avatar' do
expect(helper.avatar_icon(user).to_s) expect(helper.avatar_icon_for_user(user).to_s)
.to eq(user.avatar.url) .to eq(user.avatar.url)
end end
end end
context 'without a user object passed' do
it 'calls gravatar_icon' do
expect(helper).to receive(:gravatar_icon).with(nil, 20, 2)
helper.avatar_icon_for_user(nil, 20, 2)
end
end
end end
describe 'gravatar_icon' do describe 'gravatar_icon' do
......
...@@ -29,7 +29,7 @@ describe AvatarsHelper do ...@@ -29,7 +29,7 @@ describe AvatarsHelper do
is_expected.to eq tag( is_expected.to eq tag(
:img, :img,
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
src: avatar_icon(user, 16), src: avatar_icon_for_user(user, 16),
data: { container: 'body' }, data: { container: 'body' },
class: 'avatar s16 has-tooltip', class: 'avatar s16 has-tooltip',
title: user.name title: user.name
...@@ -43,7 +43,7 @@ describe AvatarsHelper do ...@@ -43,7 +43,7 @@ describe AvatarsHelper do
is_expected.to eq tag( is_expected.to eq tag(
:img, :img,
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
src: avatar_icon(user, 16), src: avatar_icon_for_user(user, 16),
data: { container: 'body' }, data: { container: 'body' },
class: "avatar s16 #{options[:css_class]} has-tooltip", class: "avatar s16 #{options[:css_class]} has-tooltip",
title: user.name title: user.name
...@@ -58,7 +58,7 @@ describe AvatarsHelper do ...@@ -58,7 +58,7 @@ describe AvatarsHelper do
is_expected.to eq tag( is_expected.to eq tag(
:img, :img,
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
src: avatar_icon(user, options[:size]), src: avatar_icon_for_user(user, options[:size]),
data: { container: 'body' }, data: { container: 'body' },
class: "avatar s#{options[:size]} has-tooltip", class: "avatar s#{options[:size]} has-tooltip",
title: user.name title: user.name
...@@ -89,7 +89,7 @@ describe AvatarsHelper do ...@@ -89,7 +89,7 @@ describe AvatarsHelper do
:img, :img,
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
src: LazyImageTagHelper.placeholder_image, src: LazyImageTagHelper.placeholder_image,
data: { container: 'body', src: avatar_icon(user, 16) }, data: { container: 'body', src: avatar_icon_for_user(user, 16) },
class: "avatar s16 has-tooltip lazy", class: "avatar s16 has-tooltip lazy",
title: user.name title: user.name
) )
...@@ -104,7 +104,7 @@ describe AvatarsHelper do ...@@ -104,7 +104,7 @@ describe AvatarsHelper do
is_expected.to eq tag( is_expected.to eq tag(
:img, :img,
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
src: avatar_icon(user, 16), src: avatar_icon_for_user(user, 16),
data: { container: 'body' }, data: { container: 'body' },
class: "avatar s16 has-tooltip", class: "avatar s16 has-tooltip",
title: user.name title: user.name
...@@ -119,7 +119,7 @@ describe AvatarsHelper do ...@@ -119,7 +119,7 @@ describe AvatarsHelper do
is_expected.to eq tag( is_expected.to eq tag(
:img, :img,
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
src: avatar_icon(user, 16), src: avatar_icon_for_user(user, 16),
class: "avatar s16", class: "avatar s16",
title: user.name title: user.name
) )
...@@ -137,7 +137,7 @@ describe AvatarsHelper do ...@@ -137,7 +137,7 @@ describe AvatarsHelper do
is_expected.to eq tag( is_expected.to eq tag(
:img, :img,
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
src: avatar_icon(user, 16), src: avatar_icon_for_user(user, 16),
data: { container: 'body' }, data: { container: 'body' },
class: "avatar s16 has-tooltip", class: "avatar s16 has-tooltip",
title: user.name title: user.name
...@@ -149,7 +149,7 @@ describe AvatarsHelper do ...@@ -149,7 +149,7 @@ describe AvatarsHelper do
is_expected.to eq tag( is_expected.to eq tag(
:img, :img,
alt: "#{options[:user_name]}'s avatar", alt: "#{options[:user_name]}'s avatar",
src: avatar_icon(options[:user_email], 16), src: avatar_icon_for_email(options[:user_email], 16),
data: { container: 'body' }, data: { container: 'body' },
class: "avatar s16 has-tooltip", class: "avatar s16 has-tooltip",
title: options[:user_name] title: options[:user_name]
......
...@@ -215,7 +215,7 @@ describe ProjectsHelper do ...@@ -215,7 +215,7 @@ describe ProjectsHelper do
let(:expected) { double } let(:expected) { double }
before do before do
expect(helper).to receive(:avatar_icon).with(user, 16).and_return(expected) expect(helper).to receive(:avatar_icon_for_user).with(user, 16).and_return(expected)
end end
it 'returns image tag for member avatar' do it 'returns image tag for member avatar' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment