mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Bug 1357021 - Part 1: Handle tours completed state, r=mossop
This commit - turns on the `onboarding-complete` css style for completed tours - sets individual tour as completed when action button of that tour is clicked - sets all tours as completed if hide-the-tour checkbox is checked after toggling the overlay MozReview-Commit-ID: mps3BrdhOz --HG-- extra : rebase_source : 3023997897dc80f18b59b69e79a82c211338f88c
This commit is contained in:
parent
a6052d02e5
commit
219d62f6f1
9
browser/extensions/onboarding/bootstrap.js
vendored
9
browser/extensions/onboarding/bootstrap.js
vendored
@ -15,6 +15,15 @@ const PREF_WHITELIST = [
|
||||
"browser.onboarding.notification.lastPrompted"
|
||||
];
|
||||
|
||||
[
|
||||
"onboarding-tour-private-browsing",
|
||||
"onboarding-tour-addons",
|
||||
"onboarding-tour-customize",
|
||||
"onboarding-tour-search",
|
||||
"onboarding-tour-default-browser",
|
||||
"onboarding-tour-sync",
|
||||
].forEach(tourId => PREF_WHITELIST.push(`browser.onboarding.tour.${tourId}.completed`));
|
||||
|
||||
/**
|
||||
* Set pref. Why no `getPrefs` function is due to the priviledge level.
|
||||
* We cannot set prefs inside a framescript but can read.
|
||||
|
@ -177,7 +177,7 @@
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
#onboarding-tour-sync-page form > button {
|
||||
#onboarding-tour-sync-page form > #onboarding-tour-sync-button {
|
||||
padding: 10px 20px;
|
||||
min-width: 40%;
|
||||
font-size: 15px;
|
||||
@ -190,6 +190,7 @@
|
||||
box-shadow: 0 1px 0 rgba(0,0,0,0.23);
|
||||
cursor: pointer;
|
||||
margin: 15px 0;
|
||||
float: none;
|
||||
}
|
||||
|
||||
/* Onboarding tour pages */
|
||||
@ -242,18 +243,18 @@
|
||||
grid-column: tour-content-start / tour-page-end;
|
||||
}
|
||||
|
||||
.onboarding-tour-button {
|
||||
.onboarding-tour-button-container {
|
||||
grid-row: tour-button-start / tour-page-end;
|
||||
grid-column: tour-content-start / tour-page-end;
|
||||
}
|
||||
|
||||
.onboarding-tour-page.onboarding-no-button > .onboarding-tour-button {
|
||||
.onboarding-tour-page.onboarding-no-button > .onboarding-tour-button-container {
|
||||
display: none;
|
||||
grid-row: tour-page-end;
|
||||
grid-column: tour-page-end;
|
||||
}
|
||||
|
||||
.onboarding-tour-button > button {
|
||||
.onboarding-tour-action-button {
|
||||
padding: 10px 20px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
@ -269,7 +270,7 @@
|
||||
margin-top: -32px;
|
||||
}
|
||||
|
||||
.onboarding-tour-button > button:active {
|
||||
.onboarding-tour-action-button:active {
|
||||
background: #0881dd;
|
||||
}
|
||||
|
||||
@ -418,6 +419,7 @@
|
||||
#onboarding-notification-tour-icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
background-size: 64px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
|
@ -34,9 +34,9 @@ const BRAND_SHORT_NAME = Services.strings
|
||||
* - button: // The string of tour notification action button title
|
||||
* // Return a div appended with elements for this tours.
|
||||
* // Each tour should contain the following 3 sections in the div:
|
||||
* // .onboarding-tour-description, .onboarding-tour-content, .onboarding-tour-button.
|
||||
* // Add onboarding-no-button css class in the div if this tour does not need a button.
|
||||
* // The overlay layout will responsively position and distribute space for these 3 sections based on viewport size
|
||||
* // .onboarding-tour-description, .onboarding-tour-content, .onboarding-tour-button-container.
|
||||
* // Add onboarding-no-button css class in the div if this tour does not need a button container.
|
||||
* // If there was a .onboarding-tour-action-button present and was clicked, tour would be marked as completed.
|
||||
* getPage() {},
|
||||
* },
|
||||
**/
|
||||
@ -61,8 +61,8 @@ var onboardingTours = [
|
||||
<section class="onboarding-tour-content">
|
||||
<img src="resource://onboarding/img/figure_private.svg" />
|
||||
</section>
|
||||
<aside class="onboarding-tour-button">
|
||||
<button id="onboarding-tour-private-browsing-button" data-l10n-id="onboarding.tour-private-browsing.button"></button>
|
||||
<aside class="onboarding-tour-button-container">
|
||||
<button id="onboarding-tour-private-browsing-button" class="onboarding-tour-action-button" data-l10n-id="onboarding.tour-private-browsing.button"></button>
|
||||
</aside>
|
||||
`;
|
||||
return div;
|
||||
@ -88,8 +88,8 @@ var onboardingTours = [
|
||||
<section class="onboarding-tour-content">
|
||||
<img src="resource://onboarding/img/figure_addons.svg" />
|
||||
</section>
|
||||
<aside class="onboarding-tour-button">
|
||||
<button id="onboarding-tour-addons-button" data-l10n-id="onboarding.tour-addons.button"></button>
|
||||
<aside class="onboarding-tour-button-container">
|
||||
<button id="onboarding-tour-addons-button" class="onboarding-tour-action-button" data-l10n-id="onboarding.tour-addons.button"></button>
|
||||
</aside>
|
||||
`;
|
||||
return div;
|
||||
@ -115,8 +115,8 @@ var onboardingTours = [
|
||||
<section class="onboarding-tour-content">
|
||||
<img src="resource://onboarding/img/figure_customize.svg" />
|
||||
</section>
|
||||
<aside class="onboarding-tour-button">
|
||||
<button id="onboarding-tour-customize-button" data-l10n-id="onboarding.tour-customize.button"></button>
|
||||
<aside class="onboarding-tour-button-container">
|
||||
<button id="onboarding-tour-customize-button" class="onboarding-tour-action-button" data-l10n-id="onboarding.tour-customize.button"></button>
|
||||
</aside>
|
||||
`;
|
||||
return div;
|
||||
@ -142,8 +142,8 @@ var onboardingTours = [
|
||||
<section class="onboarding-tour-content">
|
||||
<img src="resource://onboarding/img/figure_search.svg" />
|
||||
</section>
|
||||
<aside class="onboarding-tour-button">
|
||||
<button id="onboarding-tour-search-button" data-l10n-id="onboarding.tour-search.button"></button>
|
||||
<aside class="onboarding-tour-button-container">
|
||||
<button id="onboarding-tour-search-button" class="onboarding-tour-action-button" data-l10n-id="onboarding.tour-search.button"></button>
|
||||
</aside>
|
||||
`;
|
||||
return div;
|
||||
@ -171,8 +171,8 @@ var onboardingTours = [
|
||||
<section class="onboarding-tour-content">
|
||||
<img src="resource://onboarding/img/figure_default.svg" />
|
||||
</section>
|
||||
<aside class="onboarding-tour-button">
|
||||
<button id="onboarding-tour-default-browser-button" data-l10n-id="${defaultBrowserButtonId}"></button>
|
||||
<aside class="onboarding-tour-button-container">
|
||||
<button id="onboarding-tour-default-browser-button" class="onboarding-tour-action-button" data-l10n-id="${defaultBrowserButtonId}"></button>
|
||||
</aside>
|
||||
`;
|
||||
return div;
|
||||
@ -201,7 +201,7 @@ var onboardingTours = [
|
||||
<h3 data-l10n-id="onboarding.tour-sync.form.title"></h3>
|
||||
<p data-l10n-id="onboarding.tour-sync.form.description"></p>
|
||||
<input id="onboarding-tour-sync-email-input" type="text"></input><br />
|
||||
<button id="onboarding-tour-sync-button" data-l10n-id="onboarding.tour-sync.button"></button>
|
||||
<button id="onboarding-tour-sync-button" class="onboarding-tour-action-button" data-l10n-id="onboarding.tour-sync.button"></button>
|
||||
</form>
|
||||
<img src="resource://onboarding/img/figure_sync.svg" />
|
||||
</section>
|
||||
@ -278,6 +278,12 @@ class Onboarding {
|
||||
this.destroy();
|
||||
}
|
||||
});
|
||||
onboardingTours.forEach(tour => {
|
||||
let tourId = tour.id;
|
||||
this._prefsObserved.set(`browser.onboarding.tour.${tourId}.completed`, () => {
|
||||
this.markTourCompletionState(tourId);
|
||||
});
|
||||
});
|
||||
for (let [name, callback] of this._prefsObserved) {
|
||||
Preferences.observe(name, callback);
|
||||
}
|
||||
@ -323,8 +329,12 @@ class Onboarding {
|
||||
this.gotoPage(tourId);
|
||||
break;
|
||||
}
|
||||
if (evt.target.classList.contains("onboarding-tour-item")) {
|
||||
let classList = evt.target.classList;
|
||||
if (classList.contains("onboarding-tour-item")) {
|
||||
this.gotoPage(evt.target.id);
|
||||
} else if (classList.contains("onboarding-tour-action-button")) {
|
||||
let activeItem = this._tourItems.find(item => item.classList.contains("onboarding-active"));
|
||||
this.setToursCompleted([ activeItem.id ]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,6 +380,29 @@ class Onboarding {
|
||||
return Preferences.get(`browser.onboarding.tour.${tourId}.completed`, false);
|
||||
}
|
||||
|
||||
setToursCompleted(tourIds) {
|
||||
let params = [];
|
||||
tourIds.forEach(id => {
|
||||
if (!this.isTourCompleted(id)) {
|
||||
params.push({
|
||||
name: `browser.onboarding.tour.${id}.completed`,
|
||||
value: true
|
||||
});
|
||||
}
|
||||
});
|
||||
if (params.length > 0) {
|
||||
this.sendMessageToChrome("set-prefs", params);
|
||||
}
|
||||
}
|
||||
|
||||
markTourCompletionState(tourId) {
|
||||
// We are doing lazy load so there might be no items.
|
||||
if (this._tourItems.length > 0 && this.isTourCompleted(tourId)) {
|
||||
let targetItem = this._tourItems.find(item => item.id == tourId);
|
||||
targetItem.classList.add("onboarding-complete");
|
||||
}
|
||||
}
|
||||
|
||||
showNotification() {
|
||||
if (Preferences.get("browser.onboarding.notification.finished", false)) {
|
||||
return;
|
||||
@ -469,6 +502,7 @@ class Onboarding {
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.setToursCompleted(onboardingTours.map(tour => tour.id));
|
||||
this.sendMessageToChrome("set-prefs", [
|
||||
{
|
||||
name: "browser.onboarding.hidden",
|
||||
@ -500,7 +534,7 @@ class Onboarding {
|
||||
`;
|
||||
|
||||
div.querySelector("label[for='onboarding-tour-hidden-checkbox']").textContent =
|
||||
this._bundle.GetStringFromName("onboarding.hidden-checkbox-label");
|
||||
this._bundle.GetStringFromName("onboarding.hidden-checkbox-label-text");
|
||||
div.querySelector("#onboarding-header").textContent =
|
||||
this._bundle.formatStringFromName("onboarding.overlay-title", [BRAND_SHORT_NAME], 1);
|
||||
return div;
|
||||
@ -544,6 +578,7 @@ class Onboarding {
|
||||
this._tourItems.push(li);
|
||||
this._tourPages.push(div);
|
||||
}
|
||||
tours.forEach(tour => this.markTourCompletionState(tour.id));
|
||||
|
||||
let dialog = this._window.document.getElementById("onboarding-overlay-dialog");
|
||||
let ul = this._window.document.getElementById("onboarding-tour-list");
|
||||
|
@ -3,6 +3,11 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
# LOCALIZATION NOTE(onboarding.overlay-title): This string will be used in the overlay title. %S is brandShortName
|
||||
onboarding.overlay-title=Getting started with %S
|
||||
onboarding.hidden-checkbox-label-text=Mark all as complete, and hide the tour
|
||||
#LOCALIZATION NOTE(onboarding.button.learnMore): this string is used as a button label, displayed near the message, and shared across all the onboarding notifications.
|
||||
onboarding.button.learnMore=Learn More
|
||||
# LOCALIZATION NOTE(onboarding.notification-icon-tool-tip): %S is brandShortName.
|
||||
onboarding.notification-icon-tool-tip=New to %S?
|
||||
|
||||
onboarding.tour-search=One-Click Search
|
||||
onboarding.tour-search.title=Find the needle or the haystack.
|
||||
@ -26,13 +31,13 @@ onboarding.notification.onboarding-tour-private-browsing.message=There’s no re
|
||||
|
||||
onboarding.tour-addons=Add-ons
|
||||
onboarding.tour-addons.title=Add more functionality.
|
||||
# LOCALIZATION NOTE(onboarding.tour-addons.description): This string will be used in the add-on tour description. %1$S is brandShortName
|
||||
onboarding.tour-addons.description=Add-ons expand %1$S’s built-in features, so %1$S works the way you do. Compare prices, check the weather or express your personality with a custom theme.
|
||||
onboarding.tour-addons.button=Show Add-ons in Menu
|
||||
onboarding.notification.onboarding-tour-addons.title=Get more done.
|
||||
# LOCALIZATION NOTE(onboarding.notification.onboarding-tour-addons.message): %S is brandShortName.
|
||||
onboarding.notification.onboarding-tour-addons.message=Add-ons are small apps you can add to %S that do lots of things — from managing to-do lists, to downloading videos, to changing the look of your browser.
|
||||
|
||||
# LOCALIZATION NOTE(onboarding.tour-addons.description): This string will be used in the add-on tour description. %1$S is brandShortName
|
||||
onboarding.tour-addons.description=Add-ons expand %1$S’s built-in features, so %1$S works the way you do. Compare prices, check the weather or express your personality with a custom theme.
|
||||
onboarding.tour-addons.button=Show Add-ons in Menu
|
||||
onboarding.tour-customize=Customize
|
||||
onboarding.tour-customize.title=Do things your way.
|
||||
# LOCALIZATION NOTE(onboarding.tour-customize.description): This string will be used in the customize tour description. %S is brandShortName
|
||||
@ -55,14 +60,6 @@ onboarding.notification.onboarding-tour-default-browser.title=Make %S your go-to
|
||||
# LOCALIZATION NOTE(onboarding.notification.onboarding-tour-default-browser.message): %1$S is brandShortName
|
||||
onboarding.notification.onboarding-tour-default-browser.message=It doesn’t take much to get the most from %1$S. Just set %1$S as your default browser and put control, customization, and protection on autopilot.
|
||||
|
||||
onboarding.hidden-checkbox-label=Hide the tour
|
||||
|
||||
#LOCALIZATION NOTE(onboarding.button.learnMore): this string is used as a button label, displayed near the message, and shared across all the onboarding notifications.
|
||||
onboarding.button.learnMore=Learn More
|
||||
|
||||
# LOCALIZATION NOTE(onboarding.notification-icon-tool-tip): %S is brandShortName.
|
||||
onboarding.notification-icon-tool-tip=New to %S?
|
||||
|
||||
onboarding.tour-sync=Firefox Sync
|
||||
onboarding.tour-sync.title=Sync brings it all together.
|
||||
onboarding.tour-sync.description=Access your bookmarks and passwords on any device. You can even send a tab from your laptop to your phone! Better yet, you can choose what you sync and what you don’t.
|
||||
|
Loading…
Reference in New Issue
Block a user