Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorSteven Thonus <steven@ln2.nl>2014-01-25 21:15:44 +0400
committerHannes Rosenögger <123haynes@gmail.com>2015-01-24 20:51:16 +0300
commit42bac7f9f27b0e8fb113e452fc2106882262172d (patch)
treebadf9efefbdf95e02cac54c48d1495cd062476e9 /app
parentc8c05edcd500c0a755cb6962b51f97381663bd1a (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.pngbin0 -> 3387 bytes
-rw-r--r--app/assets/javascripts/project.js.coffee10
-rw-r--r--app/assets/stylesheets/generic/avatar.scss13
-rw-r--r--app/assets/stylesheets/sections/dashboard.scss6
-rw-r--r--app/controllers/projects/avatars_controller.rb29
-rw-r--r--app/helpers/application_helper.rb25
-rw-r--r--app/models/project.rb25
-rw-r--r--app/services/projects/fork_service.rb3
-rw-r--r--app/views/dashboard/_project.html.haml2
-rw-r--r--app/views/dashboard/projects.html.haml2
-rw-r--r--app/views/projects/_home_panel.html.haml1
-rw-r--r--app/views/projects/edit.html.haml28
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
new file mode 100644
index 00000000000..8e9529c67ec
--- /dev/null
+++ b/app/assets/images/no_project_icon.png
Binary files differ
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 ...
+ &nbsp;
+ %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"