2015-05-28 08:52:41 +03:00
|
|
|
import Ember from 'ember';
|
2016-03-25 07:03:45 +03:00
|
|
|
import AjaxService from 'ember-ajax/services/ajax';
|
2016-04-12 14:34:40 +03:00
|
|
|
import {NotFoundError} from 'ghost/services/ajax';
|
2015-05-28 08:52:41 +03:00
|
|
|
|
2016-01-19 16:03:27 +03:00
|
|
|
const {
|
|
|
|
Component,
|
|
|
|
computed,
|
|
|
|
inject: {service},
|
2016-04-12 14:34:40 +03:00
|
|
|
isBlank,
|
2016-01-19 16:03:27 +03:00
|
|
|
run
|
|
|
|
} = Ember;
|
2016-04-12 14:34:40 +03:00
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
const {notEmpty} = computed;
|
|
|
|
|
2015-05-28 08:52:41 +03:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*
|
2015-10-26 14:48:38 +03:00
|
|
|
* Example: {{gh-profile-image email=controllerEmailProperty setImage="controllerActionName" debounce=500}}
|
2015-05-28 08:52:41 +03:00
|
|
|
*
|
2015-10-26 14:48:38 +03:00
|
|
|
* @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
|
2015-05-28 08:52:41 +03:00
|
|
|
*/
|
2015-10-28 14:36:45 +03:00
|
|
|
export default Component.extend({
|
2015-05-28 08:52:41 +03:00
|
|
|
email: '',
|
|
|
|
size: 90,
|
2015-10-26 14:48:38 +03:00
|
|
|
debounce: 300,
|
|
|
|
|
|
|
|
validEmail: '',
|
2015-05-28 08:52:41 +03:00
|
|
|
hasUploadedImage: false,
|
2015-07-17 15:57:09 +03:00
|
|
|
fileStorage: true,
|
2016-03-25 07:03:45 +03:00
|
|
|
ajax: AjaxService.create(),
|
|
|
|
config: service(),
|
2015-05-28 08:52:41 +03:00
|
|
|
|
2016-01-19 16:03:27 +03:00
|
|
|
ghostPaths: service(),
|
2015-10-28 14:36:45 +03:00
|
|
|
displayGravatar: notEmpty('validEmail'),
|
2015-05-28 08:52:41 +03:00
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
init() {
|
2015-11-20 19:40:41 +03:00
|
|
|
this._super(...arguments);
|
|
|
|
// Fire this immediately in case we're initialized with a valid email
|
|
|
|
this.trySetValidEmail();
|
|
|
|
},
|
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
defaultImage: computed('ghostPaths', function () {
|
2016-01-14 19:25:29 +03:00
|
|
|
let url = `${this.get('ghostPaths.subdir')}/ghost/img/user-image.png`;
|
2015-10-26 14:48:38 +03:00
|
|
|
return Ember.String.htmlSafe(`background-image: url(${url})`);
|
2015-05-28 08:52:41 +03:00
|
|
|
}),
|
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
trySetValidEmail() {
|
2015-10-26 14:48:38 +03:00
|
|
|
if (!this.get('isDestroyed')) {
|
2015-10-28 14:36:45 +03:00
|
|
|
let email = this.get('email');
|
2015-10-26 14:48:38 +03:00
|
|
|
this.set('validEmail', validator.isEmail(email) ? email : '');
|
|
|
|
}
|
2015-09-06 18:03:49 +03:00
|
|
|
},
|
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
didReceiveAttrs(attrs) {
|
2015-11-15 14:06:49 +03:00
|
|
|
this._super(...arguments);
|
2015-10-28 14:36:45 +03:00
|
|
|
let timeout = parseInt(attrs.newAttrs.throttle || this.get('debounce'));
|
|
|
|
run.debounce(this, 'trySetValidEmail', timeout);
|
2015-09-06 18:03:49 +03:00
|
|
|
},
|
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
imageBackground: computed('validEmail', 'size', function () {
|
|
|
|
let email = this.get('validEmail');
|
|
|
|
let size = this.get('size');
|
2015-11-21 01:45:43 +03:00
|
|
|
let style = '';
|
2016-03-25 07:03:45 +03:00
|
|
|
|
2016-04-12 14:34:40 +03:00
|
|
|
if (!isBlank(email)) {
|
2016-03-25 07:03:45 +03:00
|
|
|
let gravatarUrl = `//www.gravatar.com/avatar/${window.md5(email)}?s=${size}&d=404`;
|
|
|
|
|
|
|
|
this.get('ajax').request(gravatarUrl)
|
2016-04-12 14:34:40 +03:00
|
|
|
.catch((error) => {
|
2016-03-25 07:03:45 +03:00
|
|
|
let defaultImageUrl = `url("${this.get('ghostPaths.subdir')}/ghost/img/user-image.png")`;
|
|
|
|
|
2016-04-12 14:34:40 +03:00
|
|
|
if (error instanceof NotFoundError) {
|
2016-03-25 07:03:45 +03:00
|
|
|
this.$('.placeholder-img')[0].style.backgroundImage = Ember.String.htmlSafe(defaultImageUrl);
|
|
|
|
} else {
|
|
|
|
this.$('.placeholder-img')[0].style.backgroundImage = 'url()';
|
|
|
|
}
|
|
|
|
});
|
2016-04-12 14:34:40 +03:00
|
|
|
|
2016-03-25 07:03:45 +03:00
|
|
|
style = `background-image: url(${gravatarUrl})`;
|
2015-05-28 08:52:41 +03:00
|
|
|
}
|
2015-11-21 01:45:43 +03:00
|
|
|
return Ember.String.htmlSafe(style);
|
2015-05-28 08:52:41 +03:00
|
|
|
}),
|
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
didInsertElement() {
|
|
|
|
let size = this.get('size');
|
|
|
|
let uploadElement = this.$('.js-file-input');
|
2015-05-28 08:52:41 +03:00
|
|
|
|
2015-11-15 14:06:49 +03:00
|
|
|
this._super(...arguments);
|
|
|
|
|
2015-05-28 08:52:41 +03:00
|
|
|
// 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,
|
2015-07-07 20:34:23 +03:00
|
|
|
autoUpload: false
|
2015-05-28 08:52:41 +03:00
|
|
|
})
|
2015-10-28 14:36:45 +03:00
|
|
|
.on('fileuploadadd', run.bind(this, this.queueFile))
|
|
|
|
.on('fileuploadprocessalways', run.bind(this, this.triggerPreview));
|
2015-05-28 08:52:41 +03:00
|
|
|
},
|
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
willDestroyElement() {
|
2015-12-21 14:08:49 +03:00
|
|
|
let $input = this.$('.js-file-input');
|
|
|
|
|
2015-11-15 14:06:49 +03:00
|
|
|
this._super(...arguments);
|
|
|
|
|
2015-12-21 14:08:49 +03:00
|
|
|
if ($input.length && $input.data()['blueimp-fileupload']) {
|
|
|
|
$input.fileupload('destroy');
|
2015-10-26 14:48:38 +03:00
|
|
|
}
|
2015-05-28 08:52:41 +03:00
|
|
|
},
|
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
queueFile(e, data) {
|
|
|
|
let fileName = data.files[0].name;
|
2015-07-07 20:34:23 +03:00
|
|
|
|
|
|
|
if ((/\.(gif|jpe?g|png|svg?z)$/i).test(fileName)) {
|
|
|
|
this.sendAction('setImage', data);
|
|
|
|
}
|
2015-05-28 08:52:41 +03:00
|
|
|
},
|
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
triggerPreview(e, data) {
|
|
|
|
let file = data.files[data.index];
|
|
|
|
|
2015-05-28 08:52:41 +03:00
|
|
|
if (file.preview) {
|
2015-07-07 20:34:23 +03:00
|
|
|
this.set('hasUploadedImage', true);
|
2015-05-28 08:52:41 +03:00
|
|
|
// 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'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|