[iOS][TGS][1/N] Show snackbar when closing tab groups
This CL shows a snackbar when closing a group from the tab grid view.
Tapping on the CTA opens the Tab Groups panel.
Bug: 358351829
Change-Id: I34860cc127fc635488d057ac4c5921be2150825f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5777142
Reviewed-by: Gauthier Ambard <gambard@chromium.org>
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Commit-Queue: Ewann Pellé <ewannpv@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1340835}
diff --git a/ios/chrome/browser/shared/public/commands/tab_grid_commands.h b/ios/chrome/browser/shared/public/commands/tab_grid_commands.h
index 448b773..4a339943 100644
--- a/ios/chrome/browser/shared/public/commands/tab_grid_commands.h
+++ b/ios/chrome/browser/shared/public/commands/tab_grid_commands.h
@@ -23,6 +23,9 @@
// Shows the recent tabs panel searching for `text`.
- (void)showRecentTabsForText:(NSString*)text;
+// Shows the tab groups panel.
+- (void)showTabGroupsPanel;
+
@end
#endif // IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_TAB_GRID_COMMANDS_H_
diff --git a/ios/chrome/browser/shared/public/commands/tab_groups_commands.h b/ios/chrome/browser/shared/public/commands/tab_groups_commands.h
index 213f4327..ca1df4d 100644
--- a/ios/chrome/browser/shared/public/commands/tab_groups_commands.h
+++ b/ios/chrome/browser/shared/public/commands/tab_groups_commands.h
@@ -48,6 +48,9 @@
group:(const TabGroup*)tabGroup
sourceButtonItem:(UIBarButtonItem*)sourceButtonItem;
+// Displays a snackbar after closing tab groups locally.
+- (void)showTabGroupSnackbarAfterClosingGroups:(int)numberOfClosedGroups;
+
@end
#endif // IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_TAB_GROUPS_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
index 9de708a..fb1fb83 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
@@ -15,8 +15,10 @@
":grid_ui",
":tab_group_grid_ui",
"//base",
+ "//components/feature_engagement/public",
"//components/strings",
"//ios/chrome/app/strings",
+ "//ios/chrome/browser/feature_engagement/model",
"//ios/chrome/browser/shared/coordinator/alert",
"//ios/chrome/browser/shared/coordinator/chrome_coordinator",
"//ios/chrome/browser/shared/model/browser",
@@ -24,12 +26,14 @@
"//ios/chrome/browser/shared/model/web_state_list",
"//ios/chrome/browser/shared/public/commands",
"//ios/chrome/browser/shared/public/features",
+ "//ios/chrome/browser/shared/ui/util:snackbar_util",
"//ios/chrome/browser/ui/tab_switcher:tab_group_confirmation",
"//ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu:tab_item",
"//ios/chrome/browser/ui/tab_switcher/tab_grid/tab_groups",
"//ios/chrome/browser/ui/tab_switcher/tab_grid/tab_groups:tab_group_creation",
"//ios/chrome/browser/ui/tab_switcher/tab_grid/tab_groups:tab_groups_ui",
"//ios/chrome/browser/ui/tab_switcher/tab_grid/transitions",
+ "//ios/third_party/material_components_ios",
"//ios/web/public",
]
}
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_coordinator.mm
index 82af6be..4cb6cdc8 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_coordinator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_coordinator.mm
@@ -2,16 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#import <MaterialComponents/MaterialSnackbar.h>
+
#import "base/check.h"
+#import "base/strings/sys_string_conversions.h"
+#import "components/feature_engagement/public/feature_constants.h"
+#import "components/feature_engagement/public/tracker.h"
#import "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
#import "ios/chrome/browser/shared/model/browser/browser.h"
#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
+#import "ios/chrome/browser/shared/public/commands/snackbar_commands.h"
#import "ios/chrome/browser/shared/public/commands/tab_grid_commands.h"
#import "ios/chrome/browser/shared/public/commands/tab_grid_toolbar_commands.h"
#import "ios/chrome/browser/shared/public/commands/tab_group_confirmation_commands.h"
#import "ios/chrome/browser/shared/public/features/features.h"
+#import "ios/chrome/browser/shared/ui/util/snackbar_util.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_coordinator+subclassing.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.h"
@@ -311,6 +319,43 @@
self.browser->GetCommandDispatcher(), TabGroupConfirmationCommands);
}
+- (void)showTabGroupSnackbarAfterClosingGroups:(int)numberOfClosedGroups {
+ if (!IsTabGroupSyncEnabled()) {
+ return;
+ }
+
+ // Don't show the snackbar if the IPH will be presented.
+ feature_engagement::Tracker* tracker =
+ feature_engagement::TrackerFactory::GetForBrowserState(
+ self.browser->GetBrowserState());
+ if (tracker->WouldTriggerHelpUI(
+ feature_engagement::kIPHiOSSavedTabGroupClosed)) {
+ return;
+ }
+
+ // Create the "Open Tab Groups" action.
+ CommandDispatcher* dispatcher = self.browser->GetCommandDispatcher();
+ __weak id<TabGridCommands> tabGridHandler =
+ HandlerForProtocol(dispatcher, TabGridCommands);
+ void (^openTabGroupPanelAction)() = ^{
+ [tabGridHandler showTabGroupsPanel];
+ };
+
+ // Create and config the snackbar.
+ NSString* messageLabel =
+ base::SysUTF16ToNSString(l10n_util::GetPluralStringFUTF16(
+ IDS_IOS_TAB_GROUP_SNACKBAR_LABEL, numberOfClosedGroups));
+ MDCSnackbarMessage* message = CreateSnackbarMessage(messageLabel);
+ MDCSnackbarMessageAction* action = [[MDCSnackbarMessageAction alloc] init];
+ action.handler = openTabGroupPanelAction;
+ action.title = l10n_util::GetNSString(IDS_IOS_TAB_GROUP_SNACKBAR_ACTION);
+ message.action = action;
+
+ id<SnackbarCommands> snackbarCommandsHandler =
+ HandlerForProtocol(dispatcher, SnackbarCommands);
+ [snackbarCommandsHandler showSnackbarMessage:message];
+}
+
#pragma mark - CreateOrEditTabGroupCoordinatorDelegate
- (void)createOrEditTabGroupCoordinatorDidDismiss:
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm
index 8931727..197bfd9 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm
@@ -453,7 +453,7 @@
}
if (IsTabGroupSyncEnabled() && !deleteGroup) {
- // TODO(crbug.com/329627077): Add a mechanism to show it only once.
+ [self.tabGroupsHandler showTabGroupSnackbarAfterClosingGroups:1];
[self.tabGridToolbarHandler showSavedTabGroupIPH];
tab_groups::TabGroupSyncService* syncService =
tab_groups::TabGroupSyncServiceFactory::GetForBrowserState(
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
index 0796b2d6..f48d8609 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
@@ -1642,6 +1642,12 @@
animated:YES];
}
+- (void)showTabGroupsPanel {
+ CHECK(IsTabGroupSyncEnabled());
+ [self.baseViewController setCurrentPageAndPageControl:TabGridPageTabGroups
+ animated:YES];
+}
+
#pragma mark - SnackbarCoordinatorDelegate
- (CGFloat)snackbarCoordinatorBottomOffsetForCurrentlyPresentedView: