diff --git a/app/assets/javascripts/application/avatar.js b/app/assets/javascripts/application/avatar.js
index 3f4b127bf..c6034c88c 100644
--- a/app/assets/javascripts/application/avatar.js
+++ b/app/assets/javascripts/application/avatar.js
@@ -38,14 +38,14 @@ $(function () {
// on submit take the parameters of the box to crop the avatar
$('#form_photo').on("submit", () => {
- let total_width = parseInt(getComputedStyle(document.getElementById("containerCrop")).width);
- let photo_width = parseInt(getComputedStyle(document.getElementById("foto")).width);
+ let total_width = parseInt(getComputedStyle(document.getElementById("container_crop")).width);
+ let photo_width = parseInt(getComputedStyle(document.getElementById("original_img")).width);
let left_displacement = total_width - photo_width;
$('#height_offset').val(parseInt(panel.css('top')) - 15);
$('#width_offset').val(parseInt(panel.css('left')) - 15 - (left_displacement/2));
$('#height_width').val(parseInt(panel.css('width')));
- $('#original_width').val($('#foto').width());
+ $('#original_width').val($('#original_img').width());
});
function resize(e) {
@@ -93,7 +93,7 @@ $(function () {
}
function preview_image_modal() {
- var preview = document.querySelector('#foto');
+ var preview = document.querySelector('#original_img');
var file = document.querySelector('#avatar-js').files[0];
var reader = new FileReader();
diff --git a/app/assets/stylesheets/application/avatar.scss b/app/assets/stylesheets/application/avatar.scss
index d87ab1d6b..7ed2d7c8d 100644
--- a/app/assets/stylesheets/application/avatar.scss
+++ b/app/assets/stylesheets/application/avatar.scss
@@ -6,8 +6,8 @@
#crop_panel {
position: absolute;
- width: 140px;
- height: 140px;
+ width: 200px;
+ height: 200px;
border-left: 4px dashed black;
cursor: move;
touch-action: none;
@@ -21,7 +21,7 @@
right: 0;
width: 16px;
height: 100%;
- cursor: w-resize;
+ cursor: ew-resize;
}
#crop_panel::after {
@@ -32,5 +32,5 @@
bottom: 0;
width: 100%;
height: 16px;
- cursor: n-resize;
+ cursor: ns-resize;
}
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index eded58ee7..79e48b807 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -66,14 +66,12 @@ def update
end
def update_avatar
- avatar = params[:avatar]
+ operation = AvatarGenerator.new(current_user, params)
- if avatar && content_type_permitted(avatar.content_type)
- current_user.avatar.purge if current_user.avatar.attached?
-
- crop_image_and_save(current_user, avatar)
+ if operation.errors.empty?
+ operation.call
else
- flash[:error] = t 'users.show.invalid_format'
+ flash[:error] = operation.errors.join("
")
end
redirect_to current_user
@@ -130,28 +128,4 @@ def redirect_to_after_create
name: @user.username)
end
end
-
- def crop_image_and_save(user, avatar)
- orig_width = params[:original_width].to_i
- width = params[:height_width].to_i
- left = params[:width_offset].to_i
- top = params[:height_offset].to_i
-
- image_processed = ImageProcessing::MiniMagick.
- source(avatar.tempfile).
- resize_to_fit(orig_width, nil).
- crop("#{width}x#{width}+#{left}+#{top}!").
- convert("png").
- call
-
- user.avatar.attach(
- io: image_processed,
- filename: user.username,
- content_type: avatar.content_type
- )
- end
-
- def content_type_permitted(avatar_content_type)
- %w[image/jpeg image/pjpeg image/png image/x-png].include? avatar_content_type
- end
end
diff --git a/app/services/avatar_generator.rb b/app/services/avatar_generator.rb
new file mode 100644
index 000000000..d04187f4c
--- /dev/null
+++ b/app/services/avatar_generator.rb
@@ -0,0 +1,51 @@
+class AvatarGenerator
+ MAX_SIZE = 5
+ CONTENT_TYPES = %w[image/jpeg image/pjpeg image/png image/x-png]
+
+ attr_accessor :errors
+
+ def initialize(user, params)
+ @user = user
+ @params = params
+ @avatar = params[:avatar]
+ @errors = []
+
+ validate_avatar
+ end
+
+ def call
+ @user.avatar.purge if @user.avatar.attached?
+
+ @user.avatar.attach(
+ io: process_image,
+ filename: @user.username,
+ content_type: @avatar.content_type
+ )
+ end
+
+ private
+
+ def process_image
+ orig_width = @params[:original_width].to_i
+ width = @params[:height_width].to_i
+ left = @params[:width_offset].to_i
+ top = @params[:height_offset].to_i
+
+ ImageProcessing::MiniMagick.
+ source(@avatar.tempfile).
+ resize_to_fit(orig_width, nil).
+ crop("#{width}x#{width}+#{left}+#{top}!").
+ convert("png").
+ call
+ end
+
+ def validate_avatar
+ if CONTENT_TYPES.exclude?(@avatar.content_type)
+ @errors << I18n.t("users.show.invalid_format")
+ end
+
+ if @avatar.size.to_f > MAX_SIZE.megabytes
+ @errors << I18n.t("users.avatar.max_size_warning", size: MAX_SIZE)
+ end
+ end
+end
diff --git a/app/views/layouts/_messages.html.erb b/app/views/layouts/_messages.html.erb
index 0222a2c35..d1db057d0 100644
--- a/app/views/layouts/_messages.html.erb
+++ b/app/views/layouts/_messages.html.erb
@@ -5,7 +5,7 @@