0

[image search] Update the layout of single image info container

With the new layout spec, we are not showing the title of the metadata,
e.g. "Last Modified", in the info container. The image size and the
file type is also removed. Details are listed in the spec posted in
the issue.

Bug: b:309902131
Change-Id: Ic01f4a0f0bfcc9a5b60623f3e8877edb3a1cd74d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5029801
Reviewed-by: Toni Barzic <tbarzic@chromium.org>
Commit-Queue: Wen-Chien Wang <wcwang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1225746}
This commit is contained in:
Wen-Chien Wang
2023-11-16 22:04:21 +00:00
committed by Chromium LUCI CQ
parent ecb652144b
commit 7544b03ca5
12 changed files with 63 additions and 112 deletions

@ -65,10 +65,9 @@ ash::FileMetadata MetadataLoaderForTest() {
EXPECT_TRUE(base::Time::FromString("23 Dec 2021 09:01:00", &last_modified));
metadata.file_info.last_modified = last_modified;
metadata.file_info.size = 20 * 1024.0; // 20.0 KB
metadata.mime_type = "image/jpeg";
metadata.file_path = base::FilePath("full file path");
metadata.virtual_path = base::FilePath("virtual file path");
metadata.file_name = base::FilePath("file name");
metadata.displayable_folder_path = base::FilePath("displayable folder");
return metadata;
}
@ -408,12 +407,11 @@ TEST_P(SearchResultImageViewTest, OneResultShowsImageInfo) {
// the narrowed space \x202F is used in formatting the time of the day.
const std::vector<views::Label*>& content_labels =
image_list_view->metadata_content_labels_for_test();
EXPECT_EQ(content_labels[0]->GetText(), u"20.0 KB");
EXPECT_EQ(content_labels[1]->GetText(),
u"Dec 23, 2021, 9:01\x202F"
EXPECT_EQ(content_labels[0]->GetText(), u"file name");
EXPECT_EQ(content_labels[1]->GetText(), u"displayable folder");
EXPECT_EQ(content_labels[2]->GetText(),
u"Modified Dec 23, 2021, 9:01\x202F"
u"AM");
EXPECT_EQ(content_labels[2]->GetText(), u"image/jpeg");
EXPECT_EQ(content_labels[3]->GetText(), u"virtual file path");
client->set_search_callback(TestAppListClient::SearchCallback());
}

@ -21,11 +21,9 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/time_format.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/text/bytes_formatting.h"
#include "ui/compositor/layer.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout_view.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/layout/flex_layout_view.h"
@ -46,30 +44,30 @@ constexpr int kSpaceBetweenImages = 8;
// Layout constants for `image_info_container_`.
constexpr auto kInfoContainerMargins = gfx::Insets::TLBR(0, 8, 0, 0);
constexpr int kSpaceBetweenInfoTitleAndContent = 16;
constexpr auto kSpaceBetweenLabels = gfx::Insets::VH(12, 0);
// The title string ids used as the title of `image_info_container_`.
constexpr std::array<int, 4> kTitleStringIds = {
IDS_ASH_SEARCH_RESULT_IMAGE_FILE_SIZE,
IDS_ASH_SEARCH_RESULT_IMAGE_DATE_MODIFIED,
IDS_ASH_SEARCH_RESULT_IMAGE_FILE_TYPE,
IDS_ASH_SEARCH_RESULT_IMAGE_FILE_LOCATION};
// The number of labels shown in `image_info_container_`, which should also be
// the size of `metadata_content_labels_`.
constexpr size_t kNumOfContentLabels = 3;
// Returns a displayable time for the last modified date in
// `image_info_container_`.
std::u16string GetFormattedTime(base::Time time) {
std::u16string date_time_of_day = base::TimeFormatTimeOfDay(time);
std::u16string date_str = ui::TimeFormat::RelativeDate(time, nullptr);
if (!date_str.empty()) {
return l10n_util::GetStringFUTF16(
std::u16string relative_date = ui::TimeFormat::RelativeDate(time, nullptr);
std::u16string formatted_time;
if (!relative_date.empty()) {
relative_date = base::ToLowerASCII(relative_date);
formatted_time = l10n_util::GetStringFUTF16(
IDS_ASH_SEARCH_RESULT_IMAGE_LAST_MODIFIED_RELATIVE_DATE_AND_TIME,
date_str, date_time_of_day);
relative_date, date_time_of_day);
} else {
formatted_time = l10n_util::GetStringFUTF16(
IDS_ASH_SEARCH_RESULT_IMAGE_LAST_MODIFIED_DATE_AND_TIME,
base::TimeFormatShortDate(time), date_time_of_day);
}
return l10n_util::GetStringFUTF16(
IDS_ASH_SEARCH_RESULT_IMAGE_LAST_MODIFIED_DATE_AND_TIME,
base::TimeFormatShortDate(time), date_time_of_day);
IDS_ASH_SEARCH_RESULT_IMAGE_LAST_MODIFIED_STRING, formatted_time);
}
} // namespace
@ -126,24 +124,15 @@ SearchResultImageListView::SearchResultImageListView(
}
image_info_container_ = image_view_container_->AddChildView(
std::make_unique<views::BoxLayoutView>());
std::make_unique<views::FlexLayoutView>());
image_info_container_->SetBorder(
views::CreateEmptyBorder(kInfoContainerMargins));
image_info_container_->SetBetweenChildSpacing(
kSpaceBetweenInfoTitleAndContent);
// Initialize the vertical container in `image_info_container_`.
auto create_vertical_container = [this]() {
auto* container = image_info_container_->AddChildView(
std::make_unique<views::FlexLayoutView>());
container->SetOrientation(views::LayoutOrientation::kVertical);
container->SetCollapseMargins(true);
container->SetMainAxisAlignment(LayoutAlignment::kCenter);
container->SetCrossAxisAlignment(LayoutAlignment::kStart);
return container;
};
image_info_title_container_ = create_vertical_container();
image_info_content_container_ = create_vertical_container();
image_info_container_->SetOrientation(views::LayoutOrientation::kVertical);
image_info_container_->SetCollapseMargins(true);
image_info_container_->SetMainAxisAlignment(LayoutAlignment::kCenter);
image_info_container_->SetCrossAxisAlignment(LayoutAlignment::kStart);
// Set the flex to restrict the sizes of the child labels.
image_info_container_->SetProperty(
@ -151,40 +140,31 @@ SearchResultImageListView::SearchResultImageListView(
views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
views::MaximumFlexSizeRule::kScaleToMaximum)
.WithWeight(1));
image_info_content_container_->SetDefault(
views::kFlexBehaviorKey,
views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
views::MaximumFlexSizeRule::kScaleToMaximum)
.WithWeight(1));
// Initialize the labels in the info container.
for (size_t i = 0; i < kTitleStringIds.size(); ++i) {
auto title_label = std::make_unique<views::Label>(
l10n_util::GetStringUTF16(kTitleStringIds[i]));
TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosButton2,
*title_label);
title_label->SetEnabledColorId(cros_tokens::kColorPrimary);
title_label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
for (size_t i = 0; i < kNumOfContentLabels; ++i) {
auto content_label = std::make_unique<views::Label>();
TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody2,
*content_label);
content_label->SetEnabledColorId(cros_tokens::kCrosSysSecondary);
content_label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
// Only set the margins between children but not the container edge.
if (i != 0 && i != kTitleStringIds.size() - 1) {
title_label->SetProperty(views::kMarginsKey, kSpaceBetweenLabels);
content_label->SetProperty(views::kMarginsKey, kSpaceBetweenLabels);
}
// Elide the file path if needed.
if (kTitleStringIds[i] == IDS_ASH_SEARCH_RESULT_IMAGE_FILE_LOCATION) {
if (i == 0) {
// Make the image result file name, which is the first metadata label,
// more prominent.
content_label->SetProperty(views::kMarginsKey,
gfx::Insets::TLBR(8, 0, 12, 0));
content_label->SetMultiLine(true);
content_label->SetAllowCharacterBreak(true);
TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosButton1,
*content_label);
content_label->SetEnabledColorId(cros_tokens::kColorPrimary);
} else {
content_label->SetElideBehavior(gfx::ElideBehavior::ELIDE_MIDDLE);
TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody2,
*content_label);
content_label->SetEnabledColorId(cros_tokens::kTextColorSecondary);
}
metadata_content_labels_.push_back(content_label.get());
image_info_title_container_->AddChildView(std::move(title_label));
image_info_content_container_->AddChildView(std::move(content_label));
image_info_container_->AddChildView(std::move(content_label));
}
}
@ -233,27 +213,14 @@ void SearchResultImageListView::OnImageMetadataLoaded(
return;
}
// Check that there are 4 labels in `metadata_content_labels_`.
DUMP_WILL_BE_CHECK_EQ(metadata_content_labels_.size(), 4u);
for (size_t i = 0; i < kTitleStringIds.size(); ++i) {
int title_id = kTitleStringIds[i];
std::u16string text;
switch (title_id) {
case IDS_ASH_SEARCH_RESULT_IMAGE_FILE_SIZE:
text = ui::FormatBytes(metadata.file_info.size);
break;
case IDS_ASH_SEARCH_RESULT_IMAGE_DATE_MODIFIED:
text = GetFormattedTime(metadata.file_info.last_modified);
break;
case IDS_ASH_SEARCH_RESULT_IMAGE_FILE_TYPE:
text = base::UTF8ToUTF16(metadata.mime_type);
break;
case IDS_ASH_SEARCH_RESULT_IMAGE_FILE_LOCATION:
text = base::UTF8ToUTF16(metadata.virtual_path.value());
break;
}
metadata_content_labels_[i]->SetText(text);
}
// Check that there are 3 labels in `metadata_content_labels_`.
CHECK_EQ(metadata_content_labels_.size(), kNumOfContentLabels);
metadata_content_labels_[0]->SetText(
base::UTF8ToUTF16(metadata.file_name.value()));
metadata_content_labels_[1]->SetText(
base::UTF8ToUTF16(metadata.displayable_folder_path.value()));
metadata_content_labels_[2]->SetText(
GetFormattedTime(metadata.file_info.last_modified));
}
int SearchResultImageListView::DoUpdate() {

@ -14,7 +14,6 @@
#include "ui/base/metadata/metadata_header_macros.h"
namespace views {
class BoxLayoutView;
class FlexLayoutView;
class Label;
} // namespace views
@ -51,7 +50,7 @@ class ASH_EXPORT SearchResultImageListView : public SearchResultContainerView {
// `image_info_container_` if needed.
void OnImageMetadataLoaded(ash::FileMetadata metadata);
const views::BoxLayoutView* image_info_container_for_test() const {
const views::FlexLayoutView* image_info_container_for_test() const {
return image_info_container_.get();
}
const std::vector<views::Label*>& metadata_content_labels_for_test() const {
@ -73,15 +72,13 @@ class ASH_EXPORT SearchResultImageListView : public SearchResultContainerView {
// Owned by views hierarchy.
raw_ptr<views::Label> title_label_ = nullptr;
raw_ptr<views::FlexLayoutView> image_view_container_ = nullptr;
raw_ptr<views::BoxLayoutView> image_info_container_ = nullptr;
raw_ptr<views::FlexLayoutView> image_info_title_container_ = nullptr;
raw_ptr<views::FlexLayoutView> image_info_content_container_ = nullptr;
raw_ptr<views::FlexLayoutView> image_info_container_ = nullptr;
std::vector<SearchResultImageView*> image_views_;
// Labels that show the file metadata in `image_info_container_`. There should
// always be 4 labels, which in the order of {file size, date modified, mime
// type, file path}.
// always be 3 labels, which in the order of {file name, file directory, date
// modified}.
std::vector<views::Label*> metadata_content_labels_;
base::WeakPtrFactory<SearchResultImageListView> weak_ptr_factory_{this};

@ -2270,11 +2270,8 @@ Style notes:
<message name="IDS_ASH_SEARCH_RESULT_CATEGORY_LABEL_IMAGES" desc="Category title for the list of image results shown in launcher search relevant to the query in the search box.">
Images
</message>
<message name="IDS_ASH_SEARCH_RESULT_IMAGE_FILE_SIZE" desc="The title for the file size of the image file search result, where the information is listed beside the launcher image result.">
Size
</message>
<message name="IDS_ASH_SEARCH_RESULT_IMAGE_DATE_MODIFIED" desc="The title for the last modified date of the image file search result, where the information is listed beside the launcher image result.">
Date modified
<message name="IDS_ASH_SEARCH_RESULT_IMAGE_LAST_MODIFIED_STRING" desc="The last modified date and time of the image file displayed in launcher search results. This string will be used along with the formatted date and time variable.">
Modified <ph name="date_and_time">$1<ex>Today 4:00 PM</ex></ph>
</message>
<message name="IDS_ASH_SEARCH_RESULT_IMAGE_LAST_MODIFIED_DATE_AND_TIME" desc="The last modified date and time of the image file displayed in launcher search results. Depending on launguage, please choose the best separator(eg ',') between abbreviated date and time">
<ph name="date">$1<ex>May 23, 2023</ex></ph>, <ph name="time">$2<ex>11:28 AM</ex></ph>
@ -2282,12 +2279,6 @@ Style notes:
<message name="IDS_ASH_SEARCH_RESULT_IMAGE_LAST_MODIFIED_RELATIVE_DATE_AND_TIME" desc="The last modified date and time of the image file displayed in launcher search results, where the relative date (today, yesterday) is used and the date string is already translated. Depending on launguage, please choose the best separator(eg ',') between abbreviated date and time">
<ph name="relative_date">$1<ex>Today</ex></ph> <ph name="time">$2<ex>4:00 PM</ex></ph>
</message>
<message name="IDS_ASH_SEARCH_RESULT_IMAGE_FILE_TYPE" desc="The title for the file type of the image file search result, where the information is listed beside the launcher image result.">
Type
</message>
<message name="IDS_ASH_SEARCH_RESULT_IMAGE_FILE_LOCATION" desc="The title for the file location of the image file search result, where the information is listed beside the launcher image result.">
Location
</message>
<message name="IDS_ASH_SEARCH_BOX_FILTER_BUTTON_TOOLTIP" desc="The tooltip text of the filter button in the search box, which is used to open a menu to filter the search results by their categories.">
Toggle search result categories
</message>

@ -1 +0,0 @@
ce08897322366dfc848bb808315e6bbf40ad446d

@ -1 +0,0 @@
ce08897322366dfc848bb808315e6bbf40ad446d

@ -1 +0,0 @@
ce08897322366dfc848bb808315e6bbf40ad446d

@ -1 +0,0 @@
ce08897322366dfc848bb808315e6bbf40ad446d

@ -0,0 +1 @@
0b6f3d5bf0b74b7c472268b56f75ace0c6dcf372

@ -557,9 +557,10 @@ struct ASH_PUBLIC_EXPORT FileMetadata {
~FileMetadata();
base::File::Info file_info;
std::string mime_type;
base::FilePath file_path;
base::FilePath virtual_path;
base::FilePath file_name;
// The folder path that is formatted for display.
base::FilePath displayable_folder_path;
};
class ASH_PUBLIC_EXPORT FileMetadataLoader {

@ -81,10 +81,10 @@ ash::FileMetadata GetFileMetadata(base::FilePath file_path,
base::File::Info info;
if (base::GetFileInfo(file_path, &info)) {
metadata.file_info = info;
net::GetMimeTypeFromFile(file_path, &metadata.mime_type);
}
metadata.file_path = file_path;
metadata.virtual_path = displayable_path;
metadata.file_name = displayable_path.BaseName();
metadata.displayable_folder_path = displayable_path.DirName();
return metadata;
}

@ -200,8 +200,8 @@ TEST_F(FileResultTest, FileMetadataPopulatedForDisplay) {
EXPECT_EQ(metadata.file_info.size, kJpegDataSize);
EXPECT_EQ(metadata.file_info.last_modified,
base::Time::FromSecondsSinceUnixEpoch(2));
EXPECT_EQ(metadata.mime_type, "image/jpeg");
EXPECT_EQ(metadata.virtual_path.value(), "My files/test.jpg");
EXPECT_EQ(metadata.file_name.value(), "test.jpg");
EXPECT_EQ(metadata.displayable_folder_path.value(), "My files");
storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
}