Mhurd has uploaded a new change for review. https://gerrit.wikimedia.org/r/132587
Change subject: Anonymous editing killswitch. ...................................................................... Anonymous editing killswitch. Syncs with config/ios.json at most once a day. Adjusts saving interface to hide anon saving option if ios.json has flag for disabling anon editing. The periodic sync code is done in generic fashion to make future sync between server and bundled app json files painless. Change-Id: Ia64c060806c14cbf08cacb3168af8f471c8de048 --- M Wikipedia.xcodeproj/project.pbxproj A wikipedia/BundledJson/BundledJson.h A wikipedia/BundledJson/BundledJson.m A wikipedia/BundledJson/BundledJsonEnum.h A wikipedia/BundledPaths/BundledPaths.h A wikipedia/BundledPaths/BundledPaths.m A wikipedia/BundledPaths/BundledPathsEnum.h A wikipedia/Data/Operations/ConfigFileSyncOp.h A wikipedia/Data/Operations/ConfigFileSyncOp.m M wikipedia/Queues/QueuesSingleton.h M wikipedia/Queues/QueuesSingleton.m M wikipedia/Session/SessionSingleton.h M wikipedia/Session/SessionSingleton.m M wikipedia/View Controllers/Languages/LanguagesTableVC.m M wikipedia/View Controllers/Preview/PreviewChoicesMenuView.m M wikipedia/View Controllers/Preview/PreviewChoicesMenuView.xib M wikipedia/View Controllers/TopNav/NavController.m M wikipedia/View Controllers/WebView/WebViewController.m 18 files changed, 382 insertions(+), 43 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/apps/ios/wikipedia refs/changes/87/132587/1 diff --git a/Wikipedia.xcodeproj/project.pbxproj b/Wikipedia.xcodeproj/project.pbxproj index 262a856..04abf62 100644 --- a/Wikipedia.xcodeproj/project.pbxproj +++ b/Wikipedia.xcodeproj/project.pbxproj @@ -43,6 +43,10 @@ 043DAC4B1901C3EE001CD17C /* CreditsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 043DAC4A1901C3EE001CD17C /* CreditsViewController.m */; }; 043F18E118D9691D00D8489A /* TopActionSheetLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 043F18DC18D9691D00D8489A /* TopActionSheetLabel.m */; }; 043F18E518D9691D00D8489A /* UINavigationController+TopActionSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 043F18E018D9691D00D8489A /* UINavigationController+TopActionSheet.m */; }; + 044213C5191C3A91006C03BF /* config in Resources */ = {isa = PBXBuildFile; fileRef = 044213C4191C3A91006C03BF /* config */; }; + 044213C8191C3C2A006C03BF /* ConfigFileSyncOp.m in Sources */ = {isa = PBXBuildFile; fileRef = 044213C7191C3C2A006C03BF /* ConfigFileSyncOp.m */; }; + 044213D0191D6F43006C03BF /* BundledPaths.m in Sources */ = {isa = PBXBuildFile; fileRef = 044213CF191D6F43006C03BF /* BundledPaths.m */; }; + 044213D4191D70E9006C03BF /* BundledJson.m in Sources */ = {isa = PBXBuildFile; fileRef = 044213D3191D70E9006C03BF /* BundledJson.m */; }; 0442F57B19006DCC00F55DF9 /* PageHistoryLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0442F57A19006DCC00F55DF9 /* PageHistoryLabel.m */; }; 0442F57E190071A100F55DF9 /* WikiFont.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0442F57D190071A100F55DF9 /* WikiFont.ttf */; }; 0447862F185145090050563B /* HistoryResultCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 04478621185145090050563B /* HistoryResultCell.m */; }; @@ -230,6 +234,15 @@ 043F18DF18D9691D00D8489A /* UINavigationController+TopActionSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationController+TopActionSheet.h"; sourceTree = "<group>"; }; 043F18E018D9691D00D8489A /* UINavigationController+TopActionSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UINavigationController+TopActionSheet.m"; sourceTree = "<group>"; }; 043F18F118DCDD3A00D8489A /* WMF_Colors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMF_Colors.h; sourceTree = "<group>"; }; + 044213C4191C3A91006C03BF /* config */ = {isa = PBXFileReference; lastKnownFileType = folder; path = config; sourceTree = "<group>"; }; + 044213C6191C3C2A006C03BF /* ConfigFileSyncOp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConfigFileSyncOp.h; sourceTree = "<group>"; }; + 044213C7191C3C2A006C03BF /* ConfigFileSyncOp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConfigFileSyncOp.m; sourceTree = "<group>"; }; + 044213CE191D6F43006C03BF /* BundledPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BundledPaths.h; sourceTree = "<group>"; }; + 044213CF191D6F43006C03BF /* BundledPaths.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BundledPaths.m; sourceTree = "<group>"; }; + 044213D2191D70E9006C03BF /* BundledJson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BundledJson.h; sourceTree = "<group>"; }; + 044213D3191D70E9006C03BF /* BundledJson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BundledJson.m; sourceTree = "<group>"; }; + 044213D5191D7FEA006C03BF /* BundledJsonEnum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BundledJsonEnum.h; sourceTree = "<group>"; }; + 044213D6191D7FFC006C03BF /* BundledPathsEnum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BundledPathsEnum.h; sourceTree = "<group>"; }; 0442F57919006DCC00F55DF9 /* PageHistoryLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageHistoryLabel.h; sourceTree = "<group>"; }; 0442F57A19006DCC00F55DF9 /* PageHistoryLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PageHistoryLabel.m; sourceTree = "<group>"; }; 0442F57D190071A100F55DF9 /* WikiFont.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = WikiFont.ttf; sourceTree = "<group>"; }; @@ -708,6 +721,26 @@ path = TopActionSheet; sourceTree = "<group>"; }; + 044213CD191D6F43006C03BF /* BundledPaths */ = { + isa = PBXGroup; + children = ( + 044213D6191D7FFC006C03BF /* BundledPathsEnum.h */, + 044213CE191D6F43006C03BF /* BundledPaths.h */, + 044213CF191D6F43006C03BF /* BundledPaths.m */, + ); + path = BundledPaths; + sourceTree = "<group>"; + }; + 044213D1191D70BC006C03BF /* BundledJson */ = { + isa = PBXGroup; + children = ( + 044213D5191D7FEA006C03BF /* BundledJsonEnum.h */, + 044213D2191D70E9006C03BF /* BundledJson.h */, + 044213D3191D70E9006C03BF /* BundledJson.m */, + ); + path = BundledJson; + sourceTree = "<group>"; + }; 0442F57C1900718600F55DF9 /* Fonts */ = { isa = PBXGroup; children = ( @@ -999,6 +1032,8 @@ 04D149E5188889CA006B4104 /* Operations */ = { isa = PBXGroup; children = ( + 044213C6191C3C2A006C03BF /* ConfigFileSyncOp.h */, + 044213C7191C3C2A006C03BF /* ConfigFileSyncOp.m */, 04F27B7918FE19B700EDD838 /* PageHistoryOp.h */, 04F27B7A18FE19B700EDD838 /* PageHistoryOp.m */, 0406CEF418F8C390007EE43E /* LogEventOp.h */, @@ -1197,7 +1232,10 @@ D469889318B52DA200DBE014 /* Main_iPhone.strings */, D46CD8C218A1AC4F0042959E /* Localizable.strings */, 045A9F0C18F6090E0057EA85 /* assets */, + 044213D1191D70BC006C03BF /* BundledJson */, + 044213CD191D6F43006C03BF /* BundledPaths */, 04C43AB7183442FC006C643B /* Categories */, + 044213C4191C3A91006C03BF /* config */, 040E5C50184673F2007AFE6F /* Data */, 04292FFB185FC026002A13FC /* Defines */, 0442F57C1900718600F55DF9 /* Fonts */, @@ -1401,6 +1439,7 @@ 04CF1CB6187C8F4400E9516F /* Languages in Resources */, 0466F44F183A30CC00EA1FD7 /* logo-search-placeholder.png in Resources */, D46CD8C418A1AC4F0042959E /* InfoPlist.strings in Resources */, + 044213C5191C3A91006C03BF /* config in Resources */, D4991454181D51DE00E6073C /* Images.xcassets in Resources */, D499144C181D51DE00E6073C /* Main_iPhone.storyboard in Resources */, D46CD8C518A1AC4F0042959E /* Localizable.strings in Resources */, @@ -1457,6 +1496,7 @@ 044BD6B618849AD000FFE4BE /* SectionEditorViewController.m in Sources */, 04D34DAB1863D2D600610A87 /* TFHpple.m in Sources */, 0429301018604898002A13FC /* SavedPagesViewController.m in Sources */, + 044213D4191D70E9006C03BF /* BundledJson.m in Sources */, 04D149DF18877343006B4104 /* UIViewController+Alert.m in Sources */, 04FD6C7A184EBFCD002CA02F /* ArticleData.xcdatamodeld in Sources */, 048A26771906268100395F53 /* PaddedLabel.m in Sources */, @@ -1492,6 +1532,7 @@ 040E533C1885FB4E00AFBFE9 /* ImageData.m in Sources */, 04DB0BE618BC2E1E00B4BCF3 /* CaptchaResetOp.m in Sources */, 0415581C18ADFA5D00B81A59 /* UIImage+ColorMask.m in Sources */, + 044213C8191C3C2A006C03BF /* ConfigFileSyncOp.m in Sources */, 04A70FD7185BB6C300E24515 /* URLCache.m in Sources */, 04992BC018B687AF00A6C22B /* SearchOp.m in Sources */, 041A3B5E18E11ED90079FF1C /* LanguagesCell.m in Sources */, @@ -1552,6 +1593,7 @@ 0442F57B19006DCC00F55DF9 /* PageHistoryLabel.m in Sources */, 0447862F185145090050563B /* HistoryResultCell.m in Sources */, 04B0EA45190AFDD8007458AF /* ArticleImporter.m in Sources */, + 044213D0191D6F43006C03BF /* BundledPaths.m in Sources */, 0406CEF618F8C390007EE43E /* LogEventOp.m in Sources */, 0476967C18BBFC9400071963 /* AccountCreationOp.m in Sources */, ); diff --git a/wikipedia/BundledJson/BundledJson.h b/wikipedia/BundledJson/BundledJson.h new file mode 100644 index 0000000..1935ae1 --- /dev/null +++ b/wikipedia/BundledJson/BundledJson.h @@ -0,0 +1,15 @@ +// Created by Monte Hurd on 5/9/14. +// Copyright (c) 2013 Wikimedia Foundation. Provided under MIT-style license; please copy and modify! + +#import "BundledPathsEnum.h" +#import "BundledJsonEnum.h" + +@interface BundledJson : NSObject + ++ (NSMutableDictionary *)dictionaryFromBundledJsonFile:(BundledJsonFile)file; + ++ (NSMutableArray *)arrayFromBundledJsonFile:(BundledJsonFile)file; + ++ (BOOL)isRefreshNeededForBundledJsonFile:(BundledJsonFile)file maxAge:(CGFloat)maxAge; + +@end diff --git a/wikipedia/BundledJson/BundledJson.m b/wikipedia/BundledJson/BundledJson.m new file mode 100644 index 0000000..8ed7271 --- /dev/null +++ b/wikipedia/BundledJson/BundledJson.m @@ -0,0 +1,58 @@ +// Created by Monte Hurd on 5/9/14. +// Copyright (c) 2013 Wikimedia Foundation. Provided under MIT-style license; please copy and modify! + +#import "BundledJson.h" +#import "BundledPaths.h" + +@implementation BundledJson + ++ (NSMutableDictionary *)dictionaryFromBundledJsonFile:(BundledJsonFile)file +{ + NSError *error = nil; + NSData *fileData = [NSData dataWithContentsOfFile:[BundledPaths bundledJsonFilePath:file] options:0 error:&error]; + if (error) return @{}.mutableCopy; + error = nil; + NSMutableDictionary *result = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:&error]; + return (error) ? @{}.mutableCopy: [result mutableCopy]; +} + ++ (NSMutableArray *)arrayFromBundledJsonFile:(BundledJsonFile)file +{ + NSError *error = nil; + NSData *fileData = [NSData dataWithContentsOfFile:[BundledPaths bundledJsonFilePath:file] options:0 error:&error]; + if (error) return [@[] mutableCopy]; + error = nil; + NSArray *result = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:&error]; + return (error) ? [@[] mutableCopy]: [result mutableCopy]; +} + +// Returns YES if the local version of the config file doesn't exist or is older than maxAge. ++ (BOOL)isRefreshNeededForBundledJsonFile:(BundledJsonFile)file maxAge:(CGFloat)maxAge +{ + NSString *path = [BundledPaths bundledJsonFilePath:file]; + + BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:NO]; + if (!fileExists){ + NSLog(@"REFRESH NEEDED"); + return YES; + } + + NSDate *lastModified = nil; + NSError *error = nil; + NSURL *url = [NSURL fileURLWithPath:path]; + [url getResourceValue: &lastModified + forKey: NSURLContentModificationDateKey + error: &error]; + if (!error){ + NSTimeInterval currentAge = [[NSDate date] timeIntervalSinceDate:lastModified]; + NSLog(@"currentAge = %f maxAge = %f", currentAge, maxAge); + if (currentAge > maxAge){ + NSLog(@"REFRESH NEEDED"); + return YES; + } + } + NSLog(@"NO REFRESH NEEDED"); + return NO; +} + +@end diff --git a/wikipedia/BundledJson/BundledJsonEnum.h b/wikipedia/BundledJson/BundledJsonEnum.h new file mode 100644 index 0000000..e301b98 --- /dev/null +++ b/wikipedia/BundledJson/BundledJsonEnum.h @@ -0,0 +1,7 @@ + +typedef NS_ENUM(NSUInteger, BundledJsonFile) { + BUNDLED_JSON_UNDEFINED = 0, + BUNDLED_JSON_CONFIG = 1, + BUNDLED_JSON_LANGUAGES = 2, + BUNDLED_JSON_MAINPAGES = 3 +}; diff --git a/wikipedia/BundledPaths/BundledPaths.h b/wikipedia/BundledPaths/BundledPaths.h new file mode 100644 index 0000000..7601df1 --- /dev/null +++ b/wikipedia/BundledPaths/BundledPaths.h @@ -0,0 +1,12 @@ +// Created by Monte Hurd on 5/9/14. +// Copyright (c) 2013 Wikimedia Foundation. Provided under MIT-style license; please copy and modify! + +#import "BundledPathsEnum.h" +#import "BundledJsonEnum.h" + +@interface BundledPaths : NSObject + ++ (NSString *)bundledJsonFilePath:(BundledJsonFile)file; ++ (NSURL *)bundledJsonFileRemoteUrl:(BundledJsonFile)file; + +@end diff --git a/wikipedia/BundledPaths/BundledPaths.m b/wikipedia/BundledPaths/BundledPaths.m new file mode 100644 index 0000000..2d95c55 --- /dev/null +++ b/wikipedia/BundledPaths/BundledPaths.m @@ -0,0 +1,92 @@ +// Created by Monte Hurd on 5/9/14. +// Copyright (c) 2013 Wikimedia Foundation. Provided under MIT-style license; please copy and modify! + +#import "BundledPaths.h" +#import "BundledJson.h" + +@implementation BundledPaths + ++ (NSString *)nameForFile:(BundledJsonFile)bundledJsonFile +{ + switch (bundledJsonFile) { + case BUNDLED_JSON_CONFIG: + return @"ios.json"; + break; + case BUNDLED_JSON_LANGUAGES: + return @"languages.json"; + break; + case BUNDLED_JSON_MAINPAGES: + return @"mainpages.json"; + break; + default: + return BUNDLED_JSON_UNDEFINED; + break; + } +} + ++ (NSString *)nameForPath:(BundledPath)bundledPath +{ + switch (bundledPath) { + case BUNDLED_PATH_CONFIG: + return @"config"; + break; + case BUNDLED_PATH_LANGUAGES: + case BUNDLED_PATH_MAINPAGES: + return @"Languages"; + break; + default: + return BUNDLED_PATH_UNDEFINED; + break; + } +} + ++ (BundledPath)bundledPathForFile:(BundledJsonFile)file +{ + switch (file) { + case BUNDLED_JSON_CONFIG: + return BUNDLED_PATH_CONFIG; + break; + case BUNDLED_JSON_LANGUAGES: + return BUNDLED_PATH_LANGUAGES; + break; + case BUNDLED_JSON_MAINPAGES: + return BUNDLED_PATH_MAINPAGES; + break; + default: + return BUNDLED_PATH_UNDEFINED; + break; + } +} + ++ (NSString *)remoteUrlForFile:(BundledJsonFile)bundledJsonFile +{ + // For now only the config file is remote synced. + switch (bundledJsonFile) { + case BUNDLED_JSON_CONFIG: + return @"https://bits.wikimedia.org/static-current/extensions/MobileApp/config/ios.json"; + break; + default: + return @""; + break; + } +} + ++(NSString *)pathForFolder:(BundledPath)folder file:(BundledJsonFile)file +{ + NSString *folderName = [self nameForPath:folder]; + NSString *fileName = [self nameForFile:file]; + return [[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName]; +} + ++ (NSString *)bundledJsonFilePath:(BundledJsonFile)file +{ + BundledPath bundledPath = [self bundledPathForFile:file]; + return [self pathForFolder:bundledPath file:file]; +} + ++ (NSURL *)bundledJsonFileRemoteUrl:(BundledJsonFile)file +{ + return [NSURL URLWithString:[self remoteUrlForFile:file]]; +} + +@end diff --git a/wikipedia/BundledPaths/BundledPathsEnum.h b/wikipedia/BundledPaths/BundledPathsEnum.h new file mode 100644 index 0000000..189a518 --- /dev/null +++ b/wikipedia/BundledPaths/BundledPathsEnum.h @@ -0,0 +1,7 @@ + +typedef NS_ENUM(NSUInteger, BundledPath) { + BUNDLED_PATH_UNDEFINED = 0, + BUNDLED_PATH_CONFIG = 1, + BUNDLED_PATH_LANGUAGES = 2, + BUNDLED_PATH_MAINPAGES = 3 +}; diff --git a/wikipedia/Data/Operations/ConfigFileSyncOp.h b/wikipedia/Data/Operations/ConfigFileSyncOp.h new file mode 100644 index 0000000..a27fc90 --- /dev/null +++ b/wikipedia/Data/Operations/ConfigFileSyncOp.h @@ -0,0 +1,22 @@ +// Created by Monte Hurd on 5/8/14. +// Copyright (c) 2013 Wikimedia Foundation. Provided under MIT-style license; please copy and modify! + +#import "MWNetworkOp.h" + +#import "BundledJsonEnum.h" + +@interface ConfigFileSyncOp : MWNetworkOp + +// Syncs any bundled app json file with a remote file. + +// Only does so if age of app file exceeds maxAge or if the file isn't found in app. + +// Nice because we can sync any bundled files with any periodicity +// required just by firing these operations off occasionally. + +// They self-cancel if maxAge has not been exceeded, so fire away. + +- (id)initForBundledJsonFile: (BundledJsonFile)file + maxAge: (CGFloat)maxAge; + +@end diff --git a/wikipedia/Data/Operations/ConfigFileSyncOp.m b/wikipedia/Data/Operations/ConfigFileSyncOp.m new file mode 100644 index 0000000..87fc1c2 --- /dev/null +++ b/wikipedia/Data/Operations/ConfigFileSyncOp.m @@ -0,0 +1,63 @@ +// Created by Monte Hurd on 5/8/14. +// Copyright (c) 2013 Wikimedia Foundation. Provided under MIT-style license; please copy and modify! + +#import "ConfigFileSyncOp.h" +#import "MWNetworkActivityIndicatorManager.h" +#import "NSURLRequest+DictionaryRequest.h" + +#import "BundledJson.h" +#import "BundledPaths.h" + +@implementation ConfigFileSyncOp + +- (id)initForBundledJsonFile: (BundledJsonFile)file + maxAge: (CGFloat)maxAge +{ + self = [super init]; + if (self) { + + self.request = [NSURLRequest getRequestWithURL: [BundledPaths bundledJsonFileRemoteUrl:file] + parameters: nil]; + + __weak ConfigFileSyncOp *weakSelf = self; + self.aboutToStart = ^{ + + // Cancel the operation if the existing file hasn't aged enough. + BOOL shouldRefresh = [BundledJson isRefreshNeededForBundledJsonFile:file maxAge:maxAge]; + + if (!shouldRefresh) { + [weakSelf cancel]; + return; + } + + [[MWNetworkActivityIndicatorManager sharedManager] push]; + }; + self.completionBlock = ^(){ + [[MWNetworkActivityIndicatorManager sharedManager] pop]; + + if(weakSelf.isCancelled){ + return; + } + + if (weakSelf.error) { + return; + } + + // If it got this far, then a refresh was needed and has completed. + if (weakSelf.dataRetrieved) { + NSString *jsonString = [[NSString alloc] initWithData:weakSelf.dataRetrieved encoding:NSUTF8StringEncoding]; + //NSLog(@"jsonString = %@", jsonString); + if (!jsonString) return; + NSString *filePath = [BundledPaths bundledJsonFilePath:file]; + NSError *error = nil; + [jsonString writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error]; + if (error) { + NSLog(@"%@", error.localizedDescription); + } + } + }; + } + return self; +} + +@end diff --git a/wikipedia/Queues/QueuesSingleton.h b/wikipedia/Queues/QueuesSingleton.h index 1607054..9618d2c 100644 --- a/wikipedia/Queues/QueuesSingleton.h +++ b/wikipedia/Queues/QueuesSingleton.h @@ -22,6 +22,8 @@ @property (strong, nonatomic) NSOperationQueue *eventLoggingQ; @property (strong, nonatomic) NSOperationQueue *pageHistoryQ; +@property (strong, nonatomic) NSOperationQueue *bundledFileSyncQ; + + (QueuesSingleton *)sharedInstance; @end diff --git a/wikipedia/Queues/QueuesSingleton.m b/wikipedia/Queues/QueuesSingleton.m index 6289a5a..bbf87c2 100644 --- a/wikipedia/Queues/QueuesSingleton.m +++ b/wikipedia/Queues/QueuesSingleton.m @@ -32,6 +32,7 @@ self.randomArticleQ = [[NSOperationQueue alloc] init]; self.eventLoggingQ = [[NSOperationQueue alloc] init]; self.pageHistoryQ = [[NSOperationQueue alloc] init]; + self.bundledFileSyncQ = [[NSOperationQueue alloc] init]; //[self setupQMonitorLogging]; } return self; diff --git a/wikipedia/Session/SessionSingleton.h b/wikipedia/Session/SessionSingleton.h index 55c03be..33e7897 100644 --- a/wikipedia/Session/SessionSingleton.h +++ b/wikipedia/Session/SessionSingleton.h @@ -28,7 +28,6 @@ @property (strong, atomic) NSArray *unsupportedCharactersLanguageIds; -(NSURL *)urlForDomain:(NSString *)domain; --(NSMutableArray *)getBundledLanguagesJson; -(NSString *)domainNameForCode:(NSString *)code; -(NSString *)mainArticleTitleForCode:(NSString *)code; diff --git a/wikipedia/Session/SessionSingleton.m b/wikipedia/Session/SessionSingleton.m index d10fe95..278c6a5 100644 --- a/wikipedia/Session/SessionSingleton.m +++ b/wikipedia/Session/SessionSingleton.m @@ -2,6 +2,8 @@ // Copyright (c) 2013 Wikimedia Foundation. Provided under MIT-style license; please copy and modify! #import "SessionSingleton.h" +#import "BundledPaths.h" +#import "BundledJson.h" @implementation SessionSingleton @@ -117,12 +119,8 @@ -(NSString *)domainNameForCode:(NSString *)code { - NSError *error = nil; - NSData *fileData = [NSData dataWithContentsOfFile:[self bundledLanguagesJsonPath] options:0 error:&error]; - if (error) return nil; - error = nil; - NSArray *result = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:&error]; - if (!error) { + NSArray *result = [BundledJson arrayFromBundledJsonFile:BUNDLED_JSON_LANGUAGES]; + if (result.count > 0) { for (NSDictionary *d in result) { if ([d[@"code"] isEqualToString:code]) { return d[@"name"]; @@ -134,39 +132,9 @@ } } -- (NSString *)bundledLanguagesJsonPath -{ - return [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/Languages/languages.json"]; -} - --(NSMutableArray *)getBundledLanguagesJson -{ - NSError *error = nil; - NSData *fileData = [NSData dataWithContentsOfFile:[[SessionSingleton sharedInstance] bundledLanguagesJsonPath] options:0 error:&error]; - if (error) return [@[] mutableCopy]; - error = nil; - NSArray *result = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:&error]; - return (error) ? [@[] mutableCopy]: [result mutableCopy]; -} - -- (NSString *)bundledMainArticleTitlesJsonPath -{ - return [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/Languages/mainpages.json"]; -} - --(NSMutableDictionary *)getBundledMainArticleTitlesJson -{ - NSError *error = nil; - NSData *fileData = [NSData dataWithContentsOfFile:[[SessionSingleton sharedInstance] bundledMainArticleTitlesJsonPath] options:0 error:&error]; - if (error) return @{}.mutableCopy; - error = nil; - NSDictionary *result = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:&error]; - return (error) ? @{}.mutableCopy: [result mutableCopy]; -} - -(NSString *)mainArticleTitleForCode:(NSString *)code { - NSMutableDictionary *mainPageNames = [self getBundledMainArticleTitlesJson]; + NSMutableDictionary *mainPageNames = [BundledJson dictionaryFromBundledJsonFile:BUNDLED_JSON_MAINPAGES]; return mainPageNames[code]; } diff --git a/wikipedia/View Controllers/Languages/LanguagesTableVC.m b/wikipedia/View Controllers/Languages/LanguagesTableVC.m index 1f31fa4..a6cadea 100644 --- a/wikipedia/View Controllers/Languages/LanguagesTableVC.m +++ b/wikipedia/View Controllers/Languages/LanguagesTableVC.m @@ -10,6 +10,7 @@ #import "LanguagesSectionHeadingLabel.h" #import "NavController.h" #import "Defines.h" +#import "BundledJson.h" #import "UIViewController+Alert.h" @@ -70,7 +71,7 @@ if(self.downloadLanguagesForCurrentArticle){ [self downloadLangLinkData]; }else{ - self.languagesData = [[SessionSingleton sharedInstance] getBundledLanguagesJson]; + self.languagesData = [BundledJson arrayFromBundledJsonFile:BUNDLED_JSON_LANGUAGES]; self.headerView.hidden = NO; [self reloadTableDataFiltered]; } @@ -292,7 +293,7 @@ DownloadLangLinksOp *langLinksOp = [[DownloadLangLinksOp alloc] initForPageTitle: [SessionSingleton sharedInstance].currentArticleTitle domain: [SessionSingleton sharedInstance].currentArticleDomain - allLanguages: [[SessionSingleton sharedInstance] getBundledLanguagesJson] + allLanguages: [BundledJson arrayFromBundledJsonFile:BUNDLED_JSON_LANGUAGES] completionBlock: ^(NSArray *result){ [[NSOperationQueue mainQueue] addOperationWithBlock: ^ { diff --git a/wikipedia/View Controllers/Preview/PreviewChoicesMenuView.m b/wikipedia/View Controllers/Preview/PreviewChoicesMenuView.m index ae0b7f9..770ffbe 100644 --- a/wikipedia/View Controllers/Preview/PreviewChoicesMenuView.m +++ b/wikipedia/View Controllers/Preview/PreviewChoicesMenuView.m @@ -5,6 +5,7 @@ #import "PaddedLabel.h" #import "WikipediaAppUtils.h" #import "NSString+FormattedAttributedString.h" +#import "BundledJson.h" #define PREVIEW_BLUE_COLOR [UIColor colorWithRed:0.13 green:0.42 blue:0.68 alpha:1.0] @@ -14,6 +15,8 @@ @interface PreviewChoicesMenuView(){ } + +@property (weak, nonatomic) IBOutlet UIView *topRowContainer; @end @@ -52,7 +55,6 @@ self.signInView.backgroundColor = PREVIEW_BLUE_COLOR; [self underlineLabelText: self.signInTitleLabel]; - [self underlineLabelText: self.saveAnonTitleLabel]; /* self.signInTitleLabel.text = [@" abc " randomlyRepeatMaxTimes:100]; @@ -61,6 +63,21 @@ self.saveAnonSubTitleLabel.text = [@" abc " randomlyRepeatMaxTimes:100]; [self randomlyColorSubviews]; */ + + if ([self isAnonymousEditingDisabled]) { + [self.saveAnonView removeFromSuperview]; + // The right side of the signInView had been constrained to the left side of the + // saveAnonView, but now that the saveAnonView is gone the right side of the + // signInView needs to be constrained to the right side of the topRowContainer. + [self.topRowContainer addConstraints: + [NSLayoutConstraint constraintsWithVisualFormat: @"H:[signInView]|" + options: 0 + metrics: nil + views: @{@"signInView" : self.signInView}] + ]; + }else{ + [self underlineLabelText: self.saveAnonTitleLabel]; + } } -(void)underlineLabelText:(UILabel *)label @@ -79,4 +96,14 @@ label.attributedText = aString; } +-(BOOL)isAnonymousEditingDisabled +{ + NSDictionary *iosConfigJson = [BundledJson dictionaryFromBundledJsonFile:BUNDLED_JSON_CONFIG]; + NSNumber *disableAnonEditing = iosConfigJson[@"disableAnonEditing"]; + if (disableAnonEditing && (disableAnonEditing.boolValue == YES)) { + return YES; + } + return NO; +} + @end diff --git a/wikipedia/View Controllers/Preview/PreviewChoicesMenuView.xib b/wikipedia/View Controllers/Preview/PreviewChoicesMenuView.xib index 2ad687f..57d3cd9 100644 --- a/wikipedia/View Controllers/Preview/PreviewChoicesMenuView.xib +++ b/wikipedia/View Controllers/Preview/PreviewChoicesMenuView.xib @@ -102,6 +102,7 @@ <outlet property="signInSubTitleLabel" destination="dVR-8O-7eG" id="hus-QR-GXZ"/> <outlet property="signInTitleLabel" destination="PPh-Eu-usA" id="LO3-x5-pCZ"/> <outlet property="signInView" destination="JYT-4n-1ej" id="k1q-zU-i4A"/> + <outlet property="topRowContainer" destination="2HE-pz-gbX" id="8XN-KB-zcG"/> </connections> </view> </objects> diff --git a/wikipedia/View Controllers/TopNav/NavController.m b/wikipedia/View Controllers/TopNav/NavController.m index f6b3b0b..4eaa78f 100644 --- a/wikipedia/View Controllers/TopNav/NavController.m +++ b/wikipedia/View Controllers/TopNav/NavController.m @@ -473,7 +473,7 @@ case NAVBAR_MODE_EDIT_WIKITEXT_LOGIN_OR_SAVE_ANONYMOUSLY: self.label.text = @""; self.navBarSubViewsHorizontalVFLString = - @"H:|[NAVBAR_BUTTON_PENCIL(50)][NAVBAR_VERTICAL_LINE_1(singlePixel)]-(10)-[NAVBAR_LABEL]-(10)-[NAVBAR_VERTICAL_LINE_2(singlePixel)][NAVBAR_BUTTON_CHECK(50)]|"; + @"H:|[NAVBAR_BUTTON_PENCIL(50)][NAVBAR_VERTICAL_LINE_1(singlePixel)]-(10)-[NAVBAR_LABEL]|"; break; case NAVBAR_MODE_EDIT_WIKITEXT_SAVE: self.label.text = MWLocalizedString(@"navbar-title-mode-edit-wikitext-save", nil); diff --git a/wikipedia/View Controllers/WebView/WebViewController.m b/wikipedia/View Controllers/WebView/WebViewController.m index 4e299a7..86598ba 100644 --- a/wikipedia/View Controllers/WebView/WebViewController.m +++ b/wikipedia/View Controllers/WebView/WebViewController.m @@ -39,6 +39,8 @@ #import "DataMigrator.h" #import "ArticleImporter.h" +#import "ConfigFileSyncOp.h" + #define TOC_TOGGLE_ANIMATION_DURATION 0.3f #define NAV ((NavController *)self.navigationController) @@ -174,7 +176,12 @@ -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - + + // Don't move this to viewDidLoad - this is because viewDidLoad may only get + // called very occasionally as app suspend/resume probably doesn't cause + // viewDidLoad to fire. + [self sycnConfigIosJsonIfNecessary]; + //[self.view randomlyColorSubviews]; } @@ -191,6 +198,21 @@ [super viewWillDisappear:animated]; } +#pragma mark Sync bundled config/ios.json if necessary + +-(void)sycnConfigIosJsonIfNecessary +{ + // Sync config/ios.json at most once per day. + CGFloat maxAge = 60 * 60 * 24; + + ConfigFileSyncOp *configSyncOp = + [[ConfigFileSyncOp alloc] initForBundledJsonFile: BUNDLED_JSON_CONFIG + maxAge: maxAge]; + + [[QueuesSingleton sharedInstance].bundledFileSyncQ cancelAllOperations]; + [[QueuesSingleton sharedInstance].bundledFileSyncQ addOperation:configSyncOp]; +} + #pragma mark Edit section -(void)showSectionEditor -- To view, visit https://gerrit.wikimedia.org/r/132587 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia64c060806c14cbf08cacb3168af8f471c8de048 Gerrit-PatchSet: 1 Gerrit-Project: apps/ios/wikipedia Gerrit-Branch: master Gerrit-Owner: Mhurd <mh...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits