Commit a03ce481 authored by stevenjb's avatar stevenjb Committed by Commit bot

MD Settings: user list fixes

This CL:
* Updates the API code to make better use of user_manager::User.
* Adds an isSUpervised property to usersPrivate::User.
* Hides the email address for supervised users and whitelisted users not on the device (where the name is unknown).
* Adds CrScrollableBehavior to the user list so that top and bottom borders for the list display properly.
* Adds a requestUpdateScroll method to CrScrollableBehavior so that borders are set properly when the list updates (in addition to when it scrolls).

BUG=715518
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation

Review-Url: https://codereview.chromium.org/2840313002
Cr-Commit-Position: refs/heads/master@{#468360}
parent 280730d8
......@@ -98,17 +98,25 @@ UsersPrivateGetWhitelistedUsersFunction::Run() {
// Now populate the list of User objects for returning to the JS.
for (size_t i = 0; i < email_list->GetSize(); ++i) {
api::users_private::User user;
email_list->GetString(i, &user.email);
AccountId account_id = AccountId::FromUserEmail(user.email);
user.name = base::UTF16ToUTF8(user_manager->GetUserDisplayName(account_id));
if (user.name.empty()) {
// User is not associated with a gaia account.
user.name = user_manager->GetUserDisplayEmail(account_id);
std::string email;
email_list->GetString(i, &email);
AccountId account_id = AccountId::FromUserEmail(email);
const user_manager::User* user = user_manager->FindUser(account_id);
api::users_private::User api_user;
if (user) {
api_user.email = user->GetDisplayEmail();
api_user.name = base::UTF16ToUTF8(user->GetDisplayName());
api_user.is_owner =
user->GetAccountId() == user_manager->GetOwnerAccountId();
api_user.is_supervised = user->IsSupervised();
} else {
// User is unknown (i.e. not on device).
api_user.email = email;
api_user.name = email;
api_user.is_owner = false;
api_user.is_supervised = false;
}
user.is_owner = chromeos::ProfileHelper::IsOwnerProfile(profile) &&
user.email == profile->GetProfileUserName();
user_list->Append(user.ToValue());
user_list->Append(api_user.ToValue());
}
return RespondNow(OneArgument(std::move(user_list)));
......
......@@ -216,6 +216,7 @@
'target_name': 'user_list',
'dependencies': [
'../compiled_resources2.gyp:route',
'<(DEPTH)/ui/webui/resources/cr_elements/compiled_resources2.gyp:cr_scrollable_behavior',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
'<(EXTERNS_GYP):settings_private',
'<(EXTERNS_GYP):users_private',
......
<link rel="import" href="chrome://resources/cr_elements/cr_scrollable_behavior.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/polymer.html">
......@@ -33,13 +34,15 @@
-webkit-padding-start: 20px;
}
</style>
<div class="user-list">
<div class="user-list" scrollable>
<template is="dom-repeat" items="[[users_]]">
<div class="user layout horizontal center two-line">
<img class="user-icon" src="[[getProfilePictureUrl_(item)]]">
<div class="flex user-info">
<div>[[getUserName_(item)]]</div>
<div class="secondary">[[item.email]]</div>
<template is="dom-if" if="[[shouldShowEmail_(item)]]">
<div class="secondary">[[item.email]]</div>
</template>
</div>
<paper-icon-button icon="cr:clear" class="clear-icon"
on-tap="removeUser_"
......
......@@ -15,7 +15,11 @@
Polymer({
is: 'settings-user-list',
behaviors: [I18nBehavior, settings.RouteObserverBehavior],
behaviors: [
CrScrollableBehavior,
I18nBehavior,
settings.RouteObserverBehavior,
],
properties: {
/**
......@@ -84,6 +88,7 @@ Polymer({
else
return -1;
});
this.requestUpdateScroll();
},
/**
......@@ -106,5 +111,13 @@ Polymer({
*/
getProfilePictureUrl_: function(user) {
return 'chrome://userimage/' + user.email + '?id=' + Date.now();
}
},
/**
* @param {chrome.usersPrivate.User} user
* @private
*/
shouldShowEmail_: function(user) {
return !user.isSupervised && user.name != user.email;
},
});
......@@ -16,6 +16,9 @@ namespace usersPrivate {
// Whether this user is the device owner.
boolean isOwner;
// Whether this user is supervised.
boolean isSupervised;
};
callback UsersCallback = void (User[] users);
......
......@@ -3,7 +3,7 @@
// found in the LICENSE file.
// This file was generated by:
// tools/json_schema_compiler/compiler.py.
// ./tools/json_schema_compiler/compiler.py.
// NOTE: The format of types has changed. 'FooType' is now
// 'chrome.usersPrivate.FooType'.
// Please run the closure compiler before committing changes.
......@@ -20,7 +20,8 @@ chrome.usersPrivate = {};
* @typedef {{
* email: string,
* name: string,
* isOwner: boolean
* isOwner: boolean,
* isSupervised: boolean
* }}
* @see https://developer.chrome.com/extensions/usersPrivate#type-User
*/
......
......@@ -41,15 +41,10 @@ var CrScrollableBehavior = {
intervalId_: null,
ready: function() {
var scrollableElements = this.root.querySelectorAll('[scrollable]');
// Setup the intial scrolling related classes for each scrollable container.
requestAnimationFrame(function() {
for (var i = 0; i < scrollableElements.length; i++)
this.updateScroll_(scrollableElements[i]);
}.bind(this));
this.requestUpdateScroll();
// Listen to the 'scroll' event for each scrollable container.
var scrollableElements = this.root.querySelectorAll('[scrollable]');
for (var i = 0; i < scrollableElements.length; i++) {
scrollableElements[i].addEventListener(
'scroll', this.updateScrollEvent_.bind(this));
......@@ -70,7 +65,12 @@ var CrScrollableBehavior = {
if (this.intervalId_ !== null)
return; // notifyResize is arelady in progress.
this.requestUpdateScroll();
var nodeList = this.root.querySelectorAll('[scrollable] iron-list');
if (!nodeList.length)
return;
// Use setInterval to avoid initial render / sizing issues.
this.intervalId_ = window.setInterval(function() {
var unreadyNodes = [];
......@@ -92,6 +92,19 @@ var CrScrollableBehavior = {
}.bind(this), 10);
},
/**
* Setup the intial scrolling related classes for each scrollable container.
* Called from ready() and updateScrollableContents(). May also be called
* directly when the contents change (e.g. when not using iron-list).
*/
requestUpdateScroll: function() {
requestAnimationFrame(function() {
var scrollableElements = this.root.querySelectorAll('[scrollable]');
for (var i = 0; i < scrollableElements.length; i++)
this.updateScroll_(/** @type {!HTMLElement} */(scrollableElements[i]));
}.bind(this));
},
/** @param {!IronListElement} list */
saveScroll: function(list) {
// Store a FIFO of saved scroll positions so that multiple updates in a
......
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