Skip to content

Commit

Permalink
[ios] Add single module Magic Stack layout
Browse files Browse the repository at this point in the history
This change ensures that a module's width is the same wide width
as the Magic Stack itself if it is the only module in the Magic Stack.
This will allow it to be the same width as the MVT module, giving a
consistent layout.

(cherry picked from commit 2e13eb2)

Bug: 1432252, 1449339
Change-Id: Ic7800aedb7048e89c7107f94e3e3758f95bf92c0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4568589
Reviewed-by: Scott Yoder <scottyoder@google.com>
Commit-Queue: Chris Lu <thegreenfrog@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1149906}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4582091
Auto-Submit: Chris Lu <thegreenfrog@chromium.org>
Commit-Queue: Scott Yoder <scottyoder@google.com>
Cr-Commit-Position: refs/branch-heads/5790@{#266}
Cr-Branched-From: 1d71a33-refs/heads/main@{#1148114}
  • Loading branch information
Chris Lu authored and Chromium LUCI CQ committed Jun 2, 2023
1 parent 85c13d6 commit 423d7f0
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 24 deletions.
1 change: 1 addition & 0 deletions ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn
Expand Up @@ -26,6 +26,7 @@ source_set("cells") {
"content_suggestions_tile_view.mm",
"magic_stack_module_container.h",
"magic_stack_module_container.mm",
"magic_stack_module_container_delegate.h",
"multi_row_container_view.h",
"multi_row_container_view.mm",
"query_suggestion_view.h",
Expand Down
Expand Up @@ -8,13 +8,16 @@
#import <UIKit/UIKit.h>

enum class ContentSuggestionsModuleType;
@protocol MagicStackModuleContainerDelegate;

// Container View for a module in the Magic Stack.
@interface MagicStackModuleContainer : UIView

// Initialize and configure with `contentView` for `type`.
- (instancetype)initWithContentView:(UIView*)contentView
type:(ContentSuggestionsModuleType)type;
type:(ContentSuggestionsModuleType)type
delegate:
(id<MagicStackModuleContainerDelegate>)delegate;
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;

Expand Down
Expand Up @@ -5,6 +5,7 @@
#import "ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.h"

#import "base/notreached.h"
#import "ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container_delegate.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h"
#import "ios/chrome/common/ui/colors/semantic_color_names.h"
Expand Down Expand Up @@ -48,6 +49,7 @@ @interface MagicStackModuleContainer ()

@implementation MagicStackModuleContainer {
NSLayoutConstraint* _contentViewWidthAnchor;
id<MagicStackModuleContainerDelegate> _delegate;
}

- (instancetype)initWithType:(ContentSuggestionsModuleType)type {
Expand All @@ -58,11 +60,13 @@ - (instancetype)initWithType:(ContentSuggestionsModuleType)type {
}

- (instancetype)initWithContentView:(UIView*)contentView
type:(ContentSuggestionsModuleType)type {
type:(ContentSuggestionsModuleType)type
delegate:
(id<MagicStackModuleContainerDelegate>)delegate {
self = [super initWithFrame:CGRectZero];
if (self) {
_type = type;

_delegate = delegate;
self.layer.cornerRadius = kCornerRadius;
self.backgroundColor = [UIColor colorNamed:kBackgroundColor];

Expand Down Expand Up @@ -136,12 +140,19 @@ - (NSDirectionalEdgeInsets)contentMargins {
}

- (CGSize)intrinsicContentSize {
// When the Most Visited Tiles module is not in the Magic Stack in a wider
// screen, the module is wider to match the wider Magic Stack ScrollView.
if (_type == ContentSuggestionsModuleType::kMostVisited &&
!ShouldPutMostVisitedSitesInMagicStack() &&
// When the Most Visited Tiles module is not in the Magic Stack or if a module
// is the only module in the Magic Stack in a wider screen, the module should
// be wider to match the wider Magic Stack ScrollView.
BOOL MVTModuleShouldUseWideWidth =
(_type == ContentSuggestionsModuleType::kMostVisited &&
!ShouldPutMostVisitedSitesInMagicStack() &&
self.traitCollection.horizontalSizeClass ==
UIUserInterfaceSizeClassRegular);
BOOL moduleShouldUseWideWidth =
self.traitCollection.horizontalSizeClass ==
UIUserInterfaceSizeClassRegular) {
UIUserInterfaceSizeClassRegular &&
[_delegate doesMagicStackShowOnlyOneModule:_type];
if (MVTModuleShouldUseWideWidth || moduleShouldUseWideWidth) {
return CGSizeMake(kMagicStackWideWidth, self.bounds.size.height);
}
return CGSizeMake(
Expand Down
@@ -0,0 +1,19 @@
// Copyright 2023 The Chromium Authors
// 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_CONTENT_SUGGESTIONS_CELLS_MAGIC_STACK_MODULE_CONTAINER_DELEGATE_H_
#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_MAGIC_STACK_MODULE_CONTAINER_DELEGATE_H_

enum class ContentSuggestionsModuleType;

// Protocol asking the receiver for more contextual information about modules.
@protocol MagicStackModuleContainerDelegate

// YES if the module of `type` is the only module being shown in the Magic
// Stack.
- (BOOL)doesMagicStackShowOnlyOneModule:(ContentSuggestionsModuleType)type;

@end

#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_MAGIC_STACK_MODULE_CONTAINER_DELEGATE_H_
Expand Up @@ -23,6 +23,7 @@
#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_shortcut_tile_view.h"
#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_tile_layout_util.h"
#import "ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.h"
#import "ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container_delegate.h"
#import "ios/chrome/browser/ui/content_suggestions/cells/multi_row_container_view.h"
#import "ios/chrome/browser/ui/content_suggestions/cells/query_suggestion_view.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h"
Expand Down Expand Up @@ -78,6 +79,7 @@
@interface ContentSuggestionsViewController () <
UIGestureRecognizerDelegate,
ContentSuggestionsSelectionActions,
MagicStackModuleContainerDelegate,
SetUpListItemViewTapDelegate,
URLDropDelegate,
UIScrollViewDelegate,
Expand Down Expand Up @@ -407,6 +409,7 @@ - (void)updateMostVisitedTileConfig:(ContentSuggestionsMostVisitedItem*)config {
}

- (void)setMagicStackOrder:(NSArray<NSNumber*>*)order {
CHECK([order count] > 0);
_shouldShowMagicStack = YES;
_magicStackModuleOrder = order;
}
Expand Down Expand Up @@ -483,7 +486,8 @@ - (void)showSetUpListWithItems:(NSArray<SetUpListItemViewData*>*)items {
[[MagicStackModuleContainer alloc]
initWithContentView:multiRowContainer
type:ContentSuggestionsModuleType::
kCompactedSetUpList];
kCompactedSetUpList
delegate:self];
[_magicStack
insertArrangedSubview:setUpListCompactedModule
atIndex:[self indexForMagicStackModule:
Expand All @@ -492,7 +496,8 @@ - (void)showSetUpListWithItems:(NSArray<SetUpListItemViewData*>*)items {
} else {
MagicStackModuleContainer* setUpListModule =
[[MagicStackModuleContainer alloc] initWithContentView:view
type:type];
type:type
delegate:self];
[_magicStack
insertArrangedSubview:setUpListModule
atIndex:[self indexForMagicStackModule:type]];
Expand Down Expand Up @@ -583,7 +588,8 @@ - (void)showSetUpListDoneWithAnimations:(ProceduralBlock)animations {
[[SetUpListItemView alloc] initWithData:allSetData];
MagicStackModuleContainer* allSetModule = [[MagicStackModuleContainer alloc]
initWithContentView:view
type:ContentSuggestionsModuleType::kSetUpListAllSet];
type:ContentSuggestionsModuleType::kSetUpListAllSet
delegate:self];
// Determine which module to swap out.
[self replaceModuleAtIndex:
[self indexForMagicStackModule:[self currentlyShownModule]]
Expand Down Expand Up @@ -699,8 +705,7 @@ - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
if (previousTraitCollection.horizontalSizeClass !=
self.traitCollection.horizontalSizeClass) {
if (self.traitCollection.horizontalSizeClass ==
UIUserInterfaceSizeClassRegular) {
if ([self shouldShowWiderMagicStackLayer]) {
_magicStackScrollView.clipsToBounds = YES;
_magicStackScrollViewWidthAnchor.constant = kMagicStackWideWidth;
} else {
Expand Down Expand Up @@ -730,6 +735,20 @@ - (NSString*)accessibilityScrollStatusForScrollView:(UIScrollView*)scrollView {
titleStringForModule:[self currentlyShownModule]];
}

#pragma mark - MagicStackModuleContainer

- (BOOL)doesMagicStackShowOnlyOneModule:(ContentSuggestionsModuleType)type {
// Return NO if Most Visited Module is asking while it is not in the Magic
// Stack.
if (type == ContentSuggestionsModuleType::kMostVisited &&
!ShouldPutMostVisitedSitesInMagicStack()) {
return NO;
}
ContentSuggestionsModuleType firstModuleType = (ContentSuggestionsModuleType)[
[_magicStackModuleOrder objectAtIndex:0] intValue];
return [_magicStackModuleOrder count] == 1 && firstModuleType == type;
}

#pragma mark - Private

- (void)addUIElement:(UIView*)view withCustomBottomSpacing:(CGFloat)spacing {
Expand All @@ -756,7 +775,8 @@ - (void)createAndInsertMostVisitedModule {
if (IsMagicStackEnabled()) {
self.mostVisitedModuleContainer = [[MagicStackModuleContainer alloc]
initWithContentView:self.mostVisitedStackView
type:ContentSuggestionsModuleType::kMostVisited];
type:ContentSuggestionsModuleType::kMostVisited
delegate:self];
if (ShouldPutMostVisitedSitesInMagicStack()) {
// Only add it to the Magic Stack here if it is after the inital
// construction of the Magic Stack.
Expand Down Expand Up @@ -832,9 +852,7 @@ - (UIStackView*)createShortcutsStackView {
- (void)createMagicStack {
_magicStackScrollView = [[UIScrollView alloc] init];
[_magicStackScrollView setShowsHorizontalScrollIndicator:NO];
_magicStackScrollView.clipsToBounds =
self.traitCollection.horizontalSizeClass ==
UIUserInterfaceSizeClassRegular;
_magicStackScrollView.clipsToBounds = [self shouldShowWiderMagicStackLayer];
_magicStackScrollView.delegate = self;
_magicStackScrollView.accessibilityIdentifier =
kMagicStackScrollViewAccessibilityIdentifier;
Expand All @@ -858,7 +876,8 @@ - (void)createMagicStack {
case ContentSuggestionsModuleType::kShortcuts: {
self.shortcutsModuleContainer = [[MagicStackModuleContainer alloc]
initWithContentView:self.shortcutsStackView
type:type];
type:type
delegate:self];
[_magicStack addArrangedSubview:self.shortcutsModuleContainer];
break;
}
Expand All @@ -872,23 +891,26 @@ - (void)createMagicStack {
MagicStackModuleContainer* setUpListSyncModule =
[[MagicStackModuleContainer alloc]
initWithContentView:_setUpListSyncItemView
type:type];
type:type
delegate:self];
[_magicStack addArrangedSubview:setUpListSyncModule];
break;
}
case ContentSuggestionsModuleType::kSetUpListDefaultBrowser: {
MagicStackModuleContainer* setUpListDefaultBrowserModule =
[[MagicStackModuleContainer alloc]
initWithContentView:_setUpListDefaultBrowserItemView
type:type];
type:type
delegate:self];
[_magicStack addArrangedSubview:setUpListDefaultBrowserModule];
break;
}
case ContentSuggestionsModuleType::kSetUpListAutofill: {
MagicStackModuleContainer* setUpListAutofillModule =
[[MagicStackModuleContainer alloc]
initWithContentView:_setUpListAutofillItemView
type:type];
type:type
delegate:self];
[_magicStack addArrangedSubview:setUpListAutofillModule];
break;
}
Expand All @@ -900,7 +922,8 @@ - (void)createMagicStack {
[[MagicStackModuleContainer alloc]
initWithContentView:multiRowContainer
type:ContentSuggestionsModuleType::
kCompactedSetUpList];
kCompactedSetUpList
delegate:self];
[_magicStack addArrangedSubview:setUpListCompactedModule];
break;
}
Expand All @@ -916,8 +939,7 @@ - (void)createMagicStack {
moduleWidthForHorizontalTraitCollection:self.traitCollection];
// Magic Stack has a wider width for wider screens so that clipToBounds can be
// YES with a peeking module still visible.
if (self.traitCollection.horizontalSizeClass ==
UIUserInterfaceSizeClassRegular) {
if ([self shouldShowWiderMagicStackLayer]) {
width = kMagicStackWideWidth;
}
_magicStackScrollViewWidthAnchor =
Expand All @@ -930,6 +952,12 @@ - (void)createMagicStack {
]];
}

// YES if the Magic Stack should be using a wider layout.
- (BOOL)shouldShowWiderMagicStackLayer {
return self.traitCollection.horizontalSizeClass ==
UIUserInterfaceSizeClassRegular;
}

// Returns the index position `moduleType` should be placed in the Magic Stack.
// This should only be used when looking to add a module after the inital Magic
// Stack construction.
Expand Down

0 comments on commit 423d7f0

Please sign in to comment.