зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1139677 - Display the user's FxA profile image in the Sync Pref pane r=markh,rfeeley
This commit is contained in:
Родитель
b7bbc0176d
Коммит
8007600342
|
@ -95,7 +95,9 @@ let gSyncPane = {
|
|||
"weave:service:start-over:finish",
|
||||
"weave:service:setup-complete",
|
||||
"weave:service:logout:finish",
|
||||
FxAccountsCommon.ONVERIFIED_NOTIFICATION];
|
||||
FxAccountsCommon.ONVERIFIED_NOTIFICATION,
|
||||
FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION,
|
||||
];
|
||||
let migrateTopic = "fxa-migration:state-changed";
|
||||
|
||||
// Add the observers now and remove them on unload
|
||||
|
@ -123,6 +125,8 @@ let gSyncPane = {
|
|||
}),
|
||||
|
||||
this.updateWeavePrefs();
|
||||
|
||||
this._initProfileImageUI();
|
||||
},
|
||||
|
||||
_setupEventListeners: function() {
|
||||
|
@ -224,6 +228,14 @@ let gSyncPane = {
|
|||
});
|
||||
},
|
||||
|
||||
_initProfileImageUI: function () {
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("identity.fxaccounts.profile_image.enabled")) {
|
||||
document.getElementById("fxaProfileImage").hidden = false;
|
||||
}
|
||||
} catch (e) { }
|
||||
},
|
||||
|
||||
updateWeavePrefs: function () {
|
||||
// ask the migration module to broadcast its current state (and nothing will
|
||||
// happen if it's not loaded - which is good, as that means no migration
|
||||
|
@ -244,10 +256,11 @@ let gSyncPane = {
|
|||
}
|
||||
// determine the fxa status...
|
||||
this.page = PAGE_PLEASE_WAIT;
|
||||
|
||||
fxAccounts.getSignedInUser().then(data => {
|
||||
if (!data) {
|
||||
this.page = FXA_PAGE_LOGGED_OUT;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
this.page = FXA_PAGE_LOGGED_IN;
|
||||
// We are logged in locally, but maybe we are in a state where the
|
||||
|
@ -281,7 +294,36 @@ let gSyncPane = {
|
|||
for (let checkbox of engines.querySelectorAll("checkbox")) {
|
||||
checkbox.disabled = enginesListDisabled;
|
||||
}
|
||||
|
||||
// Clear the profile image (if any) of the previously logged in account.
|
||||
document.getElementById("fxaProfileImage").style.removeProperty("background-image");
|
||||
|
||||
// If the account is verified the next promise in the chain will
|
||||
// fetch profile data.
|
||||
return data.verified;
|
||||
}).then(shouldGetProfile => {
|
||||
if (shouldGetProfile) {
|
||||
return fxAccounts.getSignedInUserProfile();
|
||||
}
|
||||
}).then(data => {
|
||||
if (data && data.avatar) {
|
||||
// Make sure the image is available before displaying it,
|
||||
// as we don't want to overwrite the default profile image
|
||||
// with a broken/unavailable image
|
||||
let img = new Image();
|
||||
img.onload = () => {
|
||||
let bgImage = "url('" + data.avatar + "')";
|
||||
document.getElementById("fxaProfileImage").style.backgroundImage = bgImage;
|
||||
};
|
||||
img.src = data.avatar;
|
||||
}
|
||||
}, err => {
|
||||
FxAccountsCommon.log.error(err);
|
||||
}).catch(err => {
|
||||
// If we get here something's really busted
|
||||
Cu.reportError(String(err));
|
||||
});
|
||||
|
||||
// If fxAccountEnabled is false and we are in a "not configured" state,
|
||||
// then fxAccounts is probably fully disabled rather than just unconfigured,
|
||||
// so handle this case. This block can be removed once we remove support
|
||||
|
@ -521,6 +563,15 @@ let gSyncPane = {
|
|||
});
|
||||
},
|
||||
|
||||
openChangeProfileImage: function() {
|
||||
fxAccounts.promiseAccountsChangeProfileURI("avatar")
|
||||
.then(url => {
|
||||
this.openContentInBrowser(url, {
|
||||
replaceQueryString: true
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
manageFirefoxAccount: function() {
|
||||
let url = Services.prefs.getCharPref("identity.fxaccounts.settings.uri");
|
||||
this.openContentInBrowser(url);
|
||||
|
|
|
@ -233,7 +233,11 @@
|
|||
<!-- logged in and verified and all is good -->
|
||||
<hbox id="fxaLoginVerified"
|
||||
align="center">
|
||||
<label id="fxaEmailAddress1"/>
|
||||
<hbox align="center">
|
||||
<image id="fxaProfileImage"
|
||||
onclick="gSyncPane.openChangeProfileImage();" hidden="true"/>
|
||||
<label id="fxaEmailAddress1"/>
|
||||
</hbox>
|
||||
<spacer flex="1"/>
|
||||
<button id="verifiedManage"
|
||||
label="&manage.label;"/>
|
||||
|
|
|
@ -179,6 +179,7 @@ browser.jar:
|
|||
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
|
||||
skin/classic/browser/preferences/in-content/icons.svg (../shared/incontentprefs/icons.svg)
|
||||
skin/classic/browser/preferences/in-content/search.css (../shared/incontentprefs/search.css)
|
||||
skin/classic/browser/preferences/in-content/default-profile-image.svg (../shared/incontentprefs/default-profile-image.svg)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/preferences/search.css (preferences/search.css)
|
||||
|
|
|
@ -284,6 +284,7 @@ browser.jar:
|
|||
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
|
||||
skin/classic/browser/preferences/in-content/icons.svg (../shared/incontentprefs/icons.svg)
|
||||
skin/classic/browser/preferences/in-content/search.css (../shared/incontentprefs/search.css)
|
||||
skin/classic/browser/preferences/in-content/default-profile-image.svg (../shared/incontentprefs/default-profile-image.svg)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/preferences/search.css (preferences/search.css)
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||
<path fill="#C3CFD8" d="M500-0.3c276.1,0,500,223.9,500,500s-223.9,500-500,500S0,775.8,0,499.7C0,223.5,223.9-0.3,500-0.3z"/>
|
||||
<circle fill="#FFFFFF" cx="500" cy="317" r="139.1"/>
|
||||
<path fill="#FFFFFF" d="M751.8,643.6L751.8,643.6c0.1-2.3,0.2-4.6,0.2-6.9c0-68-55.3-127-136.2-156.3L505.9,590.4h0
|
||||
c-0.4,29.8-1.4,58.8-2.8,86.6c-1,0.1-2,0.3-3.1,0.3s-2-0.2-3.1-0.3c-1.4-27.9-2.4-56.9-2.8-86.7h0L384.3,480.4
|
||||
C303.3,509.7,248,568.7,248,636.7c0,2.3,0.1,4.6,0.2,6.9l7.4,49.7c57.1,72,145.4,118.2,244.4,118.2c99,0,187.3-46.2,244.4-118.2
|
||||
L751.8,643.6z"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 993 B |
|
@ -216,6 +216,22 @@ description > html|a {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
#fxaProfileImage {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
border-width: 5px;
|
||||
border-color: red;
|
||||
background-image: url(chrome://browser/skin/preferences/in-content/default-profile-image.svg);
|
||||
background-size: contain;
|
||||
cursor: pointer;
|
||||
-moz-margin-end: 15px;
|
||||
}
|
||||
|
||||
#fxaProfileImage:hover {
|
||||
border-color: blue;
|
||||
}
|
||||
|
||||
#noFxaAccount {
|
||||
/* Overriding the margins from the base preferences.css theme file.
|
||||
These overrides can be simplified by fixing bug 1027174 */
|
||||
|
|
|
@ -207,6 +207,7 @@ browser.jar:
|
|||
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
|
||||
skin/classic/browser/preferences/in-content/icons.svg (../shared/incontentprefs/icons.svg)
|
||||
skin/classic/browser/preferences/in-content/search.css (../shared/incontentprefs/search.css)
|
||||
skin/classic/browser/preferences/in-content/default-profile-image.svg (../shared/incontentprefs/default-profile-image.svg)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/preferences/search.css (preferences/search.css)
|
||||
|
|
|
@ -44,6 +44,7 @@ let publicProperties = [
|
|||
"localtimeOffsetMsec",
|
||||
"now",
|
||||
"promiseAccountsForceSigninURI",
|
||||
"promiseAccountsChangeProfileURI",
|
||||
"resendVerificationEmail",
|
||||
"setSignedInUser",
|
||||
"signOut",
|
||||
|
@ -961,6 +962,34 @@ FxAccountsInternal.prototype = {
|
|||
}).then(result => currentState.resolve(result));
|
||||
},
|
||||
|
||||
// Returns a promise that resolves with the URL to use to change
|
||||
// the current account's profile image.
|
||||
// if settingToEdit is set, the profile page should hightlight that setting
|
||||
// for the user to edit.
|
||||
promiseAccountsChangeProfileURI: function(settingToEdit = null) {
|
||||
let url = Services.urlFormatter.formatURLPref("identity.fxaccounts.settings.uri");
|
||||
|
||||
if (settingToEdit) {
|
||||
url += (url.indexOf("?") == -1 ? "?" : "&") +
|
||||
"setting=" + encodeURIComponent(settingToEdit);
|
||||
}
|
||||
|
||||
if (this._requireHttps() && !/^https:/.test(url)) { // Comment to un-break emacs js-mode highlighting
|
||||
throw new Error("Firefox Accounts server must use HTTPS");
|
||||
}
|
||||
let currentState = this.currentAccountState;
|
||||
// but we need to append the email address onto a query string.
|
||||
return this.getSignedInUser().then(accountData => {
|
||||
if (!accountData) {
|
||||
return null;
|
||||
}
|
||||
let newQueryPortion = url.indexOf("?") == -1 ? "?" : "&";
|
||||
newQueryPortion += "email=" + encodeURIComponent(accountData.email);
|
||||
newQueryPortion += "&uid=" + encodeURIComponent(accountData.uid);
|
||||
return url + newQueryPortion;
|
||||
}).then(result => currentState.resolve(result));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get an OAuth token for the user
|
||||
*
|
||||
|
@ -1078,30 +1107,13 @@ FxAccountsInternal.prototype = {
|
|||
getSignedInUserProfile: function () {
|
||||
let accountState = this.currentAccountState;
|
||||
return accountState.getProfile()
|
||||
.then(
|
||||
(profileData) => {
|
||||
let profile = JSON.parse(JSON.stringify(profileData));
|
||||
// profileData doesn't include "verified", but it must be true
|
||||
// if we've gotten this far.
|
||||
profile.verified = true;
|
||||
return accountState.resolve(profile);
|
||||
},
|
||||
(error) => {
|
||||
log.error("Could not retrieve profile data", error);
|
||||
|
||||
return this.getSignedInUser().then(data => {
|
||||
let profile = null;
|
||||
if (data) {
|
||||
// If we fail to fetch the profile and have no profile cached
|
||||
// we resort to using the account data for basic profile data.
|
||||
profile = {
|
||||
email: data.email,
|
||||
uid: data.uid,
|
||||
verified: data.verified
|
||||
};
|
||||
}
|
||||
return accountState.resolve(profile);
|
||||
});
|
||||
.then((profileData) => {
|
||||
let profile = JSON.parse(JSON.stringify(profileData));
|
||||
return accountState.resolve(profile);
|
||||
},
|
||||
(error) => {
|
||||
log.error("Could not retrieve profile data", error);
|
||||
return accountState.reject(error);
|
||||
})
|
||||
.then(null, err => this._errorToErrorClass(err));
|
||||
},
|
||||
|
|
|
@ -923,7 +923,6 @@ add_test(function test_getSignedInUserProfile_ok() {
|
|||
fxa.getSignedInUserProfile()
|
||||
.then(result => {
|
||||
do_check_eq(result.avatar, "image");
|
||||
do_check_true(result.verified);
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
|
@ -946,9 +945,24 @@ add_test(function test_getSignedInUserProfile_error_uses_account_data() {
|
|||
};
|
||||
|
||||
fxa.getSignedInUserProfile()
|
||||
.then(result => {
|
||||
do_check_eq(typeof result.avatar, "undefined");
|
||||
do_check_eq(result.email, "foo@bar.com");
|
||||
.catch(error => {
|
||||
do_check_eq(error.message, "UNKNOWN_ERROR");
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
add_test(function test_getSignedInUserProfile_unverified_account() {
|
||||
let fxa = new MockFxAccounts();
|
||||
let alice = getTestUser("alice");
|
||||
|
||||
fxa.setSignedInUser(alice).then(() => {
|
||||
let accountState = fxa.internal.currentAccountState;
|
||||
|
||||
fxa.getSignedInUserProfile()
|
||||
.catch(error => {
|
||||
do_check_eq(error.message, "UNVERIFIED_ACCOUNT");
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
|
@ -958,22 +972,13 @@ add_test(function test_getSignedInUserProfile_error_uses_account_data() {
|
|||
add_test(function test_getSignedInUserProfile_no_account_data() {
|
||||
let fxa = new MockFxAccounts();
|
||||
|
||||
fxa.internal.getSignedInUser = function () {
|
||||
return Promise.resolve({ email: "foo@bar.com" });
|
||||
};
|
||||
|
||||
let accountState = fxa.internal.currentAccountState;
|
||||
accountState.getProfile = function () {
|
||||
return Promise.reject("boom");
|
||||
};
|
||||
|
||||
fxa.internal.getSignedInUser = function () {
|
||||
return Promise.resolve(null);
|
||||
};
|
||||
|
||||
fxa.getSignedInUserProfile()
|
||||
.then(result => {
|
||||
do_check_eq(result, null);
|
||||
.catch(error => {
|
||||
do_check_eq(error.message, "NO_ACCOUNT");
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче