Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: ui/login/account_picker/md_user_pod_row.js

Issue 2931063004: Extract colors from wallpaper and dynamically update login screen overlay (Closed)
Patch Set: Address comments Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview User pod row implementation. 6 * @fileoverview User pod row implementation.
7 */ 7 */
8 8
9 cr.define('login', function() { 9 cr.define('login', function() {
10 /** 10 /**
(...skipping 2793 matching lines...) Expand 10 before | Expand all | Expand 10 after
2804 2804
2805 // Array of users that are shown (public/supervised/regular). 2805 // Array of users that are shown (public/supervised/regular).
2806 users_: [], 2806 users_: [],
2807 2807
2808 // If we're in Touch View mode. 2808 // If we're in Touch View mode.
2809 touchViewEnabled_: false, 2809 touchViewEnabled_: false,
2810 2810
2811 // If testing mode is enabled. 2811 // If testing mode is enabled.
2812 testingModeEnabled_: false, 2812 testingModeEnabled_: false,
2813 2813
2814 overlayColors_: {maskColor: undefined, scrollColor: undefined},
2815
2814 /** @override */ 2816 /** @override */
2815 decorate: function() { 2817 decorate: function() {
2816 // Event listeners that are installed for the time period during which 2818 // Event listeners that are installed for the time period during which
2817 // the element is visible. 2819 // the element is visible.
2818 this.listeners_ = { 2820 this.listeners_ = {
2819 focus: [this.handleFocus_.bind(this), true /* useCapture */], 2821 focus: [this.handleFocus_.bind(this), true /* useCapture */],
2820 click: [this.handleClick_.bind(this), true], 2822 click: [this.handleClick_.bind(this), true],
2821 mousemove: [this.handleMouseMove_.bind(this), false], 2823 mousemove: [this.handleMouseMove_.bind(this), false],
2822 keydown: [this.handleKeyDown.bind(this), false] 2824 keydown: [this.handleKeyDown.bind(this), false]
2823 }; 2825 };
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
3103 rebuildPods: function() { 3105 rebuildPods: function() {
3104 var emptyPodRow = this.pods.length == 0; 3106 var emptyPodRow = this.pods.length == 0;
3105 3107
3106 // Clear existing pods. 3108 // Clear existing pods.
3107 this.innerHTML = ''; 3109 this.innerHTML = '';
3108 this.focusedPod_ = undefined; 3110 this.focusedPod_ = undefined;
3109 this.activatedPod_ = undefined; 3111 this.activatedPod_ = undefined;
3110 this.lastFocusedPod_ = undefined; 3112 this.lastFocusedPod_ = undefined;
3111 this.mainPod_ = undefined; 3113 this.mainPod_ = undefined;
3112 this.smallPodsContainer.innerHTML = ''; 3114 this.smallPodsContainer.innerHTML = '';
3115 this.topMask.innerHTML = '';
3116 this.bottomMask.innerHTML = '';
3113 3117
3114 // Switch off animation 3118 // Switch off animation
3115 Oobe.getInstance().toggleClass('flying-pods', false); 3119 Oobe.getInstance().toggleClass('flying-pods', false);
3116 3120
3117 for (var i = 0; i < this.users_.length; ++i) 3121 for (var i = 0; i < this.users_.length; ++i)
3118 this.addUserPod(this.users_[i]); 3122 this.addUserPod(this.users_[i]);
3119 3123
3120 for (var i = 0, pod; pod = this.pods[i]; ++i) 3124 for (var i = 0, pod; pod = this.pods[i]; ++i)
3121 this.podsWithPendingImages_.push(pod); 3125 this.podsWithPendingImages_.push(pod);
3122 3126
3123 // TODO(nkostylev): Edge case handling when kiosk apps are not fitting. 3127 // TODO(nkostylev): Edge case handling when kiosk apps are not fitting.
3124 if (this.shouldShowApps_) { 3128 if (this.shouldShowApps_) {
3125 for (var i = 0; i < this.apps_.length; ++i) 3129 for (var i = 0; i < this.apps_.length; ++i)
3126 this.addUserPod(this.apps_[i]); 3130 this.addUserPod(this.apps_[i]);
3127 } 3131 }
3128 3132
3129 // Make sure we eventually show the pod row, even if some image is stuck. 3133 // Make sure we eventually show the pod row, even if some image is stuck.
3130 setTimeout(function() { 3134 setTimeout(function() {
3131 $('pod-row').classList.remove('images-loading'); 3135 $('pod-row').classList.remove('images-loading');
3136 this.smallPodsContainer.classList.remove('images-loading');
3137 this.topMask.classList.remove('images-loading');
3138 this.bottomMask.classList.remove('images-loading');
3132 }, POD_ROW_IMAGES_LOAD_TIMEOUT_MS); 3139 }, POD_ROW_IMAGES_LOAD_TIMEOUT_MS);
3133 3140
3134 var isAccountPicker = $('login-header-bar').signinUIState == 3141 var isAccountPicker = $('login-header-bar').signinUIState ==
3135 SIGNIN_UI_STATE.ACCOUNT_PICKER; 3142 SIGNIN_UI_STATE.ACCOUNT_PICKER;
3136 3143
3137 // Immediately recalculate pods layout only when current UI is account 3144 // Immediately recalculate pods layout only when current UI is account
3138 // picker. Otherwise postpone it. 3145 // picker. Otherwise postpone it.
3139 if (isAccountPicker) { 3146 if (isAccountPicker) {
3140 this.placePods_(); 3147 this.placePods_();
3141 this.maybePreselectPod(); 3148 this.maybePreselectPod();
(...skipping 18 matching lines...) Expand all
3160 3167
3161 /** 3168 /**
3162 * Gets the container of small pods. 3169 * Gets the container of small pods.
3163 * @type {!HTMLDivElement} 3170 * @type {!HTMLDivElement}
3164 */ 3171 */
3165 get smallPodsContainer() { 3172 get smallPodsContainer() {
3166 return document.querySelector('.small-pod-container'); 3173 return document.querySelector('.small-pod-container');
3167 }, 3174 },
3168 3175
3169 /** 3176 /**
3177 * Gets the gradient mask at the top.
3178 * @type {!HTMLDivElement}
3179 */
3180 get topMask() {
3181 return document.querySelector('.small-pod-container-mask');
3182 },
3183
3184 /**
3185 * Gets the gradient mask at the bottom.
3186 * @type {!HTMLDivElement}
3187 */
3188 get bottomMask() {
3189 return document.querySelector('.small-pod-container-mask.rotate');
3190 },
3191
3192 /**
3170 * Adds given apps to the pod row. 3193 * Adds given apps to the pod row.
3171 * @param {array} apps Array of apps. 3194 * @param {array} apps Array of apps.
3172 */ 3195 */
3173 setApps: function(apps) { 3196 setApps: function(apps) {
3174 this.apps_ = apps; 3197 this.apps_ = apps;
3175 this.rebuildPods(); 3198 this.rebuildPods();
3176 chrome.send('kioskAppsLoaded'); 3199 chrome.send('kioskAppsLoaded');
3177 3200
3178 // Check whether there's a pending kiosk app error. 3201 // Check whether there's a pending kiosk app error.
3179 window.setTimeout(function() { 3202 window.setTimeout(function() {
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
3670 3693
3671 /** 3694 /**
3672 * Called when the LANDSCAPE_MODE_LIMIT or PORTRAIT_MODE_LIMIT is exceeded 3695 * Called when the LANDSCAPE_MODE_LIMIT or PORTRAIT_MODE_LIMIT is exceeded
3673 * and the scrollable container is shown. 3696 * and the scrollable container is shown.
3674 * @private 3697 * @private
3675 */ 3698 */
3676 placePodsOnScrollableContainer_: function() { 3699 placePodsOnScrollableContainer_: function() {
3677 this.smallPodsContainer.hidden = false; 3700 this.smallPodsContainer.hidden = false;
3678 // Add a dark overlay. 3701 // Add a dark overlay.
3679 this.smallPodsContainer.classList.add('scroll'); 3702 this.smallPodsContainer.classList.add('scroll');
3703 // If wallpaper color extraction results are not available, use the
3704 // default value in CSS rules.
3705 if (this.overlayColors_.scrollColor) {
3706 this.smallPodsContainer.style.background =
3707 this.overlayColors_.scrollColor;
3708 }
3680 var pods = this.pods; 3709 var pods = this.pods;
3681 this.mainPod_.setPodStyle(UserPod.Style.LARGE); 3710 this.mainPod_.setPodStyle(UserPod.Style.LARGE);
3682 for (var pod of pods) { 3711 for (var pod of pods) {
3683 if (pod != this.mainPod_) { 3712 if (pod != this.mainPod_) {
3684 // All pods except the main one must be set to the extra small style. 3713 // All pods except the main one must be set to the extra small style.
3685 pod.setPodStyle(UserPod.Style.EXTRA_SMALL); 3714 pod.setPodStyle(UserPod.Style.EXTRA_SMALL);
3686 } 3715 }
3687 } 3716 }
3688 3717
3689 var SCROLL_LEFT_PADDING = this.isPortraitMode_() ? 46 : 72; 3718 var SCROLL_LEFT_PADDING = this.isPortraitMode_() ? 46 : 72;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3758 3787
3759 /** 3788 /**
3760 * Called each time before pod placement to ensure we start with the 3789 * Called each time before pod placement to ensure we start with the
3761 * initial state, which is ready to place only one user pod. The styles 3790 * initial state, which is ready to place only one user pod. The styles
3762 * of elements necessary for other placement methods must be set 3791 * of elements necessary for other placement methods must be set
3763 * explicitly each time. 3792 * explicitly each time.
3764 * @private 3793 * @private
3765 */ 3794 */
3766 handleBeforePodPlacement_: function() { 3795 handleBeforePodPlacement_: function() {
3767 this.smallPodsContainer.hidden = true; 3796 this.smallPodsContainer.hidden = true;
3768 document.querySelector('.small-pod-container-mask').hidden = true; 3797 this.topMask.hidden = true;
3769 document.querySelector('.small-pod-container-mask.rotate').hidden = true; 3798 this.bottomMask.hidden = true;
3770 this.smallPodsContainer.classList.remove('scroll'); 3799 this.smallPodsContainer.classList.remove('scroll');
3800 this.smallPodsContainer.style.background = 'unset';
3771 var pods = this.pods; 3801 var pods = this.pods;
3772 for (var pod of pods) { 3802 for (var pod of pods) {
3773 // There is a chance that one of the pods has a bottom padding, so 3803 // There is a chance that one of the pods has a bottom padding, so
3774 // reset all of them to be safe. This is because if the pod was at 3804 // reset all of them to be safe. This is because if the pod was at
3775 // the last position in the scrollable container, a bottom padding 3805 // the last position in the scrollable container, a bottom padding
3776 // was added to ensure a symmetric layout. 3806 // was added to ensure a symmetric layout.
3777 pod.style.paddingBottom = cr.ui.toCssPx(0); 3807 pod.style.paddingBottom = cr.ui.toCssPx(0);
3778 } 3808 }
3779 this.clearPodsAnimation_(); 3809 this.clearPodsAnimation_();
3780 this.hideEmptyArea_(); 3810 this.hideEmptyArea_();
(...skipping 20 matching lines...) Expand all
3801 */ 3831 */
3802 isScreenShrinked_: function() { 3832 isScreenShrinked_: function() {
3803 return this.screenSize.height <= Oobe.getInstance().clientAreaSize.height; 3833 return this.screenSize.height <= Oobe.getInstance().clientAreaSize.height;
3804 }, 3834 },
3805 3835
3806 /** 3836 /**
3807 * Called when scroll bar is shown and we need a mask for the header bar. 3837 * Called when scroll bar is shown and we need a mask for the header bar.
3808 * @private 3838 * @private
3809 */ 3839 */
3810 showScrollMask_: function() { 3840 showScrollMask_: function() {
3811 var topMask = document.querySelector('.small-pod-container-mask'); 3841 this.topMask.hidden = false;
3812 topMask.hidden = false; 3842 this.topMask.style.left = this.smallPodsContainer.style.left;
3813 topMask.style.left = this.smallPodsContainer.style.left; 3843 this.topMask.style.width = this.smallPodsContainer.style.width;
3814 topMask.style.width = this.smallPodsContainer.style.width; 3844 this.bottomMask.hidden = false;
3815 // The bottom mask is a rotation of the top mask. 3845 this.bottomMask.style.left = this.smallPodsContainer.style.left;
3816 var bottomMask = 3846 this.bottomMask.style.width = this.smallPodsContainer.style.width;
3817 document.querySelector('.small-pod-container-mask.rotate');
3818 bottomMask.hidden = false;
3819 bottomMask.style.left = this.smallPodsContainer.style.left;
3820 bottomMask.style.width = this.smallPodsContainer.style.width;
3821 // The bottom mask should overlap with the header bar, and its z-index 3847 // The bottom mask should overlap with the header bar, and its z-index
3822 // is chosen to ensure it does not block users from using the header bar. 3848 // is chosen to ensure it does not block users from using the header bar.
3823 bottomMask.style.top = 3849 this.bottomMask.style.top =
3824 cr.ui.toCssPx(this.screenSize.height - SCROLL_MASK_HEIGHT); 3850 cr.ui.toCssPx(this.screenSize.height - SCROLL_MASK_HEIGHT);
3851 if (this.overlayColors_.maskColor) {
3852 var maskGradient = this.getMaskGradient_(this.overlayColors_.maskColor);
3853 this.topMask.style.background = maskGradient;
3854 this.bottomMask.style.background = maskGradient;
3855 }
3825 }, 3856 },
3826 3857
3827 /** 3858 /**
3828 * Called after pod placement and before showing the pod row. Updates 3859 * Called after pod placement and before showing the pod row. Updates
3829 * elements whose style may depend on the pod placement outcome. 3860 * elements whose style may depend on the pod placement outcome.
3830 * @private 3861 * @private
3831 */ 3862 */
3832 handleAfterPodPlacement_: function() { 3863 handleAfterPodPlacement_: function() {
3833 var pods = this.pods; 3864 var pods = this.pods;
3834 for (var pod of pods) { 3865 for (var pod of pods) {
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
4049 * @param {string} message Text to be displayed or empty to hide the banner. 4080 * @param {string} message Text to be displayed or empty to hide the banner.
4050 */ 4081 */
4051 showBannerMessage: function(message) { 4082 showBannerMessage: function(message) {
4052 var banner = $('signin-banner'); 4083 var banner = $('signin-banner');
4053 banner.textContent = message; 4084 banner.textContent = message;
4054 banner.classList.toggle('message-set', !!message); 4085 banner.classList.toggle('message-set', !!message);
4055 $('signin-banner-container1').hidden = banner.textContent.length == 0; 4086 $('signin-banner-container1').hidden = banner.textContent.length == 0;
4056 }, 4087 },
4057 4088
4058 /** 4089 /**
4090 * Sets login screen overlay colors based on colors extracted from the
4091 * wallpaper.
4092 * @param {string} maskColor Color for the gradient mask.
4093 * @param {string} scrollColor Color for the small pods container.
4094 * @param {string} backgroundColor Color for the whole background.
4095 */
4096 setOverlayColors: function(maskColor, scrollColor, backgroundColor) {
4097 $('login-shield').style.backgroundColor = backgroundColor;
4098 if (this.smallPodsContainer.classList.contains('scroll'))
4099 this.smallPodsContainer.style.backgroundColor = scrollColor;
4100 if (!this.topMask.hidden) {
4101 var maskGradient = this.getMaskGradient_(maskColor);
4102 this.topMask.style.background = maskGradient;
4103 this.bottomMask.style.background = maskGradient;
4104 }
4105 // Save the colors because the scrollable container and the masks may
4106 // become visible later.
4107 this.overlayColors_.maskColor = maskColor;
4108 this.overlayColors_.scrollColor = scrollColor;
4109 },
4110
4111 /**
4112 * Helper function to create a style string for the scroll masks.
4113 * @param {string} maskColor Color for the gradient mask.
4114 * @return {string} A CSS style.
4115 */
4116 getMaskGradient_: function(maskColor) {
4117 return 'linear-gradient(' + maskColor + ', transparent)';
4118 },
4119
4120 /**
4059 * Whether the pod is currently focused. 4121 * Whether the pod is currently focused.
4060 * @param {UserPod} pod Pod to check for focus. 4122 * @param {UserPod} pod Pod to check for focus.
4061 * @return {boolean} Pod focus status. 4123 * @return {boolean} Pod focus status.
4062 */ 4124 */
4063 isFocused: function(pod) { 4125 isFocused: function(pod) {
4064 return this.focusedPod_ == pod; 4126 return this.focusedPod_ == pod;
4065 }, 4127 },
4066 4128
4067 /** 4129 /**
4068 * Focuses a given user pod or clear focus when given null. 4130 * Focuses a given user pod or clear focus when given null.
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
4551 */ 4613 */
4552 handlePodImageLoad: function(pod) { 4614 handlePodImageLoad: function(pod) {
4553 var index = this.podsWithPendingImages_.indexOf(pod); 4615 var index = this.podsWithPendingImages_.indexOf(pod);
4554 if (index == -1) { 4616 if (index == -1) {
4555 return; 4617 return;
4556 } 4618 }
4557 4619
4558 this.podsWithPendingImages_.splice(index, 1); 4620 this.podsWithPendingImages_.splice(index, 1);
4559 if (this.podsWithPendingImages_.length == 0) { 4621 if (this.podsWithPendingImages_.length == 0) {
4560 this.classList.remove('images-loading'); 4622 this.classList.remove('images-loading');
4623 this.smallPodsContainer.classList.remove('images-loading');
4624 this.topMask.classList.remove('images-loading');
4625 this.bottomMask.classList.remove('images-loading');
4561 } 4626 }
4562 }, 4627 },
4563 4628
4564 /** 4629 /**
4565 * Preselects pod, if needed. 4630 * Preselects pod, if needed.
4566 */ 4631 */
4567 maybePreselectPod: function() { 4632 maybePreselectPod: function() {
4568 var pod = this.preselectedPod; 4633 var pod = this.preselectedPod;
4569 this.focusPod(pod); 4634 this.focusPod(pod);
4570 4635
4571 // Hide user-type-bubble in case all user pods are disabled and we focus 4636 // Hide user-type-bubble in case all user pods are disabled and we focus
4572 // first pod. 4637 // first pod.
4573 if (pod && pod.multiProfilesPolicyApplied) { 4638 if (pod && pod.multiProfilesPolicyApplied) {
4574 pod.userTypeBubbleElement.classList.remove('bubble-shown'); 4639 pod.userTypeBubbleElement.classList.remove('bubble-shown');
4575 } 4640 }
4576 } 4641 }
4577 }; 4642 };
4578 4643
4579 return { 4644 return {
4580 PodRow: PodRow 4645 PodRow: PodRow
4581 }; 4646 };
4582 }); 4647 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698