Skip to content
This repository has been archived by the owner. It is now read-only.

fix(avatars): load profile image on settings and sign in pages if available #1733

Merged
merged 13 commits into from Nov 15, 2014

Conversation

@zaach
Copy link
Contributor

@zaach zaach commented Oct 2, 2014

This refactor changes a number of things:
* fix avatar background (fixes #1722)
* loads profile images on settings and sign in account chooser (fixes #1727)
* introduces User and Account models
* imports old Session based sessions into User
* handles direct link to settings page from RPs for a specified account (fixes #1686)
* redirects unverified accounts that visit /settings (fixes #1716)
* introduces a way to pass ephemeral data between views
* removes unused avatar-change-via-URL resources/tests (fixes #1544, fixes #1618)

@zaach
Copy link
Contributor Author

@zaach zaach commented Oct 2, 2014

Now that signin checks the profile server we'll have to rethink running those functional tests on travis...

@pdehaan
Copy link
Contributor

@pdehaan pdehaan commented Oct 6, 2014

@zaach is this ready for review, or still WIP while we sort out Travis issues?

@zaach
Copy link
Contributor Author

@zaach zaach commented Oct 6, 2014

@pdehaan You can begin review, I should only need to fix the tests.

@zaach zaach force-pushed the issue-1727-load-avatar-on-profile branch 2 times, most recently from b3c8f01 to cfbed6d Oct 6, 2014
promise = this.profileClient.getAvatar()
.then(function (result) {
if (result.avatar && result.id) {
Session.set('avatar', result.avatar);

This comment has been minimized.

@nchapman

nchapman Oct 6, 2014
Contributor

Since we're trying to use Session less, do you think it makes sense to use sessionStorage or localStorage directly here?

This comment has been minimized.

@zaach

zaach Oct 6, 2014
Author Contributor

Hmm, well we're using it in other views that access the avatar also. I'm inclined to refactor it all at once, e.g. if we merge it into a user model.

This comment has been minimized.

@nchapman

nchapman Oct 6, 2014
Contributor

Yep that makes sense. Carry on!

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 7, 2014
Member

I'm introducing a user model in #1646, be prepared. I'm somewhat inclined to think an Avatar could be its own model that is a child of the User model...

@@ -55,6 +56,13 @@ function (_, p, BaseView, FormView, SignInTemplate, Session, PasswordMixin, Auth
'click .use-different': 'useDifferentAccount'
},

beforeRender: function () {

This comment has been minimized.

@nchapman

nchapman Oct 6, 2014
Contributor

Could this slow down sign in if it takes a while to fetch the image? Would it be better to do this after render?

This comment has been minimized.

@zaach

zaach Oct 6, 2014
Author Contributor

Sure if we're okay with it flashing the default image.

This comment has been minimized.

@nchapman

nchapman Oct 6, 2014
Contributor

Yeah I'm not sure what's preferable. Since images traditionally load async, I don't think it'd feel too unnatural for it to load post render. I think we'd want to leave it blank and just drop in the image, rather than re-rendering the view to minimize any flicker. This isn't a show stopper. Just something to consider.

This comment has been minimized.

@ckarlof

ckarlof Oct 6, 2014
Contributor

This might be a tricky issue. I'd prefer not to see the flashing if the image load is quick, but if it's slow for some reason (say 5-10s), showing the default image (or spinner) after some reasonable amount time may signal that "nothing's obviously broken".

This comment has been minimized.

@nchapman

nchapman Oct 6, 2014
Contributor

Agreed. I do think though in many cases that loading the image after render (especially in the cached case) would be imperceptible to the user as long as nothing shifts position. It does feel a bit risky to make the sign in flow dependent on the avatar when it's not absolutely critical.

This comment has been minimized.

@zaach

zaach Oct 6, 2014
Author Contributor

Good point... Maybe we should switch to afterRender and if flashing is noticeable during dogfooding, we can do something more involved with spinners.

@nchapman
Copy link
Contributor

@nchapman nchapman commented Oct 6, 2014

So just to be clear: there's still no way to set an avatar, correct? Everyone will be seeing the default for now?

@zaach
Copy link
Contributor Author

@zaach zaach commented Oct 6, 2014

@nchapman Right, only people who know the super secret URL will be able to change their avatar.

@nchapman
Copy link
Contributor

@nchapman nchapman commented Oct 6, 2014

@nchapman Right, only people who know the super secret URL will be able to change their avatar.

Okay great.


return view.render()
.then(function () {
assert.equal(view.$('.avatar-wrapper img').length, 0);

This comment has been minimized.

@nchapman

nchapman Oct 6, 2014
Contributor

So the default image doesn't use an img tag?

This comment has been minimized.

@zaach

zaach Oct 6, 2014
Author Contributor

Right, but that might change when #1722 is fixed.

This comment has been minimized.

@nchapman

nchapman Oct 6, 2014
Contributor

Ah ok cool.

@nchapman nchapman self-assigned this Oct 6, 2014
@zaach zaach force-pushed the issue-1727-load-avatar-on-profile branch 2 times, most recently from f604d04 to ec51fd9 Oct 6, 2014
@@ -43,8 +45,28 @@ function (_, FormView, BaseView, Template, Session, Constants) {
success: t('Signed out')
});
});
},

afterVisible: function () {

This comment has been minimized.

@zaach

zaach Oct 7, 2014
Author Contributor

Updated per @nchapman's suggestion.

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 7, 2014
Member

You know, I completely forgot about afterVisible, this would have been useful in the "smooth out the verification flow" PR.

], function (p, Session) {

return {
// Attempt to load a profile image from the profile server and cache it on Session

This comment has been minimized.

@ckarlof

ckarlof Oct 7, 2014
Contributor

How does this cache get invalidated if the image changes?

This comment has been minimized.

@zaach

zaach Oct 7, 2014
Author Contributor

It won't be. Alternatively, we can always check the server.

This comment has been minimized.

@ckarlof

ckarlof Oct 7, 2014
Contributor

Let's remove the URL caching for now and push this out to the next train.

This comment has been minimized.

@zaach

zaach Oct 7, 2014
Author Contributor

It's now loaded from the server each time 👍

}
});
} else {
// We already have a profile image in Session

This comment has been minimized.

@ckarlof

ckarlof Oct 7, 2014
Contributor

This means we have a profile image URL, correct?

This comment has been minimized.

@zaach

zaach Oct 7, 2014
Author Contributor

Right.

},

afterVisible: function () {
return this.loadProfileImage();

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 7, 2014
Member

Does the base class's afterVisible need to be called?

}, function () {
// Ignore errors and just show the default image
});
},

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 7, 2014
Member

I think the base class' afterVisible should be called to force an autofocus.

This comment has been minimized.

@zaach

zaach Oct 7, 2014
Author Contributor

Added 👍

'views/decorators/progress_indicator'
],
function (_, p, BaseView, FormView, SignInTemplate, Session, PasswordMixin, AuthErrors, Validate, ServiceMixin, showProgressIndicator) {
function (_, p, BaseView, FormView, SignInTemplate, Session, PasswordMixin, AuthErrors, Validate, ServiceMixin, AvatarMixin, showProgressIndicator) {

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 7, 2014
Member

Can you break this line, it's running off the end of the screen.

'lib/session',
'lib/constants'
],
function (_, FormView, BaseView, Template, Session, Constants) {
function (_, FormView, BaseView, AvatarMixin, Template, AuthErrors, Session, Constants) {

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 7, 2014
Member

Is AuthErrors used?


view = new View({
router: routerMock,
metrics: metrics,
window: windowMock,
fxaClient: fxaClient,
profileClient: profileClientMock,

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 7, 2014
Member

@ckarlof brought up the idea a few weeks back of adding all these dependencies to a single object, that then gets passed around to the various views. I'm really beginning to see the value of that. We have both had to update tests just to pass in dependencies recently.

This comment has been minimized.

@zaach

zaach Oct 7, 2014
Author Contributor

I like it.

@zaach zaach force-pushed the issue-1727-load-avatar-on-profile branch from ec51fd9 to 7c49d22 Oct 7, 2014
@zaach zaach assigned shane-tomlinson and unassigned nchapman Oct 8, 2014
})
.then(function (found) {
if (found) {
self.logEvent(self.className + '.profile_image_shown');

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 8, 2014
Member

Should we log a profile_image_now_shown if found === false, or is that taken care of in the error handler?

return true;
}
})
.then(function (found) {

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 8, 2014
Member

Can this then be collapsed into the one above?

return this.profileClient.getAvatar()
.then(function (result) {
if (result.avatar && result.id) {
Session.set('avatar', result.avatar);

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 8, 2014
Member

It looks like we are fetching the avatar in multiple views, but then saving the avatar into the Session. Could we just skip the storage into the Session and return the avatar from profileClient.getAvatar()? Does profileClient.getAvatar cache the images?

This comment has been minimized.

@zaach

zaach Oct 8, 2014
Author Contributor

No, there's no caching in the profileClient. The other avatar pages still use Session.avatar, but we could rip that out and always load it from the server there, too.

return this._fetchProfileImage()
.then(function () {
if (Session.avatar) {
self.$('.avatar-wrapper').append(new Image());

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 8, 2014
Member

This code is also in settings.js, can it ripped out and added to the avatar-mixin?

@zaach
Copy link
Contributor Author

@zaach zaach commented Nov 13, 2014

@shane-tomlinson Aha– those tests should be removed since settings redirects unverified users.

@shane-tomlinson
Copy link
Member

@shane-tomlinson shane-tomlinson commented Nov 13, 2014

@zaach - can you try this Sync case:

1) Sign in to the sync flow
2) Open the browser's preferences, click "Forget this email" or "disconnect"
3) Click "Sign in"
4) Open another tab to stomlinson.dev.lcip.org/signin
5) No password field!
6) Click "Sign in".
7) A "Session expired" error.

Expected
In step 5, a password field should be shown.

This also reproduces in prod - filed this bug as #1877

@shane-tomlinson
Copy link
Member

@shane-tomlinson shane-tomlinson commented Nov 13, 2014

@zaach - another strange Sync case:

  1. Open the browser, if signed into Sync, sign out.
  2. Restart browser, immediately open dev tools
  3. Click the Sync icon from the home screen.
  4. Sign in
  5. Click the hamburger icon, click your sync username
  6. Under Firefox Account, click "Disconnect"
  7. Go back to the original tab.
  8. Explosion and redirect to the /500 page.

Error in the console:

"no response from browser: session_status" 5ed8b225.main.js:14:13299

"Critical error:" Error: Unexpected error
Stack trace:
.toError@https://stomlinson.dev.lcip.org/scripts/5ed8b225.main.js:7:12632
f/a.timeout<@https://stomlinson.dev.lcip.org/scripts/5ed8b225.main.js:14:13361

@zaach zaach force-pushed the issue-1727-load-avatar-on-profile branch from 8034039 to 3a6dd96 Nov 14, 2014
@zaach zaach force-pushed the issue-1727-load-avatar-on-profile branch from 3a6dd96 to 0492140 Nov 15, 2014
ckarlof added a commit that referenced this pull request Nov 15, 2014
fix(avatars): load profile image on settings and sign in pages if available

Fixes #1727, #1722, #1686, #1716, #1544, #1618
r=ckarlof,shane-tomlinson
@ckarlof ckarlof merged commit 8724e62 into master Nov 15, 2014
1 check passed
1 check passed
@zaach
continuous-integration/travis-ci The Travis CI build passed
Details
@ckarlof ckarlof deleted the issue-1727-load-avatar-on-profile branch Nov 15, 2014
@ckarlof
Copy link
Contributor

@ckarlof ckarlof commented Nov 15, 2014

Congratz @zaach!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.