Commit 41bf0bf3 authored by Shik Chen's avatar Shik Chen Committed by Chromium LUCI CQ

CCA: Show url chip from barcode

Bug: b/172879638
Test: Manually in expert mode

Change-Id: I382cd06c1c9fb06a80c82d783d3ca023a3e82542
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2570837
Auto-Submit: Shik Chen <shik@chromium.org>
Commit-Queue: Wei Lee <wtlee@chromium.org>
Reviewed-by: default avatarWei Lee <wtlee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#834571}
parent b93ba372
......@@ -75,6 +75,7 @@ copy("chrome_camera_app_js") {
"js/async_job_queue.js",
"js/background.js",
"js/background_ops.js",
"js/barcode_chip.js",
"js/chrome_util.js",
"js/dom.js",
"js/dynamic_import.js",
......
......@@ -20,6 +20,7 @@
<structure name="IDR_CAMERA_BACKGROUND_JS" file="js/background.js" type="chrome_html" />
<structure name="IDR_CAMERA_BACKGROUND_OPS_JS" file="js/background_ops.js" type="chrome_html" />
<structure name="IDR_CAMERA_BARCODE_JS" file="js/models/barcode.js" type="chrome_html" />
<structure name="IDR_CAMERA_BARCODE_CHIP_JS" file="js/barcode_chip.js" type="chrome_html" />
<structure name="IDR_CAMERA_BARCODE_WORKER_JS" file="js/models/barcode_worker.js" type="chrome_html" />
<structure name="IDR_CAMERA_BARCODE_WORKER_INTERFACE_JS" file="js/models/barcode_worker_interface.js" type="chrome_html" />
<structure name="IDR_CAMERA_BROWSER_PROXY_INTERFACE_JS" file="js/browser_proxy/browser_proxy_interface.js" type="chrome_html" />
......@@ -154,49 +155,51 @@
<include name="IDR_CAMERA_TICK_FINAL_OGG" file="sounds/tick_final.ogg" type="BINDATA" />
<include name="IDR_CAMERA_TICK_INC_OGG" file="sounds/tick_inc.ogg" type="BINDATA" />
<include name="IDR_CAMERA_TICK_START_OGG" file="sounds/tick_start.ogg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_MODE_SQUARE_SVG" file="images/camera_mode_square.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_BUTTON_BACK_SVG" file="images/settings_button_back.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_MODE_PORTRAIT_SVG" file="images/camera_mode_portrait.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_TIMER_ON_3S_SVG" file="images/camera_button_timer_on_3s.svg" type="BINDATA" />
<include name="IDR_CAMERA_SPINNER_SVG" file="images/spinner.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_GRID_OFF_SVG" file="images/camera_button_grid_off.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_MIC_ON_SVG" file="images/camera_button_mic_on.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_MODE_VIDEO_SVG" file="images/camera_mode_video.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_PHOTO_STOP_SVG" file="images/camera_shutter_photo_stop.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_MIC_OFF_SVG" file="images/camera_button_mic_off.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_EXPERT_SVG" file="images/settings_expert.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_RESOLUTION_SVG" file="images/settings_resolution.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_APP_ICONS_48_PNG" file="images/camera_app_icons_48.png" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_TIMER_OFF_SVG" file="images/camera_button_timer_off.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_PHOTO_START_ACTIVE_SVG" file="images/camera_shutter_photo_start_active.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_APP_ICONS_128_PNG" file="images/camera_app_icons_128.png" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_APP_ICONS_192_PNG" file="images/camera_app_icons_192.png" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_TIMER_DURATION_SVG" file="images/settings_timer_duration.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_HELP_SVG" file="images/settings_help.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_MIRROR_ON_SVG" file="images/camera_button_mirror_on.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_BUTTON_EXPAND_SVG" file="images/settings_button_expand.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_APP_ICONS_48_PNG" file="images/camera_app_icons_48.png" type="BINDATA" />
<include name="IDR_CAMERA_BARCODE_URL_SVG" file="images/barcode_url.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_FPS_30_SVG" file="images/camera_button_fps_30.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_FPS_60_SVG" file="images/camera_button_fps_60.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_GRID_OFF_SVG" file="images/camera_button_grid_off.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_GRID_ON_SVG" file="images/camera_button_grid_on.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_SWITCH_DEVICE_SVG" file="images/camera_button_switch_device.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_PHOTO_STOP_HOVER_SVG" file="images/camera_shutter_photo_stop_hover.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_GRID_TYPE_SVG" file="images/settings_grid_type.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_MIC_OFF_SVG" file="images/camera_button_mic_off.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_MIC_ON_SVG" file="images/camera_button_mic_on.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_MIRROR_OFF_SVG" file="images/camera_button_mirror_off.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_PHOTO_START_SVG" file="images/camera_shutter_photo_start.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_MIRROR_ON_SVG" file="images/camera_button_mirror_on.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_SETTINGS_SVG" file="images/camera_button_settings.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_SWITCH_DEVICE_SVG" file="images/camera_button_switch_device.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_SWITCH_PHOTO_SVG" file="images/camera_button_switch_photo.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_FEEDBACK_SVG" file="images/settings_feedback.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_SWITCH_VIDEO_SVG" file="images/camera_button_switch_video.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_PHOTO_START_HOVER_SVG" file="images/camera_shutter_photo_start_hover.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_VIDEO_PAUSE_SVG" file="images/camera_shutter_video_pause.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_TIMER_OFF_SVG" file="images/camera_button_timer_off.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_TIMER_ON_10S_SVG" file="images/camera_button_timer_on_10s.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_MODE_PHOTO_SVG" file="images/camera_mode_photo.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_TIMER_ON_3S_SVG" file="images/camera_button_timer_on_3s.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_FOCUS_AIM_SVG" file="images/camera_focus_aim.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_SETTINGS_SVG" file="images/camera_button_settings.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_INTENT_PLAY_VIDEO_SVG" file="images/camera_intent_play_video.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_FPS_30_SVG" file="images/camera_button_fps_30.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_FPS_60_SVG" file="images/camera_button_fps_60.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_INTENT_RESULT_CANCEL_SVG" file="images/camera_intent_result_cancel.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_INTENT_RESULT_CONFIRM_SVG" file="images/camera_intent_result_confirm.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_INTRO_BANNER_ICON_SVG" file="images/camera_intro_banner_icon.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_INTRO_BANNER_CLOSE_SVG" file="images/camera_intro_banner_close.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_INTRO_BANNER_ICON_SVG" file="images/camera_intro_banner_icon.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_MODE_PHOTO_SVG" file="images/camera_mode_photo.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_MODE_PORTRAIT_SVG" file="images/camera_mode_portrait.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_MODE_SQUARE_SVG" file="images/camera_mode_square.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_MODE_VIDEO_SVG" file="images/camera_mode_video.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_PHOTO_START_ACTIVE_SVG" file="images/camera_shutter_photo_start_active.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_PHOTO_START_HOVER_SVG" file="images/camera_shutter_photo_start_hover.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_PHOTO_START_SVG" file="images/camera_shutter_photo_start.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_PHOTO_STOP_HOVER_SVG" file="images/camera_shutter_photo_stop_hover.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_PHOTO_STOP_SVG" file="images/camera_shutter_photo_stop.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_VIDEO_PAUSE_SVG" file="images/camera_shutter_video_pause.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_BUTTON_BACK_SVG" file="images/settings_button_back.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_BUTTON_EXPAND_SVG" file="images/settings_button_expand.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_EXPERT_SVG" file="images/settings_expert.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_FEEDBACK_SVG" file="images/settings_feedback.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_GRID_TYPE_SVG" file="images/settings_grid_type.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_HELP_SVG" file="images/settings_help.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_RESOLUTION_SVG" file="images/settings_resolution.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_TIMER_DURATION_SVG" file="images/settings_timer_duration.svg" type="BINDATA" />
<include name="IDR_CAMERA_SPINNER_SVG" file="images/spinner.svg" type="BINDATA" />
</includes>
</release>
</grit>
......@@ -1498,3 +1498,65 @@ body.tab-navigation .dialog-buttons button:focus::after {
body:not(.mode-switching):not(.streaming):not(.review-result) #spinner {
visibility: visible;
}
.barcode-chip-container {
opacity: 0;
visibility: hidden;
}
/* TODO(b/172879638): Tune the animation according to the final motion spec. */
.barcode-chip-container.animate {
animation: 8s show-barcode-chip ease-out;
visibility: visible;
}
@keyframes show-barcode-chip {
0% {
opacity: 0;
}
3%,
97% {
opacity: 1;
}
100% {
opacity: 0;
}
}
/* TODO(b/172879638): Tune the position and layout after we finalized the
* responsive window design. */
.barcode-chip-url {
align-items: center;
background: rgb(32, 33, 36);
border-radius: 16px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 4px 8px rgba(0, 0, 0, 0.15);
box-sizing: border-box;
display: flex;
font: 400 15px Roboto;
height: 32px;
left: 50%;
padding: 8px;
position: absolute;
top: 15%;
transform: translate(-50%, -50%);
z-index: 50;
}
.barcode-chip-url::before {
background: url(/images/barcode_url.svg) no-repeat;
content: '';
display: inline-block;
height: 20px;
margin-inline-end: 6px;
vertical-align: middle;
width: 20px;
}
.barcode-chip-url > a {
color: rgb(138, 180, 248);
max-width: 416px;
overflow: hidden;
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
}
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 3C6.136 3 3 6.136 3 10C3 13.864 6.136 17 10 17C13.864 17 17 13.864 17 10C17 6.136 13.864 3 10 3ZM4.4 10C4.4 9.573 4.456 9.153 4.547 8.754L7.893 12.1V12.8C7.893 13.57 8.523 14.2 9.293 14.2V15.551C6.542 15.201 4.4 12.849 4.4 10ZM12.793 12.8C13.423 12.8 13.941 13.213 14.123 13.78C15.033 12.786 15.6 11.456 15.6 10C15.6 7.655 14.144 5.639 12.093 4.813V5.1C12.093 5.87 11.463 6.5 10.693 6.5H9.293V7.9C9.293 8.285 8.978 8.6 8.593 8.6H7.193V10H11.393C11.778 10 12.093 10.315 12.093 10.7V12.8H12.793Z" fill="#8BB5F9"/>
</svg>
......@@ -3,6 +3,7 @@
# found in the LICENSE file.
in_app_assets = [
"barcode_url.svg",
"camera_button_fps_30.svg",
"camera_button_fps_60.svg",
"camera_button_grid_off.svg",
......
......@@ -55,6 +55,7 @@ js_library("compile_resources") {
"async_job_queue.js",
"background.js",
"background_ops.js",
"barcode_chip.js",
"browser_proxy/browser_proxy.js",
"browser_proxy/browser_proxy_interface.js",
"browser_proxy/webui_browser_proxy.js",
......
// 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 * as dom from './dom.js';
import * as toast from './toast.js';
import * as util from './util.js';
/**
* Checks whether a string is a regular url link with http or https protocol.
* @param {string} s
* @return {boolean}
*/
function isSafeUrl(s) {
try {
const url = new URL(s);
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
console.warn('Reject url with protocol:', url.protocol);
return false;
}
return true;
} catch (e) {
return false;
}
}
/**
* Shows an actionable url chip.
* @param {string} url
*/
function showUrl(url) {
const el = dom.get('.barcode-chip-container', HTMLDivElement);
const anchor = dom.getFrom(el, 'a', HTMLAnchorElement);
Object.assign(anchor, {
href: url,
textContent: url,
});
// TODO(b/172879638): Handle a11y.
util.animateOnce(el);
// TODO(b/172879638): Show copy button.
}
/**
* Shows an actionable text chip.
* @param {string} text
*/
function showText(text) {
// TODO(b/172879638): Show text properly.
toast.showDebugMessage(text);
}
/**
* Shows an actionable chip for the string detected from a barcode.
* @param {string} s
*/
export function show(s) {
if (isSafeUrl(s)) {
showUrl(s);
} else {
showText(s);
}
}
......@@ -63,6 +63,7 @@ export class BarcodeScanner {
if (this.intervalId_ !== null) {
return;
}
// TODO(b/172879638): Move |prevCode| related logic to barcode_chip.js.
let prevCode = null;
this.intervalId_ = setAsyncInterval(async () => {
const code = await this.scan_();
......
......@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as barcodeChip from '../../barcode_chip.js';
import {browserProxy} from '../../browser_proxy/browser_proxy.js';
import * as dom from '../../dom.js';
import {BarcodeScanner} from '../../models/barcode.js';
import {DeviceOperator, parseMetadata} from '../../mojo/device_operator.js';
import * as nav from '../../nav.js';
import * as state from '../../state.js';
import * as toast from '../../toast.js';
import * as util from '../../util.js';
import {windowController} from '../../window_controller/window_controller.js';
......@@ -162,9 +162,8 @@ export class Preview {
this.onNewStreamNeeded_();
}
}, 100);
this.scanner_ = new BarcodeScanner(this.video_, (code) => {
// TODO(b/172879638): Show this with a actionable toast.
toast.showDebugMessage(code);
this.scanner_ = new BarcodeScanner(this.video_, (value) => {
barcodeChip.show(value);
});
this.updateScanBarcode_();
this.updateShowMetadata_();
......@@ -213,6 +212,7 @@ export class Preview {
if (this.scanner_ === null) {
return;
}
// TODO(b/172879638): Only enables barcode scanning in Photo mode.
if (state.get(state.State.EXPERT) && state.get(state.State.SCAN_BARCODE)) {
this.scanner_.start();
} else {
......
......@@ -400,6 +400,11 @@
</div>
</div>
<div class="centered-overlay" id="toast" aria-live="polite"></div>
<div class="barcode-chip-container">
<div class="barcode-chip-url">
<a target="_blank"></a>
</div>
</div>
<div id="tooltip" aria-hidden="true"></div>
<audio id="sound-tick-final" src="/sounds/tick_final.ogg"
data-timeout="1000">
......
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