OSDN Git Service

added group avatars
authorSteven Thonus <steven@ln2.nl>
Mon, 27 Jan 2014 21:34:05 +0000 (22:34 +0100)
committerSteven Thonus <steven@ln2.nl>
Tue, 28 Jan 2014 07:38:00 +0000 (08:38 +0100)
15 files changed:
app/assets/images/no_group_avatar.png [new file with mode: 0644]
app/assets/javascripts/groups.js.coffee
app/controllers/groups/avatars_controller.rb [new file with mode: 0644]
app/helpers/application_helper.rb
app/models/group.rb
app/models/namespace.rb
app/views/dashboard/_groups.html.haml
app/views/groups/edit.html.haml
config/routes.rb
db/migrate/20140127170938_add_group_avatars.rb [new file with mode: 0644]
db/schema.rb
features/group/group.feature
features/steps/group/group.rb
spec/helpers/application_helper_spec.rb
spec/models/group_spec.rb

diff --git a/app/assets/images/no_group_avatar.png b/app/assets/images/no_group_avatar.png
new file mode 100644 (file)
index 0000000..dac3ab1
Binary files /dev/null and b/app/assets/images/no_group_avatar.png differ
index c0ffccd..7850eb1 100644 (file)
@@ -4,3 +4,14 @@ class GroupMembers
       $(this).fadeOut()
 
 @GroupMembers = GroupMembers
+
+$ ->
+  # avatar
+  $('.js-choose-group-avatar-button').bind "click", ->
+    form = $(this).closest("form")
+    form.find(".js-group-avatar-input").click()
+
+  $('.js-group-avatar-input').bind "change", ->
+    form = $(this).closest("form")
+    filename = $(this).val().replace(/^.*[\\\/]/, '')
+    form.find(".js-avatar-filename").text(filename)
\ No newline at end of file
diff --git a/app/controllers/groups/avatars_controller.rb b/app/controllers/groups/avatars_controller.rb
new file mode 100644 (file)
index 0000000..3807141
--- /dev/null
@@ -0,0 +1,12 @@
+class Groups::AvatarsController < ApplicationController
+  layout "profile"
+
+  def destroy
+    @group = Group.find_by(path: params[:group_id])
+    @group.remove_avatar!
+
+    @group.save
+
+    redirect_to edit_group_path(@group)
+  end
+end
index e60cba2..be57b60 100644 (file)
@@ -49,6 +49,15 @@ module ApplicationHelper
     args.any? { |v| v.to_s.downcase == action_name }
   end
 
+  def group_icon(group_path)
+    group = Group.find_by(path: group_path)
+    if group && group.avatar.present?
+      group.avatar.url
+    else
+      '/assets/no_group_avatar.png'
+    end
+  end
+
   def avatar_icon(user_email = '', size = nil)
     user = User.find_by(email: user_email)
     if user && user.avatar.present?
index 0b64d5b..8de0c78 100644 (file)
 #  description :string(255)      default(""), not null
 #
 
+require 'carrierwave/orm/activerecord'
+require 'file_size_validator'
+
 class Group < Namespace
   has_many :users_groups, dependent: :destroy
   has_many :users, through: :users_groups
 
+  attr_accessible :avatar
+
+  validate :avatar_type, if: ->(user) { user.avatar_changed? }
+  validates :avatar, file_size: { maximum: 100.kilobytes.to_i }
+
+  mount_uploader :avatar, AttachmentUploader
+
   def human_name
     name
   end
@@ -50,4 +60,10 @@ class Group < Namespace
   def members
     users_groups
   end
+
+  def avatar_type
+    unless self.avatar.image?
+      self.errors.add :avatar, "only images allowed"
+    end
+  end
 end
index 8f837c7..d5b98f5 100644 (file)
@@ -10,6 +10,7 @@
 #  updated_at  :datetime         not null
 #  type        :string(255)
 #  description :string(255)      default(""), not null
+#  avatar      :string(255)
 #
 
 class Namespace < ActiveRecord::Base
index d6937ca..dd8d859 100644 (file)
@@ -10,6 +10,7 @@
     - groups.each do |group|
       %li.group-row
         = link_to group_path(id: group.path), class: dom_class(group) do
+          = image_tag group_icon(group.path), class: "avatar s32"
           %span.group-name.filter-title
             = truncate(group.name, length: 35)
           %span.arrow
index 7773481..e274a79 100644 (file)
@@ -20,7 +20,7 @@
             %strong= @group.name
             group settings:
           %div.form-holder
-            = form_for @group, html: { class: "form-horizontal" } do |f|
+            = form_for @group, html: { multipart: true, class: "form-horizontal" }, authenticity_token: true do |f|
               - if @group.errors.any?
                 .alert.alert-danger
                   %span= @group.errors.full_messages.first
                 .col-sm-10
                   = f.text_area :description, maxlength: 250, class: "form-control js-gfm-input", rows: 4
 
+              .form-group
+                .col-sm-2
+                .col-sm-10
+                  = image_tag group_icon(@group.to_param), alt: '', class: 'avatar s160'
+                  %p.light
+                    - if @group.avatar?
+                      You can change your group avatar here
+                    - else
+                      You can upload an group avatar here
+                  %a.choose-btn.btn.btn-small.js-choose-group-avatar-button
+                    %i.icon-paper-clip
+                    %span Choose File ...
+                  &nbsp;
+                  %span.file_name.js-avatar-filename File name...
+                  = f.file_field :avatar, class: "js-group-avatar-input hidden"
+                  .light The maximum file size allowed is 100KB.
+                  - if @group.avatar?
+                    %hr
+                    = link_to 'Remove avatar', group_avatar_path(@group.to_param), data: { confirm: "Group avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar"
+
               .form-actions
                 = f.submit 'Save group', class: "btn btn-save"
 
index 611e497..7724716 100644 (file)
@@ -156,6 +156,9 @@ Gitlab::Application.routes.draw do
     end
 
     resources :users_groups, only: [:create, :update, :destroy]
+    scope module: :groups do
+      resource :avatar, only: [:destroy]
+    end
   end
 
   resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create]
diff --git a/db/migrate/20140127170938_add_group_avatars.rb b/db/migrate/20140127170938_add_group_avatars.rb
new file mode 100644 (file)
index 0000000..2911096
--- /dev/null
@@ -0,0 +1,5 @@
+class AddGroupAvatars < ActiveRecord::Migration
+  def change
+    add_column :namespaces, :avatar, :string
+  end
+end
index 75a44d9..acbb793 100644 (file)
@@ -11,7 +11,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20140122122549) do
+ActiveRecord::Schema.define(version: 20140127170938) do
 
   create_table "broadcast_messages", force: true do |t|
     t.text     "message",    null: false
@@ -152,6 +152,7 @@ ActiveRecord::Schema.define(version: 20140122122549) do
     t.datetime "updated_at",               null: false
     t.string   "type"
     t.string   "description", default: "", null: false
+    t.string   "avatar"
   end
 
   add_index "namespaces", ["name"], name: "index_namespaces_on_name", using: :btree
index 9fec19a..ca3e67d 100644 (file)
@@ -31,3 +31,17 @@ Feature: Groups
     And I change group name
     Then I should see new group name
 
+  Scenario: I edit my group avatar
+    When I visit group settings page
+    And I change my group avatar
+    And I visit group settings page
+    Then I should see new group avatar
+    And I should see the "Remove avatar" button
+
+  Scenario: I remove my group avatar
+    When I visit group settings page
+    And I have an group avatar
+    And I visit group settings page
+    And I remove my group avatar
+    Then I should not see my group avatar
+    And I should not see the "Remove avatar" button
index 15d7c46..0b0f401 100644 (file)
@@ -98,6 +98,40 @@ class Groups < Spinach::FeatureSteps
     end
   end
 
+  step 'I change my group avatar' do
+    attach_file(:group_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png'))
+    click_button "Save group"
+    @group.reload
+  end
+
+  step 'I should see new group avatar' do
+    @group.avatar.should be_instance_of AttachmentUploader
+    @group.avatar.url.should == "/uploads/group/avatar/#{ @group.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 group avatar' do
+    attach_file(:group_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png'))
+    click_button "Save group"
+    @group.reload
+  end
+
+  step 'I remove my group avatar' do
+    click_link "Remove avatar"
+    @group.reload
+  end
+
+  step 'I should not see my group avatar' do
+    @group.avatar?.should be_false
+  end
+
+  step 'I should not see the "Remove avatar" button' do
+    page.should_not have_link("Remove avatar")
+  end
+
   protected
 
   def current_group
index 3644410..c58c83a 100644 (file)
@@ -39,6 +39,23 @@ describe ApplicationHelper do
     end
   end
 
+  describe "group_icon" do
+    avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png')
+
+    it "should return an url for the avatar" do
+      group = create(:group)
+      group.avatar = File.open(avatar_file_path)
+      group.save!
+      group_icon(group.path).to_s.should == "/uploads/group/avatar/#{ group.id }/gitlab_logo.png"
+    end
+
+    it "should give default avatar_icon when no avatar is present" do
+      group = create(:group)
+      group.save!
+      group_icon(group.path).to_s.should == "/assets/no_group_avatar.png"
+    end
+  end
+
   describe "avatar_icon" do
     avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png')
 
index 12b8470..686e43d 100644 (file)
@@ -54,4 +54,19 @@ describe Group do
       group.users_groups.guests.map(&:user).should_not include(user)
     end
   end
+
+  describe :avatar_type do
+    let(:user) { create(:user) }
+    before { group.add_user(user, UsersGroup::MASTER) }
+
+    it "should be true if avatar is image" do
+      group.update_attribute(:avatar, 'uploads/avatar.png')
+      group.avatar_type.should be_true
+    end
+
+    it "should be false if avatar is html page" do
+      group.update_attribute(:avatar, 'uploads/avatar.html')
+      group.avatar_type.should == ["only images allowed"]
+    end
+  end
 end