Finish changes in #5807 (debounced gravatar load in gh-profile-image)
refs #5807, #5797 - add configurable debounce period - rename `hasEmail` to `displayGravatar` to better reflect it's purpose - add tests
This commit is contained in:
parent
de30a0c0ca
commit
2a30f919d9
@ -5,46 +5,52 @@ import Ember from 'ember';
|
||||
* 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"}}
|
||||
* 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} setImage The string name of the action on the controller to be called when an image is added.
|
||||
* @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
|
||||
* @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 Ember.Component.extend({
|
||||
email: '',
|
||||
validEmail: '',
|
||||
size: 90,
|
||||
debounce: 300,
|
||||
|
||||
validEmail: '',
|
||||
hasUploadedImage: false,
|
||||
fileStorage: true,
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
hasEmail: Ember.computed.notEmpty('email'),
|
||||
displayGravatar: Ember.computed.notEmpty('validEmail'),
|
||||
|
||||
defaultImage: Ember.computed('ghostPaths', function () {
|
||||
var url = this.get('ghostPaths.url').asset('/shared/img/user-image.png');
|
||||
return `background-image: url(${url})`.htmlSafe();
|
||||
const url = this.get('ghostPaths.url').asset('/shared/img/user-image.png');
|
||||
return Ember.String.htmlSafe(`background-image: url(${url})`);
|
||||
}),
|
||||
|
||||
trySetValidEmail: function () {
|
||||
var email = this.get('email');
|
||||
this.set('validEmail', validator.isEmail(email) ? email : '');
|
||||
if (!this.get('isDestroyed')) {
|
||||
const email = this.get('email');
|
||||
this.set('validEmail', validator.isEmail(email) ? email : '');
|
||||
}
|
||||
},
|
||||
|
||||
didReceiveAttrs: function () {
|
||||
Ember.run.debounce(this, 'trySetValidEmail', 500);
|
||||
didReceiveAttrs: function (attrs) {
|
||||
const timeout = parseInt(attrs.newAttrs.throttle || this.get('debounce'));
|
||||
Ember.run.debounce(this, 'trySetValidEmail', timeout);
|
||||
},
|
||||
|
||||
imageBackground: Ember.computed('validEmail', 'size', function () {
|
||||
var email = this.get('validEmail'),
|
||||
size = this.get('size'),
|
||||
url;
|
||||
const email = this.get('validEmail'),
|
||||
size = this.get('size');
|
||||
|
||||
if (email) {
|
||||
url = `http://www.gravatar.com/avatar/${md5(email)}?s=${size}&d=blank`;
|
||||
return `background-image: url(${url})`.htmlSafe();
|
||||
let url = `http://www.gravatar.com/avatar/${md5(email)}?s=${size}&d=blank`;
|
||||
return Ember.String.htmlSafe(`background-image: url(${url})`);
|
||||
}
|
||||
}),
|
||||
|
||||
@ -52,6 +58,9 @@ export default Ember.Component.extend({
|
||||
var size = this.get('size'),
|
||||
uploadElement = this.$('.js-file-input');
|
||||
|
||||
// Fire this immediately in case we're initialized with a valid email
|
||||
this.trySetValidEmail();
|
||||
|
||||
// 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
|
||||
@ -69,11 +78,13 @@ export default Ember.Component.extend({
|
||||
},
|
||||
|
||||
willDestroyElement: function () {
|
||||
this.$('.js-file-input').fileupload('destroy');
|
||||
if (this.$('.js-file-input').data()['blueimp-fileupload']) {
|
||||
this.$('.js-file-input').fileupload('destroy');
|
||||
}
|
||||
},
|
||||
|
||||
queueFile: function (e, data) {
|
||||
var fileName = data.files[0].name;
|
||||
const fileName = data.files[0].name;
|
||||
|
||||
if ((/\.(gif|jpe?g|png|svg?z)$/i).test(fileName)) {
|
||||
this.sendAction('setImage', data);
|
||||
@ -81,7 +92,7 @@ export default Ember.Component.extend({
|
||||
},
|
||||
|
||||
triggerPreview: function (e, data) {
|
||||
var file = data.files[data.index];
|
||||
const file = data.files[data.index];
|
||||
if (file.preview) {
|
||||
this.set('hasUploadedImage', true);
|
||||
// necessary jQuery code because file.preview is a raw DOM object
|
||||
|
@ -2,7 +2,7 @@
|
||||
{{#unless hasUploadedImage}}
|
||||
<div class="placeholder-img" style={{defaultImage}}></div>
|
||||
|
||||
{{#if hasEmail}}
|
||||
{{#if displayGravatar}}
|
||||
<div id="account-image" class="gravatar-img" style={{imageBackground}}>
|
||||
<span class="sr-only">User image</span>
|
||||
</div>
|
||||
|
@ -0,0 +1,91 @@
|
||||
/* jshint expr:true */
|
||||
/* global md5 */
|
||||
import { expect } from 'chai';
|
||||
import {
|
||||
describeComponent,
|
||||
it
|
||||
} from 'ember-mocha';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import Ember from 'ember';
|
||||
|
||||
const {run} = Ember,
|
||||
pathsStub = Ember.Service.extend({
|
||||
url: {
|
||||
api: function () {
|
||||
return '';
|
||||
},
|
||||
asset: function (src) {
|
||||
return src;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describeComponent(
|
||||
'gh-profile-image',
|
||||
'Integration: Component: gh-profile-image',
|
||||
{
|
||||
integration: true
|
||||
},
|
||||
function () {
|
||||
beforeEach(function () {
|
||||
this.register('service:ghost-paths', pathsStub);
|
||||
this.inject.service('ghost-paths', {as: 'ghost-paths'});
|
||||
});
|
||||
|
||||
it('renders', function () {
|
||||
this.set('email', '');
|
||||
|
||||
this.render(hbs`
|
||||
{{gh-profile-image email=email}}
|
||||
`);
|
||||
|
||||
expect(this.$()).to.have.length(1);
|
||||
});
|
||||
|
||||
it('immediately renders the gravatar if valid email supplied', function () {
|
||||
let email = 'test@example.com',
|
||||
expectedUrl = `http://www.gravatar.com/avatar/${md5(email)}?s=100&d=blank`;
|
||||
|
||||
this.set('email', email);
|
||||
|
||||
this.render(hbs`
|
||||
{{gh-profile-image email=email size=100 debounce=300}}
|
||||
`);
|
||||
|
||||
expect(this.$('.gravatar-img').attr('style'), 'gravatar image style')
|
||||
.to.equal(`background-image: url(${expectedUrl})`);
|
||||
});
|
||||
|
||||
it('throttles gravatar loading as email is changed', function (done) {
|
||||
let email = 'test@example.com',
|
||||
expectedUrl = `http://www.gravatar.com/avatar/${md5(email)}?s=100&d=blank`;
|
||||
|
||||
this.set('email', 'test');
|
||||
|
||||
this.render(hbs`
|
||||
{{gh-profile-image email=email size=100 debounce=300}}
|
||||
`);
|
||||
|
||||
expect(this.$('.gravatar-img').length, '.gravatar-img not shown for invalid email')
|
||||
.to.equal(0);
|
||||
|
||||
run(() => {
|
||||
this.set('email', email);
|
||||
});
|
||||
|
||||
expect(this.$('.gravatar-img').length, '.gravatar-img not immediately changed on email change')
|
||||
.to.equal(0);
|
||||
|
||||
Ember.run.later(this, function () {
|
||||
expect(this.$('.gravatar-img').length, '.gravatar-img still not shown before throttle timeout')
|
||||
.to.equal(0);
|
||||
}, 250);
|
||||
|
||||
Ember.run.later(this, function () {
|
||||
expect(this.$('.gravatar-img').attr('style'), '.gravatar-img style after timeout')
|
||||
.to.equal(`background-image: url(${expectedUrl})`);
|
||||
done();
|
||||
}, 400);
|
||||
});
|
||||
}
|
||||
);
|
@ -1,51 +0,0 @@
|
||||
/* jshint expr:true */
|
||||
/* global md5 */
|
||||
import { expect } from 'chai';
|
||||
import {
|
||||
describeComponent,
|
||||
it
|
||||
} from 'ember-mocha';
|
||||
|
||||
describeComponent(
|
||||
'gh-profile-image',
|
||||
'Unit: Component: gh-profile-image',
|
||||
{
|
||||
unit: true,
|
||||
needs: ['service:ghost-paths']
|
||||
},
|
||||
function () {
|
||||
it('renders', function () {
|
||||
// creates the component instance
|
||||
var component = this.subject();
|
||||
expect(component._state).to.equal('preRender');
|
||||
|
||||
// renders the component on the page
|
||||
this.render();
|
||||
expect(component._state).to.equal('inDOM');
|
||||
});
|
||||
it('renders the gravatar image background if email is supplied', function () {
|
||||
var component = this.subject(),
|
||||
testEmail = 'test@example.com',
|
||||
style, size;
|
||||
|
||||
Ember.run(function () {
|
||||
component.set('email', testEmail);
|
||||
});
|
||||
|
||||
this.render();
|
||||
|
||||
size = component.get('size');
|
||||
|
||||
style = 'url(http://www.gravatar.com/avatar/' + md5(testEmail) + '?s=' + size + '&d=blank)';
|
||||
|
||||
expect(component.$('#account-image').css('background-image')).to.equal(style);
|
||||
});
|
||||
it('doesn\'t render the gravatar image background if email isn\'t supplied', function () {
|
||||
var component = this.subject();
|
||||
|
||||
this.render();
|
||||
|
||||
expect(component.$('#account-image').length).to.equal(0);
|
||||
});
|
||||
}
|
||||
);
|
Loading…
Reference in New Issue
Block a user