mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-15 11:34:24 +03:00
571b9e783a
no issue - review use of Ember core hooks and add a call to `this._super` if missing - fix a few occurrences of using the wrong component lifecycle hooks that could result in multiple/duplicate event handlers being attached `_super` should always be called when overriding Ember's base hooks so that core functionality or app functionality added through extensions, mixins or addons is not lost. This is important as it guards against issues arising from later refactorings or core changes. As example of lost functionality, there were a number of routes that extended from `AuthenticatedRoute` but then overrode the `beforeModel` hook without calling `_super` which meant that the route was no longer treated as authenticated.
118 lines
4.4 KiB
JavaScript
118 lines
4.4 KiB
JavaScript
import Ember from 'ember';
|
|
|
|
const {Component, computed, inject, run} = Ember;
|
|
const {notEmpty} = computed;
|
|
|
|
/**
|
|
* A component to manage a user profile image. By default it just handles picture uploads,
|
|
* but if passed a bound 'email' property it will render the user's gravatar image
|
|
*
|
|
* Example: {{gh-profile-image email=controllerEmailProperty setImage="controllerActionName" debounce=500}}
|
|
*
|
|
* @param {int} size The size of the image to render
|
|
* @param {String} email Reference to a bound email object if gravatar image behavior is desired.
|
|
* @param {String|action} setImage The string name of the action on the controller to be called when an image is added.
|
|
* @param {int} debounce Period to wait after changes to email before attempting to load gravatar
|
|
* @property {Boolean} hasUploadedImage Whether or not the user has uploaded an image (whether or not to show the default image/gravatar image)
|
|
* @property {String} defaultImage String containing the background-image css property of the default user profile image
|
|
* @property {String} imageBackground String containing the background-image css property with the gravatar url
|
|
*/
|
|
export default Component.extend({
|
|
email: '',
|
|
size: 90,
|
|
debounce: 300,
|
|
|
|
validEmail: '',
|
|
hasUploadedImage: false,
|
|
fileStorage: true,
|
|
|
|
ghostPaths: inject.service('ghost-paths'),
|
|
displayGravatar: notEmpty('validEmail'),
|
|
|
|
init() {
|
|
this._super(...arguments);
|
|
// Fire this immediately in case we're initialized with a valid email
|
|
this.trySetValidEmail();
|
|
},
|
|
|
|
defaultImage: computed('ghostPaths', function () {
|
|
let url = this.get('ghostPaths.url').asset('/shared/img/user-image.png');
|
|
return Ember.String.htmlSafe(`background-image: url(${url})`);
|
|
}),
|
|
|
|
trySetValidEmail() {
|
|
if (!this.get('isDestroyed')) {
|
|
let email = this.get('email');
|
|
this.set('validEmail', validator.isEmail(email) ? email : '');
|
|
}
|
|
},
|
|
|
|
didReceiveAttrs(attrs) {
|
|
this._super(...arguments);
|
|
let timeout = parseInt(attrs.newAttrs.throttle || this.get('debounce'));
|
|
run.debounce(this, 'trySetValidEmail', timeout);
|
|
},
|
|
|
|
imageBackground: computed('validEmail', 'size', function () {
|
|
let email = this.get('validEmail');
|
|
let size = this.get('size');
|
|
|
|
let style = '';
|
|
if (email) {
|
|
let url = `http://www.gravatar.com/avatar/${window.md5(email)}?s=${size}&d=blank`;
|
|
style = `background-image: url(${url})`;
|
|
}
|
|
return Ember.String.htmlSafe(style);
|
|
}),
|
|
|
|
didInsertElement() {
|
|
let size = this.get('size');
|
|
let uploadElement = this.$('.js-file-input');
|
|
|
|
this._super(...arguments);
|
|
|
|
// while theoretically the 'add' and 'processalways' functions could be
|
|
// added as properties of the hash passed to fileupload(), for some reason
|
|
// they needed to be placed in an on() call for the add method to work correctly
|
|
uploadElement.fileupload({
|
|
url: this.get('ghostPaths.url').api('uploads'),
|
|
dropZone: this.$('.js-img-dropzone'),
|
|
previewMaxHeight: size,
|
|
previewMaxWidth: size,
|
|
previewCrop: true,
|
|
maxNumberOfFiles: 1,
|
|
autoUpload: false
|
|
})
|
|
.on('fileuploadadd', run.bind(this, this.queueFile))
|
|
.on('fileuploadprocessalways', run.bind(this, this.triggerPreview));
|
|
},
|
|
|
|
willDestroyElement() {
|
|
this._super(...arguments);
|
|
|
|
if (this.$('.js-file-input').data()['blueimp-fileupload']) {
|
|
this.$('.js-file-input').fileupload('destroy');
|
|
}
|
|
},
|
|
|
|
queueFile(e, data) {
|
|
let fileName = data.files[0].name;
|
|
|
|
if ((/\.(gif|jpe?g|png|svg?z)$/i).test(fileName)) {
|
|
this.sendAction('setImage', data);
|
|
}
|
|
},
|
|
|
|
triggerPreview(e, data) {
|
|
let file = data.files[data.index];
|
|
|
|
if (file.preview) {
|
|
this.set('hasUploadedImage', true);
|
|
// necessary jQuery code because file.preview is a raw DOM object
|
|
// potential todo: rename 'gravatar-img' class in the CSS to be something
|
|
// that both the gravatar and the image preview can use that's not so confusing
|
|
this.$('.js-img-preview').empty().append(this.$(file.preview).addClass('gravatar-img'));
|
|
}
|
|
}
|
|
});
|