From 45ea2935f89c75fb942767f80e58cb1dc4cfafb5 Mon Sep 17 00:00:00 2001 From: Sam Foster Date: Mon, 27 Sep 2021 19:27:02 +0000 Subject: [PATCH] Bug 1724960 - Add a one-time infobar to explain session restore. r=Gijs,fluent-reviewers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add a new browser.startup.couldRestoreSession.count which counts up (max 2) each time we *could* restore a session * Show the new infobar notification when that count reaches 1 (i.e. skip it on the first startup after update) * New strings for the notification - including an inline icon image for the ☰ * The notification's button opens the app menu. * Allow Opt-out with a pref value of -1, and opt-out the testing user by default so our perf tests don't trip on it. Differential Revision: https://phabricator.services.mozilla.com/D125904 --- browser/app/profile/firefox.js | 3 + browser/components/BrowserGlue.jsm | 68 +++++++++++++++++++++++ browser/locales/en-US/browser/browser.ftl | 6 ++ testing/profiles/perf/user.js | 1 + toolkit/content/widgets/message-bar.css | 5 ++ 5 files changed, 83 insertions(+) diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 1eb995cf416b..b69544fbf81b 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -299,6 +299,9 @@ pref("browser.startup.homepage.abouthome_cache.loglevel", "Warn"); // Whether we should skip the homepage when opening the first-run page pref("browser.startup.firstrunSkipsHomepage", true); +// Whether we should show the session-restore infobar on startup +pref("browser.startup.couldRestoreSession.count", 0); + // Show an about:blank window as early as possible for quick startup feedback. // Held to nightly on Linux due to bug 1450626. // Disabled on Mac because the bouncing dock icon already provides feedback. diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm index 899923c4d27a..e5349aa11e33 100644 --- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -2389,6 +2389,7 @@ BrowserGlue.prototype = { } Sanitizer.onStartup(); + this._maybeShowRestoreSessionInfoBar(); this._scheduleStartupIdleTasks(); this._lateTasksIdleObserver = (idleService, topic, data) => { if (topic == "idle") { @@ -4177,6 +4178,73 @@ BrowserGlue.prototype = { }); }, + /** + * Only show the infobar when canRestoreLastSession and the pref value == 1 + */ + async _maybeShowRestoreSessionInfoBar() { + let count = Services.prefs.getIntPref( + "browser.startup.couldRestoreSession.count", + 0 + ); + if (count < 0 || count >= 2) { + return; + } + if (count == 0) { + // We don't show the infobar right after the update which establishes this pref + // Increment the counter so we can consider it next time + Services.prefs.setIntPref( + "browser.startup.couldRestoreSession.count", + ++count + ); + return; + } + + // We've restarted at least once; we will show the notification if possible: + if (!SessionStore.canRestoreLastSession) { + return; + } + + Services.prefs.setIntPref( + "browser.startup.couldRestoreSession.count", + ++count + ); + + const win = BrowserWindowTracker.getTopWindow(); + const messageFragment = win.document.createDocumentFragment(); + const message = win.document.createElement("span"); + const icon = win.document.createElement("img"); + icon.src = "chrome://browser/skin/menu.svg"; + icon.setAttribute("data-l10n-name", "icon"); + icon.className = "inline-icon"; + message.appendChild(icon); + messageFragment.appendChild(message); + win.document.l10n.setAttributes( + message, + "restore-session-startup-suggestion-message" + ); + + const buttons = [ + { + "l10n-id": "restore-session-startup-suggestion-button", + callback: () => { + win.PanelUI.show(); + }, + }, + ]; + + const notifyBox = win.gBrowser.getNotificationBox(); + const notification = notifyBox.appendNotification( + "startup-restore-session-suggestion", + { + label: messageFragment, + priority: notifyBox.PRIORITY_INFO_MEDIUM, + }, + buttons + ); + // Don't allow it to be immediately hidden: + notification.timeout = Date.now() + 3000; + }, + /** * Open preferences even if there are no open windows. */ diff --git a/browser/locales/en-US/browser/browser.ftl b/browser/locales/en-US/browser/browser.ftl index 45aa5a9f44a8..79e6f3ccd40f 100644 --- a/browser/locales/en-US/browser/browser.ftl +++ b/browser/locales/en-US/browser/browser.ftl @@ -814,3 +814,9 @@ tabs-toolbar-new-tab = tabs-toolbar-list-all-tabs = .label = List all tabs .tooltiptext = List all tabs + +## Infobar shown at startup to suggest session-restore + +# will be replaced by the application menu icon +restore-session-startup-suggestion-message = Open previous tabs? You can restore your previous session from the { -brand-short-name } application menu , under History. +restore-session-startup-suggestion-button = Show you how diff --git a/testing/profiles/perf/user.js b/testing/profiles/perf/user.js index c9fc85340eb7..4f62d1187162 100644 --- a/testing/profiles/perf/user.js +++ b/testing/profiles/perf/user.js @@ -34,6 +34,7 @@ user_pref("browser.safebrowsing.provider.google4.updateURL", "http://127.0.0.1/s user_pref("browser.safebrowsing.provider.mozilla.gethashURL", "http://127.0.0.1/safebrowsing-dummy/gethash"); user_pref("browser.safebrowsing.provider.mozilla.updateURL", "http://127.0.0.1/safebrowsing-dummy/update"); user_pref("browser.shell.checkDefaultBrowser", false); +user_pref("browser.startup.couldRestoreSession.count", -1); user_pref("browser.tabs.remote.autostart", true); user_pref("browser.warnOnQuit", false); user_pref("datareporting.healthreport.documentServerURI", "http://127.0.0.1/healthreport/"); diff --git a/toolkit/content/widgets/message-bar.css b/toolkit/content/widgets/message-bar.css index 61a71f64174b..9d976d11ea5d 100644 --- a/toolkit/content/widgets/message-bar.css +++ b/toolkit/content/widgets/message-bar.css @@ -216,6 +216,11 @@ vertical-align: middle; } +/* Align inline icon images in the message content */ +.container.infobar > .notification-content > .notification-message img.inline-icon { + vertical-align: bottom; +} + .close { margin: 4px 8px; background-size: 16px;