mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 07:30:16 +08:00
FEATURE: Can upload images to categories
This commit is contained in:
parent
9000c358d1
commit
e22688a204
|
@ -13,7 +13,19 @@ export default Em.Component.extend(UploadMixin, {
|
|||
this.set('imageUrl', data.result.url);
|
||||
},
|
||||
|
||||
deleteDone: function() {
|
||||
this.set('imageUrl', null);
|
||||
actions: {
|
||||
trash: function() {
|
||||
this.set('imageUrl', null);
|
||||
|
||||
// Do we want to signal the delete to the server right away?
|
||||
if (this.get('instantDelete')) {
|
||||
Discourse.ajax(this.get('uploadUrl'), {
|
||||
type: 'DELETE',
|
||||
data: { image_type: this.get('type') }
|
||||
}).then(null, function() {
|
||||
bootbox.alert(I18n.t('generic_error'));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
**/
|
||||
export default Discourse.ObjectController.extend(Discourse.ModalFunctionality, {
|
||||
foregroundColors: ['FFFFFF', '000000'],
|
||||
categoryUploadUrl: '/category/uploads',
|
||||
|
||||
parentCategories: function() {
|
||||
return Discourse.Category.list().filter(function (c) {
|
||||
|
|
|
@ -53,18 +53,6 @@ export default Em.Mixin.create({
|
|||
actions: {
|
||||
selectFile: function() {
|
||||
this.$('input[type=file]').click();
|
||||
},
|
||||
|
||||
trash: function() {
|
||||
var self = this;
|
||||
Discourse.ajax(this.get('uploadUrl'), {
|
||||
type: 'DELETE',
|
||||
data: { image_type: this.get('type') }
|
||||
}).then(function() {
|
||||
self.deleteDone();
|
||||
}).catch(function() {
|
||||
bootbox.alert(I18n.t('generic_error'));
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -68,7 +68,9 @@ Discourse.Category = Discourse.Model.extend({
|
|||
position: this.get('position'),
|
||||
email_in: this.get('email_in'),
|
||||
email_in_allow_strangers: this.get('email_in_allow_strangers'),
|
||||
parent_category_id: this.get('parent_category_id')
|
||||
parent_category_id: this.get('parent_category_id'),
|
||||
logo_url: this.get('logo_url'),
|
||||
background_url: this.get('background_url')
|
||||
},
|
||||
type: this.get('id') ? 'PUT' : 'POST'
|
||||
});
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<section class='field'>
|
||||
<label>{{i18n category.logo}}</label>
|
||||
{{image-uploader uploadUrl=categoryUploadUrl imageUrl=logo_url type="logo"}}
|
||||
</section>
|
||||
|
||||
<section class='field'>
|
||||
<label>{{i18n category.background_image}}</label>
|
||||
{{image-uploader uploadUrl=categoryUploadUrl imageUrl=background_url type="background"}}
|
||||
</section>
|
|
@ -94,6 +94,7 @@
|
|||
<div class="controls">
|
||||
{{image-uploader uploadUrl=imageUploadUrl
|
||||
imageUrl=profile_background
|
||||
instantDelete="true"
|
||||
type="profile_background"}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -186,3 +186,9 @@ animation: modal .25s;
|
|||
.uploaded-avatar {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.uploaded-image-preview {
|
||||
width: 400px;
|
||||
max-height: 150px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,19 @@ class CategoriesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def upload
|
||||
params.require(:image_type)
|
||||
guardian.ensure_can_create!(Category)
|
||||
|
||||
file = params[:file] || params[:files].first
|
||||
upload = Upload.create_for(current_user.id, file.tempfile, file.original_filename, File.size(file.tempfile))
|
||||
if upload.errors.blank?
|
||||
render json: { url: upload.url, width: upload.width, height: upload.height }
|
||||
else
|
||||
render status: 422, text: upload.errors.full_messages
|
||||
end
|
||||
end
|
||||
|
||||
def move
|
||||
guardian.ensure_can_create!(Category)
|
||||
|
||||
|
@ -105,7 +118,7 @@ class CategoriesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
params.permit(*required_param_keys, :position, :email_in, :email_in_allow_strangers, :parent_category_id, :auto_close_hours, :permissions => [*p.try(:keys)])
|
||||
params.permit(*required_param_keys, :position, :email_in, :email_in_allow_strangers, :parent_category_id, :auto_close_hours, :logo_url, :background_url, :permissions => [*p.try(:keys)])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -6,7 +6,11 @@ module Jobs
|
|||
def execute(args)
|
||||
return unless SiteSetting.clean_up_uploads?
|
||||
|
||||
uploads_used_as_profile_backgrounds = UserProfile.uniq.where("profile_background IS NOT NULL AND profile_background != ''").pluck(:profile_background)
|
||||
ignore_urls = []
|
||||
ignore_urls << UserProfile.uniq.where("profile_background IS NOT NULL AND profile_background != ''").pluck(:profile_background)
|
||||
ignore_urls << Category.uniq.where("logo_url IS NOT NULL AND logo_url != ''").pluck(:logo_url)
|
||||
ignore_urls << Category.uniq.where("background_url IS NOT NULL AND background_url != ''").pluck(:background_url)
|
||||
ignore_urls.flatten!
|
||||
|
||||
grace_period = [SiteSetting.clean_orphan_uploads_grace_period_hours, 1].max
|
||||
|
||||
|
@ -14,7 +18,7 @@ module Jobs
|
|||
.where("id NOT IN (SELECT upload_id from post_uploads)")
|
||||
.where("id NOT IN (SELECT custom_upload_id from user_avatars)")
|
||||
.where("id NOT IN (SELECT gravatar_upload_id from user_avatars)")
|
||||
.where("url NOT IN (?)", uploads_used_as_profile_backgrounds)
|
||||
.where("url NOT IN (?)", ignore_urls)
|
||||
.find_each do |upload|
|
||||
upload.destroy
|
||||
end
|
||||
|
|
|
@ -12,7 +12,9 @@ class BasicCategorySerializer < ApplicationSerializer
|
|||
:read_restricted,
|
||||
:permission,
|
||||
:parent_category_id,
|
||||
:notification_level
|
||||
:notification_level,
|
||||
:logo_url,
|
||||
:background_url
|
||||
|
||||
def include_parent_category_id?
|
||||
parent_category_id
|
||||
|
|
|
@ -1146,6 +1146,8 @@ en:
|
|||
name: "Category Name"
|
||||
description: "Description"
|
||||
topic: "category topic"
|
||||
logo: "Category Logo Image"
|
||||
background_image: "Category Background Image"
|
||||
badge_colors: "Badge colors"
|
||||
background_color: "Background color"
|
||||
foreground_color: "Foreground color"
|
||||
|
|
|
@ -275,6 +275,7 @@ Discourse::Application.routes.draw do
|
|||
|
||||
resources :categories, :except => :show
|
||||
get "category/:id/show" => "categories#show"
|
||||
post "category/uploads" => "categories#upload"
|
||||
post "category/:category_id/move" => "categories#move"
|
||||
get "category/:category.rss" => "list#category_feed", format: :rss
|
||||
get "category/:parent_category/:category.rss" => "list#category_feed", format: :rss
|
||||
|
|
6
db/migrate/20140627193814_add_images_to_categories.rb
Normal file
6
db/migrate/20140627193814_add_images_to_categories.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class AddImagesToCategories < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :categories, :logo_url, :string
|
||||
add_column :categories, :background_url, :string
|
||||
end
|
||||
end
|
|
@ -95,6 +95,37 @@ describe CategoriesController do
|
|||
|
||||
end
|
||||
|
||||
describe "upload" do
|
||||
it "requires the user to be logged in" do
|
||||
lambda { xhr :post, :upload, image_type: 'logo'}.should raise_error(Discourse::NotLoggedIn)
|
||||
end
|
||||
|
||||
describe "logged in" do
|
||||
let!(:user) { log_in(:admin) }
|
||||
|
||||
let(:logo) { File.new("#{Rails.root}/spec/fixtures/images/logo.png") }
|
||||
let(:upload) do
|
||||
ActionDispatch::Http::UploadedFile.new({ filename: 'logo.png', tempfile: logo })
|
||||
end
|
||||
|
||||
it "raises an error when you don't have permission to upload" do
|
||||
Guardian.any_instance.expects(:can_create?).with(Category).returns(false)
|
||||
xhr :post, :upload, image_type: 'logo', file: upload
|
||||
response.should be_forbidden
|
||||
end
|
||||
|
||||
it "requires the `image_type` param" do
|
||||
-> { xhr :post, :upload }.should raise_error(ActionController::ParameterMissing)
|
||||
end
|
||||
|
||||
it "calls Upload.create_for" do
|
||||
Upload.expects(:create_for).returns(Upload.new)
|
||||
xhr :post, :upload, image_type: 'logo', file: upload
|
||||
response.should be_success
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "update" do
|
||||
|
||||
it "requires the user to be logged in" do
|
||||
|
|
|
@ -1272,7 +1272,7 @@ describe UsersController do
|
|||
describe '.destroy_user_image' do
|
||||
|
||||
it 'raises an error when not logged in' do
|
||||
lambda { xhr :put, :destroy_user_image, type: 'profile_background', username: 'asdf' }.should raise_error(Discourse::NotLoggedIn)
|
||||
lambda { xhr :delete, :destroy_user_image, type: 'profile_background', username: 'asdf' }.should raise_error(Discourse::NotLoggedIn)
|
||||
end
|
||||
|
||||
context 'while logged in' do
|
||||
|
@ -1281,20 +1281,20 @@ describe UsersController do
|
|||
|
||||
it 'raises an error when you don\'t have permission to clear the profile background' do
|
||||
Guardian.any_instance.expects(:can_edit?).with(user).returns(false)
|
||||
xhr :put, :destroy_user_image, username: user.username, image_type: 'profile_background'
|
||||
xhr :delete, :destroy_user_image, username: user.username, image_type: 'profile_background'
|
||||
response.should be_forbidden
|
||||
end
|
||||
|
||||
it "requires the `image_type` param" do
|
||||
-> { xhr :put, :destroy_user_image, username: user.username }.should raise_error(ActionController::ParameterMissing)
|
||||
-> { xhr :delete, :destroy_user_image, username: user.username }.should raise_error(ActionController::ParameterMissing)
|
||||
end
|
||||
|
||||
it "only allows certain `image_types`" do
|
||||
-> { xhr :put, :destroy_user_image, username: user.username, image_type: 'wat' }.should raise_error(Discourse::InvalidParameters)
|
||||
-> { xhr :delete, :destroy_user_image, username: user.username, image_type: 'wat' }.should raise_error(Discourse::InvalidParameters)
|
||||
end
|
||||
|
||||
it 'can clear the profile background' do
|
||||
xhr :put, :destroy_user_image, image_type: 'profile_background', username: user.username
|
||||
xhr :delete, :destroy_user_image, image_type: 'profile_background', username: user.username
|
||||
user.reload.user_profile.profile_background.should == ""
|
||||
response.should be_success
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user