mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-11 01:44:34 +08:00
Add predefined avatars
This commit is contained in:
parent
1f43f35073
commit
521a367960
7 changed files with 83 additions and 90 deletions
|
@ -1,12 +1,24 @@
|
|||
/* global initInlineEditing PerfectScrollbar */
|
||||
|
||||
/* eslint-disable no-restricted-globals, no-alert */
|
||||
var avatarsModal = (function() {
|
||||
var modal = '.modal-user-avatar'
|
||||
var modal = '.modal-user-avatar';
|
||||
|
||||
function initUploadPhotoButton() {
|
||||
$(modal).find('.upload-photo').click(() => {
|
||||
$(modal).find('#raw_avatar').click()
|
||||
})
|
||||
$(modal).find('#raw_avatar').click();
|
||||
});
|
||||
}
|
||||
|
||||
function getBase64Image(img) {
|
||||
var ctx;
|
||||
var dataURL;
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = 200;
|
||||
canvas.height = 200;
|
||||
ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0);
|
||||
dataURL = canvas.toDataURL('image/png');
|
||||
return dataURL;
|
||||
}
|
||||
|
||||
function initCropTool() {
|
||||
|
@ -18,8 +30,10 @@ var avatarsModal = (function() {
|
|||
$(modal).find('.current-avatar').hide();
|
||||
reader.readAsDataURL(inputField.files[0]);
|
||||
reader.onload = function() {
|
||||
var avatarContainer = $(modal).find('.avatar-preview-container');
|
||||
$(modal).find('.save-button').removeClass('disabled');
|
||||
$(modal).find('#new_avatar').val(reader.result);
|
||||
var avatarContainer = $(modal).find('.avatar-preview-container')
|
||||
|
||||
avatarContainer.show().children().remove();
|
||||
$('<img class="avatar-cropping-preview" src="' + reader.result + '"></img>').appendTo(avatarContainer);
|
||||
croppieContainer = $('.avatar-cropping-preview');
|
||||
|
@ -36,29 +50,48 @@ var avatarsModal = (function() {
|
|||
|
||||
function initPredefinedAvatars() {
|
||||
$(modal).find('.avatar-collection .avatar').click(function() {
|
||||
$(modal).find('.save-button').removeClass('disabled');
|
||||
$(modal).find('#raw_avatar')[0].value = null;
|
||||
$(modal).find('.avatar-preview-container').hide();
|
||||
$(modal).find('.current-avatar').show().find('img')
|
||||
.attr('src',$(this).find('img').attr('src'));
|
||||
$(modal).find('#new_avatar').val(getBase64Image($(this).find('img')[0]))
|
||||
})
|
||||
.attr('src', $(this).find('img').attr('src'));
|
||||
$(modal).find('#new_avatar').val(getBase64Image($(this).find('img')[0]));
|
||||
});
|
||||
}
|
||||
|
||||
function getBase64Image(img) {
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0);
|
||||
var dataURL = canvas.toDataURL("image/png");
|
||||
return dataURL;
|
||||
function initUpdateButton() {
|
||||
$(modal).find('.save-button').click(function() {
|
||||
if ($(this).hasClass('disabled')) return;
|
||||
|
||||
$(this).addClass('disabled');
|
||||
$.ajax({
|
||||
url: $(modal).data('update-url'),
|
||||
type: 'PUT',
|
||||
data: {
|
||||
'user[avatar]': $(modal).find('#new_avatar').val(),
|
||||
'user[change_avatar]': true
|
||||
},
|
||||
dataType: 'json',
|
||||
success: () => {
|
||||
location.reload();
|
||||
},
|
||||
error: () => {
|
||||
$(this).removeClass('disabled');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: (mode) => {
|
||||
init: () => {
|
||||
if ($('.modal-user-avatar').length > 0) {
|
||||
initUploadPhotoButton()
|
||||
initCropTool()
|
||||
initPredefinedAvatars()
|
||||
initUploadPhotoButton();
|
||||
initCropTool();
|
||||
initPredefinedAvatars();
|
||||
initUpdateButton();
|
||||
$('.user-settings-edit-avatar').click(() => {
|
||||
$(modal).modal('show');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -68,27 +68,6 @@
|
|||
$(this).renderFormErrors('user', data.responseJSON);
|
||||
});
|
||||
|
||||
/*$('#user_raw_avatar').change(function() {
|
||||
var reader = new FileReader();
|
||||
var inputField = this;
|
||||
var croppieContainer;
|
||||
|
||||
reader.readAsDataURL(inputField.files[0]);
|
||||
reader.onload = function() {
|
||||
$('#user_avatar').val(reader.result);
|
||||
$('.new-avatar-preview-container').css('display', '').children().remove();
|
||||
$('<img class="new-avatar-cropping-preview" src="' + reader.result + '"></img>').appendTo('.new-avatar-preview-container');
|
||||
croppieContainer = $('.new-avatar-cropping-preview');
|
||||
croppieContainer.croppie({ viewport: { width: 150, height: 150, type: 'circle' } });
|
||||
$('.new-avatar-preview-container').off('update.croppie').on('update.croppie', function() {
|
||||
croppieContainer.croppie('result', { type: 'base64', format: 'jpeg', circle: false })
|
||||
.then(function(image) {
|
||||
$('#user_avatar').val(image);
|
||||
});
|
||||
});
|
||||
};
|
||||
});*/
|
||||
|
||||
$('#user-avatar-field :submit').click(function(ev) {
|
||||
var $form = $(ev.target.form);
|
||||
var $fileInput = $form.find('input[type=file]');
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// scss-lint:disable SelectorDepth SelectorFormat QualifyingElement
|
||||
// scss-lint:disable NestingDepth ImportantRule
|
||||
|
||||
@import "constants";
|
||||
@import "mixins";
|
||||
|
||||
|
@ -47,7 +50,7 @@
|
|||
height: 100px;
|
||||
margin-bottom: 5px;
|
||||
transition: $md-transaction;
|
||||
width:80px;
|
||||
width: 80px;
|
||||
|
||||
&:hover {
|
||||
box-shadow: $md-shadow;
|
||||
|
@ -69,7 +72,7 @@
|
|||
|
||||
.current-avatar {
|
||||
height: 150px;
|
||||
margin: 35px 0;
|
||||
margin: 25px 0 45px;
|
||||
width: 150px;
|
||||
|
||||
img {
|
||||
|
@ -93,6 +96,6 @@
|
|||
}
|
||||
|
||||
.modal-footer {
|
||||
text-align: center
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,10 +37,11 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
|||
else
|
||||
temp_file = Tempfile.new('avatar', Rails.root.join('tmp'))
|
||||
begin
|
||||
check_extension = params[:avatar].split(';')[0].split('/')[1]
|
||||
temp_file.binmode
|
||||
temp_file.write(Base64.decode64(params[:avatar].sub(%r{^data:image\/jpeg\;base64,}, '')))
|
||||
temp_file.write(Base64.decode64(params[:avatar].split(',')[1]))
|
||||
temp_file.rewind
|
||||
resource.avatar.attach(io: temp_file, filename: 'avatar.jpg')
|
||||
resource.avatar.attach(io: temp_file, filename: "avatar.#{check_extension}")
|
||||
ensure
|
||||
temp_file.close
|
||||
temp_file.unlink
|
||||
|
|
|
@ -16,46 +16,23 @@
|
|||
<%= devise_error_messages! %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= form_for(resource,
|
||||
as: resource_name,
|
||||
url: registration_path(resource_name),
|
||||
html: { method: :put, "data-for" => "avatar", id: 'user-avatar-field' }) do |f| %>
|
||||
<%= hidden_field_tag "user[change_avatar]", "true" %>
|
||||
<div data-part="view">
|
||||
<div class="form-group">
|
||||
<%= f.label t("users.registrations.edit.avatar_label") %><br />
|
||||
<div class="form-group user-settings-edit-avatar">
|
||||
<%= t("users.registrations.edit.avatar_label") %><br>
|
||||
<% @user_avatar_url ||= avatar_path(current_user, :thumb) %>
|
||||
<div class="avatar-container">
|
||||
<a href="#" data-action="edit">
|
||||
<div class="avatar-image">
|
||||
<div class="avatar-image">
|
||||
<%= image_tag @user_avatar_url %>
|
||||
</div>
|
||||
<div class="avatar-edit">
|
||||
</div>
|
||||
<div class="avatar-edit">
|
||||
<div class="btn btn-grey btn-sm">
|
||||
<span class="fas fa-pencil-alt"></span>
|
||||
<%=t "users.registrations.edit.avatar_btn" %>
|
||||
</div>
|
||||
<%=t "users.registrations.edit.avatar_btn" %>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-part="edit" style="display: none;">
|
||||
<div class="well">
|
||||
<h4><%=t "users.registrations.edit.avatar_title" %></h4>
|
||||
<div class="new-avatar-preview-container" style="display:none"></div>
|
||||
<div class="form-group avatar-file-upload">
|
||||
<%= f.label :avatar, t("users.registrations.edit.avatar_edit_label") %>
|
||||
<%= f.file_field :raw_avatar, class: "btn btn-default" %>
|
||||
<%= hidden_field_tag "user[avatar]", "" %>
|
||||
</div>
|
||||
<div class="align-right">
|
||||
<a href="#" class="btn btn-default" data-action="cancel"><%=t "general.cancel" %></a>
|
||||
<%= f.submit t("users.registrations.edit.avatar_submit"), class: 'btn btn-success' %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= form_for(resource,
|
||||
as: resource_name,
|
||||
url: registration_path(resource_name, format: :json),
|
||||
|
@ -236,9 +213,6 @@
|
|||
</div>
|
||||
|
||||
<%= render partial: 'users/shared/user_avatars_modal' %>
|
||||
<script>
|
||||
$('.modal-user-avatar').modal('show')
|
||||
</script>
|
||||
|
||||
<%= javascript_pack_tag 'custom/croppie' %>
|
||||
<%= stylesheet_pack_tag 'custom/croppie_styles' %>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<div class="modal modal-user-avatar" tabindex="-1" role="dialog" >
|
||||
<div class="modal modal-user-avatar" tabindex="-1" role="dialog"
|
||||
data-update-url="<%= registration_path(resource_name) %>"
|
||||
>
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="<%= t('general.close') %>"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">
|
||||
Change your profile photo
|
||||
<%= t('users.registrations.edit.avatar_modal.title') %>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
@ -15,10 +17,10 @@
|
|||
<%= hidden_field_tag :new_avatar, "" %>
|
||||
</div>
|
||||
<div class="avatar-preview-container" style="display:none"></div>
|
||||
<div class="btn btn-default upload-photo">Upload a photo</div>
|
||||
<div class="btn btn-default upload-photo"><%= t('users.registrations.edit.avatar_modal.upload_button') %></div>
|
||||
</div>
|
||||
<div class="option-text">
|
||||
or<br>Select a profile icon below
|
||||
<%= t('users.registrations.edit.avatar_modal.option_text_html') %>
|
||||
</div>
|
||||
<div class="avatar-collection perfect-scrollbar">
|
||||
<% Dir["public/images/avatars/*.png"].each do |avatar| %>
|
||||
|
@ -30,7 +32,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="btn btn-primary">Save</div>
|
||||
<div class="btn btn-primary save-button disabled"><%= t('general.save') %></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -91,6 +91,7 @@ en:
|
|||
initials: "Initials"
|
||||
avatar: "Avatar"
|
||||
|
||||
|
||||
head:
|
||||
title: "SciNote | %{title}"
|
||||
|
||||
|
@ -1411,10 +1412,10 @@ en:
|
|||
title: "My profile"
|
||||
avatar_label: "Avatar"
|
||||
avatar_btn: "Edit Avatar"
|
||||
avatar_title: "Change avatar"
|
||||
avatar_edit_label: "Upload new avatar file"
|
||||
avatar_submit: "Upload"
|
||||
avatar_total_size: "Your avatar file cannot be larger than 0.2 MB. (Please try again with a smaller file.)"
|
||||
avatar_modal:
|
||||
title: 'Change your profile photo'
|
||||
upload_button: 'Upload a photo'
|
||||
option_text_html: 'or<br>Select a profile icon below'
|
||||
name_label: "Full name"
|
||||
name_title: "Change name"
|
||||
initials_label: "Initials"
|
||||
|
|
Loading…
Reference in a new issue