diff options
author | Steven Thonus <steven@ln2.nl> | 2014-01-25 21:15:44 +0400 |
---|---|---|
committer | Hannes Rosenögger <123haynes@gmail.com> | 2015-01-24 20:51:16 +0300 |
commit | 42bac7f9f27b0e8fb113e452fc2106882262172d (patch) | |
tree | badf9efefbdf95e02cac54c48d1495cd062476e9 /app | |
parent | c8c05edcd500c0a755cb6962b51f97381663bd1a (diff) |
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
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/images/no_project_icon.png | bin | 0 -> 3387 bytes | |||
-rw-r--r-- | app/assets/javascripts/project.js.coffee | 10 | ||||
-rw-r--r-- | app/assets/stylesheets/generic/avatar.scss | 13 | ||||
-rw-r--r-- | app/assets/stylesheets/sections/dashboard.scss | 6 | ||||
-rw-r--r-- | app/controllers/projects/avatars_controller.rb | 29 | ||||
-rw-r--r-- | app/helpers/application_helper.rb | 25 | ||||
-rw-r--r-- | app/models/project.rb | 25 | ||||
-rw-r--r-- | app/services/projects/fork_service.rb | 3 | ||||
-rw-r--r-- | app/views/dashboard/_project.html.haml | 2 | ||||
-rw-r--r-- | app/views/dashboard/projects.html.haml | 2 | ||||
-rw-r--r-- | app/views/projects/_home_panel.html.haml | 1 | ||||
-rw-r--r-- | app/views/projects/edit.html.haml | 28 |
12 files changed, 143 insertions, 1 deletions
diff --git a/app/assets/images/no_project_icon.png b/app/assets/images/no_project_icon.png Binary files differnew file mode 100644 index 00000000000..8e9529c67ec --- /dev/null +++ b/app/assets/images/no_project_icon.png diff --git a/app/assets/javascripts/project.js.coffee b/app/assets/javascripts/project.js.coffee index 5a9cc66c8f0..8588a9d27cd 100644 --- a/app/assets/javascripts/project.js.coffee +++ b/app/assets/javascripts/project.js.coffee @@ -18,3 +18,13 @@ class @Project $.cookie('hide_no_ssh_message', 'false', { path: path }) $(@).parents('.no-ssh-key-message').hide() e.preventDefault() + + # 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 80514615559..f04848ae6dc 100644 --- a/app/assets/stylesheets/generic/avatar.scss +++ b/app/assets/stylesheets/generic/avatar.scss @@ -23,3 +23,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 824f136d300..3135056db58 100644 --- a/app/assets/stylesheets/sections/dashboard.scss +++ b/app/assets/stylesheets/sections/dashboard.scss @@ -75,6 +75,9 @@ } } } +.project-avatar { + float: left; +} .project-description { overflow: hidden; @@ -92,6 +95,9 @@ } } +.dash-project-avatar { + float: left; +} .dash-project-access-icon { float: left; margin-right: 3px; diff --git a/app/controllers/projects/avatars_controller.rb b/app/controllers/projects/avatars_controller.rb new file mode 100644 index 00000000000..a482b90880d --- /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 f65e04af205..772400d55ec 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -50,6 +50,31 @@ module ApplicationHelper 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 f102c477404..7160e704aa1 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -26,6 +26,7 @@ # star_count :integer default(0), not null # import_type :string(255) # import_source :string(255) +# avatar :string(255) # class Project < ActiveRecord::Base @@ -119,6 +120,11 @@ class Project < ActiveRecord::Base if: :import? 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) ) } @@ -338,6 +344,24 @@ class Project < ActiveRecord::Base @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 + end + def items_for(entity) case entity when 'issue' then @@ -529,6 +553,7 @@ class Project < ActiveRecord::Base # 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 4930660055a..8bb0fcf9474 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -14,6 +14,9 @@ module Projects project.name = @from_project.name project.path = @from_project.path project.creator = @current_user + if @from_project.avatar && @from_project.avatar.image? + project.avatar = @from_project.avatar + end if namespace = @params[:namespace] project.namespace = namespace diff --git a/app/views/dashboard/_project.html.haml b/app/views/dashboard/_project.html.haml index 89ed5102754..7f19fb5a81c 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 944441669e7..f60bcc72e1d 100644 --- a/app/views/dashboard/projects.html.haml +++ b/app/views/dashboard/projects.html.haml @@ -11,6 +11,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 diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index 30d063c7a36..05910c6038c 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -2,6 +2,7 @@ .project-home-panel{:class => ("empty-project" if empty_repo)} .project-home-row .project-home-desc + = project_icon(@project.to_param, alt: '', class: 'avatar s32') - if @project.description.present? = escaped_autolink(@project.description) - if can?(current_user, :admin_project, @project) diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index f2bb56b5664..fc6499de3e2 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" |