Fjalapeno has uploaded a new change for review. https://gerrit.wikimedia.org/r/219176
Change subject: Implementing full text search. ...................................................................... Implementing full text search. Follow on for Bug: T102362 Updated fetcher for full text search. Implemented search suggestion button. Added NSError category for making app specific errors. Lots of uncrustifucation. Change-Id: I748da6d9bf6c2bffe733ec49d44d5f057fec5e65 --- M MediaWikiKit/MediaWikiKit/MWKArticle.m A NSError+WMFExtensions.h A NSError+WMFExtensions.m M Wikipedia.xcodeproj/project.pbxproj M Wikipedia/Networking/Fetchers/SearchResultFetcher.m M Wikipedia/UI-V5/Global.h M Wikipedia/UI-V5/TGLStackedViewController/TGLStackedLayout.m M Wikipedia/UI-V5/UICollectionView+WMFExtensions.h M Wikipedia/UI-V5/UICollectionView+WMFExtensions.m M Wikipedia/UI-V5/UIStoryboard+WMFExtensions.m M Wikipedia/UI-V5/WMFAppViewController.m M Wikipedia/UI-V5/WMFArticleListCollectionViewController.h M Wikipedia/UI-V5/WMFArticleListCollectionViewController.m M Wikipedia/UI-V5/WMFArticleListDataSource.h M Wikipedia/UI-V5/WMFBottomStackLayout.m M Wikipedia/UI-V5/WMFOffScreenFlowLayout.m M Wikipedia/UI-V5/WMFSavedPagesDataSource.m M Wikipedia/UI-V5/WMFSearchFetcher.h M Wikipedia/UI-V5/WMFSearchFetcher.m M Wikipedia/UI-V5/WMFSearchResults.h M Wikipedia/UI-V5/WMFSearchResults.m M Wikipedia/UI-V5/WMFSearchViewController.h M Wikipedia/UI-V5/WMFSearchViewController.m M Wikipedia/UI-V5/iPhone_Root.storyboard 24 files changed, 358 insertions(+), 348 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/apps/ios/wikipedia refs/changes/76/219176/1 diff --git a/MediaWikiKit/MediaWikiKit/MWKArticle.m b/MediaWikiKit/MediaWikiKit/MWKArticle.m index b60f71a..9a7dab0 100644 --- a/MediaWikiKit/MediaWikiKit/MWKArticle.m +++ b/MediaWikiKit/MediaWikiKit/MWKArticle.m @@ -68,16 +68,15 @@ return self; } -- (instancetype)initWithTitle:(MWKTitle*)title dataStore:(MWKDataStore*)dataStore searchResultsDict:(NSDictionary*)dict{ +- (instancetype)initWithTitle:(MWKTitle*)title dataStore:(MWKDataStore*)dataStore searchResultsDict:(NSDictionary*)dict { self = [self initWithTitle:title dataStore:dataStore]; if (self) { self.entityDescription = [self optionalString:@"description" dict:dict]; - self.snippet = [self optionalString:@"snippet" dict:dict]; + self.snippet = [self optionalString:@"snippet" dict:dict]; } - + return self; } - #pragma mark - NSObject @@ -238,18 +237,17 @@ return [self.dataStore imageWithURL:url article:self]; } -- (void)loadThumbnailFromDisk{ - +- (void)loadThumbnailFromDisk { /** * The folowing logic was pulled from the Article Fetcher * Putting it here to being to coalesce populating Article data * in a single place. This will be addressed natuarlly as we * refactor model class mapping in the network layer. */ - if(!self.thumbnailURL){ + if (!self.thumbnailURL) { return; } - + if ([[self existingImageWithURL:self.thumbnailURL] isCached]) { return; } @@ -270,7 +268,6 @@ } } } - /** * Return image object if folder for that image exists diff --git a/NSError+WMFExtensions.h b/NSError+WMFExtensions.h new file mode 100644 index 0000000..1163b0a --- /dev/null +++ b/NSError+WMFExtensions.h @@ -0,0 +1,16 @@ + +#import <Foundation/Foundation.h> + +extern NSString* const WMFErrorDomain; + +typedef NS_ENUM(NSInteger, WMFErrorType) { + + WMFErrorTypeStringLength, + +}; + +@interface NSError (WMFExtensions) + ++ (NSError*)wmf_errorWithType:(WMFErrorType)type userInfo:(NSDictionary*)userInfo; + +@end diff --git a/NSError+WMFExtensions.m b/NSError+WMFExtensions.m new file mode 100644 index 0000000..14e11ad --- /dev/null +++ b/NSError+WMFExtensions.m @@ -0,0 +1,13 @@ + +#import "NSError+WMFExtensions.h" + +NSString* const WMFErrorDomain = @"WMFErrorDomain"; + +@implementation NSError (WMFExtensions) + ++ (NSError*)wmf_errorWithType:(WMFErrorType)type userInfo:(NSDictionary*)userInfo{ + + return [NSError errorWithDomain:WMFErrorDomain code:type userInfo:userInfo]; +} + +@end diff --git a/Wikipedia.xcodeproj/project.pbxproj b/Wikipedia.xcodeproj/project.pbxproj index 40779ac..c1a0456 100644 --- a/Wikipedia.xcodeproj/project.pbxproj +++ b/Wikipedia.xcodeproj/project.pbxproj @@ -180,6 +180,8 @@ 04F27B7818FE0F2E00EDD838 /* PageHistoryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 04F27B7418FE0F2E00EDD838 /* PageHistoryViewController.m */; }; 04F39590186CF80100B0D6FC /* TOCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 04F3958F186CF80100B0D6FC /* TOCViewController.m */; }; 08D631F71A69B1AB00D87AD0 /* WMFImageGalleryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08D631F61A69B1AB00D87AD0 /* WMFImageGalleryViewController.m */; }; + 0E2B06F61B2CE45800EA2F53 /* WMFSavedPagesDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E2B06F51B2CE45800EA2F53 /* WMFSavedPagesDataSource.m */; }; + 0E2B07021B2D1DE200EA2F53 /* WMFBottomStackLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E2B07011B2D1DE200EA2F53 /* WMFBottomStackLayout.m */; }; 0E30072A1B30B97300D95147 /* Article.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E30070C1B30B97300D95147 /* Article.m */; }; 0E30072B1B30B97300D95147 /* ArticleData.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 0E30070E1B30B97300D95147 /* ArticleData.xcdatamodeld */; }; 0E30072C1B30B97300D95147 /* ArticleDataContextSingleton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E3007121B30B97300D95147 /* ArticleDataContextSingleton.m */; }; @@ -194,8 +196,6 @@ 0E3007351B30B97300D95147 /* Saved.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E3007251B30B97300D95147 /* Saved.m */; }; 0E3007361B30B97300D95147 /* Section.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E3007271B30B97300D95147 /* Section.m */; }; 0E3007371B30B97300D95147 /* SectionImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E3007291B30B97300D95147 /* SectionImage.m */; }; - 0E2B06F61B2CE45800EA2F53 /* WMFSavedPagesDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E2B06F51B2CE45800EA2F53 /* WMFSavedPagesDataSource.m */; }; - 0E2B07021B2D1DE200EA2F53 /* WMFBottomStackLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E2B07011B2D1DE200EA2F53 /* WMFBottomStackLayout.m */; }; 0E366B361B2F176700ABFB86 /* WMFOffScreenFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E366B351B2F176700ABFB86 /* WMFOffScreenFlowLayout.m */; }; 0E366B3A1B2F33BC00ABFB86 /* WMFSearchResults.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E366B391B2F33BC00ABFB86 /* WMFSearchResults.m */; }; 0E366B3F1B2F5C4500ABFB86 /* WMFSearchFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E366B3E1B2F5C4500ABFB86 /* WMFSearchFetcher.m */; }; @@ -219,6 +219,7 @@ 0ED44D781B28DA4D00F284BA /* UICollectionView+WMFExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ED44D771B28DA4D00F284BA /* UICollectionView+WMFExtensions.m */; }; 0EE7687B1AF982C100A5D046 /* WMFArticleProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EE7687A1AF982C100A5D046 /* WMFArticleProtocol.m */; }; 0EE768811AFD25CC00A5D046 /* WMFSearchFunnel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EE768801AFD25CC00A5D046 /* WMFSearchFunnel.m */; }; + 0EFB0EF51B31DE7200D05C08 /* NSError+WMFExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFB0EF41B31DE7200D05C08 /* NSError+WMFExtensions.m */; }; 701FF5EE601DEA3FCAB7EFD3 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D82982ED992F47428037BDF2 /* libPods.a */; }; 954BA118838BF8BA6B01C34A /* libPods-WikipediaUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CE61C6963F825760822A28A /* libPods-WikipediaUnitTests.a */; }; BC092B961B18E89200093C59 /* NSString+WMFPageUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = BC092B951B18E89200093C59 /* NSString+WMFPageUtilities.m */; }; @@ -725,6 +726,10 @@ 08D631F81A69B8CD00D87AD0 /* WMFImageGalleryCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WMFImageGalleryCollectionViewCell.h; path = "Image Gallery/WMFImageGalleryCollectionViewCell.h"; sourceTree = "<group>"; }; 08D631F91A69B8CD00D87AD0 /* WMFImageGalleryCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WMFImageGalleryCollectionViewCell.m; path = "Image Gallery/WMFImageGalleryCollectionViewCell.m"; sourceTree = "<group>"; }; 08F646F7D0488CE3C6D6A763 /* Pods.beta.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.beta.xcconfig; path = "Pods/Target Support Files/Pods/Pods.beta.xcconfig"; sourceTree = "<group>"; }; + 0E2B06F41B2CE45800EA2F53 /* WMFSavedPagesDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMFSavedPagesDataSource.h; sourceTree = "<group>"; }; + 0E2B06F51B2CE45800EA2F53 /* WMFSavedPagesDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMFSavedPagesDataSource.m; sourceTree = "<group>"; }; + 0E2B07001B2D1DE200EA2F53 /* WMFBottomStackLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMFBottomStackLayout.h; sourceTree = "<group>"; }; + 0E2B07011B2D1DE200EA2F53 /* WMFBottomStackLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMFBottomStackLayout.m; sourceTree = "<group>"; }; 0E3007091B30B90100D95147 /* Global.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Global.h; sourceTree = "<group>"; }; 0E30070B1B30B97300D95147 /* Article.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Article.h; sourceTree = "<group>"; }; 0E30070C1B30B97300D95147 /* Article.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Article.m; sourceTree = "<group>"; }; @@ -755,10 +760,6 @@ 0E3007271B30B97300D95147 /* Section.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Section.m; sourceTree = "<group>"; }; 0E3007281B30B97300D95147 /* SectionImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SectionImage.h; sourceTree = "<group>"; }; 0E3007291B30B97300D95147 /* SectionImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SectionImage.m; sourceTree = "<group>"; }; - 0E2B06F41B2CE45800EA2F53 /* WMFSavedPagesDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMFSavedPagesDataSource.h; sourceTree = "<group>"; }; - 0E2B06F51B2CE45800EA2F53 /* WMFSavedPagesDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMFSavedPagesDataSource.m; sourceTree = "<group>"; }; - 0E2B07001B2D1DE200EA2F53 /* WMFBottomStackLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMFBottomStackLayout.h; sourceTree = "<group>"; }; - 0E2B07011B2D1DE200EA2F53 /* WMFBottomStackLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMFBottomStackLayout.m; sourceTree = "<group>"; }; 0E366B341B2F176700ABFB86 /* WMFOffScreenFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMFOffScreenFlowLayout.h; sourceTree = "<group>"; }; 0E366B351B2F176700ABFB86 /* WMFOffScreenFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMFOffScreenFlowLayout.m; sourceTree = "<group>"; }; 0E366B381B2F33BC00ABFB86 /* WMFSearchResults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMFSearchResults.h; sourceTree = "<group>"; }; @@ -791,7 +792,6 @@ 0EA4402D1AA6281200B09DBA /* NSDateFormatter+WMFExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDateFormatter+WMFExtensions.m"; path = "Wikipedia/Categories/NSDateFormatter+WMFExtensions.m"; sourceTree = SOURCE_ROOT; }; 0EBC567D1AD442CC00E82CDD /* BITHockeyManager+WMFExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "BITHockeyManager+WMFExtensions.h"; path = "Wikipedia/Categories/BITHockeyManager+WMFExtensions.h"; sourceTree = SOURCE_ROOT; }; 0EBC567E1AD442CC00E82CDD /* BITHockeyManager+WMFExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "BITHockeyManager+WMFExtensions.m"; path = "Wikipedia/Categories/BITHockeyManager+WMFExtensions.m"; sourceTree = SOURCE_ROOT; }; - 0ED44D6E1B2893C500F284BA /* Global.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Global.h; sourceTree = "<group>"; }; 0ED44D731B28AC1E00F284BA /* WMFArticleViewControllerContainerCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMFArticleViewControllerContainerCell.h; sourceTree = "<group>"; }; 0ED44D741B28AC1E00F284BA /* WMFArticleViewControllerContainerCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMFArticleViewControllerContainerCell.m; sourceTree = "<group>"; }; 0ED44D761B28DA4D00F284BA /* UICollectionView+WMFExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UICollectionView+WMFExtensions.h"; sourceTree = "<group>"; }; @@ -800,6 +800,8 @@ 0EE7687A1AF982C100A5D046 /* WMFArticleProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WMFArticleProtocol.m; path = Wikipedia/Protocols/WMFArticleProtocol.m; sourceTree = SOURCE_ROOT; }; 0EE7687F1AFD25CC00A5D046 /* WMFSearchFunnel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMFSearchFunnel.h; sourceTree = "<group>"; }; 0EE768801AFD25CC00A5D046 /* WMFSearchFunnel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMFSearchFunnel.m; sourceTree = "<group>"; }; + 0EFB0EF31B31DE7200D05C08 /* NSError+WMFExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSError+WMFExtensions.h"; path = "../../NSError+WMFExtensions.h"; sourceTree = "<group>"; }; + 0EFB0EF41B31DE7200D05C08 /* NSError+WMFExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSError+WMFExtensions.m"; path = "../../NSError+WMFExtensions.m"; sourceTree = "<group>"; }; 17A2F22335C5256576CEDBDD /* Pods-WikipediaUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WikipediaUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-WikipediaUnitTests/Pods-WikipediaUnitTests.release.xcconfig"; sourceTree = "<group>"; }; 1BC5FB470144D2C10C55A037 /* Pods-WikipediaUnitTests.alpha.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WikipediaUnitTests.alpha.xcconfig"; path = "Pods/Target Support Files/Pods-WikipediaUnitTests/Pods-WikipediaUnitTests.alpha.xcconfig"; sourceTree = "<group>"; }; 357504E50DA104E39C6ACFEB /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; }; @@ -2094,49 +2096,6 @@ name = "Image Gallery"; sourceTree = "<group>"; }; - 0E30070A1B30B97300D95147 /* LegacyCoreData */ = { - isa = PBXGroup; - children = ( - 0E30070B1B30B97300D95147 /* Article.h */, - 0E30070C1B30B97300D95147 /* Article.m */, - 0E30070D1B30B97300D95147 /* ArticleCoreDataObjects.h */, - 0E30070E1B30B97300D95147 /* ArticleData.xcdatamodeld */, - 0E3007111B30B97300D95147 /* ArticleDataContextSingleton.h */, - 0E3007121B30B97300D95147 /* ArticleDataContextSingleton.m */, - 0E3007131B30B97300D95147 /* Categories */, - 0E30071A1B30B97300D95147 /* DiscoveryContext.h */, - 0E30071B1B30B97300D95147 /* DiscoveryContext.m */, - 0E30071C1B30B97300D95147 /* GalleryImage.h */, - 0E30071D1B30B97300D95147 /* GalleryImage.m */, - 0E30071E1B30B97300D95147 /* History.h */, - 0E30071F1B30B97300D95147 /* History.m */, - 0E3007201B30B97300D95147 /* Image.h */, - 0E3007211B30B97300D95147 /* Image.m */, - 0E3007221B30B97300D95147 /* ImageData.h */, - 0E3007231B30B97300D95147 /* ImageData.m */, - 0E3007241B30B97300D95147 /* Saved.h */, - 0E3007251B30B97300D95147 /* Saved.m */, - 0E3007261B30B97300D95147 /* Section.h */, - 0E3007271B30B97300D95147 /* Section.m */, - 0E3007281B30B97300D95147 /* SectionImage.h */, - 0E3007291B30B97300D95147 /* SectionImage.m */, - ); - path = LegacyCoreData; - sourceTree = SOURCE_ROOT; - }; - 0E3007131B30B97300D95147 /* Categories */ = { - isa = PBXGroup; - children = ( - 0E3007141B30B97300D95147 /* NSManagedObject+WMFModelFactory.h */, - 0E3007151B30B97300D95147 /* NSManagedObject+WMFModelFactory.m */, - 0E3007161B30B97300D95147 /* NSManagedObjectContext+SimpleFetch.h */, - 0E3007171B30B97300D95147 /* NSManagedObjectContext+SimpleFetch.m */, - 0E3007181B30B97300D95147 /* NSManagedObjectModel+LegacyCoreData.h */, - 0E3007191B30B97300D95147 /* NSManagedObjectModel+LegacyCoreData.m */, - ); - path = Categories; - sourceTree = "<group>"; - }; 0E2B06F71B2D126700EA2F53 /* Data Sources */ = { isa = PBXGroup; children = ( @@ -2200,6 +2159,49 @@ name = Cell; sourceTree = "<group>"; }; + 0E30070A1B30B97300D95147 /* LegacyCoreData */ = { + isa = PBXGroup; + children = ( + 0E30070B1B30B97300D95147 /* Article.h */, + 0E30070C1B30B97300D95147 /* Article.m */, + 0E30070D1B30B97300D95147 /* ArticleCoreDataObjects.h */, + 0E30070E1B30B97300D95147 /* ArticleData.xcdatamodeld */, + 0E3007111B30B97300D95147 /* ArticleDataContextSingleton.h */, + 0E3007121B30B97300D95147 /* ArticleDataContextSingleton.m */, + 0E3007131B30B97300D95147 /* Categories */, + 0E30071A1B30B97300D95147 /* DiscoveryContext.h */, + 0E30071B1B30B97300D95147 /* DiscoveryContext.m */, + 0E30071C1B30B97300D95147 /* GalleryImage.h */, + 0E30071D1B30B97300D95147 /* GalleryImage.m */, + 0E30071E1B30B97300D95147 /* History.h */, + 0E30071F1B30B97300D95147 /* History.m */, + 0E3007201B30B97300D95147 /* Image.h */, + 0E3007211B30B97300D95147 /* Image.m */, + 0E3007221B30B97300D95147 /* ImageData.h */, + 0E3007231B30B97300D95147 /* ImageData.m */, + 0E3007241B30B97300D95147 /* Saved.h */, + 0E3007251B30B97300D95147 /* Saved.m */, + 0E3007261B30B97300D95147 /* Section.h */, + 0E3007271B30B97300D95147 /* Section.m */, + 0E3007281B30B97300D95147 /* SectionImage.h */, + 0E3007291B30B97300D95147 /* SectionImage.m */, + ); + path = LegacyCoreData; + sourceTree = SOURCE_ROOT; + }; + 0E3007131B30B97300D95147 /* Categories */ = { + isa = PBXGroup; + children = ( + 0E3007141B30B97300D95147 /* NSManagedObject+WMFModelFactory.h */, + 0E3007151B30B97300D95147 /* NSManagedObject+WMFModelFactory.m */, + 0E3007161B30B97300D95147 /* NSManagedObjectContext+SimpleFetch.h */, + 0E3007171B30B97300D95147 /* NSManagedObjectContext+SimpleFetch.m */, + 0E3007181B30B97300D95147 /* NSManagedObjectModel+LegacyCoreData.h */, + 0E3007191B30B97300D95147 /* NSManagedObjectModel+LegacyCoreData.m */, + ); + path = Categories; + sourceTree = "<group>"; + }; 0E366B371B2F2ACF00ABFB86 /* Layouts */ = { isa = PBXGroup; children = ( @@ -2245,6 +2247,8 @@ 0E94AFF51B209882000BC5EA /* WMFArticleViewController.m */, 0E94AFF91B20A22C000BC5EA /* WMFStyleManager.h */, 0E94AFFA1B20A22C000BC5EA /* WMFStyleManager.m */, + 0EFB0EF31B31DE7200D05C08 /* NSError+WMFExtensions.h */, + 0EFB0EF41B31DE7200D05C08 /* NSError+WMFExtensions.m */, 0E2B06FA1B2D129B00EA2F53 /* Common */, 0E2B06F71B2D126700EA2F53 /* Data Sources */, ); @@ -3284,6 +3288,7 @@ BC8340551B2233BE00A083DB /* LanguagesSectionHeaderView.m in Sources */, 04D149DD18877343006B4104 /* AlertLabel.m in Sources */, BCB669AE1A83F6C400C7B1FE /* MWKHistoryEntry.m in Sources */, + 0EFB0EF51B31DE7200D05C08 /* NSError+WMFExtensions.m in Sources */, 0433542618A093C5009305F0 /* UIView+RemoveConstraints.m in Sources */, 04D686FC1AB2949C0009B44A /* WikiGlyphButton.m in Sources */, C98990341A699DE000AF44FC /* WMFShareCardViewController.m in Sources */, diff --git a/Wikipedia/Networking/Fetchers/SearchResultFetcher.m b/Wikipedia/Networking/Fetchers/SearchResultFetcher.m index 8600b91..0e6ce3e 100644 --- a/Wikipedia/Networking/Fetchers/SearchResultFetcher.m +++ b/Wikipedia/Networking/Fetchers/SearchResultFetcher.m @@ -51,9 +51,7 @@ language:(NSString*)language maxResults:(NSUInteger)maxResults withManager:(AFHTTPRequestOperationManager*)manager - thenNotifyDelegate:(id <FetchFinishedDelegate>)delegate{ - - + thenNotifyDelegate:(id <FetchFinishedDelegate>)delegate { self.searchResults = @[]; self.searchSuggestion = nil; self.searchTerm = searchTerm ? searchTerm : @""; @@ -63,13 +61,11 @@ self.fetchFinishedDelegate = delegate; self.maxSearchResults = maxResults; self.spaceCollapsingRegex = - [NSRegularExpression regularExpressionWithPattern:@"\\s{2,}+" options:NSRegularExpressionCaseInsensitive error:nil]; + [NSRegularExpression regularExpressionWithPattern:@"\\s{2,}+" options:NSRegularExpressionCaseInsensitive error:nil]; return [self searchWithManager:manager]; - } - -- (AFHTTPRequestOperation* )searchWithManager:(AFHTTPRequestOperationManager*)manager { +- (AFHTTPRequestOperation*)searchWithManager:(AFHTTPRequestOperationManager*)manager { NSString* url = [[SessionSingleton sharedInstance] searchApiUrlForLanguage:self.language]; NSDictionary* params = [self getParams]; @@ -110,7 +106,6 @@ } } self.articleTitleToImageMap = map; - } [self finishWithError:error diff --git a/Wikipedia/UI-V5/Global.h b/Wikipedia/UI-V5/Global.h index 212e0bb..96b7c13 100644 --- a/Wikipedia/UI-V5/Global.h +++ b/Wikipedia/UI-V5/Global.h @@ -10,6 +10,7 @@ #import "WMFGCDHelpers.h" #import <BlocksKit/BlocksKit.h> +#import "NSError+WMFExtensions.h" #import "RootViewController.h" #import "CenterNavController.h" diff --git a/Wikipedia/UI-V5/TGLStackedViewController/TGLStackedLayout.m b/Wikipedia/UI-V5/TGLStackedViewController/TGLStackedLayout.m index f0566e4..1f29d7b 100644 --- a/Wikipedia/UI-V5/TGLStackedViewController/TGLStackedLayout.m +++ b/Wikipedia/UI-V5/TGLStackedViewController/TGLStackedLayout.m @@ -326,14 +326,12 @@ return [super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath]; } -- (void)prepareForTransitionToLayout:(UICollectionViewLayout *)newLayout{ - +- (void)prepareForTransitionToLayout:(UICollectionViewLayout*)newLayout { [self.collectionView removeGestureRecognizer:self.moveGestureRecognizer]; [self.collectionView removeGestureRecognizer:self.deletePanGesture]; self.moveGestureRecognizer = nil; - self.deletePanGesture = nil; + self.deletePanGesture = nil; } - #pragma mark - Update Attributes diff --git a/Wikipedia/UI-V5/UICollectionView+WMFExtensions.h b/Wikipedia/UI-V5/UICollectionView+WMFExtensions.h index 98798a9..321ecef 100644 --- a/Wikipedia/UI-V5/UICollectionView+WMFExtensions.h +++ b/Wikipedia/UI-V5/UICollectionView+WMFExtensions.h @@ -11,6 +11,6 @@ * Like other UIKit methods, the completion isn't called if you pass animated = false. * This method ensures the completion block is always called. */ -- (void)wmf_setCollectionViewLayout:(UICollectionViewLayout *)layout animated:(BOOL)animated alwaysFireCompletion:(void (^)(BOOL finished))completion; +- (void)wmf_setCollectionViewLayout:(UICollectionViewLayout*)layout animated:(BOOL)animated alwaysFireCompletion:(void (^)(BOOL finished))completion; @end diff --git a/Wikipedia/UI-V5/UICollectionView+WMFExtensions.m b/Wikipedia/UI-V5/UICollectionView+WMFExtensions.m index 785101a..eabd833 100644 --- a/Wikipedia/UI-V5/UICollectionView+WMFExtensions.m +++ b/Wikipedia/UI-V5/UICollectionView+WMFExtensions.m @@ -37,19 +37,16 @@ * Like other UIKit methods, the completion isn't called if you pass animated = false. * This method ensures the completion block is always called. */ -- (void)wmf_setCollectionViewLayout:(UICollectionViewLayout *)layout animated:(BOOL)animated alwaysFireCompletion:(void (^)(BOOL finished))completion{ - +- (void)wmf_setCollectionViewLayout:(UICollectionViewLayout*)layout animated:(BOOL)animated alwaysFireCompletion:(void (^)(BOOL finished))completion { [self setCollectionViewLayout:layout animated:animated completion:^(BOOL finished) { - if(animated && completion){ + if (animated && completion) { completion(finished); } }]; - - if(!animated && completion){ + + if (!animated && completion) { completion(YES); } - } - @end diff --git a/Wikipedia/UI-V5/UIStoryboard+WMFExtensions.m b/Wikipedia/UI-V5/UIStoryboard+WMFExtensions.m index 0786998..a1c758b 100644 --- a/Wikipedia/UI-V5/UIStoryboard+WMFExtensions.m +++ b/Wikipedia/UI-V5/UIStoryboard+WMFExtensions.m @@ -9,10 +9,8 @@ return [UIStoryboard storyboardWithName:WMFDefaultStoryBoardName bundle:nil]; } -- (id)wmf_instnatiateViewControllerWithIdentifierFromClassName:(Class)viewControllerClass{ - +- (id)wmf_instnatiateViewControllerWithIdentifierFromClassName:(Class)viewControllerClass { return [self instantiateViewControllerWithIdentifier:NSStringFromClass(viewControllerClass)]; } - @end diff --git a/Wikipedia/UI-V5/WMFAppViewController.m b/Wikipedia/UI-V5/WMFAppViewController.m index 377a07b..02b2950 100644 --- a/Wikipedia/UI-V5/WMFAppViewController.m +++ b/Wikipedia/UI-V5/WMFAppViewController.m @@ -10,8 +10,8 @@ #import <Masonry/Masonry.h> @interface WMFAppViewController ()<WMFSearchViewControllerDelegate> -@property (strong, nonatomic) IBOutlet UIView *searchContainerView; -@property (strong, nonatomic) IBOutlet UIView *articleListContainerView; +@property (strong, nonatomic) IBOutlet UIView* searchContainerView; +@property (strong, nonatomic) IBOutlet UIView* articleListContainerView; @property (nonatomic, strong) IBOutlet UIView* splashView; @property (nonatomic, strong) WMFArticleListCollectionViewController* listViewController; @@ -19,20 +19,18 @@ @property (nonatomic, strong) SessionSingleton* session; -@property (nonatomic, strong) MASConstraint *articleListVisibleConstraint; -@property (nonatomic, strong) MASConstraint *articleListMinimizedConstraint; +@property (nonatomic, strong) MASConstraint* articleListVisibleConstraint; +@property (nonatomic, strong) MASConstraint* articleListMinimizedConstraint; @end @implementation WMFAppViewController -- (SessionSingleton*)session{ - - if(!_session){ - +- (SessionSingleton*)session { + if (!_session) { _session = [SessionSingleton sharedInstance]; } - + return _session; } @@ -43,7 +41,6 @@ } - (void)launchAppInWindow:(UIWindow*)window { - WMFStyleManager* manager = [WMFStyleManager new]; [manager applyStyleToWindow:window]; [WMFStyleManager setSharedStyleManager:manager]; @@ -53,12 +50,11 @@ } - (void)loadMainUI { - [self updateListViewBasedOnSearchState:self.searchViewController.state]; self.searchViewController.searchSite = [self.session searchSite]; - self.searchViewController.dataStore = [self.session dataStore]; - self.listViewController.dataSource = [[WMFSavedPagesDataSource alloc] initWithUserDataStore:[self userDataStore]];; + self.searchViewController.dataStore = [self.session dataStore]; + self.listViewController.dataSource = [[WMFSavedPagesDataSource alloc] initWithUserDataStore:[self userDataStore]];; } - (void)resumeApp { @@ -90,7 +86,7 @@ - (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender { if ([segue.destinationViewController isKindOfClass:[WMFSearchViewController class]]) { - self.searchViewController = segue.destinationViewController; + self.searchViewController = segue.destinationViewController; self.searchViewController.delegate = self; } if ([segue.destinationViewController isKindOfClass:[WMFArticleListCollectionViewController class]]) { @@ -155,44 +151,35 @@ #pragma mark - WMFSearchViewControllerDelegate -- (void)searchController:(WMFSearchViewController*)controller searchStateDidChange:(WMFSearchState)state{ - +- (void)searchController:(WMFSearchViewController*)controller searchStateDidChange:(WMFSearchState)state { [self updateListViewBasedOnSearchState:state]; } -- (void)updateListViewBasedOnSearchState:(WMFSearchState)state{ - +- (void)updateListViewBasedOnSearchState:(WMFSearchState)state { switch (state) { - case WMFSearchStateInactive:{ - + case WMFSearchStateInactive: { [self.articleListMinimizedConstraint uninstall]; - [self.articleListContainerView mas_makeConstraints:^(MASConstraintMaker *make) { + [self.articleListContainerView mas_makeConstraints:^(MASConstraintMaker* make) { self.articleListVisibleConstraint = make.top.equalTo(self.view.mas_top).with.offset(64.0); }]; [self.view layoutIfNeeded]; - - [self.listViewController setListMode:WMFArticleListModeNormal animated:YES completion:NULL]; - - } - break; - case WMFSearchStateActive:{ - - __weak __typeof(self)weakSelf = self; - [self.listViewController setListMode:WMFArticleListModeBottomStacked animated:YES completion:^{ - __strong __typeof(weakSelf)strongSelf = weakSelf; + [self.listViewController setListMode:WMFArticleListModeNormal animated:YES completion:NULL]; + } + break; + case WMFSearchStateActive: { + __weak __typeof(self) weakSelf = self; + [self.listViewController setListMode:WMFArticleListModeBottomStacked animated:YES completion:^{ + __strong __typeof(weakSelf) strongSelf = weakSelf; [strongSelf.articleListVisibleConstraint uninstall]; - [strongSelf.articleListContainerView mas_makeConstraints:^(MASConstraintMaker *make) { + [strongSelf.articleListContainerView mas_makeConstraints:^(MASConstraintMaker* make) { strongSelf.articleListMinimizedConstraint = make.top.equalTo(strongSelf.view.mas_bottom).with.offset(-50.0); }]; [strongSelf.view layoutIfNeeded]; }]; - } - break; + break; } } - - @end diff --git a/Wikipedia/UI-V5/WMFArticleListCollectionViewController.h b/Wikipedia/UI-V5/WMFArticleListCollectionViewController.h index e394c88..57d2c25 100644 --- a/Wikipedia/UI-V5/WMFArticleListCollectionViewController.h +++ b/Wikipedia/UI-V5/WMFArticleListCollectionViewController.h @@ -4,8 +4,7 @@ NS_ASSUME_NONNULL_BEGIN -typedef NS_ENUM(NSUInteger, WMFArticleListMode) { - +typedef NS_ENUM (NSUInteger, WMFArticleListMode) { WMFArticleListModeNormal = 0, WMFArticleListModeBottomStacked }; diff --git a/Wikipedia/UI-V5/WMFArticleListCollectionViewController.m b/Wikipedia/UI-V5/WMFArticleListCollectionViewController.m index 5357007..891b6ab 100644 --- a/Wikipedia/UI-V5/WMFArticleListCollectionViewController.m +++ b/Wikipedia/UI-V5/WMFArticleListCollectionViewController.m @@ -24,69 +24,64 @@ @implementation WMFArticleListCollectionViewController -- (void)setDataSource:(id<WMFArticleListDataSource> __nullable)dataSource{ - - if([_dataSource isEqual:dataSource]){ +- (void)setDataSource:(id<WMFArticleListDataSource> __nullable)dataSource { + if ([_dataSource isEqual:dataSource]) { return; } - + _dataSource = dataSource; - + self.title = [_dataSource displayTitle]; - if([self isViewLoaded]){ + if ([self isViewLoaded]) { [self.collectionView reloadData]; } } #pragma mark - List Mode -- (void)setListMode:(WMFArticleListMode)mode animated:(BOOL)animated completion:(nullable dispatch_block_t)completion{ - - if(_mode == mode){ +- (void)setListMode:(WMFArticleListMode)mode animated:(BOOL)animated completion:(nullable dispatch_block_t)completion { + if (_mode == mode) { return; } - + _mode = mode; - - if([self isViewLoaded]){ + + if ([self isViewLoaded]) { [self updateListForMode:_mode animated:animated completion:completion]; } } -- (void)updateListForMode:(WMFArticleListMode)mode animated:(BOOL)animated completion:(nullable dispatch_block_t)completion{ - - +- (void)updateListForMode:(WMFArticleListMode)mode animated:(BOOL)animated completion:(nullable dispatch_block_t)completion { UICollectionViewLayout* layout; - - switch (mode) { - case WMFArticleListModeBottomStacked:{ - self.bottomStackLayout.itemSize = self.view.bounds.size; - layout = self.bottomStackLayout; - - } - break; - case WMFArticleListModeNormal: - default:{ - self.stackedLayout.itemSize = self.view.bounds.size; - layout = self.stackedLayout; - } - break; - } - - __weak __typeof(self)weakSelf = self; + switch (mode) { + case WMFArticleListModeBottomStacked: { + self.bottomStackLayout.itemSize = self.view.bounds.size; + layout = self.bottomStackLayout; + } + break; + case WMFArticleListModeNormal: + default: { + self.stackedLayout.itemSize = self.view.bounds.size; + layout = self.stackedLayout; + } + break; + } + + + __weak __typeof(self) weakSelf = self; [self setOffsecreenLayoutAnimated:animated completion:^(BOOL finished) { - __strong __typeof(weakSelf)strongSelf = weakSelf; + __strong __typeof(weakSelf) strongSelf = weakSelf; [strongSelf.collectionView wmf_setCollectionViewLayout:layout animated:animated alwaysFireCompletion:^(BOOL finished) { - __strong __typeof(weakSelf)strongSelf = weakSelf; - if(mode == WMFArticleListModeBottomStacked){ + __strong __typeof(weakSelf) strongSelf = weakSelf; + if (mode == WMFArticleListModeBottomStacked) { strongSelf.collectionView.scrollEnabled = NO; - }else{ + } else { strongSelf.collectionView.scrollEnabled = YES; } - - if(completion){ + + if (completion) { completion(); } }]; @@ -99,38 +94,35 @@ * The only solution I could find was to switch to an intermdeiate layout * first. This moves the items off screen and then brings them back. */ -- (void)setOffsecreenLayoutAnimated:(BOOL)animated completion:(void (^)(BOOL finished))completion{ - +- (void)setOffsecreenLayoutAnimated:(BOOL)animated completion:(void (^)(BOOL finished))completion { WMFOffScreenFlowLayout* offscreen = [[WMFOffScreenFlowLayout alloc] init]; offscreen.itemSize = self.view.bounds.size; - + [self.collectionView wmf_setCollectionViewLayout:offscreen animated:animated alwaysFireCompletion:completion]; } - #pragma mark - Accessors - (TGLStackedLayout*)stackedLayout { - if(!_stackedLayout){ + if (!_stackedLayout) { TGLStackedLayout* stacked = [[TGLStackedLayout alloc] init]; stacked.fillHeight = YES; stacked.alwaysBounce = YES; stacked.delegate = self; - stacked.itemSize = self.view.bounds.size; - _stackedLayout = stacked; + stacked.itemSize = self.view.bounds.size; + _stackedLayout = stacked; } - + return _stackedLayout; } - (WMFBottomStackLayout*)bottomStackLayout { - - if(!_bottomStackLayout){ + if (!_bottomStackLayout) { WMFBottomStackLayout* stack = [[WMFBottomStackLayout alloc] init]; - stack.itemSize = self.view.bounds.size; + stack.itemSize = self.view.bounds.size; _bottomStackLayout = stack; } - + return _bottomStackLayout; } @@ -138,7 +130,7 @@ - (void)viewDidLoad { [super viewDidLoad]; - + self.collectionView.backgroundColor = [UIColor clearColor]; [self updateListForMode:self.mode animated:NO completion:NULL]; @@ -187,7 +179,7 @@ #pragma mark - Update Cell Size - (void)updateCellSizeBasedOnViewFrame { - self.stackedLayout.itemSize = self.view.bounds.size; + self.stackedLayout.itemSize = self.view.bounds.size; self.bottomStackLayout.itemSize = self.view.bounds.size; } @@ -255,9 +247,8 @@ } - (void)stackLayout:(TGLStackedLayout*)layout deleteItemAtIndexPath:(NSIndexPath*)indexPath { - - if([self.dataSource respondsToSelector:@selector(deleteArticleAtIndexPath:)]){ - [self.dataSource deleteArticleAtIndexPath:indexPath]; + if ([self.dataSource respondsToSelector:@selector(deleteArticleAtIndexPath:)]) { + [self.dataSource deleteArticleAtIndexPath:indexPath]; } } diff --git a/Wikipedia/UI-V5/WMFArticleListDataSource.h b/Wikipedia/UI-V5/WMFArticleListDataSource.h index e5d8a83..a469ffe 100644 --- a/Wikipedia/UI-V5/WMFArticleListDataSource.h +++ b/Wikipedia/UI-V5/WMFArticleListDataSource.h @@ -7,7 +7,7 @@ - (nullable NSString*)displayTitle; -- (NSUInteger)articleCount; +- (NSUInteger) articleCount; - (MWKArticle*)articleForIndexPath:(NSIndexPath*)indexPath; - (BOOL)canDeleteItemAtIndexpath:(NSIndexPath*)indexPath; diff --git a/Wikipedia/UI-V5/WMFBottomStackLayout.m b/Wikipedia/UI-V5/WMFBottomStackLayout.m index a6ac2d8..42bc1e0 100644 --- a/Wikipedia/UI-V5/WMFBottomStackLayout.m +++ b/Wikipedia/UI-V5/WMFBottomStackLayout.m @@ -13,8 +13,7 @@ #pragma mark - Setup -- (instancetype)init -{ +- (instancetype)init { self = [super init]; if (self) { [self setupDefualts]; @@ -22,8 +21,7 @@ return self; } -- (instancetype)initWithCoder:(NSCoder *)coder -{ +- (instancetype)initWithCoder:(NSCoder*)coder { self = [super initWithCoder:coder]; if (self) { [self setupDefualts]; @@ -31,14 +29,13 @@ return self; } -- (void)setupDefualts{ - +- (void)setupDefualts { self.minimumLineSpacing = 0.0f; self.minimumInteritemSpacing = 0.0f; self.scrollDirection = UICollectionViewScrollDirectionVertical; _topCardExposedHeight = 40.0; - _overlapSpacing = 4; + _overlapSpacing = 4; } #pragma mark - Accessors @@ -50,7 +47,7 @@ } } -- (void)setTopCardExposedHeight:(CGFloat)topCardExposedHeight{ +- (void)setTopCardExposedHeight:(CGFloat)topCardExposedHeight { if (_topCardExposedHeight != topCardExposedHeight) { _topCardExposedHeight = topCardExposedHeight; [self invalidateLayout]; @@ -59,49 +56,42 @@ #pragma mark - UICollectionViewLayout -- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{ - - NSArray* items = [self.visibleIndexPaths bk_map:^id(id obj) { - +- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect { + NSArray* items = [self.visibleIndexPaths bk_map:^id (id obj) { return [self layoutAttributesForItemAtIndexPath:obj]; }]; return items; } -- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{ - +- (UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath*)indexPath { UICollectionViewLayoutAttributes* item = [super layoutAttributesForItemAtIndexPath:indexPath]; [self adjustLayoutAttributes:item]; return item; - } -- (void)adjustLayoutAttributes:(UICollectionViewLayoutAttributes*)attributes{ - +- (void)adjustLayoutAttributes:(UICollectionViewLayoutAttributes*)attributes { CGFloat spacingForIndexPath; - + //Stagger the first 2 cards, then stack the rest behind - if([self.visibleIndexPaths indexOfObject:attributes.indexPath] < 2){ - spacingForIndexPath = (self.overlapSpacing * [self.visibleIndexPaths indexOfObject:attributes.indexPath]); - }else{ + if ([self.visibleIndexPaths indexOfObject:attributes.indexPath] < 2) { + spacingForIndexPath = (self.overlapSpacing* [self.visibleIndexPaths indexOfObject:attributes.indexPath]); + } else { spacingForIndexPath = (self.overlapSpacing * 2); } - - CGFloat topCardYOffset = CGRectGetHeight(self.collectionView.bounds)-self.topCardExposedHeight; - CGRect frame = attributes.frame; - frame.origin.y = topCardYOffset + spacingForIndexPath; - attributes.frame = frame; + + CGFloat topCardYOffset = CGRectGetHeight(self.collectionView.bounds) - self.topCardExposedHeight; + CGRect frame = attributes.frame; + frame.origin.y = topCardYOffset + spacingForIndexPath; + attributes.frame = frame; attributes.zIndex = attributes.indexPath.item; } -- (CGSize)collectionViewContentSize{ - +- (CGSize)collectionViewContentSize { return self.collectionView.bounds.size; } -- (void)prepareForTransitionFromLayout:(UICollectionViewLayout *)oldLayout{ - +- (void)prepareForTransitionFromLayout:(UICollectionViewLayout*)oldLayout { self.visibleIndexPaths = [self.collectionView indexPathsForVisibleItems]; } diff --git a/Wikipedia/UI-V5/WMFOffScreenFlowLayout.m b/Wikipedia/UI-V5/WMFOffScreenFlowLayout.m index 7d1f2c2..e296885 100644 --- a/Wikipedia/UI-V5/WMFOffScreenFlowLayout.m +++ b/Wikipedia/UI-V5/WMFOffScreenFlowLayout.m @@ -6,8 +6,7 @@ #pragma mark - Setup -- (instancetype)init -{ +- (instancetype)init { self = [super init]; if (self) { [self setupDefualts]; @@ -15,8 +14,7 @@ return self; } -- (instancetype)initWithCoder:(NSCoder *)coder -{ +- (instancetype)initWithCoder:(NSCoder*)coder { self = [super initWithCoder:coder]; if (self) { [self setupDefualts]; @@ -24,8 +22,7 @@ return self; } -- (void)setupDefualts{ - +- (void)setupDefualts { self.minimumLineSpacing = 0.0f; self.minimumInteritemSpacing = 0.0f; self.scrollDirection = UICollectionViewScrollDirectionVertical; @@ -33,38 +30,31 @@ #pragma mark - UICollectionViewLayout -- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{ - +- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect { NSArray* items = [super layoutAttributesForElementsInRect:rect]; - - [items enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - + + [items enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL* stop) { [self adjustLayoutAttributes:obj]; }]; - + return items; } -- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{ - +- (UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath*)indexPath { UICollectionViewLayoutAttributes* item = [super layoutAttributesForItemAtIndexPath:indexPath]; [self adjustLayoutAttributes:item]; return item; - } -- (void)adjustLayoutAttributes:(UICollectionViewLayoutAttributes*)attributes{ - +- (void)adjustLayoutAttributes:(UICollectionViewLayoutAttributes*)attributes { CGRect frame = attributes.frame; - frame.origin.y = CGRectGetHeight(self.collectionView.bounds); - attributes.frame = frame; + frame.origin.y = CGRectGetHeight(self.collectionView.bounds); + attributes.frame = frame; attributes.zIndex = attributes.indexPath.item; } -- (CGSize)collectionViewContentSize{ - +- (CGSize)collectionViewContentSize { return self.collectionView.bounds.size; } - @end diff --git a/Wikipedia/UI-V5/WMFSavedPagesDataSource.m b/Wikipedia/UI-V5/WMFSavedPagesDataSource.m index 830f233..ef0c798 100644 --- a/Wikipedia/UI-V5/WMFSavedPagesDataSource.m +++ b/Wikipedia/UI-V5/WMFSavedPagesDataSource.m @@ -22,8 +22,8 @@ } return self; } - -- (nullable NSString*)displayTitle{ + +- (nullable NSString*)displayTitle { return MWLocalizedString(@"saved-pages-title", nil); } diff --git a/Wikipedia/UI-V5/WMFSearchFetcher.h b/Wikipedia/UI-V5/WMFSearchFetcher.h index 2fb435e..a8a5226 100644 --- a/Wikipedia/UI-V5/WMFSearchFetcher.h +++ b/Wikipedia/UI-V5/WMFSearchFetcher.h @@ -3,6 +3,7 @@ #import "PromiseKit.h" @class MWKSite; +@class WMFSearchResults; NS_ASSUME_NONNULL_BEGIN @@ -17,6 +18,8 @@ - (AnyPromise*)searchArticleTitlesForSearchTerm:(NSString*)searchTerm; +- (AnyPromise*)searchFullArticleTextForSearchTerm:(NSString*)searchTerm appendToPreviousResults:(WMFSearchResults*)results; + @end NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Wikipedia/UI-V5/WMFSearchFetcher.m b/Wikipedia/UI-V5/WMFSearchFetcher.m index 399093a..17548bc 100644 --- a/Wikipedia/UI-V5/WMFSearchFetcher.m +++ b/Wikipedia/UI-V5/WMFSearchFetcher.m @@ -26,41 +26,35 @@ @implementation WMFSearchFetcher -- (instancetype)initWithSearchSite:(MWKSite*)site dataStore:(MWKDataStore*)dataStore{ - +- (instancetype)initWithSearchSite:(MWKSite*)site dataStore:(MWKDataStore*)dataStore { self = [super init]; if (self) { - self.searchSite = site; - self.dataStore = dataStore; + self.searchSite = site; + self.dataStore = dataStore; self.maxSearchResults = kWMFmaxSearchResults; AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager wmf_createDefaultManager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; - self.operationManager = manager; + self.operationManager = manager; } return self; } -- (AnyPromise*)searchArticleTitlesForSearchTerm:(NSString*)searchTerm searchType:(SearchType)type{ - +- (AnyPromise*)searchArticleTitlesForSearchTerm:(NSString*)searchTerm searchType:(SearchType)type { [self.operation cancel]; - + return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { - self.resolver = resolve; - + self.fetcher = [[SearchResultFetcher alloc] init]; self.operation = [self.fetcher searchForTerm:searchTerm searchType:type searchReason:SEARCH_REASON_UNKNOWN language:self.searchSite.language maxResults:self.maxSearchResults withManager:self.operationManager thenNotifyDelegate:self]; }]; } -- (AnyPromise*)searchArticleTitlesForSearchTerm:(NSString*)searchTerm{ - +- (AnyPromise*)searchArticleTitlesForSearchTerm:(NSString*)searchTerm { return [self searchArticleTitlesForSearchTerm:searchTerm searchType:SEARCH_TYPE_TITLES]; } - -- (AnyPromise*)searchFullArticleTextForSearchTerm:(NSString*)searchTerm appendToPreviousResults:(WMFSearchResults*)results{ - +- (AnyPromise*)searchFullArticleTextForSearchTerm:(NSString*)searchTerm appendToPreviousResults:(WMFSearchResults*)results { self.previousResults = results; return [self searchArticleTitlesForSearchTerm:searchTerm searchType:SEARCH_TYPE_IN_ARTICLES]; } @@ -68,38 +62,49 @@ - (void)fetchFinished:(id)sender fetchedData:(id)fetchedData status:(FetchFinalStatus)status - error:(NSError*)error{ - - if(self.resolver){ - - if(!error){ + error:(NSError*)error { + if (self.resolver) { + if (!error) { self.resolver([self searchResultsFromFetcher:sender]); - }else{ + } else { self.resolver(error); } self.operation = nil; - self.resolver = nil; + self.resolver = nil; } } -- (WMFSearchResults*)searchResultsFromFetcher:(SearchResultFetcher*)resultsFetcher{ - - NSArray* articles = [resultsFetcher.searchResults bk_map:^id(NSDictionary* obj) { - +- (WMFSearchResults*)searchResultsFromFetcher:(SearchResultFetcher*)resultsFetcher { + NSArray* articles = [resultsFetcher.searchResults bk_map:^id (NSDictionary* obj) { MWKTitle* title = [MWKTitle titleWithString:obj[@"title"] site:self.searchSite]; MWKArticle* article = [[MWKArticle alloc] initWithTitle:title dataStore:self.dataStore searchResultsDict:obj]; article.thumbnailURL = resultsFetcher.articleTitleToImageMap[title.text]; [article loadThumbnailFromDisk]; - + return article; }]; - - WMFSearchResults* results = [[WMFSearchResults alloc] initWithSearchTerm:resultsFetcher.searchTerm articles:articles searchSuggestion:resultsFetcher.searchSuggestion]; + + WMFSearchResults* results = nil; + + if (self.previousResults) { + articles = [articles bk_reject:^BOOL (MWKArticle* obj) { + if ([self.previousResults.articles containsObject:obj]) { + return YES; + } + return NO; + }]; + + articles = [[NSArray arrayWithArray:[self.previousResults articles]] arrayByAddingObjectsFromArray:articles]; + results = [[WMFSearchResults alloc] initWithSearchTerm:self.previousResults.searchTerm articles:articles searchSuggestion:self.previousResults.searchSuggestion]; + self.previousResults = nil; + } else { + results = [[WMFSearchResults alloc] initWithSearchTerm:resultsFetcher.searchTerm articles:articles searchSuggestion:resultsFetcher.searchSuggestion]; + } + + return results; } - - @end diff --git a/Wikipedia/UI-V5/WMFSearchResults.h b/Wikipedia/UI-V5/WMFSearchResults.h index a671e80..5715708 100644 --- a/Wikipedia/UI-V5/WMFSearchResults.h +++ b/Wikipedia/UI-V5/WMFSearchResults.h @@ -7,7 +7,7 @@ @interface WMFSearchResults : MTLModel<WMFArticleListDataSource> @property (nonatomic, copy, readonly) NSString* searchTerm; -@property (nonatomic, strong, nullable, readonly) NSArray* resultArticles; +@property (nonatomic, strong, nullable, readonly) NSArray* articles; @property (nonatomic, copy, nullable, readonly) NSString* searchSuggestion; - (instancetype)initWithSearchTerm:(NSString*)searchTerm articles:(nullable NSArray*)articles searchSuggestion:(nullable NSString*)suggestion; diff --git a/Wikipedia/UI-V5/WMFSearchResults.m b/Wikipedia/UI-V5/WMFSearchResults.m index 984473c..1475feb 100644 --- a/Wikipedia/UI-V5/WMFSearchResults.m +++ b/Wikipedia/UI-V5/WMFSearchResults.m @@ -6,49 +6,45 @@ @interface WMFSearchResults () @property (nonatomic, copy, readwrite) NSString* searchTerm; -@property (nonatomic, strong, nullable, readwrite) NSArray* resultArticles; +@property (nonatomic, strong, nullable, readwrite) NSArray* articles; @property (nonatomic, copy, nullable, readwrite) NSString* searchSuggestion; @end @implementation WMFSearchResults -- (instancetype)initWithSearchTerm:(NSString*)searchTerm articles:(nullable NSArray*)articles searchSuggestion:(nullable NSString*)suggestion{ - +- (instancetype)initWithSearchTerm:(NSString*)searchTerm articles:(nullable NSArray*)articles searchSuggestion:(nullable NSString*)suggestion { self = [super init]; if (self) { - self.searchTerm = searchTerm; - self.resultArticles = articles; + self.searchTerm = searchTerm; + self.articles = articles; self.searchSuggestion = suggestion; } return self; } -- (nullable NSString*)displayTitle{ +- (nullable NSString*)displayTitle { return self.searchTerm; } -- (NSUInteger)articleCount{ - return [self.resultArticles count]; +- (NSUInteger)articleCount { + return [self.articles count]; } - (MWKArticle*)articleForIndexPath:(NSIndexPath*)indexPath { - return self.resultArticles[indexPath.row]; + return self.articles[indexPath.row]; } -- (BOOL)canDeleteItemAtIndexpath:(NSIndexPath*)indexPath{ +- (BOOL)canDeleteItemAtIndexpath:(NSIndexPath*)indexPath { return NO; } - -- (BOOL)noResults{ - - if(self.searchTerm && [self.resultArticles count] == 0){ +- (BOOL)noResults { + if (self.searchTerm && [self.articles count] == 0) { return YES; } return NO; } - @end diff --git a/Wikipedia/UI-V5/WMFSearchViewController.h b/Wikipedia/UI-V5/WMFSearchViewController.h index f17947d..6dea657 100644 --- a/Wikipedia/UI-V5/WMFSearchViewController.h +++ b/Wikipedia/UI-V5/WMFSearchViewController.h @@ -3,8 +3,7 @@ NS_ASSUME_NONNULL_BEGIN -typedef NS_ENUM(NSUInteger, WMFSearchState) { - +typedef NS_ENUM (NSUInteger, WMFSearchState) { WMFSearchStateInactive, WMFSearchStateActive }; diff --git a/Wikipedia/UI-V5/WMFSearchViewController.m b/Wikipedia/UI-V5/WMFSearchViewController.m index 8040942..57a0a1d 100644 --- a/Wikipedia/UI-V5/WMFSearchViewController.m +++ b/Wikipedia/UI-V5/WMFSearchViewController.m @@ -6,31 +6,41 @@ #import "WMFSearchResults.h" #import "SearchDidYouMeanButton.h" +#import <Masonry/Masonry.h> + +static NSUInteger const kWMFMinResultsBeforeAutoFullTextSearch = 12; @interface WMFSearchViewController () @property (nonatomic, strong) WMFArticleListCollectionViewController* resultsListController; -@property (strong, nonatomic) IBOutlet UISearchBar *searchBar; -@property (strong, nonatomic) IBOutlet UIButton *searchSuggestionButton; +@property (strong, nonatomic) IBOutlet UISearchBar* searchBar; +@property (strong, nonatomic) IBOutlet UIButton* searchSuggestionButton; +@property (strong, nonatomic) IBOutlet UIView* resultsListContainerView; @property (nonatomic, strong) WMFSearchFetcher* fetcher; @property (nonatomic, assign, readwrite) WMFSearchState state; +@property (nonatomic, strong) MASConstraint* suggestionButtonVisibleConstraint; +@property (nonatomic, strong) MASConstraint* suggestionButtonHiddenConstraint; + @end @implementation WMFSearchViewController -- (NSString*)currentSearchTerm{ +- (NSString*)currentSearchTerm { return [(WMFSearchResults*)self.resultsListController.dataSource searchTerm]; } -- (void)updateSearchStateAndNotifyDelegate:(WMFSearchState)state{ - - if(self.state == state){ +- (NSString*)searchSuggestion { + return [(WMFSearchResults*)self.resultsListController.dataSource searchSuggestion]; +} + +- (void)updateSearchStateAndNotifyDelegate:(WMFSearchState)state { + if (self.state == state) { return; } - + self.state = state; [self.delegate searchController:self searchStateDidChange:self.state]; @@ -40,8 +50,7 @@ - (void)viewDidLoad { [super viewDidLoad]; - - self.searchSuggestionButton.hidden = YES; + [self updateUIWithResults:nil]; } - (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender { @@ -52,92 +61,107 @@ #pragma mark - UISearchBarDelegate -- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{ - +- (void)searchBarTextDidBeginEditing:(UISearchBar*)searchBar { [self updateSearchStateAndNotifyDelegate:WMFSearchStateActive]; - + [self.searchBar setShowsCancelButton:YES animated:YES]; - + self.fetcher = [[WMFSearchFetcher alloc] initWithSearchSite:self.searchSite dataStore:self.dataStore]; - - if([self.searchBar.text length] > 2){ - - if(![[self currentSearchTerm] isEqualToString:self.searchBar.text]){ + + if ([self.searchBar.text length] > 2) { + if (![[self currentSearchTerm] isEqualToString:self.searchBar.text]) { [self searchForSearchTerm:self.searchBar.text]; } - - }else{ - + } else { self.resultsListController.dataSource = nil; } } -- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ - - if(searchText.length > 2){ - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - - if([searchText isEqualToString:self.searchBar.text]){ - [self searchForSearchTerm:searchText]; - } - }); - } +- (void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)searchText { + dispatchOnMainQueueAfterDelayInSeconds(0.4, ^{ + if ([searchText isEqualToString:self.searchBar.text]) { + [self searchForSearchTerm:searchText]; + } + }); } - -- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{ - - +- (void)searchBarTextDidEndEditing:(UISearchBar*)searchBar { } -- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ - - +- (void)searchBarSearchButtonClicked:(UISearchBar*)searchBar { } -- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{ - +- (void)searchBarCancelButtonClicked:(UISearchBar*)searchBar { [self updateSearchStateAndNotifyDelegate:WMFSearchStateInactive]; - + self.searchBar.text = nil; [self.searchBar setShowsCancelButton:NO animated:YES]; [self.searchBar resignFirstResponder]; } - #pragma mark - Search -- (void)searchForSearchTerm:(NSString*)searchTerm{ - - [self.fetcher searchArticleTitlesForSearchTerm:searchTerm].then(^(WMFSearchResults* results){ - - self.title = results.searchTerm; - - [self updateSearchButtonWithResults:results]; - +- (void)searchForSearchTerm:(NSString*)searchTerm { + dispatch_promise(^{ + return (searchTerm.length > 2 ? searchTerm : [NSError wmf_errorWithType:WMFErrorTypeStringLength userInfo:nil]); + }).then(^(NSString* searchTerm){ + return [self.fetcher searchArticleTitlesForSearchTerm:searchTerm]; + }).then((id) ^ (WMFSearchResults * results){ + [UIView animateWithDuration:0.25 animations:^{ + [self updateUIWithResults:results]; + }]; + self.resultsListController.dataSource = results; + if ([results.articles count] < kWMFMinResultsBeforeAutoFullTextSearch) { + return [self.fetcher searchFullArticleTextForSearchTerm:searchTerm appendToPreviousResults:results]; + } + + return [AnyPromise promiseWithValue:results]; + }).then(^(WMFSearchResults* results){ + self.resultsListController.dataSource = results; }).catch(^(NSError* error){ - NSLog(@"%@", [error description]); }); - } -- (void)updateSearchButtonWithResults:(WMFSearchResults*)results{ - -// if(![results noResults] && [results.searchSuggestion length]){ -// -// self.searchSuggestionButton.hidden = NO; -// -// [self.searchSuggestionButton setTitle:[NSString stringWithFormat:@"%@:%@", MWLocalizedString(@"search-did-you-mean", nil), results.searchSuggestion] forState:UIControlStateNormal]; -// -// }else{ -// -// self.searchSuggestionButton.hidden = YES; -// } - +- (void)updateUIWithResults:(WMFSearchResults*)results { + self.title = results.searchTerm; + [self updateSearchButtonWithResults:results.searchSuggestion]; } +- (void)updateSearchButtonWithResults:(NSString*)searchSuggestion { + if ([searchSuggestion length]) { + [self.searchSuggestionButton setTitle:[NSString stringWithFormat:@"%@:%@", MWLocalizedString(@"search-did-you-mean", nil), searchSuggestion] forState:UIControlStateNormal]; + + if (!self.suggestionButtonVisibleConstraint) { + [self.suggestionButtonHiddenConstraint uninstall]; + self.suggestionButtonHiddenConstraint = nil; + [self.resultsListContainerView mas_makeConstraints:^(MASConstraintMaker* make) { + self.suggestionButtonVisibleConstraint = make.top.equalTo(self.searchSuggestionButton.mas_bottom).with.offset(6.0); + }]; + [self.view layoutIfNeeded]; + } + } else { + [self.searchSuggestionButton setTitle:nil forState:UIControlStateNormal]; + + if (!self.suggestionButtonHiddenConstraint) { + [self.suggestionButtonVisibleConstraint uninstall]; + self.suggestionButtonVisibleConstraint = nil; + [self.resultsListContainerView mas_makeConstraints:^(MASConstraintMaker* make) { + self.suggestionButtonHiddenConstraint = make.top.equalTo(self.searchBar.mas_bottom); + }]; + [self.view layoutIfNeeded]; + } + } +} + +- (IBAction)searchForSuggestion:(id)sender { + self.searchBar.text = [self searchSuggestion]; + [UIView animateWithDuration:0.25 animations:^{ + [self updateSearchButtonWithResults:nil]; + }]; + + [self searchForSearchTerm:self.searchBar.text]; +} @end diff --git a/Wikipedia/UI-V5/iPhone_Root.storyboard b/Wikipedia/UI-V5/iPhone_Root.storyboard index 0f11e9e..89893f5 100644 --- a/Wikipedia/UI-V5/iPhone_Root.storyboard +++ b/Wikipedia/UI-V5/iPhone_Root.storyboard @@ -114,24 +114,27 @@ </connections> </searchBar> <containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ia7-49-Gwu"> - <rect key="frame" x="0.0" y="44" width="600" height="536"/> + <rect key="frame" x="0.0" y="84" width="600" height="496"/> <animations/> <connections> <segue destination="qVm-oc-aaW" kind="embed" id="2dT-rC-ziD"/> </connections> </containerView> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ukX-0p-5ey"> - <rect key="frame" x="277" y="79" width="46" height="30"/> + <rect key="frame" x="277" y="48" width="46" height="30"/> <animations/> <state key="normal" title="Button"> <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> </state> + <connections> + <action selector="searchForSuggestion:" destination="tkf-8P-b2O" eventType="touchUpInside" id="0Md-vC-UXr"/> + </connections> </button> </subviews> <animations/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <constraints> - <constraint firstItem="ukX-0p-5ey" firstAttribute="top" secondItem="ZNj-Jo-URc" secondAttribute="bottom" constant="35" id="32n-FT-n9y"/> + <constraint firstItem="ukX-0p-5ey" firstAttribute="top" secondItem="ZNj-Jo-URc" secondAttribute="bottom" constant="4" id="32n-FT-n9y"/> <constraint firstAttribute="centerY" secondItem="ZNj-Jo-URc" secondAttribute="centerY" id="7um-O6-iBm"/> <constraint firstItem="Ia7-49-Gwu" firstAttribute="leading" secondItem="xp5-j8-6jN" secondAttribute="leading" id="AdT-tS-YIU"/> <constraint firstItem="ZNj-Jo-URc" firstAttribute="top" secondItem="CKX-gH-RjL" secondAttribute="bottom" id="HTd-6H-IdL"/> @@ -139,6 +142,7 @@ <constraint firstItem="Ia7-49-Gwu" firstAttribute="top" secondItem="ZNj-Jo-URc" secondAttribute="bottom" id="VR7-y0-CDG"/> <constraint firstItem="8Yb-zt-F5o" firstAttribute="top" secondItem="Ia7-49-Gwu" secondAttribute="bottom" id="XlJ-cb-ymV"/> <constraint firstAttribute="centerX" secondItem="ZNj-Jo-URc" secondAttribute="centerX" id="cxv-4Q-C8N"/> + <constraint firstItem="Ia7-49-Gwu" firstAttribute="top" secondItem="ukX-0p-5ey" secondAttribute="bottom" constant="6" placeholder="YES" id="fdO-Tl-2cD"/> <constraint firstAttribute="centerX" secondItem="ukX-0p-5ey" secondAttribute="centerX" id="h5k-7F-xym"/> <constraint firstItem="ZNj-Jo-URc" firstAttribute="leading" secondItem="xp5-j8-6jN" secondAttribute="leading" id="lud-F9-Eww"/> <constraint firstAttribute="trailing" secondItem="ZNj-Jo-URc" secondAttribute="trailing" id="zhb-KY-6d8"/> @@ -147,11 +151,13 @@ <mask key="constraints"> <exclude reference="7um-O6-iBm"/> <exclude reference="cxv-4Q-C8N"/> + <exclude reference="VR7-y0-CDG"/> </mask> </variation> </view> <toolbarItems/> <connections> + <outlet property="resultsListContainerView" destination="Ia7-49-Gwu" id="xdS-en-9mw"/> <outlet property="searchBar" destination="ZNj-Jo-URc" id="Y5b-g5-7Mc"/> <outlet property="searchSuggestionButton" destination="ukX-0p-5ey" id="O0X-WP-Nym"/> </connections> @@ -165,7 +171,7 @@ <objects> <collectionViewController storyboardIdentifier="WMFArticleListCollectionViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="qVm-oc-aaW" customClass="WMFArticleListCollectionViewController" sceneMemberID="viewController"> <collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" id="cbI-aA-luO"> - <rect key="frame" x="0.0" y="0.0" width="600" height="536"/> + <rect key="frame" x="0.0" y="0.0" width="600" height="496"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <animations/> <collectionViewLayout key="collectionViewLayout" id="OM6-RR-VUO" customClass="TGLStackedLayout"/> -- To view, visit https://gerrit.wikimedia.org/r/219176 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I748da6d9bf6c2bffe733ec49d44d5f057fec5e65 Gerrit-PatchSet: 1 Gerrit-Project: apps/ios/wikipedia Gerrit-Branch: 5.0 Gerrit-Owner: Fjalapeno <cfl...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits