diff --git a/mobile/chrome/content/browser.xul b/mobile/chrome/content/browser.xul index 203ac42e06b..6cb8064d208 100644 --- a/mobile/chrome/content/browser.xul +++ b/mobile/chrome/content/browser.xul @@ -51,6 +51,10 @@ %brandDTD; %prefsDTD; +#ifdef MOZ_SERVICES_SYNC + +%syncDTD; +#endif ]> #ifdef MOZ_SERVICES_SYNC - - - - - - + + + + + +#endif + diff --git a/mobile/chrome/content/sync.js b/mobile/chrome/content/sync.js index 8d4cb5f6a15..f306bd9c6bb 100644 --- a/mobile/chrome/content/sync.js +++ b/mobile/chrome/content/sync.js @@ -40,6 +40,9 @@ let WeaveGlue = { init: function init() { Components.utils.import("resource://services-sync/main.js"); + this._bundle = Services.strings.createBundle("chrome://browser/locale/sync.properties"); + this._msg = document.getElementById("prefs-messages"); + this._addListeners(); // Generating keypairs is expensive on mobile, so disable it @@ -49,42 +52,75 @@ let WeaveGlue = { this.autoConnect = Services.prefs.getBoolPref("services.sync.autoconnect"); if (this.autoConnect) { // Put the settings UI into a state of "connecting..." if we are going to auto-connect - this._settings.account.collapsed = true; - this._settings.pass.collapsed = true; - this._settings.secret.collapsed = true; - this._settings.connect.collapsed = false; - this._settings.device.collapsed = false; - this._settings.disconnect.collapsed = true; - this._settings.sync.collapsed = false; + this._elements.connect.collapsed = false; + this._elements.sync.collapsed = false; - this._settings.connect.firstChild.disabled = true; - this._settings.sync.firstChild.disabled = true; + this._elements.connect.firstChild.disabled = true; + this._elements.sync.firstChild.disabled = true; - let bundle = Services.strings.createBundle("chrome://weave/locale/services/sync.properties"); - this._settings.connect.setAttribute("title", bundle.GetStringFromName("connecting.label")); + this._elements.connect.setAttribute("title", this._bundle.GetStringFromName("connecting.label")); + this._elements.autosync.value = true; try { - this._settings.device.value = Services.prefs.getCharPref("services.sync.client.name"); + this._elements.device.value = Services.prefs.getCharPref("services.sync.client.name"); } catch(e) {} } } }, + show: function show() { + // Show the connect UI + document.getElementById("syncsetup-container").hidden = false; + document.getElementById("syncsetup-jpake").hidden = false; + document.getElementById("syncsetup-manual").hidden = true; + }, + + close: function close() { + // Close the connect UI + document.getElementById("syncsetup-container").hidden = true; + }, + + showDetails: function showDetails() { + // Show the connect UI detail settings + let show = this._elements.details.checked; + this._elements.autosync.collapsed = show; + this._elements.device.collapsed = show; + this._elements.disconnect.collapsed = show; + }, + connect: function connect() { // Cause the Sync system to reset internals if we seem to be switching accounts - if (this._settings.account.value != Weave.Service.account) + if (this._elements.account.value != Weave.Service.account) Weave.Service.startOver(); // Remove any leftover connection string - this._settings.connect.removeAttribute("desc"); + this._elements.connect.removeAttribute("desc"); // Sync will use the account value and munge it into a username, as needed - Weave.Service.account = this._settings.account.value; - Weave.Service.login(Weave.Service.username, this._settings.pass.value, this.normalizePassphrase(this._settings.secret.value)); + Weave.Service.account = this._elements.account.value; + Weave.Service.login(Weave.Service.username, this._elements.password.value, this.normalizePassphrase(this._elements.synckey.value)); Weave.Service.persistLogin(); }, disconnect: function disconnect() { + let message = this._bundle.GetStringFromName("notificationDisconnect.label"); + let button = this._bundle.GetStringFromName("notificationDisconnect.button"); + let buttons = [ { + label: button, + accessKey: "", + callback: function() { WeaveGlue.connect(); } + } ]; + this.showMessage(message, "undo-disconnect", buttons); + + // XXX change to an event that fires when panel is changed or closed + setTimeout(function(self) { + let notification = self._msg.getNotificationWithValue("undo-disconnect"); + if (notification) + notification.close(); + }, 10000, this); + + // TODO: When the notification closes, not from the "undo" button, we should clean up the credentials + Weave.Service.logout(); }, @@ -111,22 +147,27 @@ let WeaveGlue = { }, false); }, - get _settings() { + get _elements() { // Do a quick test to see if the options exist yet let syncButton = document.getElementById("sync-syncButton"); if (syncButton == null) - return; + return null; // Get all the setting nodes from the add-ons display - let settings = {}; - let ids = ["account", "pass", "secret", "device", "connect", "disconnect", "sync"]; - ids.forEach(function(id) { - settings[id] = document.getElementById("sync-" + id); + let elements = {}; + let setupids = ["account", "password", "synckey", "customserver"]; + setupids.forEach(function(id) { + elements[id] = document.getElementById("syncsetup-" + id); + }); + + let settingids = ["device", "connect", "connected", "disconnect", "sync", "autosync", "details"]; + settingids.forEach(function(id) { + elements[id] = document.getElementById("sync-" + id); }); // Replace the getter with the collection of settings - delete this._settings; - return this._settings = settings; + delete this._elements; + return this._elements = elements; }, observe: function observe(aSubject, aTopic, aData) { @@ -141,46 +182,50 @@ let WeaveGlue = { Util.forceOnline(); // Can't do anything before settings are loaded - if (this._settings == null) + if (this._elements == null) return; // Make some aliases - let account = this._settings.account; - let pass = this._settings.pass; - let secret = this._settings.secret; - let connect = this._settings.connect; - let device = this._settings.device; - let disconnect = this._settings.disconnect; - let sync = this._settings.sync; - let syncStr = Weave.Str.sync; + let account = this._elements.account; + let password = this._elements.password; + let synckey = this._elements.synckey; + let connect = this._elements.connect; + let connected = this._elements.connected; + let autosync = this._elements.autosync; + let device = this._elements.device; + let disconnect = this._elements.disconnect; + let sync = this._elements.sync; // Make sure the options are in the right state - account.collapsed = loggedIn; - pass.collapsed = loggedIn; - secret.collapsed = loggedIn; connect.collapsed = loggedIn; - device.collapsed = !loggedIn; - disconnect.collapsed = !loggedIn; + connected.collapsed = !loggedIn; sync.collapsed = !loggedIn; + if (connected.collapsed) { + connect.setAttribute("title", this._bundle.GetStringFromName("notconnected.label")); + this._elements.details.checked = false; + this._elements.autosync.collapsed = true; + this._elements.device.collapsed = true; + this._elements.disconnect.collapsed = true; + } + // Check the lock on a timeout because it's set just after notifying - setTimeout(function() { + setTimeout(function(self) { // Prevent certain actions when the service is locked if (Weave.Service.locked) { connect.firstChild.disabled = true; sync.firstChild.disabled = true; if (aTopic == "weave:service:login:start") - connect.setAttribute("title", syncStr.get("connecting.label")); + connect.setAttribute("title", self._bundle.GetStringFromName("connecting.label")); if (aTopic == "weave:service:sync:start") - sync.setAttribute("title", syncStr.get("lastSyncInProgress.label")); + sync.setAttribute("title", self._bundle.GetStringFromName("lastSyncInProgress.label")); } else { connect.firstChild.disabled = false; sync.firstChild.disabled = false; - connect.setAttribute("title", syncStr.get("disconnected.label")); } - }, 0); + }, 0, this); // Move the disconnect and sync settings out to make connect the last item let parent = connect.parentNode; @@ -190,14 +235,14 @@ let WeaveGlue = { parent.appendChild(sync); // Dynamically generate some strings - let connectedStr = syncStr.get("connected.label", [Weave.Service.account]); - disconnect.setAttribute("title", connectedStr); + let accountStr = this._bundle.formatStringFromName("account.label", [Weave.Service.account], 1); + disconnect.setAttribute("title", accountStr); // Show the day-of-week and time (HH:MM) of last sync let lastSync = Weave.Svc.Prefs.get("lastSync"); if (lastSync != null) { let syncDate = new Date(lastSync).toLocaleFormat("%a %R"); - let dateStr = syncStr.get("lastSync.label", [syncDate]); + let dateStr = this._bundle.formatStringFromName("lastSync.label", [syncDate], 1); sync.setAttribute("title", dateStr); } @@ -227,17 +272,16 @@ let WeaveGlue = { } if (clientOutdated || remoteOutdated) { - let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties"); let brand = Services.strings.createBundle("chrome://branding/locale/brand.properties"); let brandName = brand.GetStringFromName("brandShortName"); let type = clientOutdated ? "client" : "remote"; - let message = bundle.GetStringFromName("sync.update." + type); + let message = this._bundle.GetStringFromName("sync.update." + type); message = message.replace("#1", brandName); message = message.replace("#2", Services.appinfo.version); - let title = bundle.GetStringFromName("sync.update.title") - let button = bundle.GetStringFromName("sync.update.button") - let close = bundle.GetStringFromName("sync.update.close") + let title = this._bundle.GetStringFromName("sync.update.title") + let button = this._bundle.GetStringFromName("sync.update.button") + let close = this._bundle.GetStringFromName("sync.update.close") let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING + Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_IS_STRING; @@ -249,11 +293,11 @@ let WeaveGlue = { // Load the values for the string inputs account.value = Weave.Service.account || ""; - pass.value = Weave.Service.password || ""; + password.value = Weave.Service.password || ""; let pp = Weave.Service.passphrase || ""; if (pp.length == 20) pp = this.hyphenatePassphrase(pp); - secret.value = pp; + synckey.value = pp; device.value = Weave.Clients.localName || ""; }, @@ -263,6 +307,18 @@ let WeaveGlue = { aInput.value = Weave.Clients.localName; }, + changeSync: function changeSync() { + // XXX enable/disable sync without actually disconnecting + }, + + showMessage: function showMessage(aMsg, aValue, aButtons) { + let notification = this._msg.getNotificationWithValue(aValue); + if (notification) + return; + + this._msg.appendNotification(aMsg, aValue, "", this._msg.PRIORITY_WARNING_LOW, aButtons); + }, + hyphenatePassphrase: function(passphrase) { // Hyphenate a 20 character passphrase in 4 groups of 5 return passphrase.slice(0, 5) + '-' diff --git a/mobile/locales/en-US/chrome/browser.properties b/mobile/locales/en-US/chrome/browser.properties index 5f88b5a4431..2933654391a 100644 --- a/mobile/locales/en-US/chrome/browser.properties +++ b/mobile/locales/en-US/chrome/browser.properties @@ -199,13 +199,3 @@ pageactions.password=Password # Open Search opensearch.searchWith=Search With: opensearch.searchFor=Search for "%S" - -# Mobile Sync -# LOCALIZATION NOTE (sync.clientUpdate, sync.remoteUpdate): -# #1 is the "application name" -# #2 is the "version" -sync.update.client=#1 #2 is not compatible with the latest version of Firefox Sync. Please update to the latest version. -sync.update.remote=#1 #2 is not compatible with older versions of Firefox Sync. Please update Firefox on your other computer(s). -sync.update.title=Firefox Sync -sync.update.button=Learn More -sync.update.close=Close diff --git a/mobile/locales/en-US/chrome/preferences.dtd b/mobile/locales/en-US/chrome/preferences.dtd index 43312c8d0ed..7e5f67a62cb 100644 --- a/mobile/locales/en-US/chrome/preferences.dtd +++ b/mobile/locales/en-US/chrome/preferences.dtd @@ -18,11 +18,3 @@ - - - - - - - - diff --git a/mobile/locales/en-US/chrome/sync.dtd b/mobile/locales/en-US/chrome/sync.dtd new file mode 100644 index 00000000000..f9a474f532f --- /dev/null +++ b/mobile/locales/en-US/chrome/sync.dtd @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/locales/en-US/chrome/sync.properties b/mobile/locales/en-US/chrome/sync.properties new file mode 100644 index 00000000000..83271a5ffec --- /dev/null +++ b/mobile/locales/en-US/chrome/sync.properties @@ -0,0 +1,22 @@ +# Mobile Sync + +# %S is the date and time at which the last sync successfully completed +lastSync.label=Last update: %S +lastSyncInProgress.label=Last update: in progress… + +# %S is the username logged in +account.label=Account: %S +notconnected.label=Not connected +connecting.label=Connecting… + +notificationDisconnect.label=Your Firefox Sync account has been removed +notificationDisconnect.button=Undo + +# LOCALIZATION NOTE (sync.clientUpdate, sync.remoteUpdate): +# #1 is the "application name" +# #2 is the "version" +sync.update.client=#1 #2 is not compatible with the latest version of Firefox Sync. Please update to the latest version. +sync.update.remote=#1 #2 is not compatible with older versions of Firefox Sync. Please update Firefox on your other computer(s). +sync.update.title=Firefox Sync +sync.update.button=Learn More +sync.update.close=Close diff --git a/mobile/locales/jar.mn b/mobile/locales/jar.mn index 51fa4ac1d57..16cfea4a518 100644 --- a/mobile/locales/jar.mn +++ b/mobile/locales/jar.mn @@ -13,6 +13,8 @@ locale/@AB_CD@/browser/preferences.dtd (%chrome/preferences.dtd) locale/@AB_CD@/browser/checkbox.dtd (%chrome/checkbox.dtd) locale/@AB_CD@/browser/notification.dtd (%chrome/notification.dtd) + locale/@AB_CD@/browser/sync.dtd (%chrome/sync.dtd) + locale/@AB_CD@/browser/sync.properties (%chrome/sync.properties) locale/@AB_CD@/browser/prompt.dtd (%chrome/prompt.dtd) locale/@AB_CD@/browser/feedback.dtd (%chrome/feedback.dtd) locale/@AB_CD@/browser/bookmarks.json (bookmarks.json)