Commit 3fb1042d authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge pull request #5281 from Popl7/upload_avatar_to_gitlab

avatar upload on profile page
parents 6fbb7e6c 65cad57a
...@@ -13,6 +13,7 @@ v 6.2.0 ...@@ -13,6 +13,7 @@ v 6.2.0
- Rake tasks for web hooks management (Jonhnny Weslley) - Rake tasks for web hooks management (Jonhnny Weslley)
- Extended User API to expose admin and can_create_group for user creation/updating (Boyan Tabakov) - Extended User API to expose admin and can_create_group for user creation/updating (Boyan Tabakov)
- API: Remove group - API: Remove group
- Avatar upload on profile page with a maximum of 200KB (Steven Thonus)
v 6.1.0 v 6.1.0
- Project specific IDs for issues, mr, milestones - Project specific IDs for issues, mr, milestones
......
...@@ -16,3 +16,13 @@ $ -> ...@@ -16,3 +16,13 @@ $ ->
$('.update-notifications').on 'ajax:complete', -> $('.update-notifications').on 'ajax:complete', ->
$(this).find('.btn-save').enableButton() $(this).find('.btn-save').enableButton()
$('.js-choose-user-avatar-button').bind "click", ->
form = $(this).closest("form")
form.find(".js-user-avatar-input").click()
$('.js-user-avatar-input').bind "change", ->
form = $(this).closest("form")
filename = $(this).val().replace(/^.*[\\\/]/, '')
form.find(".js-avatar-filename").text(filename)
$ -> $ ->
userFormatResult = (user) -> userFormatResult = (user) ->
avatar = gon.gravatar_url if user.avatar
avatar = avatar.replace('%{hash}', md5(user.email)) avatar = user.avatar.url
avatar = avatar.replace('%{size}', '24') else
avatar = gon.gravatar_url
avatar = avatar.replace('%{hash}', md5(user.email))
avatar = avatar.replace('%{size}', '24')
markup = "<div class='user-result'>" markup = "<div class='user-result'>"
markup += "<div class='user-image'><img class='avatar s24' src='" + avatar + "'></div>" markup += "<div class='user-image'><img class='avatar s24' src='" + avatar + "'></div>"
markup += "<div class='user-name'>" + user.name + "</div>" markup += "<div class='user-name'>" + user.name + "</div>"
......
...@@ -49,6 +49,15 @@ module ApplicationHelper ...@@ -49,6 +49,15 @@ module ApplicationHelper
args.any? { |v| v.to_s.downcase == action_name } args.any? { |v| v.to_s.downcase == action_name }
end end
def avatar_icon(user_email = '', size = nil)
user = User.find_by_email(user_email)
if user && user.avatar.present?
user.avatar.url
else
gravatar_icon(user_email, size)
end
end
def gravatar_icon(user_email = '', size = nil) def gravatar_icon(user_email = '', size = nil)
size = 40 if size.nil? || size <= 0 size = 40 if size.nil? || size <= 0
......
...@@ -108,7 +108,7 @@ module CommitsHelper ...@@ -108,7 +108,7 @@ module CommitsHelper
source_name = commit.send "#{options[:source]}_name".to_sym source_name = commit.send "#{options[:source]}_name".to_sym
source_email = commit.send "#{options[:source]}_email".to_sym source_email = commit.send "#{options[:source]}_email".to_sym
text = if options[:avatar] text = if options[:avatar]
avatar = image_tag(gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: "") avatar = image_tag(avatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: "")
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>} %Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>}
else else
source_name source_name
......
...@@ -25,7 +25,7 @@ module ProjectsHelper ...@@ -25,7 +25,7 @@ module ProjectsHelper
author_html = "" author_html = ""
# Build avatar image tag # Build avatar image tag
author_html << image_tag(gravatar_icon(author.try(:email), opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar] author_html << image_tag(avatar_icon(author.try(:email), opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar]
# Build name span tag # Build name span tag
author_html << content_tag(:span, sanitize(author.name), class: 'author') if opts[:name] author_html << content_tag(:span, sanitize(author.name), class: 'author') if opts[:name]
......
...@@ -38,13 +38,16 @@ ...@@ -38,13 +38,16 @@
# created_by_id :integer # created_by_id :integer
# #
require 'carrierwave/orm/activerecord'
require 'file_size_validator'
class User < ActiveRecord::Base class User < ActiveRecord::Base
devise :database_authenticatable, :token_authenticatable, :lockable, devise :database_authenticatable, :token_authenticatable, :lockable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :registerable :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :registerable
attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name, :username, attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name, :username,
:skype, :linkedin, :twitter, :color_scheme_id, :theme_id, :force_random_password, :skype, :linkedin, :twitter, :color_scheme_id, :theme_id, :force_random_password,
:extern_uid, :provider, :password_expires_at, :extern_uid, :provider, :password_expires_at, :avatar,
as: [:default, :admin] as: [:default, :admin]
attr_accessible :projects_limit, :can_create_group, attr_accessible :projects_limit, :can_create_group,
...@@ -113,6 +116,8 @@ class User < ActiveRecord::Base ...@@ -113,6 +116,8 @@ class User < ActiveRecord::Base
validate :namespace_uniq, if: ->(user) { user.username_changed? } validate :namespace_uniq, if: ->(user) { user.username_changed? }
validates :avatar, file_size: { maximum: 100.kilobytes.to_i }
before_validation :generate_password, on: :create before_validation :generate_password, on: :create
before_validation :sanitize_attrs before_validation :sanitize_attrs
...@@ -150,6 +155,8 @@ class User < ActiveRecord::Base ...@@ -150,6 +155,8 @@ class User < ActiveRecord::Base
end end
end end
mount_uploader :avatar, AttachmentUploader
# Scopes # Scopes
scope :admins, -> { where(admin: true) } scope :admins, -> { where(admin: true) }
scope :blocked, -> { with_state(:blocked) } scope :blocked, -> { with_state(:blocked) }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
.title .title
Account: Account:
.pull-right .pull-right
= image_tag gravatar_icon(@user.email, 32), class: "avatar s32" = image_tag avatar_icon(@user.email, 32), class: "avatar s32"
%ul.well-list %ul.well-list
%li %li
%span.light Name: %span.light Name:
......
...@@ -12,7 +12,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -12,7 +12,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
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.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(issue.author_email) xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(issue.author_email)
xml.author do |author| xml.author do |author|
xml.name issue.author_name xml.name issue.author_name
xml.email issue.author_email xml.email issue.author_email
......
...@@ -17,7 +17,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -17,7 +17,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.link :href => event_link xml.link :href => event_link
xml.title truncate(event_title, :length => 80) xml.title truncate(event_title, :length => 80)
xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(event.author_email) xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(event.author_email)
xml.author do |author| xml.author do |author|
xml.name event.author_name xml.name event.author_name
xml.email event.author_email xml.email event.author_email
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#{time_ago_in_words(event.created_at)} ago. #{time_ago_in_words(event.created_at)} ago.
= cache event do = cache event do
= image_tag gravatar_icon(event.author_email), class: "avatar s24", alt:'' = image_tag avatar_icon(event.author_email), class: "avatar s24", alt:''
- if event.push? - if event.push?
= render "events/event/push", event: event = render "events/event/push", event: event
......
...@@ -12,7 +12,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -12,7 +12,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
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.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(issue.author_email) xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(issue.author_email)
xml.author do |author| xml.author do |author|
xml.name issue.author_name xml.name issue.author_name
xml.email issue.author_email xml.email issue.author_email
......
...@@ -16,7 +16,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -16,7 +16,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.link :href => event_link xml.link :href => event_link
xml.title truncate(event_title, :length => 80) xml.title truncate(event_title, :length => 80)
xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(event.author_email) xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(event.author_email)
xml.author do |author| xml.author do |author|
xml.name event.author_name xml.name event.author_name
xml.email event.author_email xml.email event.author_email
......
...@@ -37,4 +37,4 @@ ...@@ -37,4 +37,4 @@
%i.icon-signout %i.icon-signout
%li %li
= link_to current_user, class: "profile-pic", id: 'profile-pic' do = link_to current_user, class: "profile-pic", id: 'profile-pic' do
= image_tag gravatar_icon(current_user.email, 26), alt: '' = image_tag avatar_icon(current_user.email, 26), alt: ''
= image_tag gravatar_icon(@user.email, 60), alt: '', class: 'avatar s60' = image_tag avatar_icon(@user.email, 60), alt: '', class: 'avatar s60'
%h3.page-title %h3.page-title
= @user.name = @user.name
%br %br
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
Logout Logout
%hr %hr
= form_for @user, url: profile_path, method: :put, html: { class: "edit_user form-horizontal" } do |f| = form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit_user form-horizontal" } do |f|
-if @user.errors.any? -if @user.errors.any?
%div.alert.alert-error %div.alert.alert-error
%ul %ul
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
= f.label :email, class: "control-label" = f.label :email, class: "control-label"
.controls .controls
= f.text_field :email, class: "input-xlarge", required: true = f.text_field :email, class: "input-xlarge", required: true
%span.help-block We also use email for avatar detection. %span.help-block We also use email for avatar detection if no avatar is uploaded.
.control-group .control-group
= f.label :skype, class: "control-label" = f.label :skype, class: "control-label"
.controls= f.text_field :skype, class: "input-xlarge" .controls= f.text_field :skype, class: "input-xlarge"
...@@ -39,6 +39,17 @@ ...@@ -39,6 +39,17 @@
.control-group .control-group
= f.label :twitter, class: "control-label" = f.label :twitter, class: "control-label"
.controls= f.text_field :twitter, class: "input-xlarge" .controls= f.text_field :twitter, class: "input-xlarge"
.control-group
= f.label :avatar, class: "control-label"
.controls
.profile-avatar-form-option
%a.choose-btn.btn.btn-small.js-choose-user-avatar-button
%i.icon-paper-clip
%span Choose File ...
&nbsp;
%span.file_name.js-avatar-filename File name...
= f.file_field :avatar, class: "js-user-avatar-input hide"
%span.help-block The maximum file size allowed is 200KB.
.control-group .control-group
= f.label :bio, class: "control-label" = f.label :bio, class: "control-label"
.controls .controls
...@@ -53,7 +64,7 @@ ...@@ -53,7 +64,7 @@
%p You can change your password on the Account page %p You can change your password on the Account page
- if Gitlab.config.gravatar.enabled - if Gitlab.config.gravatar.enabled
%li %li
%p You can change your avatar at #{link_to "gravatar.com", "http://gravatar.com"} %p You can upload an avatar here or change it at #{link_to "gravatar.com", "http://gravatar.com"}
- if Gitlab.config.omniauth.enabled && @user.provider? - if Gitlab.config.omniauth.enabled && @user.provider?
%li %li
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
%p %p
= link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do
= commit.short_id = commit.short_id
= image_tag gravatar_icon(commit.author_email), class: "avatar s16", alt: '' = image_tag avatar_icon(commit.author_email), class: "avatar s16", alt: ''
%span.light %span.light
= gfm escape_once(truncate(commit.title, length: 40)) = gfm escape_once(truncate(commit.title, length: 40))
%span %span
......
...@@ -12,7 +12,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -12,7 +12,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
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) xml.title truncate(commit.title, :length => 80)
xml.updated commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ") xml.updated commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ")
xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(commit.author_email) xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(commit.author_email)
xml.author do |author| xml.author do |author|
xml.name commit.author_name xml.name commit.author_name
xml.email commit.author_email xml.email commit.author_email
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
- @project.team.members.sort_by(&:name).each do |user| - @project.team.members.sort_by(&:name).each do |user|
%li %li
= link_to project_filter_path(assignee_id: user.id) do = link_to project_filter_path(assignee_id: user.id) do
= image_tag gravatar_icon(user.email), class: "avatar s16", alt: '' = image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
= user.name = user.name
.dropdown.inline.prepend-left-10 .dropdown.inline.prepend-left-10
......
...@@ -12,7 +12,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -12,7 +12,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.link :href => project_issue_url(@project, issue) xml.link :href => project_issue_url(@project, issue)
xml.title truncate(issue.title, :length => 80) xml.title truncate(issue.title, :length => 80)
xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(issue.author_email) xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(issue.author_email)
xml.author do |author| xml.author do |author|
xml.name issue.author_name xml.name issue.author_name
xml.email issue.author_email xml.email issue.author_email
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
- @project.team.members.sort_by(&:name).each do |user| - @project.team.members.sort_by(&:name).each do |user|
%li %li
= link_to project_filter_path(assignee_id: user.id) do = link_to project_filter_path(assignee_id: user.id) do
= image_tag gravatar_icon(user.email), class: "avatar s16", alt: '' = image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
= user.name = user.name
.dropdown.inline.prepend-left-10 .dropdown.inline.prepend-left-10
......
...@@ -8,4 +8,4 @@ ...@@ -8,4 +8,4 @@
= link_to_gfm truncate(issue.title, length: 40), [@project, issue] = link_to_gfm truncate(issue.title, length: 40), [@project, issue]
- if issue.assignee - if issue.assignee
.pull-right .pull-right
= image_tag gravatar_icon(issue.assignee.email, 16), class: "avatar s16" = image_tag avatar_icon(issue.assignee.email, 16), class: "avatar s16"
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
- @users.each do |user| - @users.each do |user|
%li %li
= link_to user, title: user.name, class: "dark" do = link_to user, title: user.name, class: "dark" do
= image_tag gravatar_icon(user.email, 32), class: "avatar s32" = image_tag avatar_icon(user.email, 32), class: "avatar s32"
%strong= truncate(user.name, lenght: 40) %strong= truncate(user.name, lenght: 40)
%br %br
%small.cgray= user.username %small.cgray= user.username
...@@ -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: gravatar_icon(c.author_email, 20) icon: avatar_icon(c.author_email, 20)
}, },
time: c.time, time: c.time,
space: c.spaces.first, space: c.spaces.first,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
= link_to "javascript:;", class: "js-details-target turn-off js-toggler-target" do = link_to "javascript:;", class: "js-details-target turn-off js-toggler-target" do
%i.icon-eye-open %i.icon-eye-open
Show discussion Show discussion
= image_tag gravatar_icon(note.author_email), class: "avatar s32" = image_tag avatar_icon(note.author_email), class: "avatar s32"
%div %div
= link_to_member(@project, note.author, avatar: false) = link_to_member(@project, note.author, avatar: false)
- if note.for_merge_request? - if note.for_merge_request?
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
= link_to project_note_path(@project, note), title: "Remove comment", method: :delete, confirm: 'Are you sure you want to remove this comment?', remote: true, class: "danger js-note-delete" do = link_to project_note_path(@project, note), title: "Remove comment", method: :delete, confirm: 'Are you sure you want to remove this comment?', remote: true, class: "danger js-note-delete" do
%i.icon-trash.cred %i.icon-trash.cred
Remove Remove
= image_tag gravatar_icon(note.author_email), class: "avatar s32" = image_tag avatar_icon(note.author_email), class: "avatar s32"
= link_to_member(@project, note.author, avatar: false) = link_to_member(@project, note.author, avatar: false)
%span.note-last-update %span.note-last-update
= note_timestamp(note) = note_timestamp(note)
......
...@@ -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 gravatar_icon(commit.author_email), class: "", width: 16, alt: '' = image_tag avatar_icon(commit.author_email), class: "", width: 16, alt: ''
= gfm escape_once(truncate(commit.title, length: 40)) = gfm escape_once(truncate(commit.title, length: 40))
%td %td
%span.pull-right.cgray %span.pull-right.cgray
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
%ol.styled %ol.styled
- @stats.authors[0...50].each do |author| - @stats.authors[0...50].each do |author|
%li %li
= image_tag gravatar_icon(author.email, 16), class: 'avatar s16', alt: '' = image_tag avatar_icon(author.email, 16), class: 'avatar s16', alt: ''
= author.name = author.name
%small.light= author.email %small.light= author.email
.pull-right .pull-right
......
...@@ -16,6 +16,6 @@ ...@@ -16,6 +16,6 @@
= "##{snippet.id}" = "##{snippet.id}"
%span %span
by by
= image_tag gravatar_icon(snippet.author_email), class: "avatar avatar-inline s16" = image_tag avatar_icon(snippet.author_email), class: "avatar avatar-inline s16"
= snippet.author_name = snippet.author_name
%span.light #{time_ago_in_words(snippet.created_at)} ago %span.light #{time_ago_in_words(snippet.created_at)} ago
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
= "##{@snippet.id}" = "##{@snippet.id}"
%span.light %span.light
by by
= image_tag gravatar_icon(@snippet.author_email), class: "avatar avatar-inline s16" = image_tag avatar_icon(@snippet.author_email), class: "avatar avatar-inline s16"
= @snippet.author_name = @snippet.author_name
%div= render 'projects/snippets/blob' %div= render 'projects/snippets/blob'
%div#notes= render "projects/notes/notes_with_form" %div#notes= render "projects/notes/notes_with_form"
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
&nbsp; &nbsp;
= link_to project_team_member_path(@project, user), confirm: remove_from_project_team_message(@project, user), method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from team' do = link_to project_team_member_path(@project, user), confirm: remove_from_project_team_message(@project, user), method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from team' do
%i.icon-minus.icon-white %i.icon-minus.icon-white
= image_tag gravatar_icon(user.email, 32), class: "avatar s32" = image_tag avatar_icon(user.email, 32), class: "avatar s32"
%p %p
%strong= user.name %strong= user.name
%span.cgray= user.username %span.cgray= user.username
......
...@@ -18,6 +18,6 @@ ...@@ -18,6 +18,6 @@
%span %span
by by
= link_to user_snippets_path(snippet.author) do = link_to user_snippets_path(snippet.author) do
= image_tag gravatar_icon(snippet.author_email), class: "avatar avatar-inline s16", alt: '' = image_tag avatar_icon(snippet.author_email), class: "avatar avatar-inline s16", alt: ''
= snippet.author_name = snippet.author_name
%span.light #{time_ago_in_words(snippet.created_at)} ago %span.light #{time_ago_in_words(snippet.created_at)} ago
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
%span.light %span.light
by by
= link_to user_snippets_path(@snippet.author) do = link_to user_snippets_path(@snippet.author) do
= image_tag gravatar_icon(@snippet.author_email), class: "avatar avatar-inline s16" = image_tag avatar_icon(@snippet.author_email), class: "avatar avatar-inline s16"
= @snippet.author_name = @snippet.author_name
.back-link .back-link
......
%h3.page-title %h3.page-title
= image_tag gravatar_icon(@user.email), class: "avatar s24" = image_tag avatar_icon(@user.email), class: "avatar s24"
= @user.name = @user.name
%span %span
\/ \/
......
.row .row
.span8 .span8
%h3.page-title %h3.page-title
= image_tag gravatar_icon(@user.email, 90), class: "avatar s90", alt: '' = image_tag avatar_icon(@user.email, 90), class: "avatar s90", alt: ''
= @user.name = @user.name
- if @user == current_user - if @user == current_user
.pull-right .pull-right
......
- user = member.user - user = member.user
- return unless user - return unless user
%li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)} %li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)}
= image_tag gravatar_icon(user.email, 16), class: "avatar s16" = image_tag avatar_icon(user.email, 16), class: "avatar s16"
%strong= user.name %strong= user.name
%span.cgray= user.username %span.cgray= user.username
- if user == current_user - if user == current_user
......
class AddAvatarToUsers < ActiveRecord::Migration
def change
add_column :users, :avatar, :string
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130926081215) do ActiveRecord::Schema.define(:version => 20131005191208) do
create_table "deploy_keys_projects", :force => true do |t| create_table "deploy_keys_projects", :force => true do |t|
t.integer "deploy_key_id", :null => false t.integer "deploy_key_id", :null => false
...@@ -283,6 +283,7 @@ ActiveRecord::Schema.define(:version => 20130926081215) do ...@@ -283,6 +283,7 @@ ActiveRecord::Schema.define(:version => 20130926081215) do
t.integer "notification_level", :default => 1, :null => false t.integer "notification_level", :default => 1, :null => false
t.datetime "password_expires_at" t.datetime "password_expires_at"
t.integer "created_by_id" t.integer "created_by_id"
t.string "avatar"
end end
add_index "users", ["admin"], :name => "index_users_on_admin" add_index "users", ["admin"], :name => "index_users_on_admin"
......
...@@ -22,6 +22,11 @@ Feature: Profile ...@@ -22,6 +22,11 @@ Feature: Profile
Then I change my password Then I change my password
And I should be redirected to sign in page And I should be redirected to sign in page
Scenario: I edit my avatar
Given I visit profile page
Then I change my avatar
And I should see new avatar
Scenario: My password is expired Scenario: My password is expired
Given my password is expired Given my password is expired
And I am not an ldap user And I am not an ldap user
......
...@@ -22,6 +22,17 @@ class Profile < Spinach::FeatureSteps ...@@ -22,6 +22,17 @@ class Profile < Spinach::FeatureSteps
@user.twitter.should == 'testtwitter' @user.twitter.should == 'testtwitter'
end end
step 'I change my avatar' do
attach_file(:user_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png'))
click_button "Save changes"
@user.reload
end
step 'I should see new avatar' do
@user.avatar.should be_instance_of AttachmentUploader
@user.avatar.url.should == "/uploads/user/avatar/#{ @user.id }/gitlab_logo.png"
end
step 'I try change my password w/o old one' do step 'I try change my password w/o old one' do
within '.update-password' do within '.update-password' do
fill_in "user_password", with: "222333" fill_in "user_password", with: "222333"
......
...@@ -38,6 +38,24 @@ describe ApplicationHelper do ...@@ -38,6 +38,24 @@ describe ApplicationHelper do
current_action?(:baz, :bar, :foo).should be_true current_action?(:baz, :bar, :foo).should be_true
end end
end end
describe "avatar_icon" do
avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png')
it "should return an url for the avatar" do
user = create(:user)
user.avatar = File.open(avatar_file_path)
user.save!
avatar_icon(user.email).to_s.should == "/uploads/user/avatar/#{ user.id }/gitlab_logo.png"
end
it "should call gravatar_icon when no avatar is present" do
user = create(:user)
user.save!
stub!(:gravatar_icon).and_return('gravatar_method_called')
avatar_icon(user.email).to_s.should == "gravatar_method_called"
end
end
describe "gravatar_icon" do describe "gravatar_icon" do
let(:user_email) { 'user@email.com' } let(:user_email) { 'user@email.com' }
......
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