0

picker: show losbter in zero state

This CL adds the logic to display the lobster entry point below the editor editor entry point in the zero state.

There is a feature flag to control the visibility of lobster in zero state as well.

Bug: b:348279987

Change-Id: I93d6c442a18b3435fb895347ee4672170635375d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6001931
Reviewed-by: Darren Shen <shend@chromium.org>
Commit-Queue: Chuong Ho <hdchuong@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1379997}
This commit is contained in:
Chuong Ho
2024-11-07 23:01:33 +00:00
committed by Chromium LUCI CQ
parent 3ff4fa8647
commit bb92d1de6d
25 changed files with 149 additions and 64 deletions

@ -1820,6 +1820,11 @@ BASE_FEATURE(kLobsterDogfood,
"LobsterDogfood",
base::FEATURE_DISABLED_BY_DEFAULT);
// Enables lobster entry point in quick insert zero state.
BASE_FEATURE(kLobsterQuickInsertZeroState,
"LobsterQuickInsertZeroState",
base::FEATURE_DISABLED_BY_DEFAULT);
// Enables lobster right click menu entry point.
BASE_FEATURE(kLobsterRightClickMenu,
"LobsterRightClickMenu",

@ -612,6 +612,8 @@ BASE_DECLARE_FEATURE(kLobster);
COMPONENT_EXPORT(ASH_CONSTANTS)
BASE_DECLARE_FEATURE(kLobsterDogfood);
COMPONENT_EXPORT(ASH_CONSTANTS)
BASE_DECLARE_FEATURE(kLobsterQuickInsertZeroState);
COMPONENT_EXPORT(ASH_CONSTANTS)
BASE_DECLARE_FEATURE(kLobsterRightClickMenu);
COMPONENT_EXPORT(ASH_CONSTANTS)
BASE_DECLARE_FEATURE(kFeatureManagementLobster);

@ -109,7 +109,8 @@ cros_events::PickerAction ConvertToCrosEventAction(
return cros_events::PickerAction::OPEN_EDITOR_WRITE;
case QuickInsertCategory::kEditorRewrite:
return cros_events::PickerAction::OPEN_EDITOR_REWRITE;
case QuickInsertCategory::kLobster:
case QuickInsertCategory::kLobsterWithSelectedText:
case QuickInsertCategory::kLobsterWithNoSelectedText:
return cros_events::PickerAction::OPEN_LOBSTER;
case QuickInsertCategory::kLinks:
return cros_events::PickerAction::OPEN_LINKS;

@ -90,7 +90,7 @@ std::vector<QuickInsertCategory> QuickInsertModel::GetAvailableCategories()
}
if (lobster_status_ == LobsterStatus::kEnabled) {
categories.push_back(QuickInsertCategory::kLobster);
categories.push_back(QuickInsertCategory::kLobsterWithSelectedText);
}
return categories;
}
@ -101,7 +101,7 @@ std::vector<QuickInsertCategory> QuickInsertModel::GetAvailableCategories()
}
if (lobster_status_ == LobsterStatus::kEnabled) {
categories.push_back(QuickInsertCategory::kLobster);
categories.push_back(QuickInsertCategory::kLobsterWithNoSelectedText);
}
categories.push_back(QuickInsertCategory::kLinks);

@ -45,7 +45,8 @@ TEST(QuickInsertModelTest,
EXPECT_THAT(
model.GetAvailableCategories(),
ElementsAre(
QuickInsertCategory::kEditorWrite, QuickInsertCategory::kLobster,
QuickInsertCategory::kEditorWrite,
QuickInsertCategory::kLobsterWithNoSelectedText,
QuickInsertCategory::kLinks, QuickInsertCategory::kEmojis,
QuickInsertCategory::kClipboard, QuickInsertCategory::kDriveFiles,
QuickInsertCategory::kLocalFiles, QuickInsertCategory::kDatesTimes,
@ -63,7 +64,7 @@ TEST(QuickInsertModelTest,
QuickInsertModel::LobsterStatus::kEnabled);
EXPECT_THAT(model.GetAvailableCategories(),
ElementsAre(QuickInsertCategory::kEditorRewrite,
QuickInsertCategory::kLobster));
QuickInsertCategory::kLobsterWithSelectedText));
}
TEST(QuickInsertModelTest, AvailableCategoriesContainsEditorWriteWhenEnabled) {
@ -121,7 +122,7 @@ TEST(QuickInsertModelTest, AvailableCategoriesContainsLobsterWhenEnabled) {
QuickInsertModel::EditorStatus::kDisabled,
QuickInsertModel::LobsterStatus::kEnabled);
EXPECT_THAT(model.GetAvailableCategories(),
Contains(QuickInsertCategory::kLobster));
Contains(QuickInsertCategory::kLobsterWithNoSelectedText));
}
TEST(QuickInsertModelTest, AvailableCategoriesOmitsLobsterWriteWhenDisabled) {
@ -132,7 +133,9 @@ TEST(QuickInsertModelTest, AvailableCategoriesOmitsLobsterWriteWhenDisabled) {
QuickInsertModel::EditorStatus::kDisabled,
QuickInsertModel::LobsterStatus::kDisabled);
EXPECT_THAT(model.GetAvailableCategories(),
Not(Contains(QuickInsertCategory::kLobster)));
Not(Contains(QuickInsertCategory::kLobsterWithNoSelectedText)));
EXPECT_THAT(model.GetAvailableCategories(),
Not(Contains(QuickInsertCategory::kLobsterWithSelectedText)));
}
TEST(QuickInsertModelTest,

@ -14,7 +14,8 @@ enum class ASH_EXPORT QuickInsertCategory {
// Editor categories:
kEditorWrite,
kEditorRewrite,
kLobster,
kLobsterWithSelectedText,
kLobsterWithNoSelectedText,
// General categories:
kLinks,
kEmojisGifs,

@ -231,8 +231,9 @@ QuickInsertEditorResult::~QuickInsertEditorResult() = default;
bool QuickInsertEditorResult::operator==(const QuickInsertEditorResult&) const =
default;
QuickInsertLobsterResult::QuickInsertLobsterResult(std::u16string display_name)
: display_name(std::move(display_name)) {}
QuickInsertLobsterResult::QuickInsertLobsterResult(Mode mode,
std::u16string display_name)
: mode(mode), display_name(std::move(display_name)) {}
QuickInsertLobsterResult::QuickInsertLobsterResult(
const QuickInsertLobsterResult&) = default;

@ -241,9 +241,12 @@ struct ASH_EXPORT QuickInsertEditorResult {
};
struct ASH_EXPORT QuickInsertLobsterResult {
enum class Mode { kNoSelection, kWithSelection };
Mode mode;
std::u16string display_name;
QuickInsertLobsterResult(std::u16string display_name);
QuickInsertLobsterResult(Mode mode, std::u16string display_name);
QuickInsertLobsterResult(const QuickInsertLobsterResult&);
QuickInsertLobsterResult& operator=(const QuickInsertLobsterResult&);
~QuickInsertLobsterResult();

@ -65,9 +65,9 @@ void PickerSuggestionsController::GetSuggestions(QuickInsertClient& client,
}
if (base::Contains(model.GetAvailableCategories(),
QuickInsertCategory::kLobster) &&
model.GetMode() == PickerModeType::kHasSelection) {
callback.Run({QuickInsertLobsterResult(/*display_name=*/u"")});
QuickInsertCategory::kLobsterWithSelectedText)) {
callback.Run({QuickInsertLobsterResult(
QuickInsertLobsterResult::Mode::kWithSelection, /*display_name=*/u"")});
}
if (model.GetMode() == PickerModeType::kHasSelection) {
@ -129,7 +129,8 @@ void PickerSuggestionsController::GetSuggestionsForCategory(
switch (category) {
case QuickInsertCategory::kEditorWrite:
case QuickInsertCategory::kEditorRewrite:
case QuickInsertCategory::kLobster:
case QuickInsertCategory::kLobsterWithNoSelectedText:
case QuickInsertCategory::kLobsterWithSelectedText:
NOTREACHED_NORETURN();
case QuickInsertCategory::kLinks:
// TODO: b/366237507 - Request only kMaxRecentLinks results once

@ -101,9 +101,11 @@ TEST_F(QuickInsertSuggestionsControllerTest,
base::MockCallback<PickerSuggestionsController::SuggestionsCallback> callback;
EXPECT_CALL(callback, Run(_)).Times(AnyNumber());
EXPECT_CALL(callback, Run(IsSupersetOf({
QuickInsertLobsterResult(u""),
})))
EXPECT_CALL(callback,
Run(IsSupersetOf({
QuickInsertLobsterResult(
QuickInsertLobsterResult::Mode::kWithSelection, u""),
})))
.Times(1);
controller.GetSuggestions(client, model, callback.Get());

@ -14,10 +14,12 @@
namespace ash {
std::optional<QuickInsertSearchResult> PickerLobsterSearch(
QuickInsertLobsterResult::Mode mode,
std::u16string_view query) {
CHECK(!query.empty());
// TODO: b/369508495 - implement matching logic.
return std::make_optional(QuickInsertLobsterResult(/*display_name=*/u""));
return std::make_optional(
QuickInsertLobsterResult(mode, /*display_name=*/u""));
}
} // namespace ash

@ -15,6 +15,7 @@ namespace ash {
// `query` must not be empty.
ASH_EXPORT std::optional<QuickInsertSearchResult> PickerLobsterSearch(
QuickInsertLobsterResult::Mode mode,
std::u16string_view query);
} // namespace ash

@ -51,7 +51,8 @@ QuickInsertSectionType SectionTypeFromSearchSource(
return QuickInsertSectionType::kDriveFiles;
case QuickInsertSearchSource::kEditorWrite:
case QuickInsertSearchSource::kEditorRewrite:
case QuickInsertSearchSource::kLobster:
case QuickInsertSearchSource::kLobsterWithNoSelectedText:
case QuickInsertSearchSource::kLobsterWithSelectedText:
return QuickInsertSectionType::kContentEditor;
}
}

@ -109,7 +109,11 @@ const TestCase kContentEditorSectionTestCases[] = {
.section_type = QuickInsertSectionType::kContentEditor,
},
TestCase{
.source = QuickInsertSearchSource::kLobster,
.source = QuickInsertSearchSource::kLobsterWithNoSelectedText,
.section_type = QuickInsertSectionType::kContentEditor,
},
TestCase{
.source = QuickInsertSearchSource::kLobsterWithSelectedText,
.section_type = QuickInsertSectionType::kContentEditor,
},
};
@ -542,7 +546,10 @@ TEST_F(QuickInsertSearchAggregatorMultipleSourcesTest,
u"rewrite")),
VariantWith<QuickInsertTextResult>(Field(
"primary_text", &QuickInsertTextResult::primary_text,
u"lobster"))))))))
u"lobster_with_no_selected_text")),
VariantWith<QuickInsertTextResult>(Field(
"primary_text", &QuickInsertTextResult::primary_text,
u"lobster_with_selected_text"))))))))
.Times(1);
QuickInsertSearchAggregator aggregator(
@ -584,9 +591,14 @@ TEST_F(QuickInsertSearchAggregatorMultipleSourcesTest,
aggregator.HandleSearchSourceResults(QuickInsertSearchSource::kEditorRewrite,
{QuickInsertTextResult(u"rewrite")},
/*has_more_results=*/false);
aggregator.HandleSearchSourceResults(QuickInsertSearchSource::kLobster,
{QuickInsertTextResult(u"lobster")},
/*has_more_results=*/false);
aggregator.HandleSearchSourceResults(
QuickInsertSearchSource::kLobsterWithNoSelectedText,
{QuickInsertTextResult(u"lobster_with_no_selected_text")},
/*has_more_results=*/false);
aggregator.HandleSearchSourceResults(
QuickInsertSearchSource::kLobsterWithSelectedText,
{QuickInsertTextResult(u"lobster_with_selected_text")},
/*has_more_results=*/false);
task_environment().FastForwardBy(kBurnInPeriod);
}
@ -794,9 +806,14 @@ TEST_F(QuickInsertSearchAggregatorMultipleSourcesTest,
aggregator.HandleSearchSourceResults(QuickInsertSearchSource::kEditorRewrite,
{QuickInsertTextResult(u"rewrite")},
/*has_more_results=*/false);
aggregator.HandleSearchSourceResults(QuickInsertSearchSource::kLobster,
{QuickInsertTextResult(u"lobster")},
/*has_more_results=*/false);
aggregator.HandleSearchSourceResults(
QuickInsertSearchSource::kLobsterWithNoSelectedText,
{QuickInsertTextResult(u"lobster")},
/*has_more_results=*/false);
aggregator.HandleSearchSourceResults(
QuickInsertSearchSource::kLobsterWithSelectedText,
{QuickInsertTextResult(u"lobster")},
/*has_more_results=*/false);
}
TEST_F(QuickInsertSearchAggregatorMultipleSourcesTest,

@ -73,7 +73,8 @@ const char* SearchSourceToHistogram(QuickInsertSearchSource source) {
case QuickInsertSearchSource::kEditorWrite:
case QuickInsertSearchSource::kEditorRewrite:
return "Ash.Picker.Search.EditorProvider.QueryTime";
case QuickInsertSearchSource::kLobster:
case QuickInsertSearchSource::kLobsterWithNoSelectedText:
case QuickInsertSearchSource::kLobsterWithSelectedText:
return "Ash.Picker.Search.LobsterProvider.QueryTime";
}
NOTREACHED() << "Unexpected search source " << base::to_underlying(source);
@ -204,11 +205,24 @@ QuickInsertSearchRequest::QuickInsertSearchRequest(
PickerEditorSearch(QuickInsertEditorResult::Mode::kRewrite, query));
}
if (base::Contains(available_categories, QuickInsertCategory::kLobster)) {
// Editor results are currently synchronous.
MarkSearchStarted(QuickInsertSearchSource::kLobster);
HandleLobsterSearchResults(QuickInsertSearchSource::kLobster,
PickerLobsterSearch(query));
if (base::Contains(available_categories,
QuickInsertCategory::kLobsterWithNoSelectedText)) {
// Lobster results are currently synchronous.
MarkSearchStarted(QuickInsertSearchSource::kLobsterWithNoSelectedText);
HandleLobsterSearchResults(
QuickInsertSearchSource::kLobsterWithNoSelectedText,
PickerLobsterSearch(QuickInsertLobsterResult::Mode::kNoSelection,
query));
}
if (base::Contains(available_categories,
QuickInsertCategory::kLobsterWithSelectedText)) {
// Lobster results are currently synchronous.
MarkSearchStarted(QuickInsertSearchSource::kLobsterWithSelectedText);
HandleLobsterSearchResults(
QuickInsertSearchSource::kLobsterWithSelectedText,
PickerLobsterSearch(QuickInsertLobsterResult::Mode::kWithSelection,
query));
}
}

@ -1117,10 +1117,11 @@ TEST_P(QuickInsertSearchRequestLobsterTest, RecordsLobsterMetrics) {
INSTANTIATE_TEST_SUITE_P(
,
QuickInsertSearchRequestLobsterTest,
testing::Values(std::make_pair(QuickInsertCategory::kLobster,
QuickInsertSearchSource::kLobster),
std::make_pair(QuickInsertCategory::kLobster,
QuickInsertSearchSource::kLobster)));
testing::Values(
std::make_pair(QuickInsertCategory::kLobsterWithNoSelectedText,
QuickInsertSearchSource::kLobsterWithNoSelectedText),
std::make_pair(QuickInsertCategory::kLobsterWithSelectedText,
QuickInsertSearchSource::kLobsterWithSelectedText)));
TEST_F(QuickInsertSearchRequestTest, DoneClosureCalledImmediatelyWhenNoSearch) {
// This actually calls category search.

@ -17,8 +17,9 @@ enum class QuickInsertSearchSource {
kClipboard,
kEditorWrite,
kEditorRewrite,
kLobster,
kMaxValue = kLobster,
kLobsterWithNoSelectedText,
kLobsterWithSelectedText,
kMaxValue = kLobsterWithSelectedText,
};
}

@ -15,8 +15,10 @@ GetQuickInsertCategoryType(QuickInsertCategory category) {
return QuickInsertCategoryType::kEditorWrite;
case QuickInsertCategory::kEditorRewrite:
return QuickInsertCategoryType::kEditorRewrite;
case QuickInsertCategory::kLobster:
case QuickInsertCategory::kLobsterWithNoSelectedText:
return QuickInsertCategoryType::kEditorWrite;
case QuickInsertCategory::kLobsterWithSelectedText:
return QuickInsertCategoryType::kEditorRewrite;
case QuickInsertCategory::kLinks:
case QuickInsertCategory::kEmojisGifs:
case QuickInsertCategory::kEmojis:

@ -26,7 +26,8 @@ const gfx::VectorIcon& GetVectorIconForQuickInsertCategory(
case QuickInsertCategory::kEditorRewrite:
// TODO: b/322926823 - Use correct icons.
return kPencilIcon;
case QuickInsertCategory::kLobster:
case QuickInsertCategory::kLobsterWithNoSelectedText:
case QuickInsertCategory::kLobsterWithSelectedText:
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
return kLobsterIcon;
#else

@ -79,6 +79,16 @@ QuickInsertCategory GetCategoryForEditorData(
}
}
QuickInsertCategory GetCategoryForLobsterData(
const QuickInsertLobsterResult& data) {
switch (data.mode) {
case QuickInsertLobsterResult::Mode::kNoSelection:
return QuickInsertCategory::kLobsterWithNoSelectedText;
case QuickInsertLobsterResult::Mode::kWithSelection:
return QuickInsertCategory::kLobsterWithSelectedText;
}
}
std::u16string GetLabelForNewWindowType(QuickInsertNewWindowResult::Type type) {
switch (type) {
case QuickInsertNewWindowResult::Type::kDoc:
@ -360,7 +370,8 @@ QuickInsertSectionView::CreateItemFromResult(
auto item_view = std::make_unique<QuickInsertListItemView>(
std::move(select_result_callback));
const QuickInsertCategory category = QuickInsertCategory::kLobster;
const QuickInsertCategory category =
GetCategoryForLobsterData(data);
item_view->SetPrimaryText(GetLabelForQuickInsertCategory(category));
item_view->SetLeadingIcon(GetIconForQuickInsertCategory(category));
return item_view;

@ -35,7 +35,8 @@ std::u16string GetLabelForQuickInsertCategory(QuickInsertCategory category) {
#else
return u"";
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
case QuickInsertCategory::kLobster:
case QuickInsertCategory::kLobsterWithNoSelectedText:
case QuickInsertCategory::kLobsterWithSelectedText:
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
return l10n_util::GetStringUTF16(IDS_PICKER_LOBSTER_SELECTION_LABEL);
#else
@ -83,7 +84,8 @@ std::u16string GetSearchFieldPlaceholderTextForQuickInsertCategory(
IDS_PICKER_UNITS_MATHS_CATEGORY_SEARCH_FIELD_PLACEHOLDER_TEXT);
case QuickInsertCategory::kEditorWrite:
case QuickInsertCategory::kEditorRewrite:
case QuickInsertCategory::kLobster:
case QuickInsertCategory::kLobsterWithNoSelectedText:
case QuickInsertCategory::kLobsterWithSelectedText:
case QuickInsertCategory::kEmojisGifs:
case QuickInsertCategory::kEmojis:
NOTREACHED_NORETURN();

@ -243,7 +243,8 @@ std::u16string GetNoResultsFoundDescription(QuickInsertCategory category) {
return l10n_util::GetStringUTF16(IDS_PICKER_NO_RESULTS_TEXT);
case QuickInsertCategory::kEditorWrite:
case QuickInsertCategory::kEditorRewrite:
case QuickInsertCategory::kLobster:
case QuickInsertCategory::kLobsterWithNoSelectedText:
case QuickInsertCategory::kLobsterWithSelectedText:
case QuickInsertCategory::kEmojisGifs:
case QuickInsertCategory::kEmojis:
NOTREACHED_NORETURN();
@ -756,7 +757,8 @@ void QuickInsertView::SelectCategoryWithQuery(QuickInsertCategory category,
return;
}
if (category == QuickInsertCategory::kLobster) {
if (category == QuickInsertCategory::kLobsterWithNoSelectedText ||
category == QuickInsertCategory::kLobsterWithSelectedText) {
if (auto* widget = GetWidget()) {
widget->CloseWithReason(views::Widget::ClosedReason::kLostFocus);
}

@ -107,12 +107,17 @@ PickerZeroStateView::PickerZeroStateView(
picker_view_width, asset_fetcher, submenu_controller_));
for (QuickInsertCategory category : available_categories) {
// kEditorRewrite is not visible in the zero-state, since it's replaced with
// the rewrite suggestions.
// TODO: b/369701127 - Shows kLobster entry once its implementation is
// ready.
// kEditorRewrite and LobsterWithSelectedText are not visible in the
// zero-state, since it's replaced with the rewrite suggestions and the
// lobster result, respectively.
if (category == QuickInsertCategory::kEditorRewrite ||
category == QuickInsertCategory::kLobster) {
category == QuickInsertCategory::kLobsterWithSelectedText) {
continue;
}
if (!base::FeatureList::IsEnabled(
ash::features::kLobsterQuickInsertZeroState) &&
category == QuickInsertCategory::kLobsterWithNoSelectedText) {
continue;
}

@ -86,7 +86,8 @@ constexpr base::span<const QuickInsertCategory> kAllCategories = {
(QuickInsertCategory[]){
QuickInsertCategory::kEditorWrite,
QuickInsertCategory::kEditorRewrite,
QuickInsertCategory::kLobster,
QuickInsertCategory::kLobsterWithNoSelectedText,
QuickInsertCategory::kLobsterWithSelectedText,
QuickInsertCategory::kLinks,
QuickInsertCategory::kEmojisGifs,
QuickInsertCategory::kClipboard,
@ -490,17 +491,18 @@ TEST_F(QuickInsertZeroStateViewTest, ShowsEditorSuggestionsBehindSubmenu) {
}
TEST_F(QuickInsertZeroStateViewTest,
DoesntShowLobsterCategoryForEmptySuggestions) {
DoesntShowLobsterWithTextSelectionCategoryForEmptySuggestions) {
MockZeroStateViewDelegate mock_delegate;
EXPECT_CALL(mock_delegate, GetZeroStateSuggestedResults)
.WillOnce(
[](MockZeroStateViewDelegate::SuggestedResultsCallback callback) {
std::move(callback).Run({});
});
PickerZeroStateView view(&mock_delegate,
base::span_from_ref(QuickInsertCategory::kLobster),
kPickerWidth, &asset_fetcher_, &submenu_controller_,
&preview_controller_);
PickerZeroStateView view(
&mock_delegate,
base::span_from_ref(QuickInsertCategory::kLobsterWithSelectedText),
kPickerWidth, &asset_fetcher_, &submenu_controller_,
&preview_controller_);
EXPECT_THAT(view.category_section_views_for_testing(), IsEmpty());
}
@ -511,12 +513,14 @@ TEST_F(QuickInsertZeroStateViewTest, ShowLobsterCategoryAsListItem) {
.WillOnce(
[](MockZeroStateViewDelegate::SuggestedResultsCallback callback) {
std::move(callback).Run({QuickInsertLobsterResult(
QuickInsertLobsterResult::Mode::kWithSelection,
/*display_name=*/u"lobster")});
});
PickerZeroStateView view(&mock_delegate,
base::span_from_ref(QuickInsertCategory::kLobster),
kPickerWidth, &asset_fetcher_, &submenu_controller_,
&preview_controller_);
PickerZeroStateView view(
&mock_delegate,
base::span_from_ref(QuickInsertCategory::kLobsterWithSelectedText),
kPickerWidth, &asset_fetcher_, &submenu_controller_,
&preview_controller_);
EXPECT_THAT(
view.category_section_views_for_testing(),

@ -308,7 +308,8 @@ void QuickInsertClientImpl::StartCrosSearch(
switch (*category) {
case ash::QuickInsertCategory::kEditorWrite:
case ash::QuickInsertCategory::kEditorRewrite:
case ash::QuickInsertCategory::kLobster:
case ash::QuickInsertCategory::kLobsterWithNoSelectedText:
case ash::QuickInsertCategory::kLobsterWithSelectedText:
case ash::QuickInsertCategory::kEmojisGifs:
case ash::QuickInsertCategory::kEmojis:
case ash::QuickInsertCategory::kClipboard:
@ -585,7 +586,8 @@ QuickInsertClientImpl::CreateSearchProviderForCategory(
switch (category) {
case ash::QuickInsertCategory::kEditorWrite:
case ash::QuickInsertCategory::kEditorRewrite:
case ash::QuickInsertCategory::kLobster:
case ash::QuickInsertCategory::kLobsterWithNoSelectedText:
case ash::QuickInsertCategory::kLobsterWithSelectedText:
case ash::QuickInsertCategory::kEmojisGifs:
case ash::QuickInsertCategory::kEmojis:
case ash::QuickInsertCategory::kClipboard: