blob: f1c71c4461e5b3f088a379cb321c8cfa39f915b5 [file] [log] [blame]
// Copyright 2017 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/bookmarks/bookmark_table_view.h"
#include "base/mac/bind_objc_block.h"
#include "base/mac/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/favicon/core/fallback_url_util.h"
#include "components/favicon/core/favicon_server_fetcher_params.h"
#include "components/favicon/core/large_icon_service.h"
#include "components/favicon_base/fallback_icon_style.h"
#include "components/favicon_base/favicon_types.h"
#include "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
#include "ios/chrome/browser/bookmarks/bookmarks_utils.h"
#include "ios/chrome/browser/experimental_flags.h"
#include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h"
#include "ios/chrome/browser/ui/bookmarks/bookmark_empty_background.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_home_shared_state.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_home_waiting_view.h"
#include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
#import "ios/chrome/browser/ui/bookmarks/cells/bookmark_home_node_item.h"
#import "ios/chrome/browser/ui/bookmarks/cells/bookmark_table_cell.h"
#import "ios/chrome/browser/ui/commands/application_commands.h"
#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
#import "ios/chrome/browser/ui/table_view/table_view_model.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/third_party/material_components_ios/src/components/FlexibleHeader/src/MDCFlexibleHeaderView.h"
#include "skia/ext/skia_utils_ios.h"
#include "ui/base/l10n/l10n_util_mac.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
using bookmarks::BookmarkNode;
@interface BookmarkTableView ()
// State used by this table view.
@property(nonatomic, strong) BookmarkHomeSharedState* sharedState;
// The browser state.
@property(nonatomic, assign) ios::ChromeBrowserState* browserState;
// The delegate for actions on the table.
@property(nonatomic, weak) id<BookmarkTableViewDelegate> delegate;
// Background shown when there is no bookmarks or folders at the current root
// node.
@property(nonatomic, strong) BookmarkEmptyBackground* emptyTableBackgroundView;
// The loading spinner background which appears when syncing.
@property(nonatomic, strong) BookmarkHomeWaitingView* spinnerView;
@end
@implementation BookmarkTableView
@synthesize browserState = _browserState;
@synthesize delegate = _delegate;
@synthesize emptyTableBackgroundView = _emptyTableBackgroundView;
@synthesize spinnerView = _spinnerView;
@synthesize sharedState = _sharedState;
- (instancetype)initWithSharedState:(BookmarkHomeSharedState*)sharedState
browserState:(ios::ChromeBrowserState*)browserState
delegate:(id<BookmarkTableViewDelegate>)delegate
frame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
DCHECK(sharedState.tableViewDisplayedRootNode);
_sharedState = sharedState;
_browserState = browserState;
_delegate = delegate;
// Temporary calls to ensure that we're initializing to the right values.
DCHECK_EQ(self.sharedState.bookmarkModel,
ios::BookmarkModelFactory::GetForBrowserState(browserState));
// Create and setup tableview.
self.sharedState.tableView =
[[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain];
// Remove extra rows.
self.sharedState.tableView.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:self.sharedState.tableView];
[self bringSubviewToFront:self.sharedState.tableView];
}
return self;
}
#pragma mark - Public
// Shows loading spinner background view.
- (void)showLoadingSpinnerBackground {
if (!self.spinnerView) {
self.spinnerView = [[BookmarkHomeWaitingView alloc]
initWithFrame:self.sharedState.tableView.bounds
backgroundColor:[UIColor clearColor]];
[self.spinnerView startWaiting];
}
self.sharedState.tableView.backgroundView = self.spinnerView;
}
// Hide the loading spinner if it is showing.
- (void)hideLoadingSpinnerBackground {
if (self.spinnerView) {
[self.spinnerView stopWaitingWithCompletion:^{
[UIView animateWithDuration:0.2
animations:^{
self.spinnerView.alpha = 0.0;
}
completion:^(BOOL finished) {
self.sharedState.tableView.backgroundView = nil;
self.spinnerView = nil;
}];
}];
}
}
// Shows empty bookmarks background view.
- (void)showEmptyBackground {
if (!self.emptyTableBackgroundView) {
// Set up the background view shown when the table is empty.
self.emptyTableBackgroundView = [[BookmarkEmptyBackground alloc]
initWithFrame:self.sharedState.tableView.bounds];
self.emptyTableBackgroundView.autoresizingMask =
UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.emptyTableBackgroundView.text =
l10n_util::GetNSString(IDS_IOS_BOOKMARK_NO_BOOKMARKS_LABEL);
self.emptyTableBackgroundView.frame = self.sharedState.tableView.bounds;
}
self.sharedState.tableView.backgroundView = self.emptyTableBackgroundView;
}
- (void)hideEmptyBackground {
self.sharedState.tableView.backgroundView = nil;
}
@end