Commit 63a09d82 authored by Curt Clemens's avatar Curt Clemens Committed by Commit Bot

[Nearby] Add placeholder for empty share target list on discovery page

Adds "Scanning for nearby devices..." in place of the share target
list on the discovery page when the list is empty. Needed because
the only other indication on the screen that something is happening
is the animation, which isn't accessible for screen readers.

Bug: b/163036847
Change-Id: I22cf34025727315bd2a02934fdec7ba179b6b169
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2490661
Commit-Queue: Curt Clemens <cclem@google.com>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarJames Vecore <vecore@google.com>
Cr-Commit-Position: refs/heads/master@{#824105}
parent b53eda52
...@@ -65,6 +65,9 @@ ...@@ -65,6 +65,9 @@
<message name="IDS_NEARBY_DISCOVERY_PAGE_TITLE" desc="Title of the Nearby Share device discovery page. This is where users select a device to share files with. Nearby Share is the feature name."> <message name="IDS_NEARBY_DISCOVERY_PAGE_TITLE" desc="Title of the Nearby Share device discovery page. This is where users select a device to share files with. Nearby Share is the feature name.">
Nearby Share Nearby Share
</message> </message>
<message name="IDS_NEARBY_DISCOVERY_PAGE_PLACEHOLDER" desc="Text shown on the Nearby Share device discovery page. This is where users select a device to share files with. This placeholder text is shown when the list of devices to share with is empty, and is meant to inform the user that we are currently looking for a device to share with.">
Scanning for nearby devices...
</message>
<!-- Onboarding page --> <!-- Onboarding page -->
<message name="IDS_NEARBY_ONBOARDING_PAGE_DEVICE_NAME" desc="Label of the text input field to set the name of a users device which is shown to other devices for the Nearby Share feature."> <message name="IDS_NEARBY_ONBOARDING_PAGE_DEVICE_NAME" desc="Label of the text input field to set the name of a users device which is shown to other devices for the Nearby Share feature.">
......
ad2deca34ed306b69cb58d999ae7c16ad860f519
\ No newline at end of file
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
} }
#deviceList { #deviceList {
display: block;
overflow: auto; overflow: auto;
padding-inline-end: var(--nearby-page-space-large-inline); padding-inline-end: var(--nearby-page-space-large-inline);
padding-inline-start: var(--nearby-page-space-large-inline); padding-inline-start: var(--nearby-page-space-large-inline);
...@@ -57,6 +58,7 @@ ...@@ -57,6 +58,7 @@
} }
#process-row { #process-row {
align-items: center;
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
justify-content: space-between; justify-content: space-between;
...@@ -69,6 +71,13 @@ ...@@ -69,6 +71,13 @@
height: 100px; height: 100px;
position: absolute; position: absolute;
} }
#placeholder {
color: rgb(95, 99, 104);
font-size: 13px;
line-height: 20px;
margin-inline-end: var(--nearby-page-space-large-inline);
}
</style> </style>
<nearby-page-template title="$i18n{nearbyShareDiscoveryPageTitle}" <nearby-page-template title="$i18n{nearbyShareDiscoveryPageTitle}"
...@@ -82,22 +91,28 @@ ...@@ -82,22 +91,28 @@
<div id="process-row"> <div id="process-row">
<nearby-preview title="[[sendPreview.description]]" <nearby-preview title="[[sendPreview.description]]"
share-type="[[sendPreview.shareType]]"></nearby-preview> share-type="[[sendPreview.shareType]]"></nearby-preview>
<iron-list items="[[shareTargets_]]" id="deviceList" <div id="placeholder"
selected-item="{{selectedShareTarget}}" hidden="[[!isShareTargetsEmpty_(shareTargets_.*)]]">
on-selected-item-changed="onSelectedShareTargetChanged_" $i18n{nearbyShareDiscoveryPagePlaceholder}
preserve-focus selection-enabled </div>
role="radiogroup" aria-live="polite" <template is="dom-if" if="[[!isShareTargetsEmpty_(shareTargets_.*)]]">
aria-label="$i18n{nearbyShareDiscoveryPageSubtitle}"> <iron-list items="[[shareTargets_]]" id="deviceList"
<template> selected-item="{{selectedShareTarget}}"
<nearby-device tabindex$="[[tabIndex]]" share-target="[[item]]" on-selected-item-changed="onSelectedShareTargetChanged_"
is-selected="[[isShareTargetSelected_( preserve-focus selection-enabled
item, selectedShareTarget)]]" role="radiogroup" aria-live="polite"
role="radio" aria-label="$i18n{nearbyShareDiscoveryPageSubtitle}">
aria-checked$="[[isShareTargetSelectedStr_( <template>
item, selectedShareTarget)]]"> <nearby-device tabindex$="[[tabIndex]]" share-target="[[item]]"
</nearby-device> is-selected="[[isShareTargetSelected_(
</template> item, selectedShareTarget)]]"
</iron-list> role="radio"
aria-checked$="[[isShareTargetSelectedStr_(
item, selectedShareTarget)]]">
</nearby-device>
</template>
</iron-list>
</template>
</div> </div>
<div id="help"> <div id="help">
<iron-icon id="infoIcon" icon="nearby20:info"></iron-icon> <iron-icon id="infoIcon" icon="nearby20:info"></iron-icon>
......
...@@ -271,6 +271,11 @@ Polymer({ ...@@ -271,6 +271,11 @@ Polymer({
/** @private */ /** @private */
onSelectedShareTargetChanged_() { onSelectedShareTargetChanged_() {
// The device list gets removed from the DOM if there are no share targets.
if (!this.$.deviceList) {
return;
}
// <iron-list> causes |this.$.deviceList.selectedItem| to be null if tapped // <iron-list> causes |this.$.deviceList.selectedItem| to be null if tapped
// a second time. Manually reselect the last item to preserve selection. // a second time. Manually reselect the last item to preserve selection.
if (!this.$.deviceList.selectedItem && this.lastSelectedShareTarget_) { if (!this.$.deviceList.selectedItem && this.lastSelectedShareTarget_) {
...@@ -297,6 +302,14 @@ Polymer({ ...@@ -297,6 +302,14 @@ Polymer({
return this.isShareTargetSelected_(shareTarget).toString(); return this.isShareTargetSelected_(shareTarget).toString();
}, },
/**
* @return {boolean}
* @private
*/
isShareTargetsEmpty_() {
return this.shareTargets_.length === 0;
},
/** /**
* Updates the selected share target to |shareTarget| if its id matches |id|. * Updates the selected share target to |shareTarget| if its id matches |id|.
* @param {!mojoBase.mojom.UnguessableToken} id * @param {!mojoBase.mojom.UnguessableToken} id
......
...@@ -126,6 +126,8 @@ void RegisterNearbySharedStrings(content::WebUIDataSource* data_source) { ...@@ -126,6 +126,8 @@ void RegisterNearbySharedStrings(content::WebUIDataSource* data_source) {
{"nearbyShareDeviceNameInvalidCharactersError", {"nearbyShareDeviceNameInvalidCharactersError",
IDS_NEARBY_DEVICE_NAME_INVALID_CHARACTERS_ERROR}, IDS_NEARBY_DEVICE_NAME_INVALID_CHARACTERS_ERROR},
{"nearbyShareDiscoveryPageInfo", IDS_NEARBY_DISCOVERY_PAGE_INFO}, {"nearbyShareDiscoveryPageInfo", IDS_NEARBY_DISCOVERY_PAGE_INFO},
{"nearbyShareDiscoveryPagePlaceholder",
IDS_NEARBY_DISCOVERY_PAGE_PLACEHOLDER},
{"nearbyShareDiscoveryPageSubtitle", IDS_NEARBY_DISCOVERY_PAGE_SUBTITLE}, {"nearbyShareDiscoveryPageSubtitle", IDS_NEARBY_DISCOVERY_PAGE_SUBTITLE},
{"nearbyShareDiscoveryPageTitle", IDS_NEARBY_DISCOVERY_PAGE_TITLE}, {"nearbyShareDiscoveryPageTitle", IDS_NEARBY_DISCOVERY_PAGE_TITLE},
{"nearbyShareFeatureName", IDS_NEARBY_SHARE_FEATURE_NAME}, {"nearbyShareFeatureName", IDS_NEARBY_SHARE_FEATURE_NAME},
......
...@@ -10,6 +10,7 @@ import {setDiscoveryManagerForTesting} from 'chrome://nearby/discovery_manager.j ...@@ -10,6 +10,7 @@ import {setDiscoveryManagerForTesting} from 'chrome://nearby/discovery_manager.j
import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {assertEquals, assertFalse, assertTrue} from '../chai_assert.js'; import {assertEquals, assertFalse, assertTrue} from '../chai_assert.js';
import {isVisible} from '../test_util.m.js';
import {FakeConfirmationManagerRemote, FakeDiscoveryManagerRemote} from './fake_mojo_interfaces.js'; import {FakeConfirmationManagerRemote, FakeDiscoveryManagerRemote} from './fake_mojo_interfaces.js';
...@@ -53,8 +54,15 @@ suite('DiscoveryPageTest', function() { ...@@ -53,8 +54,15 @@ suite('DiscoveryPageTest', function() {
function getShareTargetElements() { function getShareTargetElements() {
// Make sure the iron-list had time to render its elements. // Make sure the iron-list had time to render its elements.
flush(); flush();
return [...discoveryPageElement.$$('#deviceList') const deviceList = discoveryPageElement.$$('#deviceList');
.querySelectorAll('nearby-device:not([hidden])')];
// If the device list isn't found, it's because the dom-if wrapping it
// isn't showing because there are no elements.
if (!deviceList) {
return [];
}
return [...deviceList.querySelectorAll('nearby-device:not([hidden])')];
} }
/** /**
...@@ -182,6 +190,12 @@ suite('DiscoveryPageTest', function() { ...@@ -182,6 +190,12 @@ suite('DiscoveryPageTest', function() {
const listener = await startDiscovery(); const listener = await startDiscovery();
listener.onShareTargetDiscovered(createShareTarget('Device Name')); listener.onShareTargetDiscovered(createShareTarget('Device Name'));
await listener.$.flushForTesting(); await listener.$.flushForTesting();
flush();
const deviceList = /** @type{?HTMLElement} */
(discoveryPageElement.$$('#deviceList'));
const placeholder = discoveryPageElement.$$('#placeholder');
assertTrue(!!deviceList && isVisible(deviceList));
assertTrue(placeholder.hidden);
assertEquals(1, getShareTargetElements().length); assertEquals(1, getShareTargetElements().length);
const onConnectionClosedPromise = new Promise( const onConnectionClosedPromise = new Promise(
...@@ -189,7 +203,8 @@ suite('DiscoveryPageTest', function() { ...@@ -189,7 +203,8 @@ suite('DiscoveryPageTest', function() {
discoveryPageElement.fire('view-exit-finish'); discoveryPageElement.fire('view-exit-finish');
await onConnectionClosedPromise; await onConnectionClosedPromise;
assertEquals(0, getShareTargetElements().length); assertFalse(!!deviceList && isVisible(deviceList));
assertFalse(placeholder.hidden);
}); });
test('shows newly discovered device', async function() { test('shows newly discovered device', async function() {
......
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