From 7848b2fe1eced5e300d790e0bc700ef87bac8974 Mon Sep 17 00:00:00 2001 From: Mark Hammond Date: Wed, 7 Jan 2015 13:57:38 +1100 Subject: [PATCH] Bug 1114445 - update sync migration flows to reflect latest requirements. r=adw --- browser/base/content/browser-fxaccounts.js | 21 ++++-- .../components/preferences/in-content/sync.js | 68 ++++++++++++++++--- .../preferences/in-content/sync.xul | 3 +- .../en-US/chrome/browser/accounts.properties | 13 ++++ .../en-US/chrome/browser/preferences/sync.dtd | 3 - .../shared/incontentprefs/preferences.inc.css | 5 ++ services/sync/modules/FxaMigrator.jsm | 18 +++-- 7 files changed, 107 insertions(+), 24 deletions(-) diff --git a/browser/base/content/browser-fxaccounts.js b/browser/base/content/browser-fxaccounts.js index 537705d85fb..773a9236bdd 100644 --- a/browser/base/content/browser-fxaccounts.js +++ b/browser/base/content/browser-fxaccounts.js @@ -274,11 +274,22 @@ let gFxAccounts = { let note = null; switch (this._migrationInfo.state) { case this.fxaMigrator.STATE_USER_FXA: { - let msg = this.strings.GetStringFromName("needUserLong"); - let upgradeLabel = - this.strings.GetStringFromName("upgradeToFxA.label"); - let upgradeAccessKey = - this.strings.GetStringFromName("upgradeToFxA.accessKey"); + // There are 2 cases here - no email address means it is an offer on + // the first device (so the user is prompted to create an account). + // If there is an email address it is the "join the party" flow, so the + // user is prompted to sign in with the address they previously used. + let msg, upgradeLabel, upgradeAccessKey; + if (this._migrationInfo.email) { + msg = this.strings.formatStringFromName("signInAfterUpgradeOnOtherDevice.description", + [this._migrationInfo.email], + 1); + upgradeLabel = this.strings.GetStringFromName("signInAfterUpgradeOnOtherDevice.label"); + upgradeAccessKey = this.strings.GetStringFromName("signInAfterUpgradeOnOtherDevice.accessKey"); + } else { + msg = this.strings.GetStringFromName("needUserLong"); + upgradeLabel = this.strings.GetStringFromName("upgradeToFxA.label"); + upgradeAccessKey = this.strings.GetStringFromName("upgradeToFxA.accessKey"); + } note = new Weave.Notification( undefined, msg, undefined, Weave.Notifications.PRIORITY_WARNING, [ new Weave.NotificationButton(upgradeLabel, upgradeAccessKey, () => { diff --git a/browser/components/preferences/in-content/sync.js b/browser/components/preferences/in-content/sync.js index e234738ab50..92617360794 100644 --- a/browser/components/preferences/in-content/sync.js +++ b/browser/components/preferences/in-content/sync.js @@ -114,12 +114,6 @@ let gSyncPane = { Weave.Svc.Obs.remove(migrateTopic, gSyncPane.updateMigrationState, gSyncPane); }, false); - // 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 - // is pending/necessary) - we don't want to suck that module in just to - // find there's nothing to do. - Services.obs.notifyObservers(null, "fxa-migration:state-request", null); - XPCOMUtils.defineLazyGetter(this, '_stringBundle', () => { return Services.strings.createBundle("chrome://browser/locale/preferences/preferences.properties"); }), @@ -218,6 +212,9 @@ let gSyncPane = { let win = Services.wm.getMostRecentWindow("navigator:browser"); fxaMigrator.createFxAccount(win); }); + setEventListener("sync-migrate-unlink", "click", function () { + gSyncPane.startOverMigration(); + }); setEventListener("sync-migrate-forget", "click", function () { fxaMigrator.forgetFxAccount(); }); @@ -228,6 +225,12 @@ let gSyncPane = { }, 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 + // is pending/necessary) - we don't want to suck that module in just to + // find there's nothing to do. + Services.obs.notifyObservers(null, "fxa-migration:state-request", null); + let service = Components.classes["@mozilla.org/weave/service;1"] .getService(Components.interfaces.nsISupports) .wrappedJSObject; @@ -299,9 +302,35 @@ let gSyncPane = { switch (state) { case fxaMigrator.STATE_USER_FXA: { let sb = this._accountsStringBundle; + // There are 2 cases here - no email address means it is an offer on + // the first device (so the user is prompted to create an account). + // If there is an email address it is the "join the party" flow, so the + // user is prompted to sign in with the address they previously used. + let email = subject ? subject.QueryInterface(Components.interfaces.nsISupportsString).data : null; + let elt = document.getElementById("sync-migrate-upgrade-description"); + elt.textContent = email ? + sb.formatStringFromName("signInAfterUpgradeOnOtherDevice.description", + [email], 1) : + sb.GetStringFromName("needUserLong"); + + // The "upgrade" button. let button = document.getElementById("sync-migrate-upgrade"); - button.setAttribute("label", sb.GetStringFromName("upgradeToFxA.label")); - button.setAttribute("accesskey", sb.GetStringFromName("upgradeToFxA.accessKey")); + button.setAttribute("label", + sb.GetStringFromName(email + ? "signInAfterUpgradeOnOtherDevice.label" + : "upgradeToFxA.label")); + button.setAttribute("accesskey", + sb.GetStringFromName(email + ? "signInAfterUpgradeOnOtherDevice.accessKey" + : "upgradeToFxA.accessKey")); + // The "unlink" button - this is only shown for first migration + button = document.getElementById("sync-migrate-unlink"); + if (email) { + button.hidden = true; + } else { + button.setAttribute("label", sb.GetStringFromName("unlinkMigration.label")); + button.setAttribute("accesskey", sb.GetStringFromName("unlinkMigration.accessKey")); + } selIndex = 0; break; } @@ -355,6 +384,29 @@ let gSyncPane = { this.updateWeavePrefs(); }, + // When the "Unlink" button in the migration header is selected we display + // a slightly different message. + startOverMigration: function () { + let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING + + Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_CANCEL + + Services.prompt.BUTTON_POS_1_DEFAULT; + let sb = this._accountsStringBundle; + let buttonChoice = + Services.prompt.confirmEx(window, + sb.GetStringFromName("unlinkVerificationTitle"), + sb.GetStringFromName("unlinkVerificationDescription"), + flags, + sb.GetStringFromName("unlinkVerificationConfirm"), + null, null, null, {}); + + // If the user selects cancel, just bail + if (buttonChoice == 1) + return; + + Weave.Service.startOver(); + this.updateWeavePrefs(); + }, + updatePass: function () { if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) gSyncUtils.changePassword(); diff --git a/browser/components/preferences/in-content/sync.xul b/browser/components/preferences/in-content/sync.xul index d23e8a778cf..0473fcae089 100644 --- a/browser/components/preferences/in-content/sync.xul +++ b/browser/components/preferences/in-content/sync.xul @@ -46,8 +46,9 @@ - + +