Commit 9b251c59 authored by John Lee's avatar John Lee Committed by Commit Bot

Navi: Allow users to preview NTP backgrounds

https://i.imgur.com/BAXJzRC.png

Bug: 924176
Change-Id: I4328752370dafa3c00d178b0b28a3320e26b071d
Reviewed-on: https://chromium-review.googlesource.com/c/1490053
Commit-Queue: John Lee <johntlee@chromium.org>
Reviewed-by: default avatarHector Carmona <hcarmona@chromium.org>
Cr-Commit-Position: refs/heads/master@{#636627}
parent f3c31fc7
......@@ -18,6 +18,12 @@ cr.define('nux', function() {
/** @return {!Promise<!Array<!nux.NtpBackgroundData>>} */
getBackgrounds() {}
/**
* @param {string} url
* @return {!Promise<void>}
*/
preloadImage(url) {}
/** @param {number} id */
setBackground(id) {}
}
......@@ -29,6 +35,16 @@ cr.define('nux', function() {
return cr.sendWithPromise('getBackgrounds');
}
/** @override */
preloadImage(url) {
return new Promise((resolve, reject) => {
const preloadedImage = new Image();
preloadedImage.onerror = reject;
preloadedImage.onload = resolve;
preloadedImage.src = url;
});
}
/** @override */
setBackground(id) {
chrome.send('setBackground', [id]);
......
......@@ -20,6 +20,41 @@
text-align: center;
}
#backgroundPreview {
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
bottom: 0;
left: 0;
opacity: 0;
position: fixed;
right: 0;
top: 0;
transition: background 300ms, opacity 400ms;
}
#backgroundPreview.active {
opacity: 1;
}
#backgroundPreview::before {
/* Copied from browser/resources/local_ntp/custom_backgrounds.js */
background-image: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.3));
/* Pseudo element needs some content (even an empty string) to be
* displayed. */
content: '';
display: block;
height: 100%;
width: 100%;
}
.content {
/* Put a non-static position on the content so that it can have a
* higher stacking level than its previous sibling,
* the #backgroundPreview element. */
position: relative;
}
.ntp-background-logo {
content: -webkit-image-set(
url(chrome://welcome/images/ntp_background_1x.png) 1x,
......@@ -37,6 +72,11 @@
margin: 0;
margin-bottom: 46px;
outline: none;
transition: color 400ms;
}
#backgroundPreview.active + .content h1 {
color: white;
}
.ntp-backgrounds-grid {
......@@ -116,6 +156,11 @@
margin-top: 56px;
}
.skip-button-container {
background: white;
border-radius: 4px;
}
iron-icon[icon='cr:chevron-right'] {
height: 20px;
margin-inline-end: -10px;
......@@ -127,6 +172,12 @@
transform: scaleX(-1);
}
</style>
<div
id="backgroundPreview"
on-transitionend="onBackgroundPreviewTransitionEnd_">
</div>
<div class="content">
<div class="ntp-background-logo"></div>
<h1 tabindex="-1">$i18n{ntpBackgroundDescription}</h1>
......@@ -134,21 +185,26 @@
<template is="dom-repeat" items="[[backgrounds_]]">
<button
active$="[[isSelectedBackground_(item, selectedBackground_)]]"
aria-pressed$="[[getAriaPressedValue_(item, selectedBackground_)]]"
aria-pressed$="[[getAriaPressedValue_(item,
selectedBackground_)]]"
class="ntp-background-grid-button"
on-click="onBackgroundClick_"
on-keyup="onBackgroundKeyUp_"
on-pointerdown="onBackgroundPointerDown_">
<div class$="ntp-background-thumbnail [[item.thumbnailClass]]"></div>
<div
class$="ntp-background-thumbnail [[item.thumbnailClass]]">
</div>
<div class="ntp-background-title">[[item.title]]</div>
</button>
</template>
</div>
<div class="button-bar">
<div class="skip-button-container">
<paper-button on-click="onSkipClicked_">
$i18n{skip}
</paper-button>
</div>
<step-indicator model="[[indicatorModel]]"></step-indicator>
<paper-button class="action-button"
disabled$="[[!hasValidSelectedBackground_(selectedBackground_)]]"
......@@ -157,6 +213,7 @@
<iron-icon icon="cr:chevron-right"></iron-icon>
</paper-button>
</div>
</div>
</template>
<script src="nux_ntp_background.js"></script>
......
......@@ -17,7 +17,10 @@ Polymer({
indicatorModel: Object,
/** @private {?nux.NtpBackgroundData} */
selectedBackground_: Object,
selectedBackground_: {
observer: 'onSelectedBackgroundChange_',
type: Object,
},
},
/** @private {?Array<!nux.NtpBackgroundData>} */
......@@ -38,13 +41,17 @@ Polymer({
thumbnailClass: '',
title: this.i18n('ntpBackgroundDefault'),
};
if (!this.selectedBackground_) {
this.selectedBackground_ = defaultBackground;
}
if (!this.backgrounds_) {
this.ntpBackgroundProxy_.getBackgrounds().then((backgrounds) => {
this.backgrounds_ = [
defaultBackground,
...backgrounds,
];
});
}
},
/**
......@@ -71,6 +78,33 @@ Polymer({
return background == this.selectedBackground_;
},
/** @private */
onSelectedBackgroundChange_: function() {
const id = this.selectedBackground_.id;
if (id > -1) {
const imageUrl = this.selectedBackground_.imageUrl;
this.ntpBackgroundProxy_.preloadImage(imageUrl).then(() => {
if (this.selectedBackground_.id === id) {
this.$.backgroundPreview.classList.add('active');
this.$.backgroundPreview.style.backgroundImage = `url(${imageUrl})`;
}
});
} else {
this.$.backgroundPreview.classList.remove('active');
}
},
/** @private */
onBackgroundPreviewTransitionEnd_: function() {
// Whenever the #backgroundPreview transitions to a non-active, hidden
// state, remove the background image. This way, when the element
// transitions back to active, the previous background is not displayed.
if (!this.$.backgroundPreview.classList.contains('active')) {
this.$.backgroundPreview.style.backgroundImage = '';
}
},
/**
* @param {!{model: !{item: !nux.NtpBackgroundData}}} e
* @private
......
......@@ -54,6 +54,7 @@ void NtpBackgroundHandler::HandleGetBackgrounds(const base::ListValue* args) {
base::ListValue list_value;
std::array<GURL, kOnboardingNtpBackgroundsCount> onboardingNtpBackgrounds =
GetOnboardingNtpBackgrounds();
const std::string kUrlPrefix = "preview-background.jpg?";
auto element = std::make_unique<base::DictionaryValue>();
int id = static_cast<int>(NtpBackgrounds::kEarth);
......@@ -61,7 +62,7 @@ void NtpBackgroundHandler::HandleGetBackgrounds(const base::ListValue* args) {
element->SetString("title",
l10n_util::GetStringUTF8(
IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_EARTH_TITLE));
element->SetString("imageUrl", onboardingNtpBackgrounds[id].spec());
element->SetString("imageUrl", kUrlPrefix + std::to_string(id));
element->SetString("thumbnailClass", "earth");
list_value.Append(std::move(element));
......@@ -71,7 +72,7 @@ void NtpBackgroundHandler::HandleGetBackgrounds(const base::ListValue* args) {
element->SetString(
"title", l10n_util::GetStringUTF8(
IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_CITYSCAPE_TITLE));
element->SetString("imageUrl", onboardingNtpBackgrounds[id].spec());
element->SetString("imageUrl", kUrlPrefix + std::to_string(id));
element->SetString("thumbnailClass", "cityscape");
list_value.Append(std::move(element));
......@@ -81,7 +82,7 @@ void NtpBackgroundHandler::HandleGetBackgrounds(const base::ListValue* args) {
element->SetString(
"title", l10n_util::GetStringUTF8(
IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_LANDSCAPE_TITLE));
element->SetString("imageUrl", onboardingNtpBackgrounds[id].spec());
element->SetString("imageUrl", kUrlPrefix + std::to_string(id));
element->SetString("thumbnailClass", "landscape");
list_value.Append(std::move(element));
......@@ -91,7 +92,7 @@ void NtpBackgroundHandler::HandleGetBackgrounds(const base::ListValue* args) {
element->SetString("title",
l10n_util::GetStringUTF8(
IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_ART_TITLE));
element->SetString("imageUrl", onboardingNtpBackgrounds[id].spec());
element->SetString("imageUrl", kUrlPrefix + std::to_string(id));
element->SetString("thumbnailClass", "art");
list_value.Append(std::move(element));
......@@ -102,7 +103,7 @@ void NtpBackgroundHandler::HandleGetBackgrounds(const base::ListValue* args) {
"title",
l10n_util::GetStringUTF8(
IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_GEOMETRIC_SHAPES_TITLE));
element->SetString("imageUrl", onboardingNtpBackgrounds[id].spec());
element->SetString("imageUrl", kUrlPrefix + std::to_string(id));
element->SetString("thumbnailClass", "geometric-shapes");
list_value.Append(std::move(element));
......
......@@ -8,15 +8,17 @@ cr.define('onboarding_ntp_background_test', function() {
let backgrounds = [
{
id: 0,
title: 'Cat',
imageUrl: 'some/cute/photo/of/a/cat',
thumbnailClass: 'cat',
title: 'Art',
/* Image URLs are set to actual static images to prevent requesting
* an external image. */
imageUrl: '../images/ntp_thumbnails/art.jpg',
thumbnailClass: 'art',
},
{
id: 1,
title: 'Venice',
imageUrl: 'some/scenic/photo/of/a/beach',
thumbnailClass: 'venice',
title: 'Cityscape',
imageUrl: '../images/ntp_thumbnails/cityscape.jpg',
thumbnailClass: 'cityscape',
},
];
......@@ -66,6 +68,29 @@ cr.define('onboarding_ntp_background_test', function() {
}
});
test('test previewing a background and going back to default', function() {
const options = testElement.shadowRoot.querySelectorAll(
'.ntp-background-grid-button');
options[1].click();
return testNtpBackgroundProxy.whenCalled('preloadImage').then(() => {
assertEquals(
testElement.$.backgroundPreview.style.backgroundImage,
`url("${backgrounds[0].imageUrl}")`);
assertTrue(
testElement.$.backgroundPreview.classList.contains('active'));
// go back to the default option, and pretend all CSS transitions
// have completed
options[0].click();
testElement.$.backgroundPreview.dispatchEvent(
new Event('transitionend'));
assertEquals(testElement.$.backgroundPreview.style.backgroundImage, '');
assertFalse(
testElement.$.backgroundPreview.classList.contains('active'));
});
});
test('test disabling and enabling of the next button', function() {
const nextButton = testElement.shadowRoot.querySelector('.action-button');
assertTrue(nextButton.disabled);
......
......@@ -7,6 +7,7 @@ class TestNtpBackgroundProxy extends TestBrowserProxy {
constructor() {
super([
'getBackgrounds',
'preloadImage',
'setBackground',
]);
......@@ -20,6 +21,12 @@ class TestNtpBackgroundProxy extends TestBrowserProxy {
return Promise.resolve(this.backgroundsList_);
}
/** @override */
preloadImage(url) {
this.methodCalled('preloadImage');
return Promise.resolve();
}
/** @override */
setBackground(id) {
this.methodCalled('setBackground', id);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment