Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Unified Diff: ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm

Issue 2659693004: Add context menu when long press on a reading list entry (Closed)
Patch Set: Address comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm
index a8a394d9081fd2ec83e8293685567ea86d7c49d6..4a4861337fd18581a3e4f7164ce6a72b77d85957 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm
@@ -19,8 +19,6 @@
#include "components/url_formatter/url_formatter.h"
#include "ios/chrome/browser/reading_list/offline_url_utils.h"
#include "ios/chrome/browser/reading_list/reading_list_download_service.h"
-#import "ios/chrome/browser/tabs/tab.h"
-#import "ios/chrome/browser/tabs/tab_model.h"
#import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h"
#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
#import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
@@ -86,8 +84,6 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
std::unique_ptr<ReadingListModelBridge> _modelBridge;
UIView* _emptyCollectionBackground;
- // Whether the model modifications should be taken into account.
- BOOL _shouldMonitorModel;
// Whether the model has pending modifications.
BOOL _modelHasBeenModified;
}
@@ -95,6 +91,9 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
// Lazily instantiated.
@property(nonatomic, strong, readonly)
FaviconAttributesProvider* attributesProvider;
+// Whether the Reading List Model (by opposition to the CollectionViewModel)
+// modifications should be taken into account.
+@property(nonatomic, assign) BOOL shouldMonitorModel;
// Returns the UIView to be displayed when the reading list is empty.
- (UIView*)emptyCollectionBackground;
@@ -126,6 +125,10 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
- (BOOL)hasItemInSection:(SectionIdentifier)sectionIdentifier;
// Adds an empty background if needed.
- (void)collectionIsEmpty;
+// Handles a long press.
+- (void)handleLongPress:(UILongPressGestureRecognizer*)gestureRecognizer;
+// Stops observing the ReadingListModel.
+- (void)stopObservingReadingListModel;
// Updates the toolbar state according to the selected items.
- (void)updateToolbarState;
// Displays an action sheet to let the user choose to mark all the elements as
@@ -186,16 +189,14 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
@implementation ReadingListViewController
@synthesize readingListModel = _readingListModel;
-@synthesize tabModel = _tabModel;
@synthesize largeIconService = _largeIconService;
@synthesize readingListDownloadService = _readingListDownloadService;
@synthesize attributesProvider = _attributesProvider;
-@synthesize audience = _audience;
-
+@synthesize delegate = _delegate;
+@synthesize shouldMonitorModel = _shouldMonitorModel;
#pragma mark lifecycle
- (instancetype)initWithModel:(ReadingListModel*)model
- tabModel:(TabModel*)tabModel
largeIconService:(favicon::LargeIconService*)largeIconService
readingListDownloadService:
(ReadingListDownloadService*)readingListDownloadService
@@ -206,7 +207,6 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
_toolbar = toolbar;
_readingListModel = model;
- _tabModel = tabModel;
_largeIconService = largeIconService;
_readingListDownloadService = readingListDownloadService;
_emptyCollectionBackground = [self emptyCollectionBackground];
@@ -237,10 +237,11 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
[_toolbar setState:toolbarState];
}
-- (void)setAudience:(id<ReadingListViewControllerAudience>)audience {
- _audience = audience;
+- (void)setDelegate:(id<ReadingListViewControllerDelegate>)delegate {
+ _delegate = delegate;
if (self.readingListModel->loaded())
- [audience setCollectionHasItems:self.readingListModel->size() > 0];
+ [delegate readingListViewController:self
+ hasItems:(self.readingListModel->size() > 0)];
}
#pragma mark - UIViewController
@@ -262,6 +263,13 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
// Customize collection view settings.
self.styler.cellStyle = MDCCollectionViewCellStyleCard;
self.styler.separatorInset = UIEdgeInsetsMake(0, 16, 0, 16);
+
+ UILongPressGestureRecognizer* longPressRecognizer =
+ [[UILongPressGestureRecognizer alloc]
+ initWithTarget:self
+ action:@selector(handleLongPress:)];
+ longPressRecognizer.numberOfTouchesRequired = 1;
+ [self.collectionView addGestureRecognizer:longPressRecognizer];
}
#pragma mark - UICollectionViewDelegate
@@ -287,7 +295,11 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
if (self.editor.editing) {
[self updateToolbarState];
} else {
- [self openItemAtIndexPath:indexPath];
+ ReadingListCollectionViewItem* readingListItem =
+ base::mac::ObjCCastStrict<ReadingListCollectionViewItem>(
+ [self.collectionViewModel itemAtIndexPath:indexPath]);
+
+ [self.delegate readingListViewController:self openItem:readingListItem];
}
}
@@ -339,7 +351,7 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
}
- (void)readingListModelDidApplyChanges:(const ReadingListModel*)model {
- if (!_shouldMonitorModel) {
+ if (!self.shouldMonitorModel) {
return;
}
@@ -360,7 +372,7 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
}
- (void)readingListModelCompletedBatchUpdates:(const ReadingListModel*)model {
- if (!_shouldMonitorModel) {
+ if (!self.shouldMonitorModel) {
return;
}
@@ -368,7 +380,23 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
[self reloadData];
}
-#pragma mark - private methods
+#pragma mark - Public methods
+
+- (void)reloadData {
+ [self loadModel];
+ if ([self isViewLoaded]) {
+ [self.collectionView reloadData];
+ }
+}
+
+- (void)willBeDismissed {
+ _readingListModel->MarkAllSeen();
+ // Reset observer to prevent further model update notifications.
+ [self stopObservingReadingListModel];
+ [_actionSheet stop];
+}
+
+#pragma mark - Private methods
- (UIView*)emptyCollectionBackground {
UIView* emptyCollectionBackground = [[UIView alloc] initWithFrame:CGRectZero];
@@ -449,30 +477,6 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
return emptyCollectionBackground;
}
-- (void)openItemAtIndexPath:(NSIndexPath*)indexPath {
- ReadingListCollectionViewItem* readingListItem =
- base::mac::ObjCCastStrict<ReadingListCollectionViewItem>(
- [self.collectionViewModel itemAtIndexPath:indexPath]);
- const ReadingListEntry* entry =
- self.readingListModel->GetEntryByURL(readingListItem.url);
- if (!entry) {
- [self reloadData];
- return;
- }
-
- base::RecordAction(base::UserMetricsAction("MobileReadingListOpen"));
-
- // Reset observer to prevent further model update notifications.
- _modelBridge.reset();
-
- Tab* currentTab = _tabModel.currentTab;
- DCHECK(currentTab);
- web::NavigationManager::WebLoadParams params(entry->URL());
- params.transition_type = ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK;
- [currentTab webState]->GetNavigationManager()->LoadURLWithParams(params);
- [self dismiss];
-}
-
- (void)donePressed {
if ([self.editor isEditing]) {
[self exitEditingModeAnimated:NO];
@@ -481,11 +485,7 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
}
- (void)dismiss {
- _readingListModel->MarkAllSeen();
- // Reset observer to prevent further model update notifications.
- _modelBridge.reset();
- [_actionSheet stop];
- [self.audience dismiss];
+ [self.delegate dismissReadingListViewController:self];
}
- (void)loadModel {
@@ -497,7 +497,7 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
self.collectionView.alwaysBounceVertical = YES;
[self loadItems];
self.collectionView.backgroundView = nil;
- [self.audience setCollectionHasItems:YES];
+ [self.delegate readingListViewController:self hasItems:YES];
}
}
@@ -542,13 +542,6 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
}
}
-- (void)reloadData {
- [self loadModel];
- if ([self isViewLoaded]) {
- [self.collectionView reloadData];
- }
-}
-
- (void)applyPendingUpdates {
if (_modelHasBeenModified) {
[self reloadData];
@@ -637,7 +630,44 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
// The collection is empty, add background.
self.collectionView.alwaysBounceVertical = NO;
self.collectionView.backgroundView = _emptyCollectionBackground;
- [self.audience setCollectionHasItems:NO];
+ [self.delegate readingListViewController:self hasItems:NO];
+}
+
+- (void)handleLongPress:(UILongPressGestureRecognizer*)gestureRecognizer {
+ if (self.editor.editing ||
+ gestureRecognizer.state != UIGestureRecognizerStateBegan) {
+ return;
+ }
+
+ CGPoint touchLocation =
+ [gestureRecognizer locationOfTouch:0 inView:self.collectionView];
+ NSIndexPath* touchedItemIndexPath =
+ [self.collectionView indexPathForItemAtPoint:touchLocation];
+ if (!touchedItemIndexPath ||
+ ![self.collectionViewModel hasItemAtIndexPath:touchedItemIndexPath]) {
+ // Make sure there is an item at this position.
+ return;
+ }
+ CollectionViewItem* touchedItem =
+ [self.collectionViewModel itemAtIndexPath:touchedItemIndexPath];
+
+ if (touchedItem == [self.collectionViewModel
+ headerForSection:touchedItemIndexPath.section] ||
+ ![touchedItem isKindOfClass:[ReadingListCollectionViewItem class]]) {
+ // Do not trigger context menu on headers.
+ return;
+ }
+
+ ReadingListCollectionViewItem* readingListItem =
+ base::mac::ObjCCastStrict<ReadingListCollectionViewItem>(touchedItem);
+
+ [self.delegate readingListViewController:self
+ displayContextMenuForItem:readingListItem
+ atPoint:touchLocation];
+}
+
+- (void)stopObservingReadingListModel {
+ _modelBridge.reset();
}
#pragma mark - ReadingListToolbarDelegate
@@ -899,7 +929,7 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
- (void)updateItemsInSectionIdentifier:(SectionIdentifier)identifier
usingEntryUpdater:(EntryUpdater)updater {
- _shouldMonitorModel = NO;
+ self.shouldMonitorModel = NO;
auto token = self.readingListModel->BeginBatchUpdates();
NSArray* readItems =
[self.collectionViewModel itemsInSectionWithIdentifier:identifier];
@@ -911,12 +941,12 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
updater(readingListItem.url);
}
token.reset();
- _shouldMonitorModel = YES;
+ self.shouldMonitorModel = YES;
}
- (void)updateIndexPaths:(NSArray<NSIndexPath*>*)indexPaths
usingEntryUpdater:(EntryUpdater)updater {
- _shouldMonitorModel = NO;
+ self.shouldMonitorModel = NO;
auto token = self.readingListModel->BeginBatchUpdates();
// Read the objects in reverse order to keep the order (last modified first).
for (NSIndexPath* index in [indexPaths reverseObjectEnumerator]) {
@@ -928,7 +958,7 @@ using ItemsMapByDate = std::multimap<int64_t, ReadingListCollectionViewItem*>;
}
// Leave the batch update while it is not monitored.
token.reset();
- _shouldMonitorModel = YES;
+ self.shouldMonitorModel = YES;
}
- (void)logDeletionHistogramsForEntry:(const GURL&)url {

Powered by Google App Engine
This is Rietveld 408576698