Brion VIBBER has submitted this change and it was merged.

Change subject: Custom pull-to-refresh for articles.
......................................................................


Custom pull-to-refresh for articles.

Change-Id: Id76ad6518cf0cdc2f2b1a05a59e09c93e7146b7a
---
M Wikipedia-iOS/View Controllers/Preview/PreviewAndSaveViewController.m
M Wikipedia-iOS/View Controllers/WebView/WebViewController.h
M Wikipedia-iOS/View Controllers/WebView/WebViewController.m
M Wikipedia-iOS/en.lproj/Localizable.strings
M Wikipedia-iOS/qqq.lproj/Localizable.strings
5 files changed, 171 insertions(+), 23 deletions(-)

Approvals:
  Dr0ptp4kt: Looks good to me, but someone else must approve
  Brion VIBBER: Verified; Looks good to me, approved
  Siebrand: Looks good to me, but someone else must approve



diff --git a/Wikipedia-iOS/View 
Controllers/Preview/PreviewAndSaveViewController.m b/Wikipedia-iOS/View 
Controllers/Preview/PreviewAndSaveViewController.m
index 5b9e811..3cfe8c8 100644
--- a/Wikipedia-iOS/View Controllers/Preview/PreviewAndSaveViewController.m
+++ b/Wikipedia-iOS/View Controllers/Preview/PreviewAndSaveViewController.m
@@ -314,32 +314,15 @@
     UploadSectionWikiTextOp *uploadWikiTextOp =
     [[UploadSectionWikiTextOp alloc] initForPageTitle:section.article.title 
domain:section.article.domain section:section.index wikiText:self.wikiText 
summary:editSummary captchaId:self.captchaId 
captchaWord:self.captchaViewController.captchaTextBox.text  
completionBlock:^(NSString *result){
         
-        // Mark article for refreshing so its data will be reloaded.
-        // (Needs to be done on worker context as worker context changes 
bubble up through
-        // main context too - so web view controller accessing main context 
will see changes.)
+        // Mark article for refreshing and reload it.
         if (articleID) {
-            [articleDataContext_.workerContext performBlockAndWait:^(){
-                Article *article = (Article 
*)[articleDataContext_.workerContext objectWithID:articleID];
-                if (article) {
-                    article.needsRefresh = @YES;
-                    NSError *error = nil;
-                    [articleDataContext_.workerContext save:&error];
-                    NSLog(@"error = %@", error);
-                }
+            [[NSOperationQueue mainQueue] addOperationWithBlock: ^ {
+                WebViewController *webVC = [self.navigationController 
searchNavStackForViewControllerOfClass:[WebViewController class]];
+                [webVC reloadCurrentArticleInvalidatingCache];
+                [self.navigationController popToViewController:webVC 
animated:YES];
+                isAleadySaving = NO;
             }];
         }
-        
-        [[NSOperationQueue mainQueue] addOperationWithBlock: ^ {
-
-            // Cause the web view to reload - now that its sections are gone 
it will try to reload them.
-
-            WebViewController *webVC = [self.navigationController 
searchNavStackForViewControllerOfClass:[WebViewController class]];
-            [webVC reloadCurrentArticle];
-            [self.navigationController popToViewController:webVC animated:YES];
-            
-            isAleadySaving = NO;
-            
-        }];
         
     } cancelledBlock:^(NSError *error){
         NSString *errorMsg = error.localizedDescription;
diff --git a/Wikipedia-iOS/View Controllers/WebView/WebViewController.h 
b/Wikipedia-iOS/View Controllers/WebView/WebViewController.h
index 7790ae8..9b6dc71 100644
--- a/Wikipedia-iOS/View Controllers/WebView/WebViewController.h
+++ b/Wikipedia-iOS/View Controllers/WebView/WebViewController.h
@@ -17,6 +17,8 @@
 
 -(void)tocToggle;
 -(void)saveWebViewScrollOffset;
+
 -(void)reloadCurrentArticle;
+-(void)reloadCurrentArticleInvalidatingCache;
 
 @end
diff --git a/Wikipedia-iOS/View Controllers/WebView/WebViewController.m 
b/Wikipedia-iOS/View Controllers/WebView/WebViewController.m
index f1439d8..f770cd0 100644
--- a/Wikipedia-iOS/View Controllers/WebView/WebViewController.m
+++ b/Wikipedia-iOS/View Controllers/WebView/WebViewController.m
@@ -79,6 +79,10 @@
 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *webViewLeftConstraint;
 @property (weak, nonatomic) IBOutlet NSLayoutConstraint 
*webViewRightConstraint;
 
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint 
*pullToRefreshViewBottomConstraint;
+@property (strong, nonatomic) UILabel *pullToRefreshLabel;
+@property (strong, nonatomic) UIView *pullToRefreshView;
+
 - (IBAction)tocButtonPushed:(id)sender;
 - (IBAction)backButtonPushed:(id)sender;
 - (IBAction)forwardButtonPushed:(id)sender;
@@ -133,6 +137,8 @@
     self.webView.backgroundColor = [UIColor colorWithRed:0.98 green:0.98 
blue:0.98 alpha:1.0];
 
     [self reloadCurrentArticle];
+    
+    [self setupPullToRefresh];
 }
 
 -(void)viewDidAppear:(BOOL)animated
@@ -474,6 +480,8 @@
         
         TOCViewController *tocVC = [self 
searchForChildViewControllerOfClass:[TOCViewController class]];
         if (tocVC) [tocVC centerCellForWebViewTopMostSection];
+
+        self.pullToRefreshView.alpha = 0.0f;
     }
 }
 
@@ -565,6 +573,8 @@
         [self hideKeyboard];
         //NSLog(@"Keyboard Hidden!");
     }
+    
+    [self updatePullToRefreshForScrollView:scrollView];
 }
 
 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
@@ -607,6 +617,30 @@
     NSString *title = [SessionSingleton sharedInstance].currentArticleTitle;
     NSString *domain = [SessionSingleton sharedInstance].currentArticleDomain;
     [self navigateToPage:title domain:domain 
discoveryMethod:DISCOVERY_METHOD_SEARCH];
+}
+
+-(void)reloadCurrentArticleInvalidatingCache
+{
+    // Mark article for refreshing so its core data records will be reloaded.
+    // (Needs to be done on worker context as worker context changes bubble up 
through
+    // main context too - so web view controller accessing main context will 
see changes.)
+
+    NSManagedObjectID *articleID =
+    [articleDataContext_.mainContext getArticleIDForTitle: [SessionSingleton 
sharedInstance].currentArticleTitle
+                                                   domain: [SessionSingleton 
sharedInstance].currentArticleDomain];
+    
+    if (articleID) {
+        [articleDataContext_.workerContext performBlockAndWait:^(){
+            Article *article = (Article *)[articleDataContext_.workerContext 
objectWithID:articleID];
+            if (article) {
+                article.needsRefresh = @YES;
+                NSError *error = nil;
+                [articleDataContext_.workerContext save:&error];
+                NSLog(@"error = %@", error);
+            }
+        }];
+        [self reloadCurrentArticle];
+    }
 }
 
 - (void)retrieveArticleForPageTitle:(NSString *)pageTitle domain:(NSString 
*)domain discoveryMethod:(NSString *)discoveryMethod
@@ -1130,4 +1164,126 @@
     }
 }
 
+#pragma mark Pull to refresh
+
+-(void)setupPullToRefresh
+{
+    self.pullToRefreshLabel = [[UILabel alloc] init];
+    self.pullToRefreshLabel.translatesAutoresizingMaskIntoConstraints = NO;
+    self.pullToRefreshLabel.backgroundColor = [UIColor clearColor];
+    self.pullToRefreshLabel.textAlignment = NSTextAlignmentCenter;
+    self.pullToRefreshLabel.numberOfLines = 2;
+    self.pullToRefreshLabel.font = [UIFont systemFontOfSize:10];
+    self.pullToRefreshLabel.textColor = [UIColor darkGrayColor];
+    
+    self.pullToRefreshView = [[UIView alloc] init];
+    self.pullToRefreshView.alpha = 0.0f;
+    self.pullToRefreshView.backgroundColor = [UIColor clearColor];
+    self.pullToRefreshView.translatesAutoresizingMaskIntoConstraints = NO;
+    [self.view addSubview:self.pullToRefreshView];
+    [self.pullToRefreshView addSubview:self.pullToRefreshLabel];
+    
+    [self constrainPullToRefresh];
+}
+
+-(void)constrainPullToRefresh
+{
+    self.pullToRefreshViewBottomConstraint =
+        [NSLayoutConstraint constraintWithItem: self.pullToRefreshView
+                                     attribute: NSLayoutAttributeBottom
+                                     relatedBy: NSLayoutRelationEqual
+                                        toItem: self.view
+                                     attribute: NSLayoutAttributeTop
+                                    multiplier: 1.0
+                                      constant: 0];
+    
+    NSDictionary *viewsDictionary = @{
+                                      @"pullToRefreshView": 
self.pullToRefreshView,
+                                      @"pullToRefreshLabel": 
self.pullToRefreshLabel,
+                                      @"selfView": self.view
+                                      };
+    
+    NSArray *viewConstraintArrays =
+        @[
+          [NSLayoutConstraint constraintsWithVisualFormat: 
@"H:|[pullToRefreshView]|"
+                                                  options: 0
+                                                  metrics: nil
+                                                    views: viewsDictionary],
+          @[self.pullToRefreshViewBottomConstraint],
+          [NSLayoutConstraint constraintsWithVisualFormat: 
@"H:|-[pullToRefreshLabel]-|"
+                                                  options: 0
+                                                  metrics: nil
+                                                    views: viewsDictionary],
+          [NSLayoutConstraint constraintsWithVisualFormat: 
@"V:|[pullToRefreshLabel]|"
+                                                  options: 0
+                                                  metrics: nil
+                                                    views: viewsDictionary],
+          ];
+    
+    [self.view addConstraints:[viewConstraintArrays 
valueForKeyPath:@"@unionOfArrays.self"]];
+}
+
+- (void)updatePullToRefreshForScrollView:(UIScrollView *)scrollView
+{
+    CGFloat pullDistance = 
(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) ? 85.0f : 55.0f;
+
+    BOOL safeToShow =
+        !scrollView.decelerating
+        &&
+        ([QueuesSingleton sharedInstance].articleRetrievalQ.operationCount == 
0)
+        &&
+        !self.tocVisible
+    ;
+
+    //NSLog(@"%@", NSStringFromCGPoint(scrollView.contentOffset));
+    if ((scrollView.contentOffset.y < 0.0f)){
+
+        self.pullToRefreshViewBottomConstraint.constant = 
-scrollView.contentOffset.y;
+        //self.pullToRefreshViewBottomConstraint.constant = 
-(fmaxf(scrollView.contentOffset.y, -self.pullToRefreshView.frame.size.height));
+
+        if (safeToShow) {
+            self.pullToRefreshView.alpha = 1.0f;
+        }
+
+        NSString *lineOneText = @"";
+        NSString *lineTwoText = 
NSLocalizedString(@"article-pull-to-refresh-prompt", nil);
+
+        if (scrollView.contentOffset.y > -(pullDistance * 0.35)){
+            lineOneText = @"▫︎ ▫︎ ▫︎ ▫︎ ▫︎";
+        }else if (scrollView.contentOffset.y > -(pullDistance * 0.52)){
+            lineOneText = @"▫︎ ▫︎ ▪︎ ▫︎ ▫︎";
+        }else if (scrollView.contentOffset.y > -(pullDistance * 0.7)){
+            lineOneText = @"▫︎ ▪︎ ▪︎ ▪︎ ▫︎";
+        }else if (scrollView.contentOffset.y > -pullDistance){
+            lineOneText = @"▫︎ ▪︎ ▪︎ ▪︎ ▫︎";
+        }else{
+            lineOneText = @"▪︎ ▪︎ ▪︎ ▪︎ ▪︎";
+            lineTwoText = 
NSLocalizedString(@"article-pull-to-refresh-is-refreshing", nil);
+        }
+
+        self.pullToRefreshLabel.text = [NSString stringWithFormat:@"%@\n%@", 
lineOneText, lineTwoText];
+    }
+
+    if (scrollView.contentOffset.y < -pullDistance) {
+        if (safeToShow) {
+            
+            //NSLog(@"REFRESH NOW!!!!!");
+            
+            [self reloadCurrentArticleInvalidatingCache];
+            
+            [UIView animateWithDuration: 0.3f
+                                  delay: 0.6f
+                                options: UIViewAnimationOptionTransitionNone
+                             animations: ^{
+                                 self.pullToRefreshView.alpha = 0.0f;
+                                 
self.pullToRefreshViewBottomConstraint.constant = 0;
+                                 [self.view layoutIfNeeded];
+                                 scrollView.panGestureRecognizer.enabled = NO;
+                             } completion: ^(BOOL done){
+                                 scrollView.panGestureRecognizer.enabled = YES;
+                             }];
+        }
+    }
+}
+
 @end
diff --git a/Wikipedia-iOS/en.lproj/Localizable.strings 
b/Wikipedia-iOS/en.lproj/Localizable.strings
index 002e132..d4b474b 100644
--- a/Wikipedia-iOS/en.lproj/Localizable.strings
+++ b/Wikipedia-iOS/en.lproj/Localizable.strings
@@ -100,3 +100,6 @@
 "edit-summary-field-placeholder-text" = "How did you improve the page?";
 
 "fetching-random-article" = "Fetching random article";
+
+"article-pull-to-refresh-prompt" = "Pull to refresh article";
+"article-pull-to-refresh-is-refreshing" = "Refreshing article";
diff --git a/Wikipedia-iOS/qqq.lproj/Localizable.strings 
b/Wikipedia-iOS/qqq.lproj/Localizable.strings
index af611ff..1bc0676 100644
--- a/Wikipedia-iOS/qqq.lproj/Localizable.strings
+++ b/Wikipedia-iOS/qqq.lproj/Localizable.strings
@@ -95,3 +95,7 @@
 "edit-summary-field-placeholder-text" = "Placeholder text which appears 
initially in the free-form edit summary text box";
 
 "fetching-random-article" = "Alert text shown when fetching a random article";
+
+"article-pull-to-refresh-prompt" = "Label text informing user article may be 
pulled down to refresh";
+"article-pull-to-refresh-is-refreshing" = "Label text shown when user pulls 
down on article to refresh";
+

-- 
To view, visit https://gerrit.wikimedia.org/r/120500
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Id76ad6518cf0cdc2f2b1a05a59e09c93e7146b7a
Gerrit-PatchSet: 3
Gerrit-Project: apps/ios/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Mhurd <mh...@wikimedia.org>
Gerrit-Reviewer: Brion VIBBER <br...@wikimedia.org>
Gerrit-Reviewer: Dr0ptp4kt <ab...@wikimedia.org>
Gerrit-Reviewer: Mhurd <mh...@wikimedia.org>
Gerrit-Reviewer: Siebrand <siebr...@kitano.nl>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to