[ticket/15769] Start integrating upload of cropped image via AJAX

PHPBB3-15769
This commit is contained in:
Marc Alexander 2021-08-15 20:14:28 +02:00
parent 8509cf2a04
commit 7cdd30958d
No known key found for this signature in database
GPG key ID: 50E0D2423696F995
5 changed files with 110 additions and 16 deletions

View file

@ -11,6 +11,9 @@
cropper: null,
image: null,
/** @type {jQuery} */
$form: null,
/** @type {jQuery} */
$buttons: $('#avatar-cropper-buttons'),
@ -45,6 +48,7 @@
this.bindInput();
this.bindSelect();
this.bindSubmit();
},
/**
@ -53,9 +57,11 @@
destroy() {
this.$buttons.find('[data-cropper-action]').off('click.phpbb.avatars');
this.image.off('crop.phpbb.avatars');
this.$form.off('submit');
this.$data.val('');
this.$buttons.hide();
this.$box.removeClass('c-cropper-avatar-box');
if (this.cropper !== null) {
this.cropper.destroy();
@ -95,6 +101,7 @@
fileReader.addEventListener('load', function() {
phpbb.avatars.image.cropper('destroy').attr('src', this.result).addClass('avatar');
phpbb.avatars.$box.addClass('c-cropper-avatar-box');
phpbb.avatars.initCropper();
phpbb.avatars.initButtons();
});
@ -104,6 +111,73 @@
});
},
bindSubmit() {
const $this = this;
$this.$form = this.$input.closest('form');
$this.$form.on('submit', () => {
const data = phpbb.avatars.$data.data();
phpbb.avatars.cropper.getCroppedCanvas({
width: data.maxWidth,
height: data.maxHeight,
maxWidth: 4096, // High values for max quality cropping
maxHeight: 4096, // High values for max quality cropping
imageSmoothingEnabled: false,
imageSmoothingQuality: 'high',
}).toBlob(blob => {
const formData = new FormData($this.$form[0]);
formData.set('avatar_upload_file', blob, $this.getUploadFileName());
formData.set('submit', '1');
$.ajax({
url: $this.$form.attr('action'),
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: $this.uploadDone,
error: () => {
console.log('Upload error');
},
}).done($this.uploadDone);
}, 'image/png', 1);
return false;
});
},
/**
* Get upload filename for the blob data
*
* As the blob data is always in png format, we'll replace the file
* extension in the upload name with one that ends with .png
*
* @return {string} Upload file name
*/
getUploadFileName() {
const originalName = this.$input[0].files[0].name;
return originalName.replace(/\.[^/\\.]+$/, '.png');
},
uploadDone(response) {
if (typeof response !== 'object') {
return;
}
// trigger_error() was called which likely means a permission error was encountered.
if (typeof response.title !== 'undefined') {
return;
}
// Handle errors while deleting file
if (typeof response.error !== 'undefined') {
phpbb.alert(response.error.title, response.error.message);
}
phpbb.avatars.destroy();
},
/**
* Bind a function to all the cropper <button> elements.
*
@ -171,14 +245,6 @@
height,
});
}
phpbb.avatars.$data.val(JSON.stringify(phpbb.avatars.cropper.getCroppedCanvas({
minWidth: data.minWidth,
minHeight: data.minHeight,
maxWidth: data.maxWidth,
maxHeight: data.maxHeight,
imageSmoothingEnabled: false, // smoothing will just look blurry
})));
},
};

View file

@ -32,7 +32,7 @@ class ucp_profile
function main($id, $mode)
{
global $config, $db, $user, $auth, $template, $phpbb_root_path, $phpEx;
global $request, $phpbb_container, $phpbb_log, $phpbb_dispatcher;
global $request, $phpbb_container, $phpbb_log, $phpbb_dispatcher, $language;
$user->add_lang('posting');
@ -669,7 +669,7 @@ class ucp_profile
);
/**
* Trigger events on successfull avatar change
* Trigger events on successful avatar change
*
* @event core.ucp_profile_avatar_sql
* @var array result Array with data to be stored in DB
@ -683,12 +683,36 @@ class ucp_profile
WHERE user_id = ' . (int) $user->data['user_id'];
$db->sql_query($sql);
if ($request->is_ajax())
{
/** @var \phpbb\avatar\helper $avatar_helper */
$avatar_helper = $phpbb_container->get('avatar.helper');
$avatar = $avatar_helper->get_user_avatar($user->data, 'USER_AVATAR', true);
$json_response = new \phpbb\json_response;
$json_response->send(array(
'success' => true,
'MESSAGE_TITLE' => $language->lang('INFORMATION'),
'MESSAGE_TEXT' => $language->lang('PROFILE_UPDATED'),
'AVATAR' => $avatar_helper->get_template_vars($avatar),
'REFRESH_DATA' => [
'time' => 3,
'url' => $this->u_action,
'text' => $language->lang('RETURN_TO_UCP'),
]
));
}
else
{
meta_refresh(3, $this->u_action);
$message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
$message = $language->lang('PROFILE_UPDATED') . '<br><br>' . $language->lang('RETURN_UCP', '<a href="' . $this->u_action . '">', '</a>');
trigger_error($message);
}
}
}
}
else
{
$error[] = 'FORM_INVALID';

View file

@ -473,6 +473,7 @@ $lang = array_merge($lang, array(
'RESIGN_SELECTED' => 'Resign selected',
'RETURN_FOLDER' => '%1$sReturn to previous folder%2$s',
'RETURN_UCP' => '%sReturn to the User Control Panel%s',
'RETURN_TO_UCP' => 'Return to the User Control Panel',
'ROTATE_LEFT' => 'Rotate left',
'ROTATE_RIGHT' => 'Rotate right',
'RULE_ADDED' => 'Rule successfully added.',

View file

@ -11,8 +11,7 @@
<input type="hidden" id="avatar-cropper-data" name="avatar_cropper_data" value=""
data-min-width="{{ AVATAR_MIN_WIDTH }}" data-max-width="{{ AVATAR_MAX_WIDTH }}"
data-min-height="{{ AVATAR_MIN_HEIGHT }}" data-max-height="{{ AVATAR_MAX_HEIGHT }}"
/>
data-min-height="{{ AVATAR_MIN_HEIGHT }}" data-max-height="{{ AVATAR_MAX_HEIGHT }}" />
{% apply spaceless %}
<div class="avatar-cropper-buttons" id="avatar-cropper-buttons">

View file

@ -357,6 +357,10 @@ ol.def-rules li {
padding: 5px;
}
.c-cropper-avatar-box {
min-height: 240px;
}
p.notification-title,
p.notification-forum,
p.notification-reason,