Commit 101061b7 authored by Chris Lu's avatar Chris Lu Committed by Commit Bot

[ios] Style Recent Tabs Signed In Sync Off Cell

Creates new tableviewtextactionbuttonitem and tableviewtextactionbuttoncell for signed in, but not synced, state in recent tabs.
Can be reused for signin promo when that time comes.

Screenshot: https://drive.google.com/open?id=14BFzN7256LtFGvGUl2yU9HDOFqaBQisJ

Bug: 822988
Change-Id: I9634282b7e65d2d740db43f6425413a69b25b5b8
Reviewed-on: https://chromium-review.googlesource.com/1048873
Commit-Queue: Chris Lu <thegreenfrog@chromium.org>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#559324}
parent 6c82fd92
......@@ -31,12 +31,14 @@
#import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_handset_view_controller.h"
#include "ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.h"
#import "ios/chrome/browser/ui/settings/sync_utils/sync_presenter.h"
#import "ios/chrome/browser/ui/settings/sync_utils/sync_util.h"
#import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_accessory_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_activity_indicator_header_footer_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_disclosure_header_footer_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_signin_promo_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_url_item.h"
#include "ios/chrome/browser/ui/ui_util.h"
......@@ -91,6 +93,7 @@ const int kRelativeTimeMaxHours = 4;
@interface RecentTabsTableViewController ()<SigninPromoViewConsumer,
SigninPresenter,
SyncPresenter,
TextButtonItemDelegate,
UIGestureRecognizerDelegate> {
std::unique_ptr<synced_sessions::SyncedSessions> _syncedSessions;
}
......@@ -418,12 +421,8 @@ const int kRelativeTimeMaxHours = 4;
NOTREACHED();
return;
case SessionsSyncUserState::USER_SIGNED_IN_SYNC_OFF:
dummyCell =
[[TableViewTextItem alloc] initWithType:ItemTypeOtherDevicesSyncOff];
dummyCell.text =
l10n_util::GetNSString(IDS_IOS_OPEN_TABS_ENABLE_SYNC_MOBILE);
dummyCell.textAlignment = NSTextAlignmentCenter;
break;
[self addUserSignedSyncOffItem];
return;
case SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_NO_SESSIONS:
dummyCell = [[TableViewTextItem alloc]
initWithType:ItemTypeOtherDevicesNoSessions];
......@@ -443,6 +442,18 @@ const int kRelativeTimeMaxHours = 4;
toSectionWithIdentifier:SectionIdentifierOtherDevices];
}
- (void)addUserSignedSyncOffItem {
TableViewTextButtonItem* signinSyncOffItem = [[TableViewTextButtonItem alloc]
initWithType:ItemTypeOtherDevicesSyncOff];
signinSyncOffItem.text =
l10n_util::GetNSString(IDS_IOS_OPEN_TABS_SYNC_IS_OFF_MOBILE);
signinSyncOffItem.buttonText =
l10n_util::GetNSString(IDS_IOS_OPEN_TABS_ENABLE_SYNC_MOBILE);
signinSyncOffItem.delegate = self;
[self.tableViewModel addItem:signinSyncOffItem
toSectionWithIdentifier:SectionIdentifierOtherDevices];
}
- (void)addSigninPromoViewItem {
// Init|_signinPromoViewMediator| if nil.
if (!self.signinPromoViewMediator) {
......@@ -1053,6 +1064,20 @@ const int kRelativeTimeMaxHours = 4;
[self.dispatcher showSyncPassphraseSettingsFromViewController:self];
}
#pragma mark - TextButtonItemDelegate
- (void)performButtonAction {
SyncSetupService::SyncServiceState syncState =
GetSyncStateForBrowserState(_browserState);
if (ShouldShowSyncSignin(syncState)) {
[self showReauthenticateSignin];
} else if (ShouldShowSyncSettings(syncState)) {
[self showSyncSettings];
} else if (ShouldShowSyncPassphraseSettings(syncState)) {
[self showSyncPassphraseSettings];
}
}
#pragma mark - SigninPresenter
- (void)showSignin:(ShowSigninCommand*)command {
......
......@@ -5,6 +5,7 @@
#import "ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_accessory_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_url_item.h"
......@@ -25,6 +26,7 @@ typedef NS_ENUM(NSInteger, ItemType) {
ItemTypeText = kItemTypeEnumZero,
ItemTypeTextHeader,
ItemTypeTextFooter,
ItemTypeTextButton,
ItemTypeURLNoMetadata,
ItemTypeTextAccessoryImage,
ItemTypeTextAccessoryNoImage,
......@@ -99,6 +101,13 @@ typedef NS_ENUM(NSInteger, ItemType) {
[model setFooter:textHeaderFooterItem
forSectionWithIdentifier:SectionIdentifierText];
TableViewTextButtonItem* textActionButtonItem =
[[TableViewTextButtonItem alloc] initWithType:ItemTypeTextButton];
textActionButtonItem.text = @"Hello, you should do something.";
textActionButtonItem.buttonText = @"Do something";
[model setFooter:textActionButtonItem
forSectionWithIdentifier:SectionIdentifierText];
// SectionIdentifierURL.
TableViewURLItem* item =
[[TableViewURLItem alloc] initWithType:ItemTypeURLNoMetadata];
......
......@@ -18,6 +18,8 @@ source_set("cells") {
"table_view_item.mm",
"table_view_signin_promo_item.h",
"table_view_signin_promo_item.mm",
"table_view_text_button_item.h",
"table_view_text_button_item.mm",
"table_view_text_header_footer_item.h",
"table_view_text_header_footer_item.mm",
"table_view_text_item.h",
......@@ -47,6 +49,7 @@ source_set("unit_tests") {
"table_view_accessory_item_unittest.mm",
"table_view_header_footer_item_unittest.mm",
"table_view_item_unittest.mm",
"table_view_text_button_item_unittest.mm",
"table_view_text_header_footer_item_unittest.mm",
"table_view_text_item_unittest.mm",
"table_view_url_item_unittest.mm",
......@@ -57,6 +60,7 @@ source_set("unit_tests") {
"//base",
"//ios/chrome/browser/ui/table_view:styler",
"//testing/gtest",
"//third_party/ocmock:ocmock",
]
configs += [ "//build/config/compiler:enable_arc" ]
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// 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_TABLE_VIEW_CELLS_TABLE_VIEW_TEXT_BUTTON_ITEM_H_
#define IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_TEXT_BUTTON_ITEM_H_
#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
@protocol TextButtonItemDelegate<NSObject>
// Delegates an action to be performed by the presenter.
- (void)performButtonAction;
@end
// TableViewTextButtonItem contains the model for
// TableViewTextButtonCell.
@interface TableViewTextButtonItem : TableViewItem
// EnableSyncActionDelegate to perform TableViewTextButtonCell actions.
@property(nonatomic, weak) id<TextButtonItemDelegate> delegate;
// Text being displayed above the button.
@property(nonatomic, readwrite, strong) NSString* text;
// Text for cell button.
@property(nonatomic, readwrite, strong) NSString* buttonText;
@end
// TableViewTextButtonCell contains a textLabel and a UIbutton
// laid out vertically and centered.
@interface TableViewTextButtonCell : UITableViewCell
// Delegate used to show sync settings options.
@property(nonatomic, weak) id<TextButtonItemDelegate> delegate;
// Cell text information.
@property(nonatomic, strong) UILabel* textLabel;
// Action button.
@property(nonatomic, strong) UIButton* button;
@end
#endif // IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_TEXT_BUTTON_ITEM_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// 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/table_view/cells/table_view_text_button_item.h"
#include "base/mac/foundation_util.h"
#import "ios/chrome/browser/ui/uikit_ui_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Text label gray color.
const CGFloat grayHexColor = 0x6d6d72;
// Action button blue background color.
const CGFloat blueHexColor = 0x1A73E8;
// Vertical spacing between stackView and cell contentView.
const CGFloat stackViewVerticalSpacing = 9.0;
// Horizontal spacing between stackView and cell contentView.
const CGFloat stackViewHorizontalSpacing = 16.0;
// SubView spacing within stackView.
const CGFloat stackViewSubViewSpacing = 13.0;
// Horizontal Inset between button contents and edge.
const CGFloat buttonTitleHorizontalContentInset = 40.0;
// Vertical Inset between button contents and edge.
const CGFloat buttonTitleVerticalContentInset = 8.0;
// Button corner radius.
const CGFloat buttonCornerRadius = 8;
} // namespace
@implementation TableViewTextButtonItem
@synthesize delegate = _delegate;
@synthesize text = _text;
@synthesize buttonText = _buttonText;
- (instancetype)initWithType:(NSInteger)type {
self = [super initWithType:type];
if (self) {
self.cellClass = [TableViewTextButtonCell class];
}
return self;
}
- (void)configureCell:(UITableViewCell*)tableCell
withStyler:(ChromeTableViewStyler*)styler {
[super configureCell:tableCell withStyler:styler];
TableViewTextButtonCell* cell =
base::mac::ObjCCastStrict<TableViewTextButtonCell>(tableCell);
cell.delegate = self.delegate;
cell.textLabel.text = self.text;
[cell.button setTitle:self.buttonText forState:UIControlStateNormal];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
@end
@implementation TableViewTextButtonCell
@synthesize delegate = _delegate;
@synthesize textLabel = _textLabel;
@synthesize button = _button;
- (instancetype)initWithStyle:(UITableViewCellStyle)style
reuseIdentifier:(NSString*)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Create informative text label.
self.textLabel = [[UILabel alloc] init];
self.textLabel.numberOfLines = 0;
self.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.textLabel.textAlignment = NSTextAlignmentCenter;
self.textLabel.font =
[UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
self.textLabel.textColor = UIColorFromRGB(grayHexColor);
// Create button.
self.button = [[UIButton alloc] init];
self.button.backgroundColor = UIColorFromRGB(blueHexColor);
[self.button setTitleColor:[UIColor whiteColor]
forState:UIControlStateNormal];
self.button.translatesAutoresizingMaskIntoConstraints = NO;
[self.button.titleLabel
setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]];
self.button.layer.cornerRadius = buttonCornerRadius;
self.button.clipsToBounds = YES;
self.button.contentEdgeInsets = UIEdgeInsetsMake(
buttonTitleVerticalContentInset, buttonTitleHorizontalContentInset,
buttonTitleVerticalContentInset, buttonTitleHorizontalContentInset);
[self.button addTarget:self
action:@selector(performButtonAction)
forControlEvents:UIControlEventTouchUpInside];
// Vertical stackView to hold label and button.
UIStackView* verticalStackView = [[UIStackView alloc]
initWithArrangedSubviews:@[ self.textLabel, self.button ]];
verticalStackView.alignment = UIStackViewAlignmentCenter;
verticalStackView.axis = UILayoutConstraintAxisVertical;
verticalStackView.spacing = stackViewSubViewSpacing;
verticalStackView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:verticalStackView];
// Add constraints for stackView
[NSLayoutConstraint activateConstraints:@[
[verticalStackView.leadingAnchor
constraintEqualToAnchor:self.contentView.leadingAnchor
constant:stackViewHorizontalSpacing],
[verticalStackView.trailingAnchor
constraintEqualToAnchor:self.contentView.trailingAnchor
constant:-stackViewHorizontalSpacing],
[verticalStackView.topAnchor
constraintEqualToAnchor:self.contentView.topAnchor
constant:stackViewVerticalSpacing],
[verticalStackView.bottomAnchor
constraintEqualToAnchor:self.contentView.bottomAnchor
constant:-stackViewVerticalSpacing]
]];
}
return self;
}
#pragma mark - TextButtonItemDelegate
- (void)performButtonAction {
[self.delegate performButtonAction];
}
@end
// Copyright 2018 The Chromium Authors. All rights reserved.
// 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/table_view/cells/table_view_text_button_item.h"
#include "base/mac/foundation_util.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"
#import "third_party/ocmock/OCMock/OCMock.h"
#import "third_party/ocmock/gtest_support.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
using TableViewTextButtonItemTest = PlatformTest;
}
// Tests that the UILabels and delegate are set properly after a call to
// |configureCell:|.
TEST_F(TableViewTextButtonItemTest, SetProperties) {
NSString* text = @"You need to do something.";
NSString* buttonText = @"Tap to do something.";
id<TextButtonItemDelegate> mock_delegate =
[OCMockObject mockForProtocol:@protocol(TextButtonItemDelegate)];
TableViewTextButtonItem* item =
[[TableViewTextButtonItem alloc] initWithType:0];
item.text = text;
item.buttonText = buttonText;
item.delegate = mock_delegate;
id cell = [[[item cellClass] alloc] init];
ASSERT_TRUE([cell isMemberOfClass:[TableViewTextButtonCell class]]);
TableViewTextButtonCell* textButtonCell =
base::mac::ObjCCastStrict<TableViewTextButtonCell>(cell);
EXPECT_FALSE(textButtonCell.textLabel.text);
EXPECT_FALSE(textButtonCell.button.titleLabel.text);
EXPECT_FALSE(textButtonCell.delegate);
[item configureCell:textButtonCell
withStyler:[[ChromeTableViewStyler alloc] init]];
EXPECT_NSEQ(text, textButtonCell.textLabel.text);
EXPECT_NSEQ(buttonText, textButtonCell.button.titleLabel.text);
EXPECT_TRUE(textButtonCell.delegate);
}
// Test that pressing the button invokes delegate.
TEST_F(TableViewTextButtonItemTest, DelegateCalled) {
TableViewTextButtonItem* item =
[[TableViewTextButtonItem alloc] initWithType:0];
id cell = [[[item cellClass] alloc] init];
ASSERT_TRUE([cell isMemberOfClass:[TableViewTextButtonCell class]]);
TableViewTextButtonCell* textButtonCell =
base::mac::ObjCCastStrict<TableViewTextButtonCell>(cell);
id<TextButtonItemDelegate> mock_delegate =
[OCMockObject mockForProtocol:@protocol(TextButtonItemDelegate)];
[textButtonCell setDelegate:mock_delegate];
OCMockObject* mock_delegate_obj = (OCMockObject*)mock_delegate;
[[mock_delegate_obj expect] performButtonAction];
UIButton* button = textButtonCell.button;
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
EXPECT_OCMOCK_VERIFY(mock_delegate_obj);
}
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