From d5d702e7a811a0d8310a622ab00942c719b2b98f Mon Sep 17 00:00:00 2001 From: Steven Thonus Date: Sat, 25 Jan 2014 18:15:44 +0100 Subject: [PATCH 1/4] adding avatar to project settings page added avatar removal show project avatar on dashboard, projects page, project page added rspec and feature tests added project avatar from repository new default project icon added added copying af avatar to forking of project added generated icon fixed avatar fork hound fix style fix test fix --- app/assets/images/no_project_icon.png | Bin 0 -> 3387 bytes app/assets/javascripts/project.js.coffee | 10 ++++ app/assets/stylesheets/generic/avatar.scss | 13 +++++ .../stylesheets/sections/dashboard.scss | 15 ++++-- .../projects/avatars_controller.rb | 29 +++++++++++ app/helpers/application_helper.rb | 25 ++++++++++ app/models/project.rb | 21 ++++++++ app/services/projects/fork_service.rb | 3 ++ app/views/dashboard/_project.html.haml | 2 + app/views/dashboard/projects.html.haml | 3 +- app/views/projects/_home_panel.html.haml | 2 + app/views/projects/edit.html.haml | 28 ++++++++++- config/routes.rb | 2 + .../20140125162722_add_avatar_to_projects.rb | 5 ++ db/schema.rb | 1 + features/project/project.feature | 13 +++++ features/steps/project/project.rb | 47 ++++++++++++++++-- spec/helpers/application_helper_spec.rb | 22 ++++++++ spec/models/project_spec.rb | 15 ++++++ spec/routing/project_routing_spec.rb | 8 +++ 20 files changed, 255 insertions(+), 9 deletions(-) create mode 100644 app/assets/images/no_project_icon.png create mode 100644 app/controllers/projects/avatars_controller.rb create mode 100644 db/migrate/20140125162722_add_avatar_to_projects.rb diff --git a/app/assets/images/no_project_icon.png b/app/assets/images/no_project_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8e9529c67ec3a7167c59f2c52bdb4b009b9803cf GIT binary patch literal 3387 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 $(@).toggleClass('on').find('.count').html(data.star_count) .on 'ajax:error', (e, xhr, status, error) -> new Flash('Star toggle failed. Try again later.', 'alert') + + # avatar + $('.js-choose-project-avatar-button').bind "click", -> + form = $(this).closest("form") + form.find(".js-project-avatar-input").click() + + $('.js-project-avatar-input').bind "change", -> + form = $(this).closest("form") + filename = $(this).val().replace(/^.*[\\\/]/, '') + form.find(".js-avatar-filename").text(filename) diff --git a/app/assets/stylesheets/generic/avatar.scss b/app/assets/stylesheets/generic/avatar.scss index 4f038b977e2c6..661dc4805e1ef 100644 --- a/app/assets/stylesheets/generic/avatar.scss +++ b/app/assets/stylesheets/generic/avatar.scss @@ -21,3 +21,16 @@ &.s90 { width: 90px; height: 90px; margin-right: 15px; } &.s160 { width: 160px; height: 160px; margin-right: 20px; } } + +.identicon { + text-align: center; + vertical-align: top; + + &.s16 { font-size: 12px; line-height: 1.33; } + &.s24 { font-size: 18px; line-height: 1.33; } + &.s26 { font-size: 20px; line-height: 1.33; } + &.s32 { font-size: 24px; line-height: 1.33; } + &.s60 { font-size: 45px; line-height: 1.33; } + &.s90 { font-size: 68px; line-height: 1.33; } + &.s160 { font-size: 120px; line-height: 1.33; } +} \ No newline at end of file diff --git a/app/assets/stylesheets/sections/dashboard.scss b/app/assets/stylesheets/sections/dashboard.scss index 6487e0acd910d..9b19a11852adf 100644 --- a/app/assets/stylesheets/sections/dashboard.scss +++ b/app/assets/stylesheets/sections/dashboard.scss @@ -88,26 +88,33 @@ } } } - +.project-avatar { + float: left; +} .project-access-icon { - margin-left: 10px; float: left; - margin-right: 15px; font-size: 20px; margin-bottom: 15px; border: 1px solid #EEE; padding: 8px 12px; - border-radius: 50px; + border-radius: 20px; background: #f5f5f5; text-align: center; + position: relative; + left: -32px; + top: 38px; i { color: #BBB; } } +.dash-project-avatar { + float: left; +} .dash-project-access-icon { float: left; margin-right: 3px; + color: #999; width: 16px; } diff --git a/app/controllers/projects/avatars_controller.rb b/app/controllers/projects/avatars_controller.rb new file mode 100644 index 0000000000000..a482b90880da9 --- /dev/null +++ b/app/controllers/projects/avatars_controller.rb @@ -0,0 +1,29 @@ +class Projects::AvatarsController < Projects::ApplicationController + layout 'project' + + before_filter :project + + def show + @blob = @project.repository.blob_at_branch('master', @project.avatar_in_git) + if @blob + headers['X-Content-Type-Options'] = 'nosniff' + send_data( + @blob.data, + type: @blob.mime_type, + disposition: 'inline', + filename: @blob.name + ) + else + not_found! + end + end + + def destroy + @project.remove_avatar! + + @project.save + @project.reset_events_cache + + redirect_to edit_project_path(@project) + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c3d89eb1b82d5..5a193df0f6c86 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -49,6 +49,31 @@ def current_action?(*args) args.any? { |v| v.to_s.downcase == action_name } end + def project_icon(project_id, options = {}) + project = Project.find_with_namespace(project_id) + if project.avatar.present? + image_tag project.avatar.url, options + elsif options[:only_uploaded] + image_tag '/assets/no_project_icon.png', options + elsif project.avatar_in_git + image_tag project_avatar_path(project), options + else # generated icon + project_identicon(project, options) + end + end + + def project_identicon(project, options = {}) + options[:class] ||= '' + options[:class] << ' identicon' + bg_color = Digest::MD5.hexdigest(project.name)[0, 6] + brightness = bg_color[0, 2].hex + bg_color[2, 2].hex + bg_color[4, 2].hex + text_color = (brightness > 375) ? '#000' : '#fff' + content_tag(:div, class: options[:class], + style: "background-color: ##{ bg_color }; color: #{ text_color }") do + project.name[0, 1].upcase + end + end + def group_icon(group_path) group = Group.find_by(path: group_path) if group && group.avatar.present? diff --git a/app/models/project.rb b/app/models/project.rb index 0e93e32162d44..d2a1c52056e85 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -23,6 +23,7 @@ # archived :boolean default(FALSE), not null # import_status :string(255) # star_count :integer +# avatar :string(255) # class Project < ActiveRecord::Base @@ -113,6 +114,12 @@ class Project < ActiveRecord::Base validates :star_count, numericality: { greater_than_or_equal_to: 0 } validate :check_limit, on: :create + validate :avatar_type, + if: ->(project) { project.avatar && project.avatar_changed? } + validates :avatar, file_size: { maximum: 100.kilobytes.to_i } + + mount_uploader :avatar, AttachmentUploader + # Scopes scope :without_user, ->(user) { where("projects.id NOT IN (:ids)", ids: user.authorized_projects.map(&:id) ) } scope :without_team, ->(team) { team.projects.present? ? where("projects.id NOT IN (:ids)", ids: team.projects.map(&:id)) : scoped } @@ -324,6 +331,19 @@ def ci_service @ci_service ||= ci_services.select(&:activated?).first end + def avatar_type + unless avatar.image? + errors.add :avatar, 'only images allowed' + end + end + + def avatar_in_git + @avatar_file ||= 'logo.png' if repository.blob_at_branch('master', 'logo.png') + @avatar_file ||= 'logo.jpg' if repository.blob_at_branch('master', 'logo.jpg') + @avatar_file ||= 'logo.gif' if repository.blob_at_branch('master', 'logo.gif') + @avatar_file + end + # For compatibility with old code def code path @@ -525,6 +545,7 @@ def rename_repo # Since we do cache @event we need to reset cache in special cases: # * when project was moved # * when project was renamed + # * when the project avatar changes # Events cache stored like events/23-20130109142513. # The cache key includes updated_at timestamp. # Thus it will automatically generate a new fragment diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb index 2f1c7b18aa042..7c7b80b370197 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -12,6 +12,9 @@ def execute project.path = @from_project.path project.namespace = current_user.namespace project.creator = current_user + if @from_project.avatar && @from_project.avatar.image? + project.avatar = @from_project.avatar + end # If the project cannot save, we do not want to trigger the project destroy # as this can have the side effect of deleting a repo attached to an existing diff --git a/app/views/dashboard/_project.html.haml b/app/views/dashboard/_project.html.haml index e326bee53abd2..c455750b38a4c 100644 --- a/app/views/dashboard/_project.html.haml +++ b/app/views/dashboard/_project.html.haml @@ -1,4 +1,6 @@ = link_to project_path(project), class: dom_class(project) do + .dash-project-avatar + = project_icon(project.to_param, alt: '', class: 'avatar s24') .dash-project-access-icon = visibility_level_icon(project.visibility_level) %span.str-truncated diff --git a/app/views/dashboard/projects.html.haml b/app/views/dashboard/projects.html.haml index 2714ebc53de02..8c11d8fea2cc4 100644 --- a/app/views/dashboard/projects.html.haml +++ b/app/views/dashboard/projects.html.haml @@ -32,6 +32,8 @@ - @projects.each do |project| %li.my-project-row %h4.project-title + .project-avatar + = project_icon(project.to_param, alt: '', class: 'avatar s60') .project-access-icon = visibility_level_icon(project.visibility_level) = link_to project_path(project), class: dom_class(project) do @@ -70,4 +72,3 @@ .nothing-here-block There are no projects here. .bottom = paginate @projects, theme: "gitlab" - diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index 62348f26f0a58..26dab243dda13 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -2,8 +2,10 @@ .project-home-panel{:class => ("empty-project" if empty_repo)} .visibility-level-label.has_tooltip{'data-title' => "#{visibility_level_label(@project.visibility_level)} project" } = visibility_level_icon(@project.visibility_level) + .row .col-sm-6 + = project_icon(@project.to_param, alt: '', class: 'avatar s32') %h4.project-home-title = @project.name_with_namespace diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 99b6d8ad2888c..214e15398c5df 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -7,7 +7,8 @@ %p.light Some settings, such as "Transfer Project", are hidden inside the danger area below. %hr .panel-body - = form_for @project, remote: true, html: { class: "edit_project form-horizontal" } do |f| + = form_for @project, remote: true, html: { multipart: true, class: "edit_project form-horizontal" }, authenticity_token: true do |f| + %fieldset .form-group.project_name_holder = f.label :name, class: 'control-label' do @@ -80,6 +81,31 @@ = f.check_box :snippets_enabled %span.descr Share code pastes with others out of git repository + %fieldset.features + %legend + Project avatar: + .form-group + .col-sm-2 + .col-sm-10 + = project_icon(@project.to_param, alt: '', class: 'avatar s160', only_uploaded: true) + %p.light + - if @project.avatar_in_git + Project avatar in repository: #{ @project.avatar_in_git } + %p.light + - if @project.avatar? + You can change your project avatar here + - else + You can upload an project avatar here + %a.choose-btn.btn.btn-small.js-choose-project-avatar-button + %i.icon-paper-clip + %span Choose File ... +   + %span.file_name.js-avatar-filename File name... + = f.file_field :avatar, class: "js-project-avatar-input hidden" + .light The maximum file size allowed is 100KB. + - if @project.avatar? + %hr + = link_to 'Remove avatar', project_avatar_path(@project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar" .form-actions = f.submit 'Save changes', class: "btn btn-save" diff --git a/config/routes.rb b/config/routes.rb index 261fbb50e3824..3678fbfb34ccd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -329,6 +329,8 @@ post :preview end end + + resource :avatar, only: [:show, :destroy] end end diff --git a/db/migrate/20140125162722_add_avatar_to_projects.rb b/db/migrate/20140125162722_add_avatar_to_projects.rb new file mode 100644 index 0000000000000..9523ac722f2fa --- /dev/null +++ b/db/migrate/20140125162722_add_avatar_to_projects.rb @@ -0,0 +1,5 @@ +class AddAvatarToProjects < ActiveRecord::Migration + def change + add_column :projects, :avatar, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 9159556ac72dc..d036796943956 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -246,6 +246,7 @@ t.string "import_status" t.float "repository_size", default: 0.0 t.integer "star_count", default: 0, null: false + t.string "avatar" end add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree diff --git a/features/project/project.feature b/features/project/project.feature index c1f192f123e60..13ed08512d1aa 100644 --- a/features/project/project.feature +++ b/features/project/project.feature @@ -5,6 +5,19 @@ Feature: Project Feature And project "Shop" has push event And I visit project "Shop" page + Scenario: I edit the project avatar + Given I visit edit project "Shop" page + When I change the project avatar + And I should see new project avatar + And I should see the "Remove avatar" button + + Scenario: I remove the project avatar + Given I visit edit project "Shop" page + And I have an project avatar + When I remove my project avatar + Then I should see the default project avatar + And I should not see the "Remove avatar" button + @javascript Scenario: I should see project activity When I visit project "Shop" page diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb index b6968152aafa4..06858fe7ad593 100644 --- a/features/steps/project/project.rb +++ b/features/steps/project/project.rb @@ -17,12 +17,53 @@ class ProjectFeature < Spinach::FeatureSteps end step 'change project path settings' do - fill_in "project_path", with: "new-path" - click_button "Rename" + fill_in 'project_path', with: 'new-path' + click_button 'Rename' end step 'I should see project with new path settings' do - project.path.should == "new-path" + project.path.should == 'new-path' + end + + step 'I change the project avatar' do + attach_file( + :project_avatar, + File.join(Rails.root, 'public', 'gitlab_logo.png') + ) + click_button 'Save changes' + @project.reload + end + + step 'I should see new project avatar' do + @project.avatar.should be_instance_of AttachmentUploader + url = @project.avatar.url + url.should == "/uploads/project/avatar/#{ @project.id }/gitlab_logo.png" + end + + step 'I should see the "Remove avatar" button' do + page.should have_link('Remove avatar') + end + + step 'I have an project avatar' do + attach_file( + :project_avatar, + File.join(Rails.root, 'public', 'gitlab_logo.png') + ) + click_button 'Save changes' + @project.reload + end + + step 'I remove my project avatar' do + click_link 'Remove avatar' + @project.reload + end + + step 'I should see the default project avatar' do + @project.avatar?.should be_false + end + + step 'I should not see the "Remove avatar" button' do + page.should_not have_link('Remove avatar') end step 'I should see project "Shop" README link' do diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 053a1fe22f536..da0b4ef326aaf 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -56,6 +56,28 @@ end end + describe 'project_icon' do + avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png') + + it 'should return an url for the avatar' do + project = create(:project) + project.avatar = File.open(avatar_file_path) + project.save! + project_icon(project.to_param).to_s.should == + "/uploads/project/avatar/#{ project.id }/gitlab_logo.png" + end + + it "should give uploaded icon when present" do + project = create(:project) + project.save! + + Project.any_instance.stub(:avatar_in_git).and_return(true) + + project_icon(project.to_param).to_s.should match( + image_tag(project_avatar_path(project))) + end + end + describe "avatar_icon" do avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png') diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index bc537b7312b94..a1f1a2579c03d 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -22,6 +22,7 @@ # visibility_level :integer default(0), not null # archived :boolean default(FALSE), not null # import_status :string(255) +# avatar :string(255) # require 'spec_helper' @@ -309,4 +310,18 @@ expect(project.star_count).to eq(0) end end + + describe :avatar_type do + let(:project) { create(:project) } + + it 'should be true if avatar is image' do + project.update_attribute(:avatar, 'uploads/avatar.png') + project.avatar_type.should be_true + end + + it 'should be false if avatar is html page' do + project.update_attribute(:avatar, 'uploads/avatar.html') + project.avatar_type.should == ['only images allowed'] + end + end end diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 4b2eb42c709b1..41c51b3fbc259 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -462,3 +462,11 @@ get("/gitlab/gitlabhq/graphs/master").should route_to('projects/graphs#show', project_id: 'gitlab/gitlabhq', id: 'master') end end + +# project_avatar DELETE /project/avatar(.:format) projects/avatars#destroy +describe Projects::AvatarsController, 'routing' do + it 'to #destroy' do + delete('/gitlab/gitlabhq/avatar').should route_to( + 'projects/avatars#destroy', project_id: 'gitlab/gitlabhq') + end +end From d5b09a50a46db5a86d001ed3ba2d17dd80aba377 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Sat, 25 Oct 2014 11:11:22 +0200 Subject: [PATCH 2/4] Fix hound --- app/helpers/application_helper.rb | 6 ++++-- app/models/project.rb | 3 ++- spec/helpers/application_helper_spec.rb | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7709c15d97ed0..95d8219795f17 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -68,8 +68,10 @@ def project_identicon(project, options = {}) bg_color = Digest::MD5.hexdigest(project.name)[0, 6] brightness = bg_color[0, 2].hex + bg_color[2, 2].hex + bg_color[4, 2].hex text_color = (brightness > 375) ? '#000' : '#fff' - content_tag(:div, class: options[:class], - style: "background-color: ##{ bg_color }; color: #{ text_color }") do + content_tag(:div, + class: options[:class], + style: "background-color: ##{bg_color}; "\ + "color: #{text_color}") do project.name[0, 1].upcase end end diff --git a/app/models/project.rb b/app/models/project.rb index 6b2aa7dae35c4..a080b652d34ef 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -118,7 +118,8 @@ class Project < ActiveRecord::Base validate :check_limit, on: :create validate :avatar_type, - if: ->(project) { project.avatar && project.avatar_changed? } + if: ->(project) { project.avatar && + project.avatar_changed? } validates :avatar, file_size: { maximum: 100.kilobytes.to_i } mount_uploader :avatar, AttachmentUploader diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 7de52535a1b9b..b578e7c91e80e 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -67,7 +67,7 @@ "/uploads/project/avatar/#{ project.id }/gitlab_logo.png" end - it "should give uploaded icon when present" do + it 'should give uploaded icon when present' do project = create(:project) project.save! From 84b484fab9c5691893781aea3c00f39fbb3636cf Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Sat, 25 Oct 2014 11:13:15 +0200 Subject: [PATCH 3/4] Fix hound 2 --- app/models/project.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index a080b652d34ef..a43a8779b28f0 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -118,8 +118,7 @@ class Project < ActiveRecord::Base validate :check_limit, on: :create validate :avatar_type, - if: ->(project) { project.avatar && - project.avatar_changed? } + if: ->(project) { project.avatar && project.avatar_changed? } validates :avatar, file_size: { maximum: 100.kilobytes.to_i } mount_uploader :avatar, AttachmentUploader From f2518227f3e667fae0ada12e4aed363f2f4f5175 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Sat, 25 Oct 2014 11:28:04 +0200 Subject: [PATCH 4/4] UPdate migrations --- ..._to_projects.rb => 20141025111418_add_avatar_to_projects.rb} | 0 db/schema.rb | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename db/migrate/{20140125162722_add_avatar_to_projects.rb => 20141025111418_add_avatar_to_projects.rb} (100%) diff --git a/db/migrate/20140125162722_add_avatar_to_projects.rb b/db/migrate/20141025111418_add_avatar_to_projects.rb similarity index 100% rename from db/migrate/20140125162722_add_avatar_to_projects.rb rename to db/migrate/20141025111418_add_avatar_to_projects.rb diff --git a/db/schema.rb b/db/schema.rb index 25e3f451bb2c0..89298bd783258 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20141007100818) do +ActiveRecord::Schema.define(version: 20141025111418) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql"