REFACTOR: Convert profile background uploader to be an ember component
This commit is contained in:
parent
06880c28f8
commit
4088fba4f2
|
@ -0,0 +1,61 @@
|
|||
export default Em.Component.extend({
|
||||
uploading: false,
|
||||
uploadProgress: 0,
|
||||
|
||||
backgroundStyle: function() {
|
||||
var imageUrl = this.get('imageUrl');
|
||||
if (Em.isNone(imageUrl)) { return; }
|
||||
|
||||
return "background-image: url(" + imageUrl + ")";
|
||||
}.property('imageUrl'),
|
||||
|
||||
_initializeUploader: function() {
|
||||
var $upload = this.$('input[type=file]'), // note: we can't cache this as fileupload replaces the input after upload
|
||||
self = this;
|
||||
|
||||
$upload.fileupload({
|
||||
url: this.get('uploadUrl'),
|
||||
dataType: "json",
|
||||
fileInput: $upload,
|
||||
formData: { image_type: this.get('type') }
|
||||
});
|
||||
|
||||
$upload.on('fileuploadsubmit', function (e, data) {
|
||||
var result = Discourse.Utilities.validateUploadedFiles(data.files, true);
|
||||
self.setProperties({ uploadProgress: 0, uploading: result });
|
||||
return result;
|
||||
});
|
||||
$upload.on("fileuploadprogressall", function(e, data) {
|
||||
var progress = parseInt(data.loaded / data.total * 100, 10);
|
||||
self.set("uploadProgress", progress);
|
||||
});
|
||||
$upload.on("fileuploaddone", function(e, data) {
|
||||
if(data.result.url) {
|
||||
self.set('imageUrl', data.result.url);
|
||||
} else {
|
||||
bootbox.alert(I18n.t('post.errors.upload'));
|
||||
}
|
||||
});
|
||||
$upload.on("fileuploadfail", function(e, data) {
|
||||
Discourse.Utilities.displayErrorForUpload(data);
|
||||
});
|
||||
$upload.on("fileuploadalways", function() {
|
||||
self.setProperties({ uploading: false, uploadProgress: 0});
|
||||
});
|
||||
}.on('didInsertElement'),
|
||||
|
||||
_destroyUploader: function() {
|
||||
this.$('input[type=file]').fileupload('destroy');
|
||||
}.on('willDestroyElement'),
|
||||
|
||||
actions: {
|
||||
selectFile: function() {
|
||||
this.$('input[type=file]').click();
|
||||
},
|
||||
|
||||
trash: function() {
|
||||
this.set('imageUrl', null);
|
||||
this.sendAction('clear');
|
||||
}
|
||||
}
|
||||
});
|
|
@ -66,7 +66,14 @@ export default Discourse.ObjectController.extend({
|
|||
return this.get('saving') ? I18n.t('saving') : I18n.t('save');
|
||||
}.property('saving'),
|
||||
|
||||
imageUploadUrl: Discourse.computed.url('username', '/users/%@/preferences/user_image'),
|
||||
|
||||
actions: {
|
||||
|
||||
clearProfileBackground: function() {
|
||||
this.get('model').clearProfileBackground();
|
||||
},
|
||||
|
||||
save: function() {
|
||||
var self = this;
|
||||
this.setProperties({ saving: true, saved: false });
|
||||
|
|
|
@ -354,8 +354,6 @@ Discourse.User = Discourse.Model.extend({
|
|||
return Discourse.ajax("/users/" + this.get("username_lower") + "/preferences/profile_background/clear", {
|
||||
type: 'PUT',
|
||||
data: { }
|
||||
}).then(function() {
|
||||
user.set('profile_background', null);
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -63,12 +63,6 @@ Discourse.PreferencesRoute = Discourse.RestrictedUserRoute.extend({
|
|||
avatarSelector.send('closeModal');
|
||||
},
|
||||
|
||||
showProfileBackgroundFileSelector: function() {
|
||||
$("#profile-background-input").click();
|
||||
},
|
||||
clearProfileBackground: function() {
|
||||
this.modelFor('user').clearProfileBackground();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<input type="file" accept="image/*" style="display:none" />
|
||||
<div class="uploaded-image-preview" class="input-xxlarge" {{bind-attr style="backgroundStyle"}}>
|
||||
<div class="image-upload-controls">
|
||||
<button {{action selectFile}} class="btn pad-left no-text"><i class="fa fa-picture-o"></i></button>
|
||||
{{#if backgroundStyle}}
|
||||
<button {{action trash}} class="btn btn-danger pad-left no-text"><i class="fa fa-trash-o"></i></button>
|
||||
{{/if}}
|
||||
<span {{bind-attr class=":btn uploading::hidden"}}>{{i18n upload_selector.uploading}} {{uploadProgress}}%</span>
|
||||
</div>
|
||||
</div>
|
|
@ -4,6 +4,7 @@
|
|||
{{#unless isUncategorizedCategory}}
|
||||
{{edit-category-tab selectedTab=selectedTab tab="security"}}
|
||||
{{edit-category-tab selectedTab=selectedTab tab="settings"}}
|
||||
{{edit-category-tab selectedTab=selectedTab tab="images"}}
|
||||
{{/unless}}
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -92,18 +92,10 @@
|
|||
<div class="control-group pref-profile-bg">
|
||||
<label class="control-label">{{i18n user.change_profile_background.title}}</label>
|
||||
<div class="controls">
|
||||
<input type="file" id="profile-background-input" accept="image/*" style="display:none" />
|
||||
<div id="profile-background-preview" class="input-xxlarge" {{bind-attr style="profileBackground"}}>
|
||||
<div id="profile-background-controls">
|
||||
<button {{action showProfileBackgroundFileSelector}} class="btn pad-left no-text"><i class="fa fa-picture-o"></i></button>
|
||||
{{#if profileBackground}}
|
||||
<button {{action clearProfileBackground}} class="btn btn-danger pad-left no-text"><i class="fa fa-trash-o"></i></button>
|
||||
{{/if}}
|
||||
{{#if view.uploading}}
|
||||
<span class="btn">{{i18n upload_selector.uploading}} {{view.uploadProgress}}%</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{image-uploader uploadUrl=imageUploadUrl
|
||||
imageUrl=profile_background
|
||||
type="profile_background"
|
||||
clear="clearProfileBackground"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -37,7 +37,7 @@ Discourse.AvatarSelectorView = Discourse.ModalBodyView.extend({
|
|||
url: Discourse.getURL("/users/" + this.get("controller.username") + "/preferences/user_image"),
|
||||
dataType: "json",
|
||||
fileInput: $upload,
|
||||
formData: { user_image_type: "avatar" }
|
||||
formData: { image_type: "avatar" }
|
||||
});
|
||||
|
||||
// when a file has been selected
|
||||
|
|
|
@ -1,55 +1,4 @@
|
|||
/**
|
||||
This view handles rendering of a user's preferences
|
||||
|
||||
@class PreferencesView
|
||||
@extends Discourse.View
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.PreferencesView = Discourse.View.extend({
|
||||
templateName: 'user/preferences',
|
||||
classNames: ['user-preferences'],
|
||||
|
||||
uploading: false,
|
||||
uploadProgress: 0,
|
||||
|
||||
didInsertElement: function() {
|
||||
var self = this;
|
||||
var $upload = $("#profile-background-input");
|
||||
|
||||
this._super();
|
||||
|
||||
$upload.fileupload({
|
||||
url: Discourse.getURL("/users/" + this.get('controller.model.username') + "/preferences/user_image"),
|
||||
dataType: "json",
|
||||
fileInput: $upload,
|
||||
formData: { user_image_type: "profile_background" }
|
||||
});
|
||||
|
||||
$upload.on('fileuploadsubmit', function (e, data) {
|
||||
var result = Discourse.Utilities.validateUploadedFiles(data.files, true);
|
||||
self.setProperties({ uploadProgress: 0, uploading: result });
|
||||
return result;
|
||||
});
|
||||
$upload.on("fileuploadprogressall", function(e, data) {
|
||||
var progress = parseInt(data.loaded / data.total * 100, 10);
|
||||
self.set("uploadProgress", progress);
|
||||
});
|
||||
$upload.on("fileuploaddone", function(e, data) {
|
||||
if(data.result.url) {
|
||||
self.set("controller.model.profile_background", data.result.url);
|
||||
} else {
|
||||
bootbox.alert(I18n.t('post.errors.upload'));
|
||||
}
|
||||
});
|
||||
$upload.on("fileuploadfail", function(e, data) {
|
||||
Discourse.Utilities.displayErrorForUpload(data);
|
||||
});
|
||||
$upload.on("fileuploadalways", function() {
|
||||
self.setProperties({ uploading: false, uploadProgress: 0});
|
||||
});
|
||||
},
|
||||
willDestroyElement: function() {
|
||||
$("#profile-background-input").fileupload("destroy");
|
||||
}
|
||||
classNames: ['user-preferences']
|
||||
});
|
||||
|
|
|
@ -29,3 +29,14 @@
|
|||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.uploaded-image-preview {
|
||||
height: 270px;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
background-color: $primary;
|
||||
}
|
||||
|
||||
.image-upload-controls {
|
||||
padding: 10px;
|
||||
}
|
||||
|
|
|
@ -43,19 +43,6 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
#profile-background-preview {
|
||||
height: 270px;
|
||||
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
|
||||
background-color: $primary;
|
||||
}
|
||||
|
||||
#profile-background-controls {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.static {
|
||||
color: $primary;
|
||||
display: inline-block;
|
||||
|
|
|
@ -10,3 +10,10 @@
|
|||
color: scale-color($primary, $lightness: 50%);
|
||||
}
|
||||
}
|
||||
|
||||
.uploaded-image-preview {
|
||||
height: 150px;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
background-color: $primary;
|
||||
}
|
||||
|
|
|
@ -63,13 +63,6 @@
|
|||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
#profile-background-preview {
|
||||
height: 150px;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
background-color: $primary;
|
||||
}
|
||||
|
||||
.bio-composer #wmd-quote-post {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -333,12 +333,12 @@ class UsersController < ApplicationController
|
|||
|
||||
# LEGACY: used by the API
|
||||
def upload_avatar
|
||||
params[:user_image_type] = "avatar"
|
||||
params[:image_type] = "avatar"
|
||||
upload_user_image
|
||||
end
|
||||
|
||||
def upload_user_image
|
||||
params.require(:user_image_type)
|
||||
params.require(:image_type)
|
||||
user = fetch_user_from_params
|
||||
guardian.ensure_can_edit!(user)
|
||||
|
||||
|
@ -353,7 +353,7 @@ class UsersController < ApplicationController
|
|||
upload = Upload.create_for(user.id, image.file, image.filename, image.filesize)
|
||||
|
||||
if upload.errors.empty?
|
||||
case params[:user_image_type]
|
||||
case params[:image_type]
|
||||
when "avatar"
|
||||
upload_avatar_for(user, upload)
|
||||
when "profile_background"
|
||||
|
|
|
@ -1158,6 +1158,7 @@ en:
|
|||
change_in_category_topic: "Edit Description"
|
||||
already_used: 'This color has been used by another category'
|
||||
security: "Security"
|
||||
images: "Images"
|
||||
auto_close_label: "Auto-close topics after:"
|
||||
auto_close_units: "hours"
|
||||
email_in: "Custom incoming email address:"
|
||||
|
|
|
@ -1126,7 +1126,7 @@ describe UsersController do
|
|||
ActionDispatch::Http::UploadedFile.new({ filename: 'logo.png', tempfile: logo })
|
||||
end
|
||||
|
||||
it 'raises an error without a user_image_type param' do
|
||||
it 'raises an error without a image_type param' do
|
||||
lambda { xhr :put, :upload_user_image, username: user.username }.should raise_error(ActionController::ParameterMissing)
|
||||
end
|
||||
|
||||
|
@ -1134,19 +1134,19 @@ describe UsersController do
|
|||
|
||||
it 'raises an error when you don\'t have permission to upload an user image' do
|
||||
Guardian.any_instance.expects(:can_edit?).with(user).returns(false)
|
||||
xhr :post, :upload_user_image, username: user.username, user_image_type: "avatar"
|
||||
xhr :post, :upload_user_image, username: user.username, image_type: "avatar"
|
||||
response.should be_forbidden
|
||||
end
|
||||
|
||||
it 'rejects large images' do
|
||||
SiteSetting.stubs(:max_image_size_kb).returns(1)
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, user_image_type: "avatar"
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, image_type: "avatar"
|
||||
response.status.should eq 422
|
||||
end
|
||||
|
||||
it 'rejects unauthorized images' do
|
||||
SiteSetting.stubs(:authorized_extensions).returns(".txt")
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, user_image_type: "avatar"
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, image_type: "avatar"
|
||||
response.status.should eq 422
|
||||
end
|
||||
|
||||
|
@ -1154,7 +1154,7 @@ describe UsersController do
|
|||
upload = Fabricate(:upload)
|
||||
Upload.expects(:create_for).returns(upload)
|
||||
# enqueues the user_image generator job
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, user_image_type: "avatar"
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, image_type: "avatar"
|
||||
# returns the url, width and height of the uploaded image
|
||||
json = JSON.parse(response.body)
|
||||
json['url'].should == "/uploads/default/1/1234567890123456.png"
|
||||
|
@ -1166,7 +1166,7 @@ describe UsersController do
|
|||
it 'is successful for profile backgrounds' do
|
||||
upload = Fabricate(:upload)
|
||||
Upload.expects(:create_for).returns(upload)
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, user_image_type: "profile_background"
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, image_type: "profile_background"
|
||||
user.reload
|
||||
|
||||
user.user_profile.profile_background.should == "/uploads/default/1/1234567890123456.png"
|
||||
|
@ -1191,13 +1191,13 @@ describe UsersController do
|
|||
|
||||
it 'rejects large images' do
|
||||
SiteSetting.stubs(:max_image_size_kb).returns(1)
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image_url, user_image_type: "profile_background"
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image_url, image_type: "profile_background"
|
||||
response.status.should eq 422
|
||||
end
|
||||
|
||||
it 'rejects unauthorized images' do
|
||||
SiteSetting.stubs(:authorized_extensions).returns(".txt")
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image_url, user_image_type: "profile_background"
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image_url, image_type: "profile_background"
|
||||
response.status.should eq 422
|
||||
end
|
||||
|
||||
|
@ -1205,7 +1205,7 @@ describe UsersController do
|
|||
upload = Fabricate(:upload)
|
||||
Upload.expects(:create_for).returns(upload)
|
||||
# enqueues the user_image generator job
|
||||
xhr :post, :upload_avatar, username: user.username, file: user_image_url, user_image_type: "avatar"
|
||||
xhr :post, :upload_avatar, username: user.username, file: user_image_url, image_type: "avatar"
|
||||
json = JSON.parse(response.body)
|
||||
json['url'].should == "/uploads/default/1/1234567890123456.png"
|
||||
json['width'].should == 100
|
||||
|
@ -1216,7 +1216,7 @@ describe UsersController do
|
|||
it 'is successful for profile backgrounds' do
|
||||
upload = Fabricate(:upload)
|
||||
Upload.expects(:create_for).returns(upload)
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image_url, user_image_type: "profile_background"
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image_url, image_type: "profile_background"
|
||||
user.reload
|
||||
user.user_profile.profile_background.should == "/uploads/default/1/1234567890123456.png"
|
||||
|
||||
|
@ -1229,7 +1229,7 @@ describe UsersController do
|
|||
end
|
||||
|
||||
it "should handle malformed urls" do
|
||||
xhr :post, :upload_user_image, username: user.username, file: "foobar", user_image_type: "profile_background"
|
||||
xhr :post, :upload_user_image, username: user.username, file: "foobar", image_type: "profile_background"
|
||||
response.status.should eq 422
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue