Commit 52fdc039 authored by Steven Bennetts's avatar Steven Bennetts Committed by Commit Bot

Settings: Change Picture: Add cr-picture-preview

This moves the preview pane into a separate element in
preparation for sharing UI between Settings and login/oobe.

Bug: 730031
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I7dae1a01579e89ca8f4b8fdc3be7393b2310c869
Reviewed-on: https://chromium-review.googlesource.com/557462Reviewed-by: default avatarTommy Li <tommycli@chromium.org>
Commit-Queue: Steven Bennetts <stevenjb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#485434}
parent a02c0cd8
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/chromeos/change_picture/cr_camera.html">
<link rel="import" href="chrome://resources/cr_elements/chromeos/change_picture/cr_picture_preview.html">
<link rel="import" href="chrome://resources/cr_elements/chromeos/change_picture/cr_picture_types.html">
<link rel="import" href="chrome://resources/cr_elements/icons.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/html/util.html">
......@@ -65,32 +66,11 @@
color: var(--paper-grey-600);
}
#previewPane {
cr-picture-preview {
-webkit-margin-end: 10px;
flex-shrink: 0;
width: 228px;
}
#previewPane img {
display: block;
height: 228px;
width: 228px;
}
#discardControlBar {
background-color: var(--paper-grey-800);
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
padding: 8px;
}
#discardOldImage {
--iron-icon-fill-color: white;
background-color: var(--paper-red-500);
border-radius: 50%;
display: block;
margin: 0 auto 0 auto;
}
</style>
<div id="container" class="settings-box" tabindex="0">
<iron-a11y-keys keys="up down left right space enter"
......@@ -115,7 +95,7 @@
title="$i18n{oldPhoto}">
<template is="dom-repeat" items="[[defaultImages_]]">
<img data-type$="[[selectionTypesEnum_.DEFAULT]]" role="radio"
data-default-image-index$="[[index]]" src="[[item.url]]"
data-index$="[[index]]" src="[[item.url]]"
title="[[item.title]]">
</template>
</iron-selector>
......@@ -130,24 +110,15 @@
</div>
</template>
</div>
<div id="previewPane">
<img alt="$i18n{previewAltText}" src="[[selectedItem_.src]]"
hidden="[[isPreviewImageHidden_(selectedItem_)]]">
<div id="discardControlBar"
hidden="[[isDiscardHidden_(selectedItem_)]]">
<button is="paper-icon-button-light" id="discardOldImage"
class="icon-delete" title="$i18n{discardPhoto}"
on-tap="onTapDiscardOldImage_">
</button>
</div>
<cr-camera id="camera"
camera-active="[[isCameraActive_(cameraPresent_, selectedItem_)]]"
on-photo-taken="onPhotoTaken_"
on-photo-flipped="onPhotoFlipped_"
flip-photo-label="$i18n{flipPhoto}"
take-photo-label="$i18n{takePhoto}">
</cr-camera>
</div>
<cr-picture-preview id="picturePreview"
camera-present="[[cameraPresent_]]",
image-src="[[getImageSrc_(selectedItem_)]]"
image-type="[[getImageType_(selectedItem_)]]"
discard-image-label="$i18n{discardPhoto}"
flip-photo-label="$i18n{flipPhoto}"
preview-alt-text="$i18n{previewAltText}"
take-photo-label="$i18n{takePhoto}">
</cr-picture-preview>
</div>
</template>
<script src="change_picture.js"></script>
......
......@@ -2,30 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Contains the possible types of Change Picture selections.
* @enum {string}
*/
var ChangePictureSelectionTypes = {
CAMERA: 'camera',
FILE: 'file',
PROFILE: 'profile',
OLD: 'old',
DEFAULT: 'default',
};
/**
* An image element.
* @typedef {{
* dataset: {
* type: !ChangePictureSelectionTypes,
* defaultImageIndex: ?number,
* },
* src: string,
* }}
*/
var ChangePictureImageElement;
/**
* @fileoverview
* 'settings-change-picture' is the settings subpage containing controls to
......@@ -54,7 +30,7 @@ Polymer({
* The currently selected item. This property is bound to the iron-selector
* and never directly assigned. This may be undefined momentarily as
* the selection changes due to iron-selector implementation details.
* @private {?ChangePictureImageElement}
* @private {?CrPicture.ImageElement}
*/
selectedItem_: Object,
......@@ -93,18 +69,24 @@ Polymer({
/** @private */
selectionTypesEnum_: {
type: Object,
value: ChangePictureSelectionTypes,
value: CrPicture.SelectionTypes,
readOnly: true,
},
},
listeners: {
'discard-image': 'onDiscardImage_',
'photo-flipped': 'onPhotoFlipped_',
'photo-taken': 'onPhotoTaken_',
},
/** @private {?settings.ChangePictureBrowserProxy} */
browserProxy_: null,
/**
* The fallback image to be selected when the user discards the Old image.
* This may be null if the user started with the Old image.
* @private {?ChangePictureImageElement}
* @private {?CrPicture.ImageElement}
*/
fallbackImage_: null,
......@@ -170,7 +152,7 @@ Polymer({
*/
receiveSelectedImage_: function(imageUrl) {
var index = this.$.selector.items.findIndex(function(image) {
return image.dataset.type == ChangePictureSelectionTypes.DEFAULT &&
return image.dataset.type == CrPicture.SelectionTypes.DEFAULT &&
image.src == imageUrl;
});
assert(index != -1, 'Default image not found: ' + imageUrl);
......@@ -179,7 +161,7 @@ Polymer({
// If user is currently taking a photo, do not steal the focus.
if (!this.selectedItem_ ||
this.selectedItem_.dataset.type != ChangePictureSelectionTypes.CAMERA) {
this.selectedItem_.dataset.type != CrPicture.SelectionTypes.CAMERA) {
this.$.selector.select(index);
}
},
......@@ -214,7 +196,7 @@ Polymer({
// If user is currently taking a photo, do not steal the focus.
if (!this.selectedItem_ ||
this.selectedItem_.dataset.type != ChangePictureSelectionTypes.CAMERA) {
this.selectedItem_.dataset.type != CrPicture.SelectionTypes.CAMERA) {
this.$.selector.select(this.$.selector.indexOf(this.$.profileImage));
}
},
......@@ -230,24 +212,24 @@ Polymer({
/**
* Selects an image element.
* @param {!ChangePictureImageElement} image
* @param {!CrPicture.ImageElement} image
* @private
*/
selectImage_: function(image) {
switch (image.dataset.type) {
case ChangePictureSelectionTypes.CAMERA:
case CrPicture.SelectionTypes.CAMERA:
// Nothing needs to be done.
break;
case ChangePictureSelectionTypes.FILE:
case CrPicture.SelectionTypes.FILE:
this.browserProxy_.chooseFile();
break;
case ChangePictureSelectionTypes.PROFILE:
case CrPicture.SelectionTypes.PROFILE:
this.browserProxy_.selectProfileImage();
break;
case ChangePictureSelectionTypes.OLD:
case CrPicture.SelectionTypes.OLD:
this.browserProxy_.selectOldImage();
break;
case ChangePictureSelectionTypes.DEFAULT:
case CrPicture.SelectionTypes.DEFAULT:
this.browserProxy_.selectDefaultImage(image.src);
break;
default:
......@@ -284,7 +266,7 @@ Polymer({
selector.selectPrevious();
} while (this.selectedItem_.hidden);
if (this.selectedItem_.dataset.type != ChangePictureSelectionTypes.FILE)
if (this.selectedItem_.dataset.type != CrPicture.SelectionTypes.FILE)
this.selectImage_(this.selectedItem_);
this.lastSelectedImageType_ = this.selectedItem_.dataset.type;
......@@ -299,7 +281,7 @@ Polymer({
selector.selectNext();
} while (this.selectedItem_.hidden);
if (this.selectedItem_.dataset.type != ChangePictureSelectionTypes.FILE)
if (this.selectedItem_.dataset.type != CrPicture.SelectionTypes.FILE)
this.selectImage_(this.selectedItem_);
this.lastSelectedImageType_ = this.selectedItem_.dataset.type;
......@@ -309,17 +291,14 @@ Polymer({
case 'enter':
case 'space':
if (this.selectedItem_.dataset.type ==
ChangePictureSelectionTypes.CAMERA) {
var /** CrCameraElement */ camera = this.$.camera;
camera.takePhoto();
CrPicture.SelectionTypes.CAMERA) {
/** CrPicturePreviewElement */ (this.$.picturePreview).takePhoto();
} else if (
this.selectedItem_.dataset.type ==
ChangePictureSelectionTypes.FILE) {
this.selectedItem_.dataset.type == CrPicture.SelectionTypes.FILE) {
this.browserProxy_.chooseFile();
} else if (
this.selectedItem_.dataset.type ==
ChangePictureSelectionTypes.OLD) {
this.onTapDiscardOldImage_();
this.selectedItem_.dataset.type == CrPicture.SelectionTypes.OLD) {
this.onDiscardImage_();
}
break;
}
......@@ -359,14 +338,14 @@ Polymer({
},
/**
* Discard currently selected Old image. Selects the first default icon.
* Discard currently selected image. Selects the first default icon.
* Returns to the camera stream if the user had just taken a picture.
* @private
*/
onTapDiscardOldImage_: function() {
onDiscardImage_: function() {
this.oldImageUrl_ = '';
if (this.lastSelectedImageType_ == ChangePictureSelectionTypes.CAMERA)
if (this.lastSelectedImageType_ == CrPicture.SelectionTypes.CAMERA)
this.$.selector.select(this.$.selector.indexOf(this.$.cameraImage));
if (this.fallbackImage_ != null) {
......@@ -383,63 +362,36 @@ Polymer({
},
/**
* @param {string} oldImageUrl
* @return {boolean} True if there is no Old image and the Old image icon
* should be hidden.
* @private
*/
isOldImageHidden_: function(oldImageUrl) {
return oldImageUrl.length == 0;
},
/**
* @param {ChangePictureImageElement} selectedItem
* @return {boolean} True if the preview image should be hidden.
* @private
*/
isPreviewImageHidden_: function(selectedItem) {
if (!selectedItem)
return true;
var type = selectedItem.dataset.type;
return type != ChangePictureSelectionTypes.DEFAULT &&
type != ChangePictureSelectionTypes.PROFILE &&
type != ChangePictureSelectionTypes.OLD;
},
/**
* @param {boolean} cameraPresent
* @param {ChangePictureImageElement} selectedItem
* @return {boolean} True if the camera is selected in the image grid.
* @param {CrPicture.ImageElement} selectedItem
* @return {string}
* @private
*/
isCameraActive_: function(cameraPresent, selectedItem) {
return cameraPresent && !!selectedItem &&
selectedItem.dataset.type == ChangePictureSelectionTypes.CAMERA;
getImageSrc_: function(selectedItem) {
return (selectedItem && selectedItem.src) || '';
},
/**
* @param {ChangePictureImageElement} selectedItem
* @return {boolean} True if the discard controls should be hidden.
* @param {CrPicture.ImageElement} selectedItem
* @return {string}
* @private
*/
isDiscardHidden_: function(selectedItem) {
return !selectedItem ||
selectedItem.dataset.type != ChangePictureSelectionTypes.OLD;
getImageType_: function(selectedItem) {
return (selectedItem && selectedItem.dataset.type) ||
CrPicture.SelectionTypes.NONE;
},
/**
* @param {ChangePictureImageElement} selectedItem
* @param {CrPicture.ImageElement} selectedItem
* @return {boolean} True if the author credit text is shown.
* @private
*/
isAuthorCreditShown_: function(selectedItem) {
return !!selectedItem &&
selectedItem.dataset.type == ChangePictureSelectionTypes.DEFAULT;
selectedItem.dataset.type == CrPicture.SelectionTypes.DEFAULT;
},
/**
* @param {!ChangePictureImageElement} selectedItem
* @param {!CrPicture.ImageElement} selectedItem
* @param {!Array<!settings.DefaultImage>} defaultImages
* @return {string} The author name for the selected default image. An empty
* string is returned if there is no valid author name.
......@@ -450,13 +402,13 @@ Polymer({
return '';
assert(
selectedItem.dataset.defaultImageIndex !== null &&
selectedItem.dataset.defaultImageIndex < defaultImages.length);
return defaultImages[selectedItem.dataset.defaultImageIndex].author;
selectedItem.dataset.index !== null &&
selectedItem.dataset.index < defaultImages.length);
return defaultImages[selectedItem.dataset.index].author;
},
/**
* @param {!ChangePictureImageElement} selectedItem
* @param {!CrPicture.ImageElement} selectedItem
* @param {!Array<!settings.DefaultImage>} defaultImages
* @return {string} The author website for the selected default image. An
* empty string is returned if there is no valid author name.
......@@ -467,8 +419,8 @@ Polymer({
return '';
assert(
selectedItem.dataset.defaultImageIndex !== null &&
selectedItem.dataset.defaultImageIndex < defaultImages.length);
return defaultImages[selectedItem.dataset.defaultImageIndex].website;
selectedItem.dataset.index !== null &&
selectedItem.dataset.index < defaultImages.length);
return defaultImages[selectedItem.dataset.index].website;
},
});
......@@ -6,7 +6,8 @@
{
'target_name': 'change_picture',
'dependencies': [
'<(DEPTH)/ui/webui/resources/cr_elements/chromeos/change_picture/compiled_resources2.gyp:cr_camera',
'<(DEPTH)/ui/webui/resources/cr_elements/chromeos/change_picture/compiled_resources2.gyp:cr_picture_preview',
'<(DEPTH)/ui/webui/resources/cr_elements/chromeos/change_picture/compiled_resources2.gyp:cr_picture_types',
'<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-selector/compiled_resources2.gyp:iron-selector-extracted',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
......
......@@ -82,8 +82,7 @@ cr.define('settings_people_page_change_picture', function() {
suite('ChangePictureTests', function() {
var changePicture = null;
var browserProxy = null;
var crCamera = null;
var discardControlBar = null;
var crPicturePreview = null;
suiteSetup(function() {
loadTimeData.overrideValues({
......@@ -98,10 +97,8 @@ cr.define('settings_people_page_change_picture', function() {
changePicture = document.createElement('settings-change-picture');
document.body.appendChild(changePicture);
crCamera = changePicture.$$('cr-camera');
assertTrue(!!crCamera);
discardControlBar = changePicture.$.discardControlBar;
assertTrue(!!discardControlBar);
crPicturePreview = changePicture.$$('cr-picture-preview');
assertTrue(!!crPicturePreview);
changePicture.currentRouteChanged(settings.routes.CHANGE_PICTURE);
......@@ -120,27 +117,44 @@ cr.define('settings_people_page_change_picture', function() {
cr.webUIListenerCallback('camera-presence-changed', false);
Polymer.dom.flush();
expectTrue(cameraIcon.hidden);
expectFalse(crCamera.cameraActive);
return new Promise(function(resolve) {
changePicture.async(resolve);
}).then(function() {
expectTrue(cameraIcon.hidden);
expectFalse(crPicturePreview.cameraPresent);
expectFalse(crPicturePreview.cameraActive_);
cr.webUIListenerCallback('camera-presence-changed', true);
Polymer.dom.flush();
expectFalse(cameraIcon.hidden);
expectFalse(crCamera.cameraActive);
MockInteractions.tap(cameraIcon);
Polymer.dom.flush();
expectFalse(cameraIcon.hidden);
expectTrue(crCamera.cameraActive);
expectEquals(ChangePictureSelectionTypes.CAMERA,
changePicture.selectedItem_.dataset.type);
expectTrue(discardControlBar.hidden);
cr.webUIListenerCallback('camera-presence-changed', true);
Polymer.dom.flush();
return new Promise(function(resolve) {
changePicture.async(resolve);
});
}).then(function() {
expectFalse(cameraIcon.hidden);
expectTrue(crPicturePreview.cameraPresent);
expectFalse(crPicturePreview.cameraActive_);
MockInteractions.tap(cameraIcon);
Polymer.dom.flush();
return new Promise(function(resolve) {
changePicture.async(resolve);
});
}).then(function() {
expectFalse(cameraIcon.hidden);
expectTrue(crPicturePreview.cameraActive_);
expectEquals(CrPicture.SelectionTypes.CAMERA,
changePicture.selectedItem_.dataset.type);
var discard = crPicturePreview.$$('#discard');
expectTrue(!discard || discard.hidden);
// Ensure that the camera is deactivated if user navigates away.
changePicture.currentRouteChanged(settings.routes.BASIC);
expectFalse(crCamera.cameraActive);
// Ensure that the camera is deactivated if user navigates away.
changePicture.currentRouteChanged(settings.routes.BASIC);
return new Promise(function(resolve) {
changePicture.async(resolve);
});
}).then(function() {
expectFalse(crPicturePreview.cameraActive_);
});
});
test('ChangePictureProfileImage', function() {
......@@ -153,16 +167,17 @@ cr.define('settings_people_page_change_picture', function() {
return browserProxy.whenCalled('selectProfileImage').then(function() {
Polymer.dom.flush();
expectEquals(ChangePictureSelectionTypes.PROFILE,
expectEquals(CrPicture.SelectionTypes.PROFILE,
changePicture.selectedItem_.dataset.type);
expectFalse(crCamera.cameraActive);
expectTrue(discardControlBar.hidden);
expectFalse(crPicturePreview.cameraActive_);
var discard = crPicturePreview.$$('#discard');
expectTrue(!discard || discard.hidden);
// Ensure that the selection is restored after navigating away and
// then back to the subpage.
changePicture.currentRouteChanged(settings.routes.BASIC);
changePicture.currentRouteChanged(settings.routes.CHANGE_PICTURE);
expectEquals(ChangePictureSelectionTypes.PROFILE,
expectEquals(CrPicture.SelectionTypes.PROFILE,
changePicture.selectedItem_.dataset.type);
});
});
......@@ -178,11 +193,13 @@ cr.define('settings_people_page_change_picture', function() {
// Expect the old image to be selected once an old image is sent via
// the native interface.
expectEquals(ChangePictureSelectionTypes.OLD,
expectEquals(CrPicture.SelectionTypes.OLD,
changePicture.selectedItem_.dataset.type);
expectFalse(oldImage.hidden);
expectFalse(crCamera.cameraActive);
expectFalse(discardControlBar.hidden);
expectFalse(crPicturePreview.cameraActive_);
var discard = crPicturePreview.$$('#discard');
assertTrue(!!discard);
expectFalse(discard.hidden);
});
test('ChangePictureSelectFirstDefaultImage', function() {
......@@ -196,11 +213,12 @@ cr.define('settings_people_page_change_picture', function() {
expectEquals('chrome://foo/1.png', args[0]);
Polymer.dom.flush();
expectEquals(ChangePictureSelectionTypes.DEFAULT,
expectEquals(CrPicture.SelectionTypes.DEFAULT,
changePicture.selectedItem_.dataset.type);
expectEquals(firstDefaultImage, changePicture.selectedItem_);
expectFalse(crCamera.cameraActive);
expectTrue(discardControlBar.hidden);
expectFalse(crPicturePreview.cameraActive_);
var discard = crPicturePreview.$$('#discard');
expectTrue(!discard || discard.hidden);
// Now verify that arrow keys actually select the new image.
browserProxy.resetResolver('selectDefaultImage');
......@@ -215,8 +233,6 @@ cr.define('settings_people_page_change_picture', function() {
test('ChangePictureRestoreImageAfterDiscard', function() {
var firstDefaultImage = changePicture.$$('img[data-type="default"]');
assertTrue(!!firstDefaultImage);
var discardOldImage = changePicture.$.discardOldImage;
assertTrue(!!discardOldImage);
MockInteractions.tap(firstDefaultImage);
......@@ -227,10 +243,12 @@ cr.define('settings_people_page_change_picture', function() {
cr.webUIListenerCallback('old-image-changed', 'fake-old-image.jpg');
Polymer.dom.flush();
expectEquals(ChangePictureSelectionTypes.OLD,
expectEquals(CrPicture.SelectionTypes.OLD,
changePicture.selectedItem_.dataset.type);
MockInteractions.tap(discardOldImage);
var discardButton = crPicturePreview.$$('#discard button');
assertTrue(!!discardButton);
MockInteractions.tap(discardButton);
Polymer.dom.flush();
expectEquals(firstDefaultImage, changePicture.selectedItem_);
......
......@@ -5,10 +5,18 @@
'targets': [
{
'target_name': 'cr_camera',
'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
},
{
'dependencies': [
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
'cr_camera',
'cr_picture_types',
],
'target_name': 'cr_picture_preview',
'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
},
{
'target_name': 'cr_picture_types',
'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
},
],
......
......@@ -64,24 +64,22 @@
margin: 0 auto 0 auto;
}
</style>
<div hidden="[[!cameraActive]]">
<div id="perspectiveBox">
<div id="userImageStreamCrop">
<video id="cameraVideo" autoplay hidden="[[!cameraOnline_]]"></video>
<paper-spinner active="[[!cameraOnline_]]"></paper-spinner>
</div>
</div>
<div id="cameraControls">
<button is="paper-icon-button-light" id="flipPhoto" tabindex="2"
title="[[flipPhotoLabel]]" on-tap="onTapFlipPhoto_"
disabled="[[!cameraOnline_]]">
</button>
<button is="paper-icon-button-light" id="takePhoto" tabindex="1"
title="[[takePhotoLabel]]" on-tap="takePhoto"
disabled="[[!cameraOnline_]]">
</button>
<div id="perspectiveBox">
<div id="userImageStreamCrop">
<video id="cameraVideo" autoplay hidden="[[!cameraOnline_]]"></video>
<paper-spinner active="[[!cameraOnline_]]"></paper-spinner>
</div>
</div>
<div id="cameraControls">
<button is="paper-icon-button-light" id="flipPhoto" tabindex="2"
title="[[flipPhotoLabel]]" on-tap="onTapFlipPhoto_"
disabled="[[!cameraOnline_]]">
</button>
<button is="paper-icon-button-light" id="takePhoto" tabindex="1"
title="[[takePhotoLabel]]" on-tap="takePhoto"
disabled="[[!cameraOnline_]]">
</button>
</div>
</template>
<script src="cr_camera.js"></script>
</dom-module>
......@@ -19,16 +19,6 @@ Polymer({
is: 'cr-camera',
properties: {
/**
* True if the user has selected the camera as the user image source.
* @type {boolean}
*/
cameraActive: {
type: Boolean,
observer: 'cameraActiveChanged_',
value: false,
},
/** Strings provided by host */
flipPhotoLabel: String,
takePhotoLabel: String,
......@@ -58,13 +48,12 @@ Polymer({
this.$.cameraVideo.addEventListener('canplay', function() {
this.cameraOnline_ = true;
}.bind(this));
if (this.cameraActive)
this.startCamera_();
this.startCamera();
},
/** @override */
detached: function() {
this.stopCamera_();
this.stopCamera();
},
/**
......@@ -88,20 +77,9 @@ Polymer({
this.fire('photo-taken', {photoDataUrl: photoDataUrl});
},
/** @private */
cameraActiveChanged_: function() {
if (this.cameraActive)
this.startCamera_();
else
this.stopCamera_();
},
/**
* Tries to start the camera stream capture.
* @private
*/
startCamera_: function() {
this.stopCamera_();
/** Tries to start the camera stream capture. */
startCamera: function() {
this.stopCamera();
this.cameraStartInProgress_ = true;
var successCallback = function(stream) {
......@@ -122,11 +100,8 @@ Polymer({
navigator.webkitGetUserMedia({video: true}, successCallback, errorCallback);
},
/**
* Stops camera capture, if it's currently active.
* @private
*/
stopCamera_: function() {
/** Stops the camera stream capture if it's currently active. */
stopCamera: function() {
this.cameraOnline_ = false;
this.$.cameraVideo.src = '';
if (this.cameraStream_)
......
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html">
<link rel="import" href="cr_camera.html">
<link rel="import" href="cr_picture_types.html">
<dom-module id="cr-picture-preview">
<template>
<style include="cr-shared-style">
img {
display: block;
width: 100%;
}
#discard {
background-color: var(--paper-grey-800);
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
padding: 8px;
}
#discard button {
--iron-icon-fill-color: white;
background-color: var(--paper-red-500);
border-radius: 50%;
display: block;
margin: 0 auto 0 auto;
}
</style>
<template is="dom-if"
if="[[showImagePreview_(cameraActive_, imageSrc)]]">
<img alt="[[previewAltText]]" src="[[imageSrc]]">
<div id="discard" hidden="[[!showDiscard_(imageType)]]">
<button is="paper-icon-button-light" id="discardImage"
class="icon-delete" title="[[discardImageLabel]]"
on-tap="onTapDiscardImage_">
</button>
</div>
</template>
<template is="dom-if" if="[[cameraActive_]]">
<cr-camera id="camera"
flip-photo-label="[[flipPhotoLabel]]"
take-photo-label="[[takePhotoLabel]]">
</cr-camera>
</template>
</template>
<script src="cr_picture_preview.js"></script>
</dom-module>
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview
* 'cr-picture-preview' is a Polymer element used to show either a profile
* picture or a camera image preview.
*/
Polymer({
is: 'cr-picture-preview',
properties: {
/** Whether the camera is present / available */
cameraPresent: Boolean,
/** Image source to show when imageType != CAMERA. */
imageSrc: String,
/**
* The type of image to display in the preview.
* @type {CrPicture.SelectionTypes}
*/
imageType: {
type: String,
value: CrPicture.SelectionTypes.NONE,
},
/** Strings provided by host */
discardImageLabel: String,
flipPhotoLabel: String,
previewAltText: String,
takePhotoLabel: String,
/** Whether the camera should be shown and active (started). */
cameraActive_: {
type: Boolean,
computed: 'getCameraActive_(cameraPresent, imageType)',
observer: 'cameraActiveChanged_',
},
},
/**
* Tells the camera to take a photo; the camera will fire a 'photo-taken'
* event when the photo is completed.
*/
takePhoto: function() {
var camera = /** @type {?CrCameraElement} */ (this.$$('#camera'));
if (camera)
camera.takePhoto();
},
/**
* @return {boolean}
* @private
*/
getCameraActive_() {
return this.cameraPresent &&
this.imageType == CrPicture.SelectionTypes.CAMERA;
},
/** @private */
cameraActiveChanged_: function() {
var camera = /** @type {?CrCameraElement} */ (this.$$('#camera'));
if (!camera)
return; // Camera will be started when attached.
if (this.cameraActive_)
camera.startCamera();
else
camera.stopCamera();
},
/**
* @return {boolean}
* @private
*/
showImagePreview_: function() {
return !this.cameraActive_ && !!this.imageSrc;
},
/**
* @return {boolean}
* @private
*/
showDiscard_: function() {
return this.imageType == CrPicture.SelectionTypes.OLD;
},
/** @private */
onTapDiscardImage_: function() {
this.fire('discard-image');
},
});
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var CrPicture = {};
/**
* Contains the possible types for picture list image elements.
* @enum {string}
*/
CrPicture.SelectionTypes = {
CAMERA: 'camera',
FILE: 'file',
PROFILE: 'profile',
OLD: 'old',
DEFAULT: 'default',
NONE: '',
};
/**
* An picture list image element.
* @typedef {{
* dataset: {
* type: !CrPicture.SelectionTypes,
* index: (number|undefined),
* },
* src: string,
* }}
*/
CrPicture.ImageElement;
......@@ -48,6 +48,18 @@
<structure name="IDR_CR_ELEMENTS_CHROMEOS_CHANGE_PICTURE_CR__CAMERA_JS"
file="../../webui/resources/cr_elements/chromeos/change_picture/cr_camera.js"
type="chrome_html" />
<structure name="IDR_CR_ELEMENTS_CHROMEOS_CHANGE_PICTURE_CR_PICTURE_PREVIEW_HTML"
file="../../webui/resources/cr_elements/chromeos/change_picture/cr_picture_preview.html"
type="chrome_html" />
<structure name="IDR_CR_ELEMENTS_CHROMEOS_CHANGE_PICTURE_CR__PICTURE_PREVIEW_JS"
file="../../webui/resources/cr_elements/chromeos/change_picture/cr_picture_preview.js"
type="chrome_html" />
<structure name="IDR_CR_ELEMENTS_CHROMEOS_CHANGE_PICTURE_CR_PICTURE_TYPES_HTML"
file="../../webui/resources/cr_elements/chromeos/change_picture/cr_picture_types.html"
type="chrome_html" />
<structure name="IDR_CR_ELEMENTS_CHROMEOS_CHANGE_PICTURE_CR__PICTURE_TYPES_JS"
file="../../webui/resources/cr_elements/chromeos/change_picture/cr_picture_types.js"
type="chrome_html" />
<structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_NETWORK_ICON_HTML"
file="../../webui/resources/cr_elements/chromeos/network/cr_network_icon.html"
type="chrome_html" />
......
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