Commit c11dd7b6 authored by Gavin Williams's avatar Gavin Williams Committed by Commit Bot

scanning: Add 'Done' page for when scan jobs complete

When a user clicks done they'll return to the initial scanning page.
The next CL will add a "Show file location" link to this page.

http://screen/3M4mPRveuCzYjoQ

Bug: 1059779
Change-Id: I74950fa83370b8339d000ec9b18d29b493587d0b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2528089
Commit-Queue: Gavin Williams <gavinwill@chromium.org>
Reviewed-by: default avatarJesse Schettler <jschettler@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826149}
parent be1c7a2e
......@@ -4,13 +4,12 @@
import 'chrome://scanning/scanning_app.js';
import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {setScanServiceForTesting} from 'chrome://scanning/mojo_interface_provider.js';
import {ScannerArr} from 'chrome://scanning/scanning_app_types.js';
import {tokenToString} from 'chrome://scanning/scanning_app_util.js';
import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
import {flushTasks} from '../../test_util.m.js';
import {flushTasks, isVisible} from '../../test_util.m.js';
import {changeSelect, createScanner, createScannerSource} from './scanning_app_test_utils.js';
......@@ -267,12 +266,23 @@ export function scanningAppTest() {
return flushTasks();
}
/**
* Clicks the "Done" button.
* @return {!Promise}
*/
function clickDoneButton() {
const button = scanningApp.$$('#doneButton');
assertTrue(!!button);
button.click();
return flushTasks();
}
/**
* Returns whether the "More settings" section is expanded or not.
* @return {boolean}
*/
function isSettingsOpen() {
return scanningApp.$.collapse.opened;
return scanningApp.$$('#collapse').opened;
}
test('Scan', () => {
......@@ -299,15 +309,15 @@ export function scanningAppTest() {
let resolutionSelect;
/** @type {!CrButtonElement} */
let scanButton;
/** @type {!Element} */
/** @type {!HTMLElement} */
let statusText;
/** @type {!Element} */
/** @type {!HTMLElement} */
let helperText;
/** @type {!Element} */
/** @type {!HTMLElement} */
let scanProgress;
/** @type {!Element} */
/** @type {!HTMLElement} */
let progressText;
/** @type {!Element} */
/** @type {!HTMLElement} */
let progressBar;
return initializeScanningApp(expectedScanners, capabilities)
......@@ -320,12 +330,11 @@ export function scanningAppTest() {
resolutionSelect = scanningApp.$$('#resolutionSelect').$$('select');
scanButton =
/** @type {!CrButtonElement} */ (scanningApp.$$('#scanButton'));
statusText = /** @type {!Element} */ (scanningApp.$$('#statusText'));
helperText = /** @type {!Element} */ (
scanningApp.$$('#scanPreview').$$('#helperText'));
statusText =
/** @type {!HTMLElement} */ (scanningApp.$$('#statusText'));
helperText = scanningApp.$$('#scanPreview').$$('#helperText');
scanProgress = scanningApp.$$('#scanPreview').$$('#scanProgress');
progressText = /** @type {!Element} */ (
scanningApp.$$('#scanPreview').$$('#progressText'));
progressText = scanningApp.$$('#scanPreview').$$('#progressText');
progressBar = scanningApp.$$('#scanPreview').$$('paper-progress');
return fakeScanService_.whenCalled('getScannerCapabilities');
})
......@@ -357,8 +366,10 @@ export function scanningAppTest() {
assertFalse(resolutionSelect.disabled);
assertFalse(scanButton.disabled);
assertEquals('', statusText.textContent.trim());
assertFalse(helperText.hidden);
assertTrue(scanProgress.hidden);
assertTrue(isVisible(helperText));
assertFalse(isVisible(scanProgress));
assertFalse(isVisible(
/** @type {!HTMLElement} */ (scanningApp.$$('#fileSaved'))));
// Click the Scan button and wait till the scan is started.
scanButton.click();
......@@ -376,8 +387,10 @@ export function scanningAppTest() {
assertTrue(pageSizeSelect.disabled);
assertTrue(resolutionSelect.disabled);
assertTrue(scanButton.disabled);
assertTrue(helperText.hidden);
assertFalse(scanProgress.hidden);
assertFalse(isVisible(helperText));
assertTrue(isVisible(scanProgress));
assertFalse(isVisible(
/** @type {!HTMLElement} */ (scanningApp.$$('#fileSaved'))));
assertEquals('Scanning page 1', progressText.textContent.trim());
assertEquals(0, progressBar.value);
......@@ -412,10 +425,19 @@ export function scanningAppTest() {
// Complete the scan.
return fakeScanService_.simulateScanComplete(true);
})
.then(() => {
assertTrue(isVisible(
/** @type {!HTMLElement} */ (scanningApp.$$('#fileSaved'))));
assertEquals(
'Scanned files saved!',
scanningApp.$$('#fileSaved').textContent.trim());
// Click the Done button to return to READY state.
return clickDoneButton();
})
.then(() => {
// After scanning is complete, the settings and scan button should be
// enabled, and the scan status should indicate that scanning is
// complete. The progress bar and text should no longer be visible.
// enabled. The progress bar and text should no longer be visible.
assertFalse(scannerSelect.disabled);
assertFalse(sourceSelect.disabled);
assertFalse(fileTypeSelect.disabled);
......@@ -423,11 +445,10 @@ export function scanningAppTest() {
assertFalse(pageSizeSelect.disabled);
assertFalse(resolutionSelect.disabled);
assertFalse(scanButton.disabled);
assertEquals(
'Scan complete! File(s) saved to /home/chronos/user/MyFiles.',
statusText.textContent.trim());
assertFalse(helperText.hidden);
assertTrue(scanProgress.hidden);
assertTrue(isVisible(helperText));
assertFalse(isVisible(scanProgress));
assertFalse(isVisible(
/** @type {!HTMLElement} */ (scanningApp.$$('#fileSaved'))));
});
});
......
......@@ -561,6 +561,15 @@ Try tapping the mic to ask me anything.
<message name="IDS_SCANNING_APP_SCAN_PREVIEW_PROGRESS_TEXT" desc="The text displayed in the scan preview to indicate which page is currently being scanned.">
Scanning page <ph name="PAGE_NUMBER">$1<ex>4</ex></ph>
</message>
<message name="IDS_SCANNING_APP_FILE_SAVED_TEXT" desc="The text displayed in the Scanning App when a scan job is completed and the file is saved.">
Scanned file saved!
</message>
<message name="IDS_SCANNING_APP_FILE_SAVED_TEXT_PLURAL" desc="The text displayed in the Scanning App when a scan job is completed and the files are saved.">
Scanned files saved!
</message>
<message name="IDS_SCANNING_APP_DONE_BUTTON_TEXT" desc="The text displayed for the button the user clicks to return to the intial Scanning App page after a scan job is completed.">
Done
</message>
<!-- Diagnostics App -->
<!-- TODO(michaelcheco): Update with finalized copies of the strings -->
......
1b72df590aaf1b6626e97203cc15a8bd8defb5d0
\ No newline at end of file
9c675fc4da82d9b94a2907160131715287febddf
\ No newline at end of file
a7a1499711de836527f96f80f5a0fba609bd3637
\ No newline at end of file
......@@ -27,6 +27,12 @@ js_type_check("closure_compile_module") {
]
}
js_library("icons") {
deps = [
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
]
}
js_library("color_mode_select") {
deps = [
":scanning_app_util",
......@@ -101,6 +107,7 @@ js_library("scanning_app") {
deps = [
":color_mode_select",
":file_type_select",
":icons",
":mojo_interface_provider",
":page_size_select",
":resolution_select",
......@@ -150,6 +157,7 @@ html_to_js("web_components") {
js_files = [
"color_mode_select.js",
"file_type_select.js",
"icons.js",
"page_size_select.js",
"resolution_select.js",
"scan_preview.js",
......
<iron-iconset-svg name="scanning">
<svg>
<defs>
<g id="check-mark" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" width="20" height="20" viewBox="0 0 20 20">
<path fill="#1A73E8" d="M8,16 C12.4183,16 16,12.4183 16,8 C16,3.58172 12.4183,0 8,0 C3.58172,0 0,3.58172 0,8 C0,12.4183 3.58172,16 8,16 Z M8,14 C11.3137,14 14,11.3137 14,8 C14,4.68629 11.3137,2 8,2 C4.68629,2 2,4.68629 2,8 C2,11.3137 4.68629,14 8,14 Z"></path>
<polygon fill="#1A73E8" fill-rule="nonzero" points="11.3310353 4.75670585 12.6689647 6.24329415 6.96376255 11.3779761 3.79289322 8.20710678 5.20710678 6.79289322 7.036 8.621"></polygon>
</g>
</defs>
</svg>
</iron-iconset-svg>
// Copyright 2020 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.
import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
const template = html`{__html_template__}`;
document.head.appendChild(template.content);
......@@ -58,7 +58,8 @@ Polymer({
* @private
*/
shouldHideHelperText_() {
return this.appState === AppState.SCANNING;
return this.appState === AppState.SCANNING ||
this.appState === AppState.DONE;
},
/**
......
<style include="cr-shared-style scanning-shared scanning-fonts">
#appTitle {
.title {
@apply --scanning-section-title-font;
color: var(--scanning-section-title-text-color);
}
#checkMarkIcon {
margin-inline-end: 12px;
min-width: 24px;
padding-bottom: 2px;
}
#fileSaved {
display: inline-block;
}
#moreSettingsButton {
--ink-color: var(--menu-text-color);
--paper-ripple-opacity: 0;
......@@ -75,6 +85,12 @@
justify-content: flex-end;
width: 289px;
}
.done-button-container {
display: flex;
justify-content: flex-end;
width: 280px;
}
</style>
<div id="scanningContainer">
<div class="panel-container">
......@@ -84,6 +100,7 @@
progress-percent="[[progressPercent_]]"></scan-preview>
</div>
<div class="right-panel">
<template is="dom-if" if="[[!shouldShowDonePage_(appState_)]]">
<h1 id="appTitle">[[i18n('appTitle')]]</h1>
<scanner-select id="scannerSelect" scanners="[[scanners_]]"
loaded="[[areScannersLoaded_(appState_)]]"
......@@ -131,5 +148,19 @@
</cr-button>
</div>
<p id="statusText">[[statusText_]]</p>
</template>
<template is="dom-if" if="[[shouldShowDonePage_(appState_)]]">
<iron-icon id="checkMarkIcon" icon="scanning:check-mark"></iron-icon>
<h1 id="fileSaved" class="title">
[[getFileSavedText_(pageNumber_)]]
</h1>
<div class="done-button-container">
<cr-button id="doneButton" class="action-button"
on-click="onDoneClick_">
[[i18n('doneButtonText')]]
</cr-button>
</div>
</template>
</div>
</div>
</div>
......@@ -12,6 +12,7 @@ import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import './file_path.mojom-lite.js';
import './color_mode_select.js';
import './file_type_select.js';
import './icons.js';
import './page_size_select.js';
import './resolution_select.js';
import './scan_preview.js';
......@@ -194,9 +195,12 @@ Polymer({
* @param {boolean} success
*/
onScanComplete(success) {
this.statusText_ = success ?
'Scan complete! File(s) saved to ' + this.selectedFilePath + '.' :
'Scan failed.';
if (success) {
this.setAppState_(AppState.DONE);
return;
}
this.statusText_ = 'Scan failed.';
this.setAppState_(AppState.READY);
},
......@@ -324,6 +328,11 @@ Polymer({
});
},
/** @private */
onDoneClick_() {
this.setAppState_(AppState.READY);
},
/**
* @param {!{success: boolean}} response
* @private
......@@ -341,7 +350,7 @@ Polymer({
/** @private */
toggleClicked_() {
this.$.collapse.toggle();
this.$$('#collapse').toggle();
},
/**
......@@ -374,6 +383,24 @@ Polymer({
return this.appState_ !== AppState.READY;
},
/**
* @return {boolean}
* @private
*/
shouldShowDonePage_() {
return this.appState_ === AppState.DONE;
},
/**
* @return {string}
* @private
*/
getFileSavedText_() {
const fileSavedText =
this.pageNumber_ > 1 ? 'fileSavedTextPlural' : 'fileSavedText';
return this.i18n(fileSavedText);
},
/**
* Sets the app state if the state transition is allowed.
* @param {!AppState} newState
......@@ -395,11 +422,15 @@ Polymer({
case (AppState.READY):
assert(
this.appState_ === AppState.GETTING_CAPS ||
this.appState_ === AppState.SCANNING);
this.appState_ === AppState.SCANNING ||
this.appState_ === AppState.DONE);
break;
case (AppState.SCANNING):
assert(this.appState_ === AppState.READY);
break;
case (AppState.DONE):
assert(this.appState_ === AppState.SCANNING);
break;
}
this.appState_ = newState;
......
......@@ -37,6 +37,7 @@
<include name="IDR_SCANNING_APP_SCANNING_FONTS_CSS_JS" file="${root_gen_dir}/chromeos/components/scanning/resources/scanning_fonts_css.js" use_base_dir="false" type="BINDATA"/>
<include name="IDR_SCANNING_APP_SCAN_PREVIEW_HTML" file="scan_preview.html" type="BINDATA"/>
<include name="IDR_SCANNING_APP_SCAN_PREVIEW_JS" file="${root_gen_dir}/chromeos/components/scanning/resources/scan_preview.js" use_base_dir="false" type="BINDATA"/>
<include name="IDR_SCANNING_APP_ICONS_JS" file="${root_gen_dir}/chromeos/components/scanning/resources/icons.js" use_base_dir="false" type="BINDATA"/>
<include name="IDR_SCANNING_APP_ICON_16" file="scanning_app_icon_16.png" type="BINDATA" />
<include name="IDR_SCANNING_APP_ICON_32" file="scanning_app_icon_32.png" type="BINDATA" />
<include name="IDR_SCANNING_APP_ICON_48" file="scanning_app_icon_48.png" type="BINDATA" />
......
......@@ -12,6 +12,7 @@ export const AppState = {
GETTING_CAPS: 2,
READY: 3,
SCANNING: 4,
DONE: 5,
};
/**
......
......@@ -58,10 +58,13 @@ void AddScanningAppStrings(content::WebUIDataSource* html_source) {
{"colorModeDropdownLabel", IDS_SCANNING_APP_COLOR_MODE_DROPDOWN_LABEL},
{"colorOptionText", IDS_SCANNING_APP_COLOR_OPTION_TEXT},
{"defaultSourceOptionText", IDS_SCANNING_APP_DEFAULT_SOURCE_OPTION_TEXT},
{"flatbedOptionText", IDS_SCANNING_APP_FLATBED_OPTION_TEXT},
{"doneButtonText", IDS_SCANNING_APP_DONE_BUTTON_TEXT},
{"fileSavedText", IDS_SCANNING_APP_FILE_SAVED_TEXT},
{"fileSavedTextPlural", IDS_SCANNING_APP_FILE_SAVED_TEXT_PLURAL},
{"fileTypeDropdownLabel", IDS_SCANNING_APP_FILE_TYPE_DROPDOWN_LABEL},
{"fitToScanAreaOptionText",
IDS_SCANNING_APP_FIT_TO_SCAN_AREA_OPTION_TEXT},
{"flatbedOptionText", IDS_SCANNING_APP_FLATBED_OPTION_TEXT},
{"grayscaleOptionText", IDS_SCANNING_APP_GRAYSCALE_OPTION_TEXT},
{"jpgOptionText", IDS_SCANNING_APP_JPG_OPTION_TEXT},
{"letterOptionText", IDS_SCANNING_APP_LETTER_OPTION_TEXT},
......
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