[Sidebar] Suppress animation when switching between panels (#36203)
Add suppress_animations=true when ActivatePanelItem is called while a panel is already active. Resolves brave/brave-browser#55285
This commit is contained in:
@@ -2223,6 +2223,101 @@ IN_PROC_BROWSER_TEST_F(SidebarBrowserTest,
|
||||
<< "No-border resize area width should equal kNoBorderResizeAreaWidth";
|
||||
}
|
||||
|
||||
class ScopedSidePanelUIForTesting {
|
||||
public:
|
||||
ScopedSidePanelUIForTesting(SidebarController* controller, SidePanelUI* ui)
|
||||
: controller_(controller) {
|
||||
controller_->SetSidePanelUIForTesting(ui);
|
||||
}
|
||||
~ScopedSidePanelUIForTesting() {
|
||||
controller_->SetSidePanelUIForTesting(nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
raw_ptr<SidebarController> controller_;
|
||||
};
|
||||
|
||||
class MockSidePanelUI : public SidePanelUI {
|
||||
public:
|
||||
MOCK_METHOD(void,
|
||||
Show,
|
||||
(SidePanelEntryId, std::optional<SidePanelOpenTrigger>, bool),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
Show,
|
||||
(SidePanelEntryKey, std::optional<SidePanelOpenTrigger>, bool),
|
||||
(override));
|
||||
MOCK_METHOD(void, ShowFrom, (SidePanelEntryKey, gfx::Rect), (override));
|
||||
MOCK_METHOD(void,
|
||||
Close,
|
||||
(SidePanelEntry::PanelType, SidePanelEntryHideReason, bool),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
Toggle,
|
||||
(SidePanelEntryKey, SidePanelOpenTrigger),
|
||||
(override));
|
||||
MOCK_METHOD(std::optional<SidePanelEntryId>,
|
||||
GetCurrentEntryId,
|
||||
(SidePanelEntry::PanelType),
|
||||
(const, override));
|
||||
MOCK_METHOD(int,
|
||||
GetCurrentEntryDefaultContentWidth,
|
||||
(SidePanelEntry::PanelType),
|
||||
(const, override));
|
||||
MOCK_METHOD(bool,
|
||||
IsSidePanelShowing,
|
||||
(SidePanelEntry::PanelType),
|
||||
(const, override));
|
||||
MOCK_METHOD(bool,
|
||||
IsSidePanelEntryShowing,
|
||||
(const SidePanelEntryKey&),
|
||||
(const, override));
|
||||
MOCK_METHOD(bool,
|
||||
IsSidePanelEntryShowing,
|
||||
(const SidePanelEntry::Key&, bool),
|
||||
(const, override));
|
||||
MOCK_METHOD(base::CallbackListSubscription,
|
||||
RegisterSidePanelShown,
|
||||
(SidePanelEntry::PanelType, ShownCallback),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
OnActiveTabChanged,
|
||||
(content::WebContents*, content::WebContents*, bool),
|
||||
(override));
|
||||
MOCK_METHOD(content::WebContents*,
|
||||
GetWebContentsForTest,
|
||||
(SidePanelEntryId),
|
||||
(override));
|
||||
MOCK_METHOD(void, DisableAnimationsForTesting, (), (override));
|
||||
MOCK_METHOD(void, SetNoDelaysForTesting, (bool), (override));
|
||||
};
|
||||
|
||||
// Verify suppress_animations is false when opening from a closed state and
|
||||
// true when switching panels while one is already active.
|
||||
IN_PROC_BROWSER_TEST_F(SidebarBrowserTest,
|
||||
SidebarV2ActivatePanelItemSuppressAnimation) {
|
||||
MockSidePanelUI mock_ui;
|
||||
ScopedSidePanelUIForTesting scoped_ui(controller(), &mock_ui);
|
||||
|
||||
// No active panel: opening should animate (suppress_animations=false).
|
||||
ASSERT_FALSE(model()->active_index().has_value())
|
||||
<< "Expected no active panel before first ActivatePanelItem call";
|
||||
EXPECT_CALL(mock_ui,
|
||||
Show(testing::An<SidePanelEntryId>(), testing::Eq(std::nullopt),
|
||||
/*suppress_animations=*/false));
|
||||
controller()->ActivatePanelItem(SidebarItem::BuiltInItemType::kBookmarks);
|
||||
testing::Mock::VerifyAndClearExpectations(&mock_ui);
|
||||
controller()->UpdateActiveItemState(SidebarItem::BuiltInItemType::kBookmarks);
|
||||
|
||||
// Active panel present: switching panels should suppress animations.
|
||||
ASSERT_TRUE(model()->active_index().has_value())
|
||||
<< "Expected active panel after UpdateActiveItemState";
|
||||
EXPECT_CALL(mock_ui,
|
||||
Show(testing::An<SidePanelEntryId>(), testing::Eq(std::nullopt),
|
||||
/*suppress_animations=*/true));
|
||||
controller()->ActivatePanelItem(SidebarItem::BuiltInItemType::kReadingList);
|
||||
}
|
||||
|
||||
#endif // BUILDFLAG(ENABLE_SIDEBAR_V2)
|
||||
|
||||
} // namespace sidebar
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/check_op.h"
|
||||
#include "brave/browser/ui/sidebar/buildflags/buildflags.h"
|
||||
#include "brave/browser/ui/sidebar/sidebar.h"
|
||||
#include "brave/browser/ui/sidebar/sidebar_model.h"
|
||||
#include "brave/browser/ui/sidebar/sidebar_service_factory.h"
|
||||
@@ -150,17 +151,25 @@ void SidebarController::ActivateItemAt(std::optional<size_t> index,
|
||||
void SidebarController::ActivatePanelItem(
|
||||
SidebarItem::BuiltInItemType panel_item) {
|
||||
// For panel item activation, SidePanelUI is the single source of truth.
|
||||
auto* side_panel_ui = browser_->GetFeatures().side_panel_ui();
|
||||
if (!side_panel_ui) {
|
||||
return;
|
||||
}
|
||||
auto* side_panel_ui = side_panel_ui_for_testing_
|
||||
? side_panel_ui_for_testing_.get()
|
||||
: browser_->GetFeatures().side_panel_ui();
|
||||
CHECK(side_panel_ui);
|
||||
if (panel_item == SidebarItem::BuiltInItemType::kNone) {
|
||||
side_panel_ui->Close(SidePanelEntry::PanelType::kContent);
|
||||
return;
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_SIDEBAR_V2)
|
||||
// Suppress opening animation when we have active item.
|
||||
// When opening another panel while other panel is visible,
|
||||
// we don't need to open new panel with animation.
|
||||
const bool suppress_animations = sidebar_model_->active_index().has_value();
|
||||
side_panel_ui->Show(sidebar::SidePanelIdFromSideBarItemType(panel_item),
|
||||
/*open_trigger*/ std::nullopt, suppress_animations);
|
||||
#else
|
||||
side_panel_ui->Show(sidebar::SidePanelIdFromSideBarItemType(panel_item));
|
||||
#endif
|
||||
}
|
||||
|
||||
void SidebarController::DeactivateCurrentPanel() {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
class Browser;
|
||||
class GURL;
|
||||
class Profile;
|
||||
class SidePanelUI;
|
||||
class TabStripModel;
|
||||
|
||||
namespace sidebar {
|
||||
@@ -63,6 +64,10 @@ class SidebarController : public SidebarService::Observer {
|
||||
void ActivatePanelItem(SidebarItem::BuiltInItemType panel_item);
|
||||
void DeactivateCurrentPanel();
|
||||
|
||||
void SetSidePanelUIForTesting(SidePanelUI* side_panel_ui) {
|
||||
side_panel_ui_for_testing_ = side_panel_ui;
|
||||
}
|
||||
|
||||
// If current browser doesn't have a tab for |url|, active tab will load
|
||||
// |url|. Otherwise, existing tab will be activated.
|
||||
// ShowSingletonTab() has similar functionality but it loads url in the
|
||||
@@ -99,6 +104,7 @@ class SidebarController : public SidebarService::Observer {
|
||||
raw_ptr<Profile> profile_ = nullptr;
|
||||
raw_ptr<Browser> browser_ = nullptr;
|
||||
raw_ptr<Sidebar> sidebar_ = nullptr;
|
||||
raw_ptr<SidePanelUI> side_panel_ui_for_testing_ = nullptr;
|
||||
|
||||
std::unique_ptr<SidebarModel> sidebar_model_;
|
||||
std::unique_ptr<SidebarWebPanelController> web_panel_controller_;
|
||||
|
||||
Reference in New Issue
Block a user