| // Copyright 2022 The Chromium Authors |
| // 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/price_notifications/price_notifications_table_view_controller.h" |
| |
| #import <MaterialComponents/MaterialSnackbar.h> |
| |
| #import "base/apple/foundation_util.h" |
| #import "ios/chrome/browser/net/crurl.h" |
| #import "ios/chrome/browser/shared/public/commands/snackbar_commands.h" |
| #import "ios/chrome/browser/shared/ui/list_model/list_item+Controller.h" |
| #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_item.h" |
| #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_link_header_footer_item.h" |
| #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_header_footer_item.h" |
| #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_link_item.h" |
| #import "ios/chrome/browser/shared/ui/table_view/table_view_model.h" |
| #import "ios/chrome/browser/ui/price_notifications/cells/price_notifications_image_container_view.h" |
| #import "ios/chrome/browser/ui/price_notifications/cells/price_notifications_table_view_item.h" |
| #import "ios/chrome/browser/ui/price_notifications/price_notifications_constants.h" |
| #import "ios/chrome/browser/ui/price_notifications/price_notifications_consumer.h" |
| #import "ios/chrome/browser/ui/price_notifications/price_notifications_mutator.h" |
| #import "ios/chrome/common/ui/colors/semantic_color_names.h" |
| #import "ios/chrome/common/ui/table_view/table_view_cells_constants.h" |
| #import "ios/chrome/common/ui/util/constraints_ui_util.h" |
| #import "ios/chrome/common/ui/util/text_view_util.h" |
| #import "ios/chrome/grit/ios_strings.h" |
| #import "net/base/mac/url_conversions.h" |
| #import "ui/base/l10n/l10n_util_mac.h" |
| #import "url/gurl.h" |
| |
| namespace { |
| |
| const CGFloat kVerticalTableViewSectionSpacing = 30; |
| |
| // Types of ListItems used by the price notifications UI. |
| typedef NS_ENUM(NSInteger, ItemType) { |
| ItemTypeHeader = kItemTypeEnumZero, |
| ItemTypeSectionHeader, |
| ItemTypeListItem, |
| ItemTypeTableViewHeader, |
| }; |
| |
| // Identifiers for sections in the price notifications. |
| typedef NS_ENUM(NSInteger, SectionIdentifier) { |
| SectionIdentifierTrackableItemsOnCurrentSite = kSectionIdentifierEnumZero, |
| SectionIdentifierTrackedItems, |
| SectionIdentifierTableViewHeader |
| }; |
| |
| const char kBookmarksSettingsURL[] = "settings://open_bookmarks"; |
| |
| } // namespace |
| |
| @interface PriceNotificationsTableViewController () < |
| TableViewTextHeaderFooterItemDelegate> |
| // The boolean indicates whether there exists an item on the current site is |
| // already tracked or the item is already being price tracked. |
| @property(nonatomic, assign) BOOL itemOnCurrentSiteIsTracked; |
| |
| @end |
| |
| @implementation PriceNotificationsTableViewController { |
| // The boolean indicates whether the user has Price tracking item |
| // subscriptions displayed on the UI. |
| BOOL _hasTrackedItems; |
| // A boolean value that indicates that data is coming from the shoppingService |
| // and that the loading state should be hidden. |
| BOOL _shouldHideLoadingState; |
| // A boolean value that indicates that the loading state is currently being |
| // displayed. |
| BOOL _displayedLoadingState; |
| // Indicates whether the TableViewController's tableViewModel has been |
| // initialized. |
| BOOL _hasModelBeenInitialized; |
| // Indicates whether the user has tracked an item over the TableView's life |
| // time. |
| BOOL _hasExecutedItemTracking; |
| } |
| |
| #pragma mark - UIViewController |
| |
| - (void)viewDidLoad { |
| [super viewDidLoad]; |
| [self initializeTableViewModelIfNeeded]; |
| [self addLoadingStateItems]; |
| |
| self.tableView.accessibilityIdentifier = |
| kPriceNotificationsTableViewIdentifier; |
| self.tableView.estimatedRowHeight = 100; |
| NSUInteger imageWidthWithPadding = |
| PriceNotificationsImageView::kPriceNotificationsImageLength + |
| kTableViewHorizontalSpacing * 2; |
| self.tableView.separatorInset = |
| UIEdgeInsetsMake(0, imageWidthWithPadding, 0, 0); |
| |
| self.title = |
| l10n_util::GetNSString(IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACK_TITLE); |
| } |
| |
| #pragma mark - UITableViewDelegate |
| |
| - (CGFloat)tableView:(UITableView*)tableView |
| heightForFooterInSection:(NSInteger)section { |
| if (section == |
| [self.tableViewModel |
| sectionForSectionIdentifier:SectionIdentifierTableViewHeader]) { |
| return 0; |
| } |
| return kVerticalTableViewSectionSpacing; |
| } |
| |
| - (NSIndexPath*)tableView:(UITableView*)tableView |
| willSelectRowAtIndexPath:(NSIndexPath*)indexPath { |
| PriceNotificationsTableViewItem* item = |
| base::apple::ObjCCastStrict<PriceNotificationsTableViewItem>( |
| [self.tableViewModel itemAtIndexPath:indexPath]); |
| |
| if (!item.tracking) { |
| return nil; |
| } |
| |
| return [super tableView:tableView willSelectRowAtIndexPath:indexPath]; |
| } |
| |
| - (void)tableView:(UITableView*)tableView |
| didSelectRowAtIndexPath:(NSIndexPath*)indexPath { |
| if (@available(iOS 16.0, *)) { |
| return; |
| } |
| |
| PriceNotificationsTableViewItem* item = |
| base::apple::ObjCCastStrict<PriceNotificationsTableViewItem>( |
| [self.tableViewModel itemAtIndexPath:indexPath]); |
| [self.mutator navigateToWebpageForItem:item]; |
| } |
| |
| - (BOOL)tableView:(UITableView*)tableView |
| canPerformPrimaryActionForRowAtIndexPath:(NSIndexPath*)indexPath { |
| PriceNotificationsTableViewItem* item = |
| base::apple::ObjCCastStrict<PriceNotificationsTableViewItem>( |
| [self.tableViewModel itemAtIndexPath:indexPath]); |
| |
| return item.tracking; |
| } |
| |
| - (void)tableView:(UITableView*)tableView |
| performPrimaryActionForRowAtIndexPath:(NSIndexPath*)indexPath { |
| PriceNotificationsTableViewItem* item = |
| base::apple::ObjCCastStrict<PriceNotificationsTableViewItem>( |
| [self.tableViewModel itemAtIndexPath:indexPath]); |
| [self.mutator navigateToWebpageForItem:item]; |
| } |
| |
| - (UIView*)tableView:(UITableView*)tableView |
| viewForHeaderInSection:(NSInteger)section { |
| UIView* header = [super tableView:tableView viewForHeaderInSection:section]; |
| TableViewTextHeaderFooterView* link = |
| base::apple::ObjCCast<TableViewTextHeaderFooterView>(header); |
| if (link) { |
| link.delegate = self; |
| } |
| |
| return header; |
| } |
| |
| #pragma mark - TableViewTextHeaderFooterItemDelegate |
| |
| - (void)view:(TableViewTextHeaderFooterView*)view didTapLinkURL:(CrURL*)URL { |
| if (URL.gurl == GURL(kBookmarksSettingsURL)) { |
| [self.mutator navigateToBookmarks]; |
| } |
| } |
| |
| #pragma mark - PriceNotificationsConsumer |
| |
| - (void)setTrackableItem:(PriceNotificationsTableViewItem*)trackableItem |
| currentlyTracking:(BOOL)currentlyTracking { |
| _shouldHideLoadingState = YES; |
| [self initializeTableViewModelIfNeeded]; |
| [self removeLoadingState]; |
| self.itemOnCurrentSiteIsTracked = currentlyTracking; |
| [self.tableViewModel |
| setHeader: |
| [self createHeaderForSectionIndex: |
| SectionIdentifierTrackableItemsOnCurrentSite |
| isEmpty:!trackableItem] |
| forSectionWithIdentifier:SectionIdentifierTrackableItemsOnCurrentSite]; |
| |
| if (trackableItem && !currentlyTracking) { |
| [self addItem:trackableItem |
| toBeginning:YES |
| ofSection:SectionIdentifierTrackableItemsOnCurrentSite |
| withRowAnimation:UITableViewRowAnimationAutomatic]; |
| } |
| |
| if (!self.viewIfLoaded.window) { |
| return; |
| } |
| |
| [self.tableView |
| reloadSections:[self createIndexSetForSectionIdentifiers: |
| {SectionIdentifierTrackableItemsOnCurrentSite}] |
| withRowAnimation:UITableViewRowAnimationAutomatic]; |
| } |
| |
| - (void)addTrackedItem:(PriceNotificationsTableViewItem*)trackedItem |
| toBeginning:(BOOL)beginning { |
| _shouldHideLoadingState = YES; |
| [self initializeTableViewModelIfNeeded]; |
| [self removeLoadingState]; |
| TableViewModel* model = self.tableViewModel; |
| if (!_hasTrackedItems) { |
| [model setHeader: |
| [self createHeaderForSectionIndex:SectionIdentifierTrackedItems |
| isEmpty:NO] |
| forSectionWithIdentifier:SectionIdentifierTrackedItems]; |
| |
| trackedItem.type = ItemTypeListItem; |
| trackedItem.delegate = self; |
| if (beginning) { |
| [self.tableViewModel insertItem:trackedItem |
| inSectionWithIdentifier:SectionIdentifierTrackedItems |
| atIndex:0]; |
| } else { |
| [self.tableViewModel addItem:trackedItem |
| toSectionWithIdentifier:SectionIdentifierTrackedItems]; |
| } |
| |
| if (self.viewIfLoaded.window) { |
| [self.tableView reloadSections:[self createIndexSetForSectionIdentifiers: |
| {SectionIdentifierTrackedItems}] |
| withRowAnimation:UITableViewRowAnimationFade]; |
| } |
| _hasTrackedItems = YES; |
| return; |
| } |
| |
| _hasTrackedItems = YES; |
| [self addItem:trackedItem |
| toBeginning:beginning |
| ofSection:SectionIdentifierTrackedItems |
| withRowAnimation:UITableViewRowAnimationTop]; |
| } |
| |
| - (void)didStopPriceTrackingItem:(PriceNotificationsTableViewItem*)trackedItem |
| onCurrentSite:(BOOL)isViewingProductSite { |
| TableViewModel* model = self.tableViewModel; |
| SectionIdentifier trackedSection = SectionIdentifierTrackedItems; |
| SectionIdentifier trackableSection = |
| SectionIdentifierTrackableItemsOnCurrentSite; |
| BOOL addItemToTrackableSection = |
| isViewingProductSite && ![model hasItemForItemType:ItemTypeListItem |
| sectionIdentifier:trackableSection]; |
| |
| trackedItem.tracking = NO; |
| NSIndexPath* index = [model indexPathForItem:trackedItem]; |
| [model removeItemWithType:ItemTypeListItem |
| fromSectionWithIdentifier:trackedSection |
| atIndex:index.item]; |
| BOOL reloadTrackedSection = ![model hasItemForItemType:ItemTypeListItem |
| sectionIdentifier:trackedSection]; |
| |
| if (reloadTrackedSection) { |
| _hasTrackedItems = NO; |
| [model setHeader: |
| [self createHeaderForSectionIndex:SectionIdentifierTrackedItems |
| isEmpty:YES] |
| forSectionWithIdentifier:trackedSection]; |
| } |
| |
| if (addItemToTrackableSection) { |
| self.itemOnCurrentSiteIsTracked = NO; |
| [model setHeader:[self createHeaderForSectionIndex:trackableSection |
| isEmpty:NO] |
| forSectionWithIdentifier:trackableSection]; |
| [model insertItem:trackedItem |
| inSectionWithIdentifier:trackableSection |
| atIndex:0]; |
| } |
| |
| NSString* messageText = l10n_util::GetNSString( |
| IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACK_MENU_ITEM_STOP_TRACKING_SNACKBAR); |
| MDCSnackbarMessage* message = |
| [MDCSnackbarMessage messageWithText:messageText]; |
| [self.snackbarCommandsHandler |
| showSnackbarMessage:message |
| withHapticType:UINotificationFeedbackTypeSuccess]; |
| |
| if (!self.viewIfLoaded.window) { |
| return; |
| } |
| |
| [self.tableView |
| performBatchUpdates:^{ |
| UITableViewRowAnimation animation = UITableViewRowAnimationMiddle; |
| if (addItemToTrackableSection) { |
| [self.tableView |
| reloadSections:[self createIndexSetForSectionIdentifiers: |
| {trackableSection}] |
| withRowAnimation:UITableViewRowAnimationFade]; |
| animation = UITableViewRowAnimationFade; |
| } |
| |
| if (reloadTrackedSection) { |
| [self.tableView |
| reloadSections: |
| [self createIndexSetForSectionIdentifiers:{trackedSection}] |
| withRowAnimation:UITableViewRowAnimationFade]; |
| return; |
| } |
| |
| [self.tableView deleteRowsAtIndexPaths:@[ index ] |
| withRowAnimation:animation]; |
| } |
| completion:^(BOOL completion){ |
| }]; |
| } |
| |
| - (void)didStartPriceTrackingForItem: |
| (PriceNotificationsTableViewItem*)trackableItem { |
| TableViewModel* model = self.tableViewModel; |
| SectionIdentifier trackableSectionID = |
| SectionIdentifierTrackableItemsOnCurrentSite; |
| _hasExecutedItemTracking = YES; |
| |
| // This code removes the price trackable item from the trackable section and |
| // adds it to the tracked section at the beginning of the list. It assumes |
| // that there exists only one trackable item per page. |
| [model removeItemWithType:ItemTypeListItem |
| fromSectionWithIdentifier:trackableSectionID |
| atIndex:0]; |
| self.itemOnCurrentSiteIsTracked = YES; |
| [model setHeader:[self createHeaderForSectionIndex:trackableSectionID |
| isEmpty:YES] |
| forSectionWithIdentifier:trackableSectionID]; |
| |
| [self.tableView |
| reloadSections:[self createIndexSetForSectionIdentifiers: |
| {SectionIdentifierTrackableItemsOnCurrentSite}] |
| withRowAnimation:UITableViewRowAnimationFade]; |
| |
| [self addTrackedItem:trackableItem toBeginning:YES]; |
| } |
| |
| - (void)resetPriceTrackingItem:(PriceNotificationsTableViewItem*)item { |
| PriceNotificationsTableViewCell* cell = [self.tableView |
| cellForRowAtIndexPath:[self.tableViewModel indexPathForItem:item]]; |
| [cell.trackButton setUserInteractionEnabled:YES]; |
| } |
| |
| #pragma mark - PriceNotificationsTableViewCellDelegate |
| |
| - (void)trackItemForCell:(PriceNotificationsTableViewCell*)cell { |
| NSIndexPath* indexPath = [self.tableView indexPathForCell:cell]; |
| PriceNotificationsTableViewItem* item = |
| base::apple::ObjCCastStrict<PriceNotificationsTableViewItem>( |
| [self.tableViewModel itemAtIndexPath:indexPath]); |
| [self.mutator trackItem:item]; |
| } |
| |
| - (void)stopTrackingItemForCell:(PriceNotificationsTableViewCell*)cell { |
| NSIndexPath* indexPath = [self.tableView indexPathForCell:cell]; |
| PriceNotificationsTableViewItem* item = |
| base::apple::ObjCCastStrict<PriceNotificationsTableViewItem>( |
| [self.tableViewModel itemAtIndexPath:indexPath]); |
| [self.mutator stopTrackingItem:item]; |
| } |
| |
| #pragma mark - Item Loading Helpers |
| |
| // Adds an item to `sectionID` and displays it to the UI. |
| - (void)addItem:(PriceNotificationsTableViewItem*)item |
| toBeginning:(BOOL)toBeginning |
| ofSection:(SectionIdentifier)sectionID |
| withRowAnimation:(UITableViewRowAnimation)animation { |
| if (sectionID == SectionIdentifierTrackableItemsOnCurrentSite && |
| [self.tableViewModel |
| hasItemForItemType:ItemTypeListItem |
| sectionIdentifier:SectionIdentifierTrackableItemsOnCurrentSite]) { |
| return; |
| } |
| |
| DCHECK(item); |
| item.type = ItemTypeListItem; |
| item.delegate = self; |
| if (toBeginning) { |
| [self.tableViewModel insertItem:item |
| inSectionWithIdentifier:sectionID |
| atIndex:0]; |
| } else { |
| [self.tableViewModel addItem:item toSectionWithIdentifier:sectionID]; |
| } |
| |
| if (!self.viewIfLoaded.window) { |
| return; |
| } |
| |
| [self.tableView |
| insertRowsAtIndexPaths:@[ [self.tableViewModel indexPathForItem:item] ] |
| withRowAnimation:animation]; |
| } |
| |
| // Returns a TableViewHeaderFooterItem that displays the title for the section |
| // designated by `sectionID`. |
| - (TableViewHeaderFooterItem*)createHeaderForSectionIndex: |
| (SectionIdentifier)sectionID |
| isEmpty:(BOOL)isEmpty { |
| switch (sectionID) { |
| case SectionIdentifierTrackableItemsOnCurrentSite: { |
| return [self createHeaderForTrackableSection:isEmpty]; |
| } |
| case SectionIdentifierTrackedItems: { |
| return [self createHeaderForTrackedSection:isEmpty]; |
| } |
| case SectionIdentifierTableViewHeader: { |
| return [self createHeaderForTableViewHeaderSection:isEmpty]; |
| } |
| } |
| |
| return nil; |
| } |
| |
| // Constructs the TableViewModel's sections and section headers and initializes |
| // their values in accordance with the desired default empty state. |
| - (void)initializeTableViewModelIfNeeded { |
| if (_hasModelBeenInitialized) { |
| return; |
| } |
| |
| _hasModelBeenInitialized = YES; |
| [super loadModel]; |
| SectionIdentifier trackableSectionID = |
| SectionIdentifierTrackableItemsOnCurrentSite; |
| SectionIdentifier trackedSectionID = SectionIdentifierTrackedItems; |
| TableViewModel* model = self.tableViewModel; |
| |
| [model addSectionWithIdentifier:SectionIdentifierTableViewHeader]; |
| [model setHeader: |
| [self createHeaderForSectionIndex:SectionIdentifierTableViewHeader |
| isEmpty:YES] |
| forSectionWithIdentifier:SectionIdentifierTableViewHeader]; |
| |
| [model addSectionWithIdentifier:trackableSectionID]; |
| [model setHeader:[self createHeaderForSectionIndex:trackableSectionID |
| isEmpty:NO] |
| forSectionWithIdentifier:trackableSectionID]; |
| |
| [model addSectionWithIdentifier:trackedSectionID]; |
| [model setHeader:[self createHeaderForSectionIndex:trackedSectionID |
| isEmpty:YES] |
| forSectionWithIdentifier:trackedSectionID]; |
| } |
| |
| // Adds placeholder items into each section. |
| - (void)addLoadingStateItems { |
| if (_shouldHideLoadingState) { |
| return; |
| } |
| |
| [self.tableViewModel setHeader:[self createHeaderForSectionIndex: |
| SectionIdentifierTrackedItems |
| isEmpty:NO] |
| forSectionWithIdentifier:SectionIdentifierTrackedItems]; |
| |
| PriceNotificationsTableViewItem* emptyTrackableItem = |
| [[PriceNotificationsTableViewItem alloc] init]; |
| PriceNotificationsTableViewItem* emptyTrackedItem = |
| [[PriceNotificationsTableViewItem alloc] init]; |
| emptyTrackableItem.loading = YES; |
| emptyTrackedItem.loading = YES; |
| emptyTrackedItem.tracking = YES; |
| [self addItem:emptyTrackableItem |
| toBeginning:YES |
| ofSection:SectionIdentifierTrackableItemsOnCurrentSite |
| withRowAnimation:UITableViewRowAnimationAutomatic]; |
| [self addItem:emptyTrackedItem |
| toBeginning:YES |
| ofSection:SectionIdentifierTrackedItems |
| withRowAnimation:UITableViewRowAnimationAutomatic]; |
| [self addItem:emptyTrackedItem |
| toBeginning:YES |
| ofSection:SectionIdentifierTrackedItems |
| withRowAnimation:UITableViewRowAnimationAutomatic]; |
| _displayedLoadingState = YES; |
| } |
| |
| // Removes the placeholder items from each section. |
| - (void)removeLoadingState { |
| if (!_displayedLoadingState) { |
| return; |
| } |
| |
| _displayedLoadingState = NO; |
| TableViewModel* model = self.tableViewModel; |
| |
| NSMutableArray<NSIndexPath*>* itemIndexPaths = |
| [[model indexPathsForItemType:ItemTypeListItem |
| sectionIdentifier:SectionIdentifierTrackedItems] mutableCopy]; |
| [itemIndexPaths |
| addObject:[model indexPathForItemType:ItemTypeListItem |
| sectionIdentifier: |
| SectionIdentifierTrackableItemsOnCurrentSite]]; |
| |
| [model removeItemWithType:ItemTypeListItem |
| fromSectionWithIdentifier:SectionIdentifierTrackableItemsOnCurrentSite |
| atIndex:0]; |
| [model setHeader:[self |
| createHeaderForSectionIndex:SectionIdentifierTrackedItems |
| isEmpty:YES] |
| forSectionWithIdentifier:SectionIdentifierTrackedItems]; |
| [model deleteAllItemsFromSectionWithIdentifier:SectionIdentifierTrackedItems]; |
| |
| if (!self.viewIfLoaded.window) { |
| return; |
| } |
| |
| [self.tableView deleteRowsAtIndexPaths:itemIndexPaths |
| withRowAnimation:UITableViewRowAnimationAutomatic]; |
| [self.tableView reloadSections:[self createIndexSetForSectionIdentifiers: |
| {SectionIdentifierTrackedItems}] |
| withRowAnimation:UITableViewRowAnimationAutomatic]; |
| } |
| |
| // Creates the IndexSet that encapsulate the various sections provided in |
| // `sectionIDs` |
| - (NSIndexSet*)createIndexSetForSectionIdentifiers: |
| (std::vector<SectionIdentifier>)sectionIDs { |
| NSMutableIndexSet* indexSet = [[NSMutableIndexSet alloc] init]; |
| for (auto& sectionID : sectionIDs) { |
| NSUInteger sectionIndex = |
| [self.tableViewModel sectionForSectionIdentifier:sectionID]; |
| [indexSet addIndex:sectionIndex]; |
| } |
| return indexSet; |
| } |
| |
| // Creates the TableViewHeaderFooterItem for the section |
| // `SectionIdentifierTrackableItemsOnCurrentSite` |
| - (TableViewHeaderFooterItem*)createHeaderForTrackableSection:(BOOL)isEmpty { |
| TableViewTextHeaderFooterItem* header = |
| [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeHeader]; |
| header.text = l10n_util::GetNSString( |
| IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACK_TRACKABLE_SECTION_HEADER); |
| if (!self.itemOnCurrentSiteIsTracked && !isEmpty) { |
| return header; |
| } |
| |
| if (self.itemOnCurrentSiteIsTracked && _hasExecutedItemTracking) { |
| header.subtitle = l10n_util::GetNSString( |
| IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACK_DESCRIPTION_FOR_TRACKED_ITEM); |
| header.URLs = @[ [[CrURL alloc] initWithGURL:GURL(kBookmarksSettingsURL)] ]; |
| return header; |
| } |
| |
| if (self.itemOnCurrentSiteIsTracked) { |
| header.subtitle = l10n_util::GetNSString( |
| IDS_IOS_PRICE_NOTIFICAITONS_PRICE_TRACK_TRACKABLE_ITEM_IS_TRACKED); |
| return header; |
| } |
| |
| header.subtitle = l10n_util::GetNSString( |
| IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACK_TRACKABLE_EMPTY_LIST); |
| return header; |
| } |
| |
| // Creates the TableViewHeaderFooterItem for the section |
| // `SectionIdentifierTrackedItems` |
| - (TableViewHeaderFooterItem*)createHeaderForTrackedSection:(BOOL)isEmpty { |
| TableViewTextHeaderFooterItem* header = |
| [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeHeader]; |
| header.text = l10n_util::GetNSString( |
| IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACK_TRACKED_SECTION_HEADER); |
| if (isEmpty) { |
| header.subtitle = l10n_util::GetNSString( |
| IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACK_TRACKING_EMPTY_LIST); |
| return header; |
| } |
| |
| return header; |
| } |
| |
| // Creates the TableViewHeaderFooterItem for the section |
| // `SectionIdentifierTableViewHeader` |
| - (TableViewTextHeaderFooterItem*)createHeaderForTableViewHeaderSection: |
| (BOOL)isEmpty { |
| TableViewTextHeaderFooterItem* header = [[TableViewTextHeaderFooterItem alloc] |
| initWithType:ItemTypeTableViewHeader]; |
| |
| if (isEmpty && !self.hasPreviouslyViewed) { |
| header.subtitle = l10n_util::GetNSString( |
| IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACK_DESCRIPTION_EMPTY_STATE); |
| return header; |
| } |
| |
| header.subtitle = l10n_util::GetNSString( |
| IDS_IOS_PRICE_NOTIFICATIONS_PRICE_TRACK_DESCRIPTION); |
| return header; |
| } |
| |
| @end |