scanner: Add try again link to action container error view.
It is never shown for now. The actual try again functionality will be added in a followup. Bug: b:378582420 Change-Id: I9c78ca07f02d2e28c55e5798776cdb4fb4ae4980 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6210899 Reviewed-by: Ahmed Fakhry <afakhry@chromium.org> Reviewed-by: Elijah Hewer <hewer@chromium.org> Commit-Queue: Michelle Chen <michellegc@google.com> Cr-Commit-Position: refs/heads/main@{#1413344}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
128a7e96f1
commit
7a8f2aa750
@ -6877,6 +6877,9 @@ Here are some things you can try to get started.
|
||||
<message name="IDS_ASH_SCANNER_ACTION_FAILURE_TOAST_COPY_TEXT_AND_FORMAT" desc="The message shown on a toast to indicate an error occurred when trying to copy text with formatting from the contents of a screenshot.">
|
||||
Couldn’t copy with formatting
|
||||
</message>
|
||||
<message name="IDS_ASH_SCANNER_ERROR_TRY_AGAIN_LINK_TEXT" desc="The text on a try again link shown next to an error message indicating that something went wrong. The link can be pressed to try the action again.">
|
||||
Try again
|
||||
</message>
|
||||
|
||||
<!-- Snap Group -->
|
||||
<message name="IDS_ASH_SNAP_GROUP_CLICK_TO_LOCK_WINDOWS" desc="Click to lock the windows.">
|
||||
|
@ -0,0 +1 @@
|
||||
0ea17fcbfdc379da42c64544320115bd4c6ce3dd
|
@ -13,12 +13,15 @@
|
||||
#include "ash/capture_mode/action_button_view.h"
|
||||
#include "ash/capture_mode/capture_mode_types.h"
|
||||
#include "ash/capture_mode/capture_mode_util.h"
|
||||
#include "ash/strings/grit/ash_strings.h"
|
||||
#include "ash/style/system_shadow.h"
|
||||
#include "ash/style/typography.h"
|
||||
#include "base/check.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/functional/callback.h"
|
||||
#include "base/time/time.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/metadata/metadata_impl_macros.h"
|
||||
#include "ui/base/models/image_model.h"
|
||||
#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
|
||||
@ -35,6 +38,7 @@
|
||||
#include "ui/views/controls/button/button.h"
|
||||
#include "ui/views/controls/image_view.h"
|
||||
#include "ui/views/controls/label.h"
|
||||
#include "ui/views/controls/link.h"
|
||||
#include "ui/views/layout/box_layout.h"
|
||||
#include "ui/views/layout/box_layout_view.h"
|
||||
#include "ui/views/vector_icons.h"
|
||||
@ -60,6 +64,9 @@ constexpr int kErrorViewLeadingIconSize = 20;
|
||||
// from the error message label.
|
||||
constexpr auto kErrorViewLeadingIconRightPadding = 4;
|
||||
|
||||
// Padding around the try again link in the error view.
|
||||
constexpr auto kErrorViewTryAgainLinkPadding = gfx::Insets::TLBR(0, 8, 0, 4);
|
||||
|
||||
// The horizontal distance between action buttons in a row.
|
||||
constexpr int kActionButtonSpacing = 10;
|
||||
|
||||
@ -113,6 +120,21 @@ ActionButtonContainerView::ErrorView::ErrorView()
|
||||
.SetFontList(TypographyProvider::Get()->ResolveTypographyToken(
|
||||
TypographyToken::kCrosAnnotation1))
|
||||
.Build());
|
||||
|
||||
// TODO(crbug.com/388451361): Implement keyboard navigation for the try again
|
||||
// link.
|
||||
AddChildView(
|
||||
views::Builder<views::Link>()
|
||||
.CopyAddressTo(&try_again_link_)
|
||||
.SetText(l10n_util::GetStringUTF16(
|
||||
IDS_ASH_SCANNER_ERROR_TRY_AGAIN_LINK_TEXT))
|
||||
.SetFontList(TypographyProvider::Get()->ResolveTypographyToken(
|
||||
TypographyToken::kCrosButton2))
|
||||
.SetEnabledColorId(cros_tokens::kCrosSysPrimary)
|
||||
.SetForceUnderline(false)
|
||||
.SetProperty(views::kMarginsKey, kErrorViewTryAgainLinkPadding)
|
||||
.SetVisible(false)
|
||||
.Build());
|
||||
}
|
||||
|
||||
ActionButtonContainerView::ErrorView::~ErrorView() = default;
|
||||
@ -143,6 +165,12 @@ void ActionButtonContainerView::ErrorView::SetErrorMessage(
|
||||
error_label_->SetText(error_message);
|
||||
}
|
||||
|
||||
void ActionButtonContainerView::ErrorView::SetTryAgainCallback(
|
||||
base::RepeatingClosure try_again_callback) {
|
||||
try_again_link_->SetVisible(!try_again_callback.is_null());
|
||||
try_again_link_->SetCallback(std::move(try_again_callback));
|
||||
}
|
||||
|
||||
const std::u16string&
|
||||
ActionButtonContainerView::ErrorView::GetErrorMessageForTesting() const {
|
||||
return error_label_->GetText();
|
||||
@ -223,8 +251,10 @@ const views::View::Views& ActionButtonContainerView::GetActionButtons() const {
|
||||
}
|
||||
|
||||
void ActionButtonContainerView::ShowErrorView(
|
||||
const std::u16string& error_message) {
|
||||
const std::u16string& error_message,
|
||||
base::RepeatingClosure try_again_callback) {
|
||||
error_view_->SetErrorMessage(error_message);
|
||||
error_view_->SetTryAgainCallback(std::move(try_again_callback));
|
||||
error_view_->SetVisible(true);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "ash/ash_export.h"
|
||||
#include "ash/capture_mode/capture_mode_types.h"
|
||||
#include "base/functional/callback_forward.h"
|
||||
#include "base/functional/callback_helpers.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "ui/base/metadata/metadata_header_macros.h"
|
||||
@ -23,6 +25,7 @@ struct VectorIcon;
|
||||
|
||||
namespace views {
|
||||
class Label;
|
||||
class Link;
|
||||
}
|
||||
|
||||
namespace ash {
|
||||
@ -36,7 +39,8 @@ class ASH_EXPORT ActionButtonContainerView : public views::View {
|
||||
METADATA_HEADER(ActionButtonContainerView, views::View)
|
||||
|
||||
public:
|
||||
// A view that displays an error message and icon.
|
||||
// A view that displays an error message and icon. It may optionally also show
|
||||
// a try again link.
|
||||
class ASH_EXPORT ErrorView : public views::BoxLayoutView {
|
||||
METADATA_HEADER(ErrorView, views::BoxLayoutView)
|
||||
|
||||
@ -53,12 +57,20 @@ class ASH_EXPORT ActionButtonContainerView : public views::View {
|
||||
// Sets the error message to show on the error view.
|
||||
void SetErrorMessage(const std::u16string& error_message);
|
||||
|
||||
// Sets the callback to run when the try again link is pressed. Note that
|
||||
// the try again link is only shown if `try_again_callback` is not null.
|
||||
void SetTryAgainCallback(base::RepeatingClosure try_again_callback);
|
||||
|
||||
views::Link* try_again_link_for_testing() { return try_again_link_; }
|
||||
|
||||
const std::u16string& GetErrorMessageForTesting() const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<SystemShadow> shadow_;
|
||||
|
||||
raw_ptr<views::Label> error_label_ = nullptr;
|
||||
|
||||
raw_ptr<views::Link> try_again_link_ = nullptr;
|
||||
};
|
||||
|
||||
ActionButtonContainerView();
|
||||
@ -83,8 +95,12 @@ class ASH_EXPORT ActionButtonContainerView : public views::View {
|
||||
// Returns the action buttons in this container.
|
||||
const views::View::Views& GetActionButtons() const;
|
||||
|
||||
// Shows an error view with the given `error_message`.
|
||||
void ShowErrorView(const std::u16string& error_message);
|
||||
// Shows an error view with the given `error_message`. If `try_again_callback`
|
||||
// is not null, then the error view will also show a try again link that runs
|
||||
// `try_again_callback` when pressed.
|
||||
void ShowErrorView(
|
||||
const std::u16string& error_message,
|
||||
base::RepeatingClosure try_again_callback = base::NullCallback());
|
||||
|
||||
// Hides the error view.
|
||||
void HideErrorView();
|
||||
@ -95,7 +111,7 @@ class ASH_EXPORT ActionButtonContainerView : public views::View {
|
||||
// copy text and search buttons.
|
||||
void StartSmartActionsButtonTransition();
|
||||
|
||||
const ErrorView* error_view_for_testing() const { return error_view_; }
|
||||
ErrorView* error_view_for_testing() { return error_view_; }
|
||||
|
||||
private:
|
||||
// Called when the smart actions button has faded out, to start the transition
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "ui/events/test/event_generator.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/views/controls/label.h"
|
||||
#include "ui/views/controls/link.h"
|
||||
#include "ui/views/test/views_test_base.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/widget/widget_utils.h"
|
||||
@ -126,7 +127,7 @@ TEST_F(ActionButtonContainerViewTest, SmartActionsButtonTransition) {
|
||||
|
||||
TEST_F(ActionButtonContainerViewTest, ShowsErrorView) {
|
||||
ActionButtonContainerView action_button_container;
|
||||
const ActionButtonContainerView::ErrorView* error_view =
|
||||
ActionButtonContainerView::ErrorView* error_view =
|
||||
action_button_container.error_view_for_testing();
|
||||
|
||||
EXPECT_FALSE(error_view->GetVisible());
|
||||
@ -135,11 +136,40 @@ TEST_F(ActionButtonContainerViewTest, ShowsErrorView) {
|
||||
|
||||
EXPECT_TRUE(error_view->GetVisible());
|
||||
EXPECT_EQ(error_view->GetErrorMessageForTesting(), u"Error message");
|
||||
EXPECT_FALSE(error_view->try_again_link_for_testing()->GetVisible());
|
||||
|
||||
action_button_container.HideErrorView();
|
||||
|
||||
EXPECT_FALSE(error_view->GetVisible());
|
||||
}
|
||||
|
||||
TEST_F(ActionButtonContainerViewTest, ShowsErrorViewWithTryAgainLink) {
|
||||
std::unique_ptr<views::Widget> widget =
|
||||
CreateTestWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET);
|
||||
widget->SetBounds(gfx::Rect(50, 50, 300, 200));
|
||||
widget->Show();
|
||||
auto* action_button_container =
|
||||
widget->SetContentsView(std::make_unique<ActionButtonContainerView>());
|
||||
base::test::TestFuture<void> try_again_future;
|
||||
|
||||
action_button_container->ShowErrorView(
|
||||
u"Error message", try_again_future.GetRepeatingCallback());
|
||||
|
||||
ActionButtonContainerView::ErrorView* error_view =
|
||||
action_button_container->error_view_for_testing();
|
||||
EXPECT_TRUE(error_view->GetVisible());
|
||||
views::Link* try_again_link = error_view->try_again_link_for_testing();
|
||||
EXPECT_TRUE(try_again_link->GetVisible());
|
||||
|
||||
// Check that clicking the try again link runs the try again callback.
|
||||
ViewDrawnWaiter().Wait(try_again_link);
|
||||
ui::test::EventGenerator event_generator(GetRootWindow(widget.get()));
|
||||
event_generator.MoveMouseTo(
|
||||
try_again_link->GetBoundsInScreen().CenterPoint());
|
||||
event_generator.ClickLeftButton();
|
||||
|
||||
EXPECT_TRUE(try_again_future.Wait());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace ash
|
||||
|
Reference in New Issue
Block a user