Commit 0cd94a51 authored by Wenzhao Zang's avatar Wenzhao Zang Committed by Commit Bot

cros: Update new wallpaper picker UI (Part I)

This CL makes the new wallpaper picker fully usable. There're some
corner cases that haven't been determined by UX and they are explicitly
marked as 'TODO'.

Mock: goo.gl/kGgEVr
Spec:
https://drive.google.com/file/d/1nxrxAmlXOMp50IkGFGNobmIS-QpkYtLY/view

Bug: 800945
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I396e5727e2f564623163424de05e86be8ecb4cb0
Reviewed-on: https://chromium-review.googlesource.com/917215Reviewed-by: default avatarAlexander Alekseev <alemate@chromium.org>
Commit-Queue: Wenzhao (Colin) Zang <wzang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537551}
parent 786ecd2e
...@@ -376,7 +376,9 @@ body:not([surprise-me-disabled]) [visibleif~='surprise-me-disabled'] { ...@@ -376,7 +376,9 @@ body:not([surprise-me-disabled]) [visibleif~='surprise-me-disabled'] {
background-image: url(../images/ui/checkbox_checked.png); background-image: url(../images/ui/checkbox_checked.png);
} }
.top-header { #top-header,
#dialog-header,
#no-images-message {
display: none; display: none;
} }
...@@ -389,16 +391,33 @@ body.v2 { ...@@ -389,16 +391,33 @@ body.v2 {
.v2 .dialog-container { .v2 .dialog-container {
background-color: #fff; background-color: #fff;
flex-direction: row; border-radius: 4px;
height: 450px; height: 512px;
position: absolute; position: absolute;
top: 180px; width: 768px;
width: 100%; }
.v2 #dialog-header {
display: flex;
height: 40px;
}
.v2 .dialog-body {
display: flex;
height: 476px;
} }
.v2 .dialog-topbar { .v2 .dialog-topbar {
-webkit-margin-end: 32px;
display: block; display: block;
height: 100%; height: 100%;
overflow: visible;
padding: unset;
width: 192px;
}
.v2 .dialog-topbar #bar {
display: none;
} }
.v2 .image-picker { .v2 .image-picker {
...@@ -411,22 +430,57 @@ body.v2 { ...@@ -411,22 +430,57 @@ body.v2 {
} }
.v2 #categories-list > li { .v2 #categories-list > li {
height: 100%; border-top: unset;
height: 36px;
margin-bottom: 8px;
}
.v2 #categories-list > li > div {
color: rgb(128, 134, 139);
font-family: 'Roboto';
font-size: 13px;
font-weight: 500;
padding: 0 30px;
}
.v2 #categories-list > li[selected] {
background-color: rgb(232, 240, 254);
border-radius: 0 32px 32px 0;
} }
.v2 #categories-list > li[selected] > div { .v2 #categories-list > li[selected] > div {
color: #000; color: rgb(66, 133, 244);
font-weight: 700;
} }
.v2 #surprise-me { .v2 #surprise-me {
display: none; display: none;
} }
.v2 .image-picker {
-webkit-padding-end: unset;
-webkit-padding-start: unset;
padding-bottom: unset;
padding-top: unset;
}
.v2 .image-picker [role=listitem] { .v2 .image-picker [role=listitem] {
-webkit-margin-end: 8px;
border-radius: 4px;
height: 160px; height: 160px;
margin-bottom: 8px;
width: 160px; width: 160px;
} }
.v2 .image-picker [role=listitem][selected] {
-webkit-margin-end: 24px;
-webkit-margin-start: 16px;
height: 128px;
margin-bottom: 24px;
margin-top: 16px;
width: 128px;
}
.v2 .image-picker img { .v2 .image-picker img {
height: unset; height: unset;
overflow: hidden; overflow: hidden;
...@@ -434,18 +488,77 @@ body.v2 { ...@@ -434,18 +488,77 @@ body.v2 {
width: unset; width: unset;
} }
.v2 .close {
background-color: rgba(128, 134, 139, 0.3);
border-radius: 4px;
left: 734px;
top: -40px;
}
.v2 .image-picker .check,
.v2 .bottom-bar { .v2 .bottom-bar {
display: none; display: none;
} }
.v2 .top-header { .v2 #top-header {
background-color: #fff; background-color: #fff;
border-radius: 0 0 48px 48px;
display: flex; display: flex;
height: 50px; height: 33px;
padding-top: 15px;
position: absolute; position: absolute;
width: 760px; top: 0;
width: 698px;
} }
.v2 .top-header .more-options { .v2 .top-header-contents {
display: none;
font-family: 'Roboto';
font-size: 13px;
font-weight: 500;
}
.v2:not(.no-images) .top-header-contents {
display: flex;
}
.v2 .top-header-contents #image-title {
-webkit-padding-start: 32px;
color: rgb(32, 33, 36);
max-width: 360px;
overflow: hidden;
}
.v2 .top-header-contents #collection-name {
-webkit-padding-start: 24px;
color: rgb(128, 134, 139);
}
.v2 .top-header-contents .more-options {
display: flex;
position: absolute;
right: 0;
}
.v2 .top-header-contents .more-options > div {
-webkit-padding-end: 32px;
color: rgb(66, 133, 244);
display: none;
}
.v2 .top-header-contents .more-options a {
color: inherit;
text-decoration: none;
}
.v2 .top-header-contents.online .online-option,
.v2 .top-header-contents.custom .custom-option {
display: flex; display: flex;
}
.v2.no-images #no-images-message {
display: block;
left: 180px;
position: absolute;
top: 220px;
} }
\ No newline at end of file
...@@ -323,26 +323,40 @@ chrome.app.runtime.onLaunched.addListener(function() { ...@@ -323,26 +323,40 @@ chrome.app.runtime.onLaunched.addListener(function() {
} }
chrome.commandLinePrivate.hasSwitch('new-wallpaper-picker', (result) => { chrome.commandLinePrivate.hasSwitch('new-wallpaper-picker', (result) => {
var windowWidth = result ? 800 : 574; var options = result ? {
var windowHeight = result ? 800 : 420; frame: 'none',
state: 'maximized',
chrome.app.window.create( resizable: true,
'main.html', { alphaEnabled: true
frame: 'none', } :
width: windowWidth, {
height: windowHeight, frame: 'none',
resizable: false, width: 574,
alphaEnabled: true height: 420,
}, resizable: false,
function(w) { alphaEnabled: true
wallpaperPickerWindow = w; };
chrome.wallpaperPrivate.minimizeInactiveWindows();
w.onClosed.addListener(function() { chrome.app.window.create('main.html', options, function(w) {
wallpaperPickerWindow = null; wallpaperPickerWindow = w;
chrome.wallpaperPrivate.restoreMinimizedWindows(); chrome.wallpaperPrivate.minimizeInactiveWindows();
}); w.onClosed.addListener(function() {
WallpaperUtil.testSendMessage('wallpaper-window-created'); wallpaperPickerWindow = null;
chrome.wallpaperPrivate.restoreMinimizedWindows();
});
if (result) {
// By design, the new wallpaper picker should never be shown on top of
// another window.
wallpaperPickerWindow.contentWindow.addEventListener(
'focus', function() {
chrome.wallpaperPrivate.minimizeInactiveWindows();
});
w.onMinimized.addListener(function() {
chrome.wallpaperPrivate.restoreMinimizedWindows();
}); });
}
WallpaperUtil.testSendMessage('wallpaper-window-created');
});
}); });
}); });
......
...@@ -94,21 +94,14 @@ cr.define('wallpapers', function() { ...@@ -94,21 +94,14 @@ cr.define('wallpapers', function() {
window.setTimeout(this.callback_.bind(this, this.dataModelId_), 0); window.setTimeout(this.callback_.bind(this, this.dataModelId_), 0);
break; break;
case Constants.WallpaperSourceEnum.Custom: case Constants.WallpaperSourceEnum.Custom:
if (loadTimeData.getBoolean('useNewWallpaperPicker')) { if (loadTimeData.getBoolean('useNewWallpaperPicker'))
this.decorateCustomWallpaper_( this.decorateCustomWallpaper_(imageEl, this.dataItem);
imageEl, this.dataItem, else
this.callback_.bind(this, this.dataModelId_)); this.decorateCustomWallpaperForOldPicker_(imageEl, this.dataItem);
} else {
this.decorateCustomWallpaperForOldPicker_(
imageEl, this.dataItem,
this.callback_.bind(this, this.dataModelId_));
}
break; break;
case Constants.WallpaperSourceEnum.OEM: case Constants.WallpaperSourceEnum.OEM:
case Constants.WallpaperSourceEnum.Online: case Constants.WallpaperSourceEnum.Online:
this.decorateOnlineOrOEMWallpaper_( this.decorateOnlineOrOEMWallpaper_(imageEl, this.dataItem);
imageEl, this.dataItem,
this.callback_.bind(this, this.dataModelId_));
break; break;
case Constants.WallpaperSourceEnum.Daily: case Constants.WallpaperSourceEnum.Daily:
case Constants.WallpaperSourceEnum.ThirdParty: case Constants.WallpaperSourceEnum.ThirdParty:
...@@ -129,10 +122,9 @@ cr.define('wallpapers', function() { ...@@ -129,10 +122,9 @@ cr.define('wallpapers', function() {
* @param {{filePath: string, baseURL: string, layout: string, * @param {{filePath: string, baseURL: string, layout: string,
* source: string, availableOffline: boolean} * source: string, availableOffline: boolean}
* dataItem The info related to the wallpaper image. * dataItem The info related to the wallpaper image.
* @param {function} callback The callback function.
* @private * @private
*/ */
decorateCustomWallpaper_(imageElement, dataItem, callback) { decorateCustomWallpaper_(imageElement, dataItem) {
if (dataItem.source != Constants.WallpaperSourceEnum.Custom) { if (dataItem.source != Constants.WallpaperSourceEnum.Custom) {
console.error( console.error(
'|decorateCustomWallpaper_| is called but the wallpaper source ' + '|decorateCustomWallpaper_| is called but the wallpaper source ' +
...@@ -148,7 +140,8 @@ cr.define('wallpapers', function() { ...@@ -148,7 +140,8 @@ cr.define('wallpapers', function() {
console.error( console.error(
'Initialization of custom wallpaper grid failed for path ' + 'Initialization of custom wallpaper grid failed for path ' +
dataItem.filePath); dataItem.filePath);
callback(null /*opt_wallpaperId=*/, imageElement); this.callback_(
this.dataModelId_, null /*opt_wallpaperId=*/, imageElement);
return; return;
} }
...@@ -157,7 +150,9 @@ cr.define('wallpapers', function() { ...@@ -157,7 +150,9 @@ cr.define('wallpapers', function() {
// frequently. // frequently.
WallpaperUtil.displayImage( WallpaperUtil.displayImage(
imageElement, imageData, imageElement, imageData,
callback.bind(null /*opt_wallpaperId=*/, imageElement)); this.callback_.bind(
this, this.dataModelId_, null /*opt_wallpaperId=*/,
imageElement));
}); });
}, },
...@@ -168,33 +163,32 @@ cr.define('wallpapers', function() { ...@@ -168,33 +163,32 @@ cr.define('wallpapers', function() {
* @param {{filePath: string, baseURL: string, layout: string, * @param {{filePath: string, baseURL: string, layout: string,
* source: string, availableOffline: boolean} * source: string, availableOffline: boolean}
* dataItem The info related to the wallpaper image. * dataItem The info related to the wallpaper image.
* @param {function} callback The callback function.
* @private * @private
*/ */
decorateCustomWallpaperForOldPicker_(imageElement, dataItem, callback) { decorateCustomWallpaperForOldPicker_(imageElement, dataItem) {
if (dataItem.source != Constants.WallpaperSourceEnum.Custom) { if (dataItem.source != Constants.WallpaperSourceEnum.Custom) {
console.error( console.error(
'|decorateCustomWallpaperForOldPicker_| is called but the ' + '|decorateCustomWallpaperForOldPicker_| is called but the ' +
'wallpaper source is not custom.'); 'wallpaper source is not custom.');
return; return;
} }
var errorHandler = function(e) { var errorHandler = e => {
console.error('Can not access file system.'); console.error('Can not access file system.');
callback(); this.callback_(this.dataModelId_);
}; };
var setURL = function(fileEntry) { var setURL = fileEntry => {
imageElement.src = fileEntry.toURL(); imageElement.src = fileEntry.toURL();
callback(dataItem.wallpaperId, imageElement); this.callback_(this.dataModelId_, dataItem.wallpaperId, imageElement);
}; };
var wallpaperDirectories = WallpaperDirectories.getInstance(); var wallpaperDirectories = WallpaperDirectories.getInstance();
var fallback = function() { var fallback = () => {
wallpaperDirectories.getDirectory( wallpaperDirectories.getDirectory(
Constants.WallpaperDirNameEnum.ORIGINAL, function(dirEntry) { Constants.WallpaperDirNameEnum.ORIGINAL, function(dirEntry) {
dirEntry.getFile( dirEntry.getFile(
dataItem.baseURL, {create: false}, setURL, errorHandler); dataItem.baseURL, {create: false}, setURL, errorHandler);
}, errorHandler); }, errorHandler);
}; };
var success = function(dirEntry) { var success = dirEntry => {
dirEntry.getFile(dataItem.baseURL, {create: false}, setURL, fallback); dirEntry.getFile(dataItem.baseURL, {create: false}, setURL, fallback);
}; };
wallpaperDirectories.getDirectory( wallpaperDirectories.getDirectory(
...@@ -207,10 +201,9 @@ cr.define('wallpapers', function() { ...@@ -207,10 +201,9 @@ cr.define('wallpapers', function() {
* @param {{filePath: string, baseURL: string, layout: string, * @param {{filePath: string, baseURL: string, layout: string,
* source: string, availableOffline: boolean} * source: string, availableOffline: boolean}
* dataItem The info related to the wallpaper image. * dataItem The info related to the wallpaper image.
* @param {function} callback The callback function.
* @private * @private
*/ */
decorateOnlineOrOEMWallpaper_(imageElement, dataItem, callback) { decorateOnlineOrOEMWallpaper_(imageElement, dataItem) {
if (dataItem.source != Constants.WallpaperSourceEnum.Online && if (dataItem.source != Constants.WallpaperSourceEnum.Online &&
dataItem.source != Constants.WallpaperSourceEnum.OEM) { dataItem.source != Constants.WallpaperSourceEnum.OEM) {
console.error( console.error(
...@@ -224,7 +217,9 @@ cr.define('wallpapers', function() { ...@@ -224,7 +217,9 @@ cr.define('wallpapers', function() {
if (data) { if (data) {
WallpaperUtil.displayImage( WallpaperUtil.displayImage(
imageElement, data, imageElement, data,
callback.bind(dataItem.wallpaperId, imageElement)); this.callback_.bind(
this, this.dataModelId_, dataItem.wallpaperId,
imageElement));
} else if ( } else if (
dataItem.source == Constants.WallpaperSourceEnum.Online) { dataItem.source == Constants.WallpaperSourceEnum.Online) {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
...@@ -235,15 +230,17 @@ cr.define('wallpapers', function() { ...@@ -235,15 +230,17 @@ cr.define('wallpapers', function() {
true); true);
xhr.responseType = 'arraybuffer'; xhr.responseType = 'arraybuffer';
xhr.send(null); xhr.send(null);
xhr.addEventListener('load', function(e) { xhr.addEventListener('load', e => {
if (xhr.status === 200) { if (xhr.status === 200) {
chrome.wallpaperPrivate.saveThumbnail( chrome.wallpaperPrivate.saveThumbnail(
dataItem.baseURL, xhr.response); dataItem.baseURL, xhr.response);
WallpaperUtil.displayImage( WallpaperUtil.displayImage(
imageElement, xhr.response, imageElement, xhr.response,
callback.bind(dataItem.wallpaperId, imageElement)); this.callback_.bind(
this, this.dataModelId_, dataItem.wallpaperId,
imageElement));
} else { } else {
callback(); this.callback_(this.dataModelId_);
} }
}); });
} }
...@@ -360,13 +357,16 @@ cr.define('wallpapers', function() { ...@@ -360,13 +357,16 @@ cr.define('wallpapers', function() {
// item is constructed in function itemConstructor below. // item is constructed in function itemConstructor below.
this.pendingItems_ = 0; this.pendingItems_ = 0;
this.style.visibility = 'hidden'; // Only show the spinner on the old wallpaper picker.
// If spinner is hidden, schedule to show the spinner after if (!this.useNewWallpaperPicker_) {
// ShowSpinnerDelayMs delay. Otherwise, keep it spinning. this.style.visibility = 'hidden';
if ($('spinner-container').hidden) { // If spinner is hidden, schedule to show the spinner after
this.spinnerTimeout_ = window.setTimeout(function() { // ShowSpinnerDelayMs delay. Otherwise, keep it spinning.
$('spinner-container').hidden = false; if ($('spinner-container').hidden) {
}, ShowSpinnerDelayMs); this.spinnerTimeout_ = window.setTimeout(function() {
$('spinner-container').hidden = false;
}, ShowSpinnerDelayMs);
}
} }
} else { } else {
// Sets dataModel to null should hide spinner immediately. // Sets dataModel to null should hide spinner immediately.
...@@ -431,7 +431,7 @@ cr.define('wallpapers', function() { ...@@ -431,7 +431,7 @@ cr.define('wallpapers', function() {
if (opt_wallpaperId != null) if (opt_wallpaperId != null)
this.thumbnailList_[opt_wallpaperId] = opt_thumbnail; this.thumbnailList_[opt_wallpaperId] = opt_thumbnail;
if (opt_thumbnail && loadTimeData.getBoolean('useNewWallpaperPicker')) if (opt_thumbnail && this.useNewWallpaperPicker_)
this.cropImageToFitGrid_(opt_thumbnail); this.cropImageToFitGrid_(opt_thumbnail);
if (this.pendingItems_ == 0) { if (this.pendingItems_ == 0) {
...@@ -439,6 +439,12 @@ cr.define('wallpapers', function() { ...@@ -439,6 +439,12 @@ cr.define('wallpapers', function() {
window.clearTimeout(this.spinnerTimeout_); window.clearTimeout(this.spinnerTimeout_);
this.spinnerTimeout_ = 0; this.spinnerTimeout_ = 0;
$('spinner-container').hidden = true; $('spinner-container').hidden = true;
if (this.useNewWallpaperPicker_) {
// TODO(crbug.com/812725): Decide what to show in the top header bar
// if the current wallpaper in use was not selected from the picker.
// For now, show the info of the first wallpaper in this collection.
wallpaperManager.setWallpaperAttribution(this.dataModel.item(0));
}
} }
}, },
...@@ -452,6 +458,8 @@ cr.define('wallpapers', function() { ...@@ -452,6 +458,8 @@ cr.define('wallpapers', function() {
this.checkmark_.classList.add('check'); this.checkmark_.classList.add('check');
this.dataModel = new ArrayDataModel([]); this.dataModel = new ArrayDataModel([]);
this.thumbnailList_ = new ArrayDataModel([]); this.thumbnailList_ = new ArrayDataModel([]);
this.useNewWallpaperPicker_ =
loadTimeData.getBoolean('useNewWallpaperPicker');
var self = this; var self = this;
this.itemConstructor = function(value) { this.itemConstructor = function(value) {
var dataModelId = self.dataModelId_; var dataModelId = self.dataModelId_;
......
...@@ -89,54 +89,64 @@ found in the LICENSE file. ...@@ -89,54 +89,64 @@ found in the LICENSE file.
</div> </div>
</div> </div>
<div class="dialog-container"> <div class="dialog-container">
<div class="dialog-topbar"> <div id="dialog-header"></div>
<div id="navstrip"> <div class="dialog-body">
<list id="categories-list"></list> <div class="dialog-topbar">
<div id="bar"></div> <div id="navstrip">
</div> <list id="categories-list"></list>
<div class="spacer"></div> <div id="bar"></div>
<div id="window-close-button" class="close"></div>
</div>
<div class="dialog-main">
<div id="category-container">
<div id="wallpaper-set-by-message"></div>
<grid id="wallpaper-grid" class="image-picker"></grid>
<div id="spinner-container" hidden></div>
<div class="progress-bar" hidden>
<div class="progress-track"></div>
</div> </div>
<div class="bottom-bar"> <div class="spacer"></div>
<div id="online-wallpaper-attribute"> <div id="window-close-button" class="close"></div>
<img id="attribute-image" hidden> </div>
<div id="wallpaper-attribute" hidden> <div class="dialog-main">
<div> <div id="category-container">
<label> <div id="wallpaper-set-by-message"></div>
<span id="author-name"></span> <grid id="wallpaper-grid" class="image-picker"></grid>
</label> <div id="spinner-container" hidden></div>
</div> <div class="progress-bar" hidden>
<div> <div class="progress-track"></div>
<a id="author-website" target="_blank"></a> </div>
<div id="no-images-message" i18n-content="noImagesAvailable"></div>
<div class="bottom-bar">
<div id="online-wallpaper-attribute">
<img id="attribute-image" hidden>
<div id="wallpaper-attribute" hidden>
<div>
<label>
<span id="author-name"></span>
</label>
</div>
<div>
<a id="author-website" target="_blank"></a>
</div>
</div> </div>
</div> </div>
</div> <div class="spacer"></div>
<div class="spacer"></div> <div id="surprise-me" hidden>
<div id="surprise-me" hidden> <div id="checkbox"></div>
<div id="checkbox"></div> <span i18n-content="surpriseMeLabel"></span>
<span i18n-content="surpriseMeLabel"></span> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="top-header"> <div id="top-header">
<div id="photographer-name"></div> <div class="top-header-contents">
<div id="collection-name"></div> <div id="image-title"></div>
<div class="more-options"> <div id="collection-name"></div>
<div id="refresh"></div> <div class="more-options">
<div> <div id="refresh" class='online-option' i18n-content="refreshLabel">
<a id="explore" target="_blank"></a> </div>
<div class='online-option'>
<a id="explore" i18n-content="exploreLabel" target="_blank"></a>
</div>
<div id="center" class='custom-option' i18n-content="centerLayout">
</div>
<div id="center-cropped" class='custom-option'
i18n-content="centerCroppedLayout"></div>
</div> </div>
<div id="preview"></div>
</div> </div>
</div> </div>
</body> </body>
......
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