Commit 2de0dc43 authored by Gauthier Ambard's avatar Gauthier Ambard Committed by Commit Bot

[iOS] Convert AboutChromeCollectionVC to TableView

This CL converts AboutChromeCollectionViewController to use TableView
instead of collection view.
It also updates the VersionItem to be displayed as a cell instead of as
an item. It means that the callback when the version is tapped cannot
happen in the VC. So the cell has a button copying the version to the
pasteboard when tapped.

Bug: 894791
Change-Id: I6cdae4b09235bb6f72e2dbffac88a5dd9f78e67a
Reviewed-on: https://chromium-review.googlesource.com/c/1291390
Commit-Queue: Gauthier Ambard <gambard@chromium.org>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#602350}
parent a6bce5f0
......@@ -5,8 +5,8 @@
source_set("settings") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [
"about_chrome_collection_view_controller.h",
"about_chrome_collection_view_controller.mm",
"about_chrome_table_view_controller.h",
"about_chrome_table_view_controller.mm",
"accounts_collection_view_controller.h",
"accounts_collection_view_controller.mm",
"alpha_animated_collection_view_flow_layout.h",
......@@ -268,7 +268,7 @@ source_set("unit_tests") {
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
"about_chrome_collection_view_controller_unittest.mm",
"about_chrome_table_view_controller_unittest.mm",
"autofill_credit_card_collection_view_controller_unittest.mm",
"autofill_profile_collection_view_controller_unittest.mm",
"autofill_profile_edit_collection_view_controller_unittest.mm",
......
......@@ -2,22 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_ABOUT_CHROME_COLLECTION_VIEW_CONTROLLER_H_
#define IOS_CHROME_BROWSER_UI_SETTINGS_ABOUT_CHROME_COLLECTION_VIEW_CONTROLLER_H_
#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_ABOUT_CHROME_TABLE_VIEW_CONTROLLER_H_
#define IOS_CHROME_BROWSER_UI_SETTINGS_ABOUT_CHROME_TABLE_VIEW_CONTROLLER_H_
#import "ios/chrome/browser/ui/settings/settings_root_collection_view_controller.h"
#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h"
// Controller for the About Google Chrome collection view, which allows users to
// Controller for the About Google Chrome Table View, which allows users to
// view open source licenses, terms of service, etc.
@interface AboutChromeCollectionViewController
: SettingsRootCollectionViewController
@interface AboutChromeTableViewController : SettingsRootTableViewController
- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithLayout:(UICollectionViewLayout*)layout
style:(CollectionViewControllerStyle)style
- (instancetype)initWithTableViewStyle:(UITableViewStyle)style
appBarStyle:
(ChromeTableViewControllerStyle)appBarStyle
NS_UNAVAILABLE;
@end
#endif // IOS_CHROME_BROWSER_UI_SETTINGS_ABOUT_CHROME_COLLECTION_VIEW_CONTROLLER_H_
#endif // IOS_CHROME_BROWSER_UI_SETTINGS_ABOUT_CHROME_TABLE_VIEW_CONTROLLER_H_
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/settings/about_chrome_collection_view_controller.h"
#import "ios/chrome/browser/ui/settings/about_chrome_table_view_controller.h"
#import "base/ios/block_types.h"
#include "base/logging.h"
......@@ -11,16 +11,14 @@
#include "base/strings/utf_string_conversions.h"
#include "components/version_info/version_info.h"
#include "ios/chrome/browser/chrome_url_constants.h"
#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
#import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
#import "ios/chrome/browser/ui/settings/cells/settings_text_item.h"
#import "ios/chrome/browser/ui/settings/cells/version_item.h"
#import "ios/chrome/browser/ui/settings/settings_utils.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h"
#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
#include "ios/chrome/browser/ui/util/uikit_ui_util.h"
#include "ios/chrome/common/channel_info.h"
#include "ios/chrome/grit/ios_chromium_strings.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
#import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_mac.h"
......@@ -34,7 +32,6 @@ namespace {
typedef NS_ENUM(NSInteger, SectionIdentifier) {
SectionIdentifierLinks = kSectionIdentifierEnumZero,
SectionIdentifierFooter,
};
typedef NS_ENUM(NSInteger, ItemType) {
......@@ -44,69 +41,88 @@ typedef NS_ENUM(NSInteger, ItemType) {
ItemTypeVersion,
};
const CGFloat kDefaultHeight = 70;
} // namespace
@implementation AboutChromeCollectionViewController
@interface AboutChromeTableViewController ()<VersionFooterDelegate>
@end
@implementation AboutChromeTableViewController
#pragma mark Initialization
#pragma mark - Public
- (instancetype)init {
UICollectionViewLayout* layout = [[MDCCollectionViewFlowLayout alloc] init];
self =
[super initWithLayout:layout style:CollectionViewControllerStyleAppBar];
[super initWithTableViewStyle:UITableViewStyleGrouped
appBarStyle:ChromeTableViewControllerStyleWithAppBar];
if (self) {
self.title = l10n_util::GetNSString(IDS_IOS_ABOUT_PRODUCT_NAME);
// TODO(crbug.com/764578): -loadModel should not be called from
// initializer. A possible fix is to move this call to -viewDidLoad.
[self loadModel];
}
return self;
}
#pragma mark SettingsRootCollectionViewController
#pragma mark - UIViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self loadModel];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = kDefaultHeight;
self.tableView.sectionFooterHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionFooterHeight = kDefaultHeight;
self.styler.cellTitleColor = [UIColor blackColor];
}
#pragma mark - SettingsRootTableViewController
- (void)loadModel {
[super loadModel];
CollectionViewModel* model = self.collectionViewModel;
TableViewModel* model = self.tableViewModel;
[model addSectionWithIdentifier:SectionIdentifierLinks];
SettingsTextItem* credits =
[[SettingsTextItem alloc] initWithType:ItemTypeLinksCredits];
TableViewDetailTextItem* credits =
[[TableViewDetailTextItem alloc] initWithType:ItemTypeLinksCredits];
credits.text = l10n_util::GetNSString(IDS_IOS_OPEN_SOURCE_LICENSES);
credits.accessoryType = MDCCollectionViewCellAccessoryDisclosureIndicator;
credits.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
credits.accessibilityTraits = UIAccessibilityTraitButton;
[model addItem:credits toSectionWithIdentifier:SectionIdentifierLinks];
SettingsTextItem* terms =
[[SettingsTextItem alloc] initWithType:ItemTypeLinksTerms];
TableViewDetailTextItem* terms =
[[TableViewDetailTextItem alloc] initWithType:ItemTypeLinksTerms];
terms.text = l10n_util::GetNSString(IDS_IOS_TERMS_OF_SERVICE);
terms.accessoryType = MDCCollectionViewCellAccessoryDisclosureIndicator;
terms.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
terms.accessibilityTraits = UIAccessibilityTraitButton;
[model addItem:terms toSectionWithIdentifier:SectionIdentifierLinks];
SettingsTextItem* privacy =
[[SettingsTextItem alloc] initWithType:ItemTypeLinksPrivacy];
TableViewDetailTextItem* privacy =
[[TableViewDetailTextItem alloc] initWithType:ItemTypeLinksPrivacy];
privacy.text = l10n_util::GetNSString(IDS_IOS_PRIVACY_POLICY);
privacy.accessoryType = MDCCollectionViewCellAccessoryDisclosureIndicator;
privacy.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
privacy.accessibilityTraits = UIAccessibilityTraitButton;
[model addItem:privacy toSectionWithIdentifier:SectionIdentifierLinks];
[model addSectionWithIdentifier:SectionIdentifierFooter];
VersionItem* version = [[VersionItem alloc] initWithType:ItemTypeVersion];
version.text = [self versionDescriptionString];
version.accessibilityTraits = UIAccessibilityTraitButton;
[model addItem:version toSectionWithIdentifier:SectionIdentifierFooter];
[model setFooter:version forSectionWithIdentifier:SectionIdentifierLinks];
}
#pragma mark UICollectionViewDelegate
#pragma mark - UITableViewDelegate
- (void)collectionView:(UICollectionView*)collectionView
didSelectItemAtIndexPath:(NSIndexPath*)indexPath {
[super collectionView:collectionView didSelectItemAtIndexPath:indexPath];
NSInteger itemType =
[self.collectionViewModel itemTypeForIndexPath:indexPath];
- (UIView*)tableView:(UITableView*)tableView
viewForFooterInSection:(NSInteger)section {
UIView* footer = [super tableView:tableView viewForFooterInSection:section];
VersionFooter* versionFooter =
base::mac::ObjCCastStrict<VersionFooter>(footer);
versionFooter.delegate = self;
return footer;
}
- (void)tableView:(UITableView*)tableView
didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
NSInteger itemType = [self.tableViewModel itemTypeForIndexPath:indexPath];
switch (itemType) {
case ItemTypeLinksCredits:
[self openURL:GURL(kChromeUICreditsURL)];
......@@ -118,49 +134,15 @@ typedef NS_ENUM(NSInteger, ItemType) {
[self openURL:GURL(l10n_util::GetStringUTF8(IDS_IOS_PRIVACY_POLICY_URL))];
break;
case ItemTypeVersion:
[self copyVersionToPasteboard];
break;
default:
// Version is a footer, it is not interactable.
NOTREACHED();
break;
}
}
#pragma mark MDCCollectionViewStylingDelegate
// MDCCollectionViewStylingDelegate protocol is implemented so that the version
// cell has an invisible background.
- (MDCCollectionViewCellStyle)collectionView:(UICollectionView*)collectionView
cellStyleForSection:(NSInteger)section {
NSInteger sectionIdentifier =
[self.collectionViewModel sectionIdentifierForSection:section];
switch (sectionIdentifier) {
case SectionIdentifierFooter:
return MDCCollectionViewCellStyleDefault;
default:
return self.styler.cellStyle;
}
}
#pragma mark - VersionFooterDelegate
- (BOOL)collectionView:(UICollectionView*)collectionView
shouldHideItemBackgroundAtIndexPath:(NSIndexPath*)indexPath {
NSInteger sectionIdentifier =
[self.collectionViewModel sectionIdentifierForSection:indexPath.section];
switch (sectionIdentifier) {
case SectionIdentifierFooter:
return YES;
default:
return NO;
}
}
#pragma mark Private methods
- (void)openURL:(GURL)URL {
BlockToOpenURL(self, self.dispatcher)(URL);
}
- (void)copyVersionToPasteboard {
- (void)didTapVersionFooter:(VersionFooter*)footer {
[[UIPasteboard generalPasteboard] setString:[self versionOnlyString]];
TriggerHapticFeedbackForNotification(UINotificationFeedbackTypeSuccess);
NSString* messageText = l10n_util::GetNSString(IDS_IOS_VERSION_COPIED);
......@@ -170,6 +152,12 @@ typedef NS_ENUM(NSInteger, ItemType) {
[MDCSnackbarManager showMessage:message];
}
#pragma mark - Private methods
- (void)openURL:(GURL)URL {
BlockToOpenURL(self, self.dispatcher)(URL);
}
- (std::string)versionString {
std::string versionString = version_info::GetVersionNumber();
std::string versionStringModifier = GetChannelString();
......
......@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/settings/about_chrome_collection_view_controller.h"
#import "ios/chrome/browser/ui/settings/about_chrome_table_view_controller.h"
#import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h"
#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h"
#include "ios/chrome/grit/ios_strings.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -14,23 +14,24 @@
namespace {
class AboutChromeCollectionViewControllerTest
: public CollectionViewControllerTest {
class AboutChromeTableViewControllerTest
: public ChromeTableViewControllerTest {
public:
CollectionViewController* InstantiateController() override {
return [[AboutChromeCollectionViewController alloc] init];
ChromeTableViewController* InstantiateController() override {
return [[AboutChromeTableViewController alloc] init];
}
};
TEST_F(AboutChromeCollectionViewControllerTest, TestModel) {
TEST_F(AboutChromeTableViewControllerTest, TestModel) {
CreateController();
CheckController();
EXPECT_EQ(2, NumberOfSections());
EXPECT_EQ(1, NumberOfSections());
EXPECT_EQ(3, NumberOfItemsInSection(0));
CheckTextCellTitleWithId(IDS_IOS_OPEN_SOURCE_LICENSES, 0, 0);
CheckTextCellTitleWithId(IDS_IOS_TERMS_OF_SERVICE, 0, 1);
CheckTextCellTitleWithId(IDS_IOS_PRIVACY_POLICY, 0, 2);
EXPECT_NE(nil, [controller().tableViewModel footerForSection:0]);
CheckTextCellTextWithId(IDS_IOS_OPEN_SOURCE_LICENSES, 0, 0);
CheckTextCellTextWithId(IDS_IOS_TERMS_OF_SERVICE, 0, 1);
CheckTextCellTextWithId(IDS_IOS_PRIVACY_POLICY, 0, 2);
}
} // namespace
......@@ -104,6 +104,7 @@ source_set("unit_tests") {
"//ios/chrome/browser/browsing_data:counters",
"//ios/chrome/browser/ui/collection_view/cells",
"//ios/chrome/browser/ui/collection_view/cells:test_support",
"//ios/chrome/browser/ui/table_view:styler",
"//ios/web/public/test:test",
"//testing/gtest",
"//ui/base",
......
......@@ -7,23 +7,35 @@
#import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h"
@class VersionFooter;
// Protocol notified when the footer is tapped.
@protocol VersionFooterDelegate
// Called when the version footer is tapped.
- (void)didTapVersionFooter:(VersionFooter*)footer;
@end
// Item to display the version of the current build.
@interface VersionItem : CollectionViewItem
@interface VersionItem : TableViewHeaderFooterItem
// The display string representing the version.
@property(nonatomic, copy) NSString* text;
@end
// Cell class associated to VersionItem.
@interface VersionCell : MDCCollectionViewCell
// Footer view class associated to VersionItem.
@interface VersionFooter : UITableViewHeaderFooterView
// Label for the current build version.
@property(nonatomic, readonly, strong) UILabel* textLabel;
// Delegate.
@property(nonatomic, weak) id<VersionFooterDelegate> delegate;
@end
#endif // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_VERSION_ITEM_H_
......@@ -5,16 +5,22 @@
#import "ios/chrome/browser/ui/settings/cells/version_item.h"
#include "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
#import "ios/chrome/common/ui_util/constraints_ui_util.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
#include "ui/base/l10n/l10n_util_mac.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
const CGFloat kVerticalSpacing = 16;
} // namespace
#pragma mark - VersionItem
@implementation VersionItem
@synthesize text = _text;
......@@ -23,26 +29,29 @@
self = [super initWithType:type];
if (self) {
self.accessibilityIdentifier = @"Version cell";
self.cellClass = [VersionCell class];
self.cellClass = [VersionFooter class];
}
return self;
}
#pragma mark CollectionViewItem
#pragma mark - TableViewHeaderFooterItem
- (void)configureCell:(VersionCell*)cell {
[super configureCell:cell];
cell.textLabel.text = self.text;
- (void)configureHeaderFooterView:(VersionFooter*)headerFooter
withStyler:(ChromeTableViewStyler*)styler {
[super configureHeaderFooterView:headerFooter withStyler:styler];
headerFooter.textLabel.text = self.text;
}
@end
@implementation VersionCell
#pragma mark - VersionFooter
@implementation VersionFooter
@synthesize textLabel = _textLabel;
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
- (instancetype)initWithReuseIdentifier:(NSString*)reuseIdentifier {
self = [super initWithReuseIdentifier:reuseIdentifier];
if (self) {
self.isAccessibilityElement = YES;
self.accessibilityTraits |= UIAccessibilityTraitButton;
......@@ -50,19 +59,35 @@
_textLabel = [[UILabel alloc] init];
_textLabel.translatesAutoresizingMaskIntoConstraints = NO;
_textLabel.font = [UIFont systemFontOfSize:kUIKitFooterFontSize];
_textLabel.textColor = UIColorFromRGB(kUIKitFooterTextColor);
_textLabel.font =
[UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
_textLabel.textColor =
UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor);
_textLabel.backgroundColor = [UIColor clearColor];
_textLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:_textLabel];
[self.contentView addSubview:_textLabel];
// Set up the constraints.
UIButton* button = [[UIButton alloc] init];
button.translatesAutoresizingMaskIntoConstraints = NO;
[button addTarget:self
action:@selector(buttonTapped)
forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:button];
AddSameConstraints(button, self.contentView);
[NSLayoutConstraint activateConstraints:@[
[_textLabel.centerXAnchor constraintEqualToAnchor:self.centerXAnchor],
[_textLabel.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],
[self.contentView.heightAnchor constraintGreaterThanOrEqualToConstant:
kTableViewHeaderFooterViewHeight],
[_textLabel.leadingAnchor
constraintEqualToAnchor:self.contentView.leadingAnchor],
[_textLabel.trailingAnchor
constraintEqualToAnchor:self.contentView.trailingAnchor],
[_textLabel.topAnchor constraintEqualToAnchor:self.contentView.topAnchor
constant:kVerticalSpacing],
[_textLabel.bottomAnchor
constraintEqualToAnchor:self.contentView.bottomAnchor
constant:-kVerticalSpacing]
]];
self.shouldHideSeparator = YES;
}
return self;
}
......@@ -71,4 +96,18 @@
return self.textLabel.text;
}
#pragma mark - UITableViewHeaderFooterView
- (void)prepareForReuse {
[super prepareForReuse];
self.delegate = nil;
}
#pragma mark - Private
// Callback for the button
- (void)buttonTapped {
[self.delegate didTapVersionFooter:self];
}
@end
......@@ -5,6 +5,7 @@
#import "ios/chrome/browser/ui/settings/cells/version_item.h"
#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
......@@ -19,11 +20,12 @@ using VersionItemTest = PlatformTest;
TEST_F(VersionItemTest, TextLabelGetsText) {
VersionItem* item = [[VersionItem alloc] initWithType:0];
VersionCell* cell = [[[item cellClass] alloc] init];
EXPECT_TRUE([cell isMemberOfClass:[VersionCell class]]);
VersionFooter* cell = [[[item cellClass] alloc] init];
EXPECT_TRUE([cell isMemberOfClass:[VersionFooter class]]);
item.text = @"Foo";
[item configureCell:cell];
[item configureHeaderFooterView:cell
withStyler:[[ChromeTableViewStyler alloc] init]];
EXPECT_NSEQ(@"Foo", cell.textLabel.text);
}
......
......@@ -42,7 +42,7 @@
#import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
#import "ios/chrome/browser/ui/commands/settings_main_page_commands.h"
#import "ios/chrome/browser/ui/settings/about_chrome_collection_view_controller.h"
#import "ios/chrome/browser/ui/settings/about_chrome_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/accounts_collection_view_controller.h"
#import "ios/chrome/browser/ui/settings/autofill_credit_card_collection_view_controller.h"
#import "ios/chrome/browser/ui/settings/autofill_profile_collection_view_controller.h"
......@@ -887,7 +887,7 @@ void IdentityObserverBridge::OnPrimaryAccountCleared(
initWithBrowserState:_browserState];
break;
case ItemTypeAboutChrome:
controller = [[AboutChromeCollectionViewController alloc] init];
controller = [[AboutChromeTableViewController alloc] init];
break;
case ItemTypeMemoryDebugging:
case ItemTypeViewSource:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment