Commit 047adda3 authored by Jérôme Lebel's avatar Jérôme Lebel Committed by Commit Bot

[iOS] Moving collapsable code from TableViewModel to ListModel

Moving code to implement collapsable model from TableViewModel to
ListModel. The benefit is to have collapsable collection view too.

Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: Iff0d0bd9c15358ba21b82fdda9e373e8b1079656
Reviewed-on: https://chromium-review.googlesource.com/1101518
Commit-Queue: Jérôme Lebel <jlebel@chromium.org>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#568382}
parent 246d8985
...@@ -21,6 +21,7 @@ source_set("unit_tests") { ...@@ -21,6 +21,7 @@ source_set("unit_tests") {
testonly = true testonly = true
sources = [ sources = [
"list_item_unittest.mm", "list_item_unittest.mm",
"list_model_collapse_unittest.mm",
"list_model_unittest.mm", "list_model_unittest.mm",
] ]
deps = [ deps = [
......
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
@class ListItem; @class ListItem;
// Key for saving collapsed state in the NSUserDefaults.
extern NSString* const kListModelCollapsedKey;
// Use these as the starting value for section identifier and item type enums. // Use these as the starting value for section identifier and item type enums.
// These are provided to help not mix between indexPath's section/item and the // These are provided to help not mix between indexPath's section/item and the
// model section identifier / item type. // model section identifier / item type.
...@@ -184,6 +187,23 @@ const NSInteger kItemTypeEnumZero = 100; ...@@ -184,6 +187,23 @@ const NSInteger kItemTypeEnumZero = 100;
// Returns the number of items in the given section. // Returns the number of items in the given section.
- (NSInteger)numberOfItemsInSection:(NSInteger)section; - (NSInteger)numberOfItemsInSection:(NSInteger)section;
#pragma mark Collapsing methods.
// Sets an existing |sectionIdentifier| |collapsedKey| to be used when
// collapsing or expanding a section. |collapsedKey| is a unique identifier for
// each section that will be used for persisting information about the collapsed
// state of a section. A |collapsedKey| its only needed when
// collapsing/expanding sections. You can't collapse/expand any sections without
// a |collapsedKey|.
- (void)setSectionIdentifier:(NSInteger)sectionIdentifier
collapsedKey:(NSString*)collapsedKey;
// Sets the state of an existing |sectionIdentifier| to |collapsed|. A
// collapsedKey has to be previously set or this method will DCHECK().
- (void)setSection:(NSInteger)sectionIdentifier collapsed:(BOOL)collapsed;
// Returns YES if |sectionIdentifier| is collapsed. If not collapsedKey has been
// set it will also return NO.
- (BOOL)sectionIsCollapsed:(NSInteger)sectionIdentifier;
@end @end
#endif // IOS_CHROME_BROWSER_UI_LIST_MODEL_LIST_MODEL_H_ #endif // IOS_CHROME_BROWSER_UI_LIST_MODEL_LIST_MODEL_H_
...@@ -12,7 +12,10 @@ ...@@ -12,7 +12,10 @@
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
NSString* const kListModelCollapsedKey = @"ChromeListModelCollapsedSections";
namespace { namespace {
typedef NSMutableArray<ListItem*> SectionItems; typedef NSMutableArray<ListItem*> SectionItems;
} }
...@@ -26,6 +29,9 @@ typedef NSMutableArray<ListItem*> SectionItems; ...@@ -26,6 +29,9 @@ typedef NSMutableArray<ListItem*> SectionItems;
// Maps from section identifier to header and footer. // Maps from section identifier to header and footer.
NSMutableDictionary<NSNumber*, ListItem*>* _headers; NSMutableDictionary<NSNumber*, ListItem*>* _headers;
NSMutableDictionary<NSNumber*, ListItem*>* _footers; NSMutableDictionary<NSNumber*, ListItem*>* _footers;
// Maps from collapsed keys to section identifier.
NSMutableDictionary<NSNumber*, NSString*>* _collapsedKeys;
} }
- (instancetype)init { - (instancetype)init {
...@@ -103,6 +109,7 @@ typedef NSMutableArray<ListItem*> SectionItems; ...@@ -103,6 +109,7 @@ typedef NSMutableArray<ListItem*> SectionItems;
NSInteger section = [self sectionForSectionIdentifier:sectionIdentifier]; NSInteger section = [self sectionForSectionIdentifier:sectionIdentifier];
[_sectionIdentifiers removeObjectAtIndex:section]; [_sectionIdentifiers removeObjectAtIndex:section];
[_sections removeObjectAtIndex:section]; [_sections removeObjectAtIndex:section];
[_collapsedKeys removeObjectForKey:@(sectionIdentifier)];
} }
- (void)setHeader:(ListItem*)header - (void)setHeader:(ListItem*)header
...@@ -285,10 +292,62 @@ typedef NSMutableArray<ListItem*> SectionItems; ...@@ -285,10 +292,62 @@ typedef NSMutableArray<ListItem*> SectionItems;
- (NSInteger)numberOfItemsInSection:(NSInteger)section { - (NSInteger)numberOfItemsInSection:(NSInteger)section {
DCHECK_LT(base::checked_cast<NSUInteger>(section), [_sections count]); DCHECK_LT(base::checked_cast<NSUInteger>(section), [_sections count]);
NSInteger sectionIdentifier = [self sectionIdentifierForSection:section];
if ([self sectionIsCollapsed:sectionIdentifier])
return 0;
SectionItems* items = [_sections objectAtIndex:section]; SectionItems* items = [_sections objectAtIndex:section];
return items.count; return items.count;
} }
#pragma mark Collapsing methods.
- (void)setSectionIdentifier:(NSInteger)sectionIdentifier
collapsedKey:(NSString*)collapsedKey {
// Check that the sectionIdentifier exists.
DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]);
// Check that the collapsedKey is not being used already.
DCHECK(![self.collapsedKeys allKeysForObject:collapsedKey].count);
[self.collapsedKeys setObject:collapsedKey forKey:@(sectionIdentifier)];
}
- (void)setSection:(NSInteger)sectionIdentifier collapsed:(BOOL)collapsed {
// TODO(crbug.com/419346): Store in the browser state preference instead of
// NSUserDefaults.
DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]);
NSString* sectionKey = [self.collapsedKeys objectForKey:@(sectionIdentifier)];
DCHECK(sectionKey);
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSDictionary* collapsedSections =
[defaults dictionaryForKey:kListModelCollapsedKey];
NSMutableDictionary* newCollapsedSection =
[NSMutableDictionary dictionaryWithDictionary:collapsedSections];
NSNumber* value = [NSNumber numberWithBool:collapsed];
[newCollapsedSection setValue:value forKey:sectionKey];
[defaults setObject:newCollapsedSection forKey:kListModelCollapsedKey];
}
- (BOOL)sectionIsCollapsed:(NSInteger)sectionIdentifier {
// TODO(crbug.com/419346): Store in the profile's preference instead of the
// NSUserDefaults.
DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]);
NSString* sectionKey = [self.collapsedKeys objectForKey:@(sectionIdentifier)];
if (!sectionKey)
return NO;
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSDictionary* collapsedSections =
[defaults dictionaryForKey:kListModelCollapsedKey];
NSNumber* value = (NSNumber*)[collapsedSections valueForKey:sectionKey];
return [value boolValue];
}
// |_collapsedKeys| lazy instantiation.
- (NSMutableDictionary*)collapsedKeys {
if (!_collapsedKeys) {
_collapsedKeys = [[NSMutableDictionary alloc] init];
}
return _collapsedKeys;
}
#pragma mark Private methods #pragma mark Private methods
// Returns the section for the given section identifier. If the section // Returns the section for the given section identifier. If the section
......
...@@ -2,10 +2,9 @@ ...@@ -2,10 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#import "ios/chrome/browser/ui/table_view/table_view_model.h" #import "ios/chrome/browser/ui/list_model/list_model.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h" #import "ios/chrome/browser/ui/list_model/list_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
#include "testing/platform_test.h" #include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
...@@ -23,62 +22,71 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -23,62 +22,71 @@ typedef NS_ENUM(NSInteger, ItemType) {
ItemTypeFooBar = kItemTypeEnumZero, ItemTypeFooBar = kItemTypeEnumZero,
}; };
class TableViewModelTest : public PlatformTest { class ListModelCollapseTest : public PlatformTest {
protected: protected:
TableViewModelTest() { ListModelCollapseTest() {
// Need to clean up NSUserDefaults before and after each test. // Need to clean up NSUserDefaults before and after each test.
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:nil forKey:kTableViewModelCollapsedKey]; [defaults setObject:nil forKey:kListModelCollapsedKey];
model = [[TableViewModel alloc] init]; model = [[ListModel alloc] init];
[model addSectionWithIdentifier:SectionIdentifierFoo]; [model addSectionWithIdentifier:SectionIdentifierFoo];
[model setSectionIdentifier:SectionIdentifierFoo collapsedKey:@"FooKey"]; [model setSectionIdentifier:SectionIdentifierFoo collapsedKey:@"FooKey"];
TableViewHeaderFooterItem* header = ListItem* header = [[ListItem alloc] initWithType:ItemTypeFooBar];
[[TableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar]; ListItem* item = [[ListItem alloc] initWithType:ItemTypeFooBar];
TableViewItem* item = [[TableViewItem alloc] initWithType:ItemTypeFooBar];
[model setHeader:header forSectionWithIdentifier:SectionIdentifierFoo]; [model setHeader:header forSectionWithIdentifier:SectionIdentifierFoo];
[model addItem:item toSectionWithIdentifier:SectionIdentifierFoo]; [model addItem:item toSectionWithIdentifier:SectionIdentifierFoo];
[model addSectionWithIdentifier:SectionIdentifierBar]; [model addSectionWithIdentifier:SectionIdentifierBar];
[model setSectionIdentifier:SectionIdentifierBar collapsedKey:@"BarKey"]; [model setSectionIdentifier:SectionIdentifierBar collapsedKey:@"BarKey"];
header = [[TableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar]; header = [[ListItem alloc] initWithType:ItemTypeFooBar];
item = [[TableViewItem alloc] initWithType:ItemTypeFooBar];
[model setHeader:header forSectionWithIdentifier:SectionIdentifierBar]; [model setHeader:header forSectionWithIdentifier:SectionIdentifierBar];
item = [[ListItem alloc] initWithType:ItemTypeFooBar];
[model addItem:item toSectionWithIdentifier:SectionIdentifierBar];
item = [[ListItem alloc] initWithType:ItemTypeFooBar];
[model addItem:item toSectionWithIdentifier:SectionIdentifierBar]; [model addItem:item toSectionWithIdentifier:SectionIdentifierBar];
} }
~TableViewModelTest() override { ~ListModelCollapseTest() override {
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:nil forKey:kTableViewModelCollapsedKey]; [defaults setObject:nil forKey:kListModelCollapsedKey];
} }
TableViewModel* model; ListModel* model;
}; };
// Tests the default collapsed value is NO. // Tests the default collapsed value is NO.
TEST_F(TableViewModelTest, DefaultCollapsedSectionValue) { TEST_F(ListModelCollapseTest, DefaultCollapsedSectionValue) {
EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierFoo]); EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierFoo]);
EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierBar]); EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierBar]);
} }
// Collapses all sections. // Collapses all sections.
TEST_F(TableViewModelTest, SetAllCollapsed) { TEST_F(ListModelCollapseTest, SetAllCollapsed) {
[model setSection:SectionIdentifierFoo collapsed:YES]; [model setSection:SectionIdentifierFoo collapsed:YES];
[model setSection:SectionIdentifierBar collapsed:YES]; [model setSection:SectionIdentifierBar collapsed:YES];
// SectionIdentifierFoo
EXPECT_EQ(0, [model numberOfItemsInSection:0]);
EXPECT_TRUE([model sectionIsCollapsed:SectionIdentifierFoo]); EXPECT_TRUE([model sectionIsCollapsed:SectionIdentifierFoo]);
// SectionIdentifierBar
EXPECT_EQ(0, [model numberOfItemsInSection:1]);
EXPECT_TRUE([model sectionIsCollapsed:SectionIdentifierBar]); EXPECT_TRUE([model sectionIsCollapsed:SectionIdentifierBar]);
[model setSection:SectionIdentifierFoo collapsed:NO]; [model setSection:SectionIdentifierFoo collapsed:NO];
[model setSection:SectionIdentifierBar collapsed:NO]; [model setSection:SectionIdentifierBar collapsed:NO];
// SectionIdentifierFoo
EXPECT_EQ(1, [model numberOfItemsInSection:0]);
EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierFoo]); EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierFoo]);
// SectionIdentifierBar
EXPECT_EQ(2, [model numberOfItemsInSection:1]);
EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierBar]); EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierBar]);
} }
// Collapses just one section at the time. // Collapses just one section at the time.
TEST_F(TableViewModelTest, SetSomeCollapsed) { TEST_F(ListModelCollapseTest, SetSomeCollapsed) {
[model setSection:SectionIdentifierFoo collapsed:NO]; [model setSection:SectionIdentifierFoo collapsed:NO];
[model setSection:SectionIdentifierBar collapsed:YES]; [model setSection:SectionIdentifierBar collapsed:YES];
...@@ -93,7 +101,7 @@ TEST_F(TableViewModelTest, SetSomeCollapsed) { ...@@ -93,7 +101,7 @@ TEST_F(TableViewModelTest, SetSomeCollapsed) {
} }
// Removes a collapsed section. // Removes a collapsed section.
TEST_F(TableViewModelTest, RemoveCollapsedSection) { TEST_F(ListModelCollapseTest, RemoveCollapsedSection) {
[model setSection:SectionIdentifierFoo collapsed:NO]; [model setSection:SectionIdentifierFoo collapsed:NO];
[model setSection:SectionIdentifierBar collapsed:YES]; [model setSection:SectionIdentifierBar collapsed:YES];
...@@ -108,7 +116,7 @@ TEST_F(TableViewModelTest, RemoveCollapsedSection) { ...@@ -108,7 +116,7 @@ TEST_F(TableViewModelTest, RemoveCollapsedSection) {
} }
// Removes a collapsed section, then re-adds it, it should still be collapsed. // Removes a collapsed section, then re-adds it, it should still be collapsed.
TEST_F(TableViewModelTest, RemoveReaddCollapsedSection) { TEST_F(ListModelCollapseTest, RemoveReaddCollapsedSection) {
[model setSection:SectionIdentifierFoo collapsed:NO]; [model setSection:SectionIdentifierFoo collapsed:NO];
[model setSection:SectionIdentifierBar collapsed:YES]; [model setSection:SectionIdentifierBar collapsed:YES];
...@@ -124,9 +132,8 @@ TEST_F(TableViewModelTest, RemoveReaddCollapsedSection) { ...@@ -124,9 +132,8 @@ TEST_F(TableViewModelTest, RemoveReaddCollapsedSection) {
[model addSectionWithIdentifier:SectionIdentifierBar]; [model addSectionWithIdentifier:SectionIdentifierBar];
// Use the same Key as the previously removed section. // Use the same Key as the previously removed section.
[model setSectionIdentifier:SectionIdentifierBar collapsedKey:@"BarKey"]; [model setSectionIdentifier:SectionIdentifierBar collapsedKey:@"BarKey"];
TableViewHeaderFooterItem* header = ListItem* header = [[ListItem alloc] initWithType:ItemTypeFooBar];
[[TableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar]; ListItem* item = [[ListItem alloc] initWithType:ItemTypeFooBar];
TableViewItem* item = [[TableViewItem alloc] initWithType:ItemTypeFooBar];
[model setHeader:header forSectionWithIdentifier:SectionIdentifierBar]; [model setHeader:header forSectionWithIdentifier:SectionIdentifierBar];
[model addItem:item toSectionWithIdentifier:SectionIdentifierBar]; [model addItem:item toSectionWithIdentifier:SectionIdentifierBar];
...@@ -136,29 +143,28 @@ TEST_F(TableViewModelTest, RemoveReaddCollapsedSection) { ...@@ -136,29 +143,28 @@ TEST_F(TableViewModelTest, RemoveReaddCollapsedSection) {
} }
// Test Collapsed persistance. // Test Collapsed persistance.
TEST_F(TableViewModelTest, PersistCollapsedSections) { TEST_F(ListModelCollapseTest, PersistCollapsedSections) {
[model setSection:SectionIdentifierFoo collapsed:NO]; [model setSection:SectionIdentifierFoo collapsed:NO];
[model setSection:SectionIdentifierBar collapsed:YES]; [model setSection:SectionIdentifierBar collapsed:YES];
EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierFoo]); EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierFoo]);
EXPECT_TRUE([model sectionIsCollapsed:SectionIdentifierBar]); EXPECT_TRUE([model sectionIsCollapsed:SectionIdentifierBar]);
TableViewModel* anotherModel = [[TableViewModel alloc] init]; ListModel* anotherModel = [[ListModel alloc] init];
[anotherModel addSectionWithIdentifier:SectionIdentifierFoo]; [anotherModel addSectionWithIdentifier:SectionIdentifierFoo];
[anotherModel setSectionIdentifier:SectionIdentifierFoo [anotherModel setSectionIdentifier:SectionIdentifierFoo
collapsedKey:@"FooKey"]; collapsedKey:@"FooKey"];
TableViewHeaderFooterItem* header = ListItem* header = [[ListItem alloc] initWithType:ItemTypeFooBar];
[[TableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar]; ListItem* item = [[ListItem alloc] initWithType:ItemTypeFooBar];
TableViewItem* item = [[TableViewItem alloc] initWithType:ItemTypeFooBar];
[anotherModel setHeader:header forSectionWithIdentifier:SectionIdentifierFoo]; [anotherModel setHeader:header forSectionWithIdentifier:SectionIdentifierFoo];
[anotherModel addItem:item toSectionWithIdentifier:SectionIdentifierFoo]; [anotherModel addItem:item toSectionWithIdentifier:SectionIdentifierFoo];
[anotherModel addSectionWithIdentifier:SectionIdentifierBar]; [anotherModel addSectionWithIdentifier:SectionIdentifierBar];
[anotherModel setSectionIdentifier:SectionIdentifierBar [anotherModel setSectionIdentifier:SectionIdentifierBar
collapsedKey:@"BarKey"]; collapsedKey:@"BarKey"];
header = [[TableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar]; header = [[ListItem alloc] initWithType:ItemTypeFooBar];
item = [[TableViewItem alloc] initWithType:ItemTypeFooBar]; item = [[ListItem alloc] initWithType:ItemTypeFooBar];
[anotherModel setHeader:header forSectionWithIdentifier:SectionIdentifierBar]; [anotherModel setHeader:header forSectionWithIdentifier:SectionIdentifierBar];
[anotherModel addItem:item toSectionWithIdentifier:SectionIdentifierBar]; [anotherModel addItem:item toSectionWithIdentifier:SectionIdentifierBar];
......
...@@ -75,7 +75,7 @@ id<GREYMatcher> TitleOfTestPage() { ...@@ -75,7 +75,7 @@ id<GREYMatcher> TitleOfTestPage() {
}}); }});
if (IsUIRefreshPhase1Enabled()) { if (IsUIRefreshPhase1Enabled()) {
[NSUserDefaults.standardUserDefaults setObject:@{} [NSUserDefaults.standardUserDefaults setObject:@{}
forKey:kTableViewModelCollapsedKey]; forKey:kListModelCollapsedKey];
} else { } else {
[NSUserDefaults.standardUserDefaults setObject:@{} [NSUserDefaults.standardUserDefaults setObject:@{}
forKey:kCollapsedSectionsKey]; forKey:kCollapsedSectionsKey];
......
...@@ -80,7 +80,6 @@ source_set("unit_tests") { ...@@ -80,7 +80,6 @@ source_set("unit_tests") {
testonly = true testonly = true
sources = [ sources = [
"chrome_table_view_controller_unittest.mm", "chrome_table_view_controller_unittest.mm",
"table_view_model_unittest.mm",
] ]
deps = [ deps = [
":table_view", ":table_view",
......
...@@ -11,28 +11,10 @@ ...@@ -11,28 +11,10 @@
#import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
// Key for saving collapsed state in the UserDefaults.
extern NSString* const kTableViewModelCollapsedKey;
// TableViewModel acts as a model class for table view controllers. // TableViewModel acts as a model class for table view controllers.
@interface TableViewModel<__covariant ObjectType : TableViewItem*> : @interface TableViewModel<__covariant ObjectType : TableViewItem*> :
ListModel<ObjectType, TableViewHeaderFooterItem*> ListModel<ObjectType, TableViewHeaderFooterItem*>
// Sets an existing |sectionIdentifier| |collapsedKey| to be used when
// collapsing or expanding a section. |collapsedKey| is a unique identifier for
// each section that will be used for persisting information about the collapsed
// state of a section. A |collapsedKey| its only needed when
// collapsing/expanding sections. You can't collapse/expand any sections without
// a |collapsedKey|.
- (void)setSectionIdentifier:(NSInteger)sectionIdentifier
collapsedKey:(NSString*)collapsedKey;
// Sets the state of an existing |sectionIdentifier| to |collapsed|. A
// collapsedKey has to be previously set or this method will DCHECK().
- (void)setSection:(NSInteger)sectionIdentifier collapsed:(BOOL)collapsed;
// Returns YES if |sectionIdentifier| is collapsed. If not collapsedKey has been
// set it will also return NO.
- (BOOL)sectionIsCollapsed:(NSInteger)sectionIdentifier;
@end @end
#endif // IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_MODEL_H_ #endif // IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_MODEL_H_
...@@ -4,84 +4,9 @@ ...@@ -4,84 +4,9 @@
#import "ios/chrome/browser/ui/table_view/table_view_model.h" #import "ios/chrome/browser/ui/table_view/table_view_model.h"
#include "base/logging.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
NSString* const kTableViewModelCollapsedKey =
@"ChromeTableViewModelCollapsedSections";
@interface TableViewModel ()
@property(strong, nonatomic) NSMutableDictionary* collapsedKeys;
@end
@implementation TableViewModel @implementation TableViewModel
@synthesize collapsedKeys = _collapsedKeys;
#pragma mark - UITableViewDataSource
// Override numberOfItemsInSection to return 0 if the section is collapsed.
- (NSInteger)numberOfItemsInSection:(NSInteger)section {
DCHECK_LT(section, [self numberOfSections]);
NSInteger sectionIdentifier = [self sectionIdentifierForSection:section];
// Check if the sectionType is collapsed. If sectionType is collapsed
// return 0.
if ([self sectionIsCollapsed:sectionIdentifier]) {
return 0;
} else {
return [super numberOfItemsInSection:section];
}
}
#pragma mark - Collapsing methods.
- (void)setSectionIdentifier:(NSInteger)sectionIdentifier
collapsedKey:(NSString*)collapsedKey {
// Check that the sectionIdentifier exists.
DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]);
// Check that the collapsedKey is not being used already.
DCHECK(![self.collapsedKeys objectForKey:collapsedKey]);
[self.collapsedKeys setObject:collapsedKey forKey:@(sectionIdentifier)];
}
- (void)setSection:(NSInteger)sectionIdentifier collapsed:(BOOL)collapsed {
// TODO(crbug.com/419346): Store in the browser state preference instead of
// NSUserDefaults.
DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]);
NSString* sectionKey = [self.collapsedKeys objectForKey:@(sectionIdentifier)];
DCHECK(sectionKey);
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSDictionary* collapsedSections =
[defaults dictionaryForKey:kTableViewModelCollapsedKey];
NSMutableDictionary* newCollapsedSection =
[NSMutableDictionary dictionaryWithDictionary:collapsedSections];
NSNumber* value = [NSNumber numberWithBool:collapsed];
[newCollapsedSection setValue:value forKey:sectionKey];
[defaults setObject:newCollapsedSection forKey:kTableViewModelCollapsedKey];
}
- (BOOL)sectionIsCollapsed:(NSInteger)sectionIdentifier {
// TODO(crbug.com/419346): Store in the profile's preference instead of the
// NSUserDefaults.
DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]);
NSString* sectionKey = [self.collapsedKeys objectForKey:@(sectionIdentifier)];
if (!sectionKey)
return NO;
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSDictionary* collapsedSections =
[defaults dictionaryForKey:kTableViewModelCollapsedKey];
NSNumber* value = (NSNumber*)[collapsedSections valueForKey:sectionKey];
return [value boolValue];
}
// |self.collapsedKeys| lazy instantiation.
- (NSMutableDictionary*)collapsedKeys {
if (!_collapsedKeys) {
_collapsedKeys = [[NSMutableDictionary alloc] init];
}
return _collapsedKeys;
}
@end @end
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