From a155df161fa3ca782b670877c062443218a5fe6c Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 30 Mar 2017 22:32:56 -0400 Subject: [PATCH] Pull out OWSTableViewController. // FREEBIE --- Signal.xcodeproj/project.pbxproj | 12 + .../ViewControllers/BlockListViewController.h | 9 + .../ViewControllers/BlockListViewController.m | 185 ++++++++++++++ .../DebugUITableViewController.h | 4 +- .../DebugUITableViewController.m | 216 ----------------- .../ViewControllers/OWSTableViewController.h | 56 +++++ .../ViewControllers/OWSTableViewController.m | 226 ++++++++++++++++++ .../SettingsTableViewController.m | 27 ++- 8 files changed, 509 insertions(+), 226 deletions(-) create mode 100644 Signal/src/ViewControllers/BlockListViewController.h create mode 100644 Signal/src/ViewControllers/BlockListViewController.m create mode 100644 Signal/src/ViewControllers/OWSTableViewController.h create mode 100644 Signal/src/ViewControllers/OWSTableViewController.m diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 799fab16a..cd2575d68 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -55,6 +55,8 @@ 34B3F8931E8DF1710035BE1A /* SignalsNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F86E1E8DF1700035BE1A /* SignalsNavigationController.m */; }; 34B3F8941E8DF1710035BE1A /* SignalsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8701E8DF1700035BE1A /* SignalsViewController.m */; }; 34B3F8991E8DF1B90035BE1A /* TSMessageAdapterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8981E8DF1B90035BE1A /* TSMessageAdapterTest.m */; }; + 34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */; }; + 34B3F89F1E8DF5490035BE1A /* OWSTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */; }; 34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */; }; 450573FE1E78A06D00615BB4 /* OWS103EnableVideoCalling.m in Sources */ = {isa = PBXBuildFile; fileRef = 450573FD1E78A06D00615BB4 /* OWS103EnableVideoCalling.m */; }; 4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4505C2BE1E648EA300CEBF41 /* ExperienceUpgrade.swift */; }; @@ -415,6 +417,10 @@ 34B3F86F1E8DF1700035BE1A /* SignalsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SignalsViewController.h; sourceTree = ""; }; 34B3F8701E8DF1700035BE1A /* SignalsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignalsViewController.m; sourceTree = ""; }; 34B3F8981E8DF1B90035BE1A /* TSMessageAdapterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSMessageAdapterTest.m; sourceTree = ""; }; + 34B3F89A1E8DF3270035BE1A /* BlockListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockListViewController.h; sourceTree = ""; }; + 34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlockListViewController.m; sourceTree = ""; }; + 34B3F89D1E8DF5490035BE1A /* OWSTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSTableViewController.h; sourceTree = ""; }; + 34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSTableViewController.m; sourceTree = ""; }; 34FD936E1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSAnyTouchGestureRecognizer.h; path = views/OWSAnyTouchGestureRecognizer.h; sourceTree = ""; }; 34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSAnyTouchGestureRecognizer.m; path = views/OWSAnyTouchGestureRecognizer.m; sourceTree = ""; }; 450573FC1E78A06D00615BB4 /* OWS103EnableVideoCalling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWS103EnableVideoCalling.h; path = Migrations/OWS103EnableVideoCalling.h; sourceTree = ""; }; @@ -809,6 +815,8 @@ 34B3F8381E8DF1700035BE1A /* AttachmentApprovalViewController.swift */, 34B3F8391E8DF1700035BE1A /* AttachmentSharing.h */, 34B3F83A1E8DF1700035BE1A /* AttachmentSharing.m */, + 34B3F89A1E8DF3270035BE1A /* BlockListViewController.h */, + 34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */, 34B3F83B1E8DF1700035BE1A /* CallViewController.swift */, 34B3F83C1E8DF1700035BE1A /* CodeVerificationViewController.h */, 34B3F83D1E8DF1700035BE1A /* CodeVerificationViewController.m */, @@ -850,6 +858,8 @@ 34B3F8611E8DF1700035BE1A /* OWSMessagesToolbarContentView.xib */, 34B3F8621E8DF1700035BE1A /* OWSQRCodeScanningViewController.h */, 34B3F8631E8DF1700035BE1A /* OWSQRCodeScanningViewController.m */, + 34B3F89D1E8DF5490035BE1A /* OWSTableViewController.h */, + 34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */, 34B3F8641E8DF1700035BE1A /* PrivacySettingsTableViewController.h */, 34B3F8651E8DF1700035BE1A /* PrivacySettingsTableViewController.m */, 34B3F8661E8DF1700035BE1A /* RegistrationViewController.h */, @@ -2010,9 +2020,11 @@ 458DE9D61DEE3FD00071BB03 /* PeerConnectionClient.swift in Sources */, 451DE9FD1DC1A28200810E42 /* SyncPushTokensJob.swift in Sources */, 45666F761D9BFE00008FE134 /* OWS100RemoveTSRecipientsMigration.m in Sources */, + 34B3F89F1E8DF5490035BE1A /* OWSTableViewController.m in Sources */, FCC81A981A44558300DFEC7D /* UIDevice+TSHardwareVersion.m in Sources */, 76EB054018170B33006006FC /* AppDelegate.m in Sources */, 341BB7491DB727EE001E2975 /* JSQMediaItem+OWS.m in Sources */, + 34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */, 45F2B1941D9C9F48000D2C69 /* OWSOutgoingMessageCollectionViewCell.m in Sources */, BFB074C919A5611000F2947C /* ObservableValue.m in Sources */, B68EF9BA1C0B1EBD009C3DCD /* FLAnimatedImage.m in Sources */, diff --git a/Signal/src/ViewControllers/BlockListViewController.h b/Signal/src/ViewControllers/BlockListViewController.h new file mode 100644 index 000000000..ba9d73b99 --- /dev/null +++ b/Signal/src/ViewControllers/BlockListViewController.h @@ -0,0 +1,9 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import + +@interface BlockListViewController : UITableViewController + +@end diff --git a/Signal/src/ViewControllers/BlockListViewController.m b/Signal/src/ViewControllers/BlockListViewController.m new file mode 100644 index 000000000..fb63d6a21 --- /dev/null +++ b/Signal/src/ViewControllers/BlockListViewController.m @@ -0,0 +1,185 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "BlockListViewController.h" +#import "DebugLogger.h" +#import "Environment.h" +#import "Pastelog.h" +#import "PropertyListPreferences.h" +#import "PushManager.h" +#import "Signal-Swift.h" +#import "TSAccountManager.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface BlockListViewController () + +@property (nonatomic) UITableViewCell *enableLogCell; +@property (nonatomic) UITableViewCell *submitLogCell; +@property (nonatomic) UITableViewCell *registerPushCell; + +@property (nonatomic) UISwitch *enableLogSwitch; +@property (nonatomic, readonly) BOOL supportsCallKit; + +@end + +typedef NS_ENUM(NSInteger, BlockListViewControllerSection) { + BlockListViewControllerSectionLogging, + BlockListViewControllerSectionPushNotifications, + BlockListViewControllerSection_Count // meta section +}; + +@implementation BlockListViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + [self.navigationController.navigationBar setTranslucent:NO]; + self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; +} + +- (instancetype)init +{ + return [super initWithStyle:UITableViewStyleGrouped]; +} + +- (void)loadView +{ + [super loadView]; + + self.title = NSLocalizedString(@"SETTINGS_ADVANCED_TITLE", @""); + + // Enable Log + self.enableLogCell = [[UITableViewCell alloc] init]; + self.enableLogCell.textLabel.text = NSLocalizedString(@"SETTINGS_ADVANCED_DEBUGLOG", @""); + self.enableLogCell.userInteractionEnabled = YES; + self.enableLogSwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; + [self.enableLogSwitch setOn:[PropertyListPreferences loggingIsEnabled]]; + [self.enableLogSwitch addTarget:self + action:@selector(didToggleEnableLogSwitch:) + forControlEvents:UIControlEventValueChanged]; + self.enableLogCell.accessoryView = self.enableLogSwitch; + + // Send Log + self.submitLogCell = [[UITableViewCell alloc] init]; + self.submitLogCell.textLabel.text = NSLocalizedString(@"SETTINGS_ADVANCED_SUBMIT_DEBUGLOG", @""); + + self.registerPushCell = [[UITableViewCell alloc] init]; + self.registerPushCell.textLabel.text = NSLocalizedString(@"REREGISTER_FOR_PUSH", nil); +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return BlockListViewControllerSection_Count; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + + BlockListViewControllerSection settingsSection = (BlockListViewControllerSection)section; + switch (settingsSection) { + case BlockListViewControllerSectionLogging: + return self.enableLogSwitch.isOn ? 2 : 1; + case BlockListViewControllerSectionPushNotifications: + return 1; + default: + return 0; + } +} + +- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + BlockListViewControllerSection settingsSection = (BlockListViewControllerSection)section; + switch (settingsSection) { + case BlockListViewControllerSectionLogging: + return NSLocalizedString(@"LOGGING_SECTION", nil); + case BlockListViewControllerSectionPushNotifications: + return NSLocalizedString( + @"PUSH_REGISTER_TITLE", @"Used in table section header and alert view title contexts"); + default: + return nil; + } +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + BlockListViewControllerSection settingsSection = (BlockListViewControllerSection)indexPath.section; + switch (settingsSection) { + case BlockListViewControllerSectionLogging: + switch (indexPath.row) { + case 0: + return self.enableLogCell; + case 1: + OWSAssert(self.enableLogSwitch.isOn); + return self.submitLogCell; + } + case BlockListViewControllerSectionPushNotifications: + return self.registerPushCell; + default: + // Unknown section + OWSAssert(NO); + return nil; + } +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + + if ([tableView cellForRowAtIndexPath:indexPath] == self.submitLogCell) { + DDLogInfo(@"%@ Submitting debug logs", self.tag); + [DDLog flushLog]; + [Pastelog submitLogs]; + } else if ([tableView cellForRowAtIndexPath:indexPath] == self.registerPushCell) { + OWSSyncPushTokensJob *syncJob = + [[OWSSyncPushTokensJob alloc] initWithPushManager:[PushManager sharedManager] + accountManager:[Environment getCurrent].accountManager + preferences:[Environment preferences]]; + syncJob.uploadOnlyIfStale = NO; + [syncJob run] + .then(^{ + SignalAlertView(NSLocalizedString(@"PUSH_REGISTER_SUCCESS", @"Alert title"), nil); + }) + .catch(^(NSError *error) { + SignalAlertView(NSLocalizedString(@"REGISTRATION_BODY", @"Alert title"), error.localizedDescription); + }); + + } else { + DDLogDebug(@"%@ Ignoring cell selection at indexPath: %@", self.tag, indexPath); + } +} + +#pragma mark - Actions + +- (void)didToggleEnableLogSwitch:(UISwitch *)sender +{ + if (!sender.isOn) { + [[DebugLogger sharedLogger] wipeLogs]; + [[DebugLogger sharedLogger] disableFileLogging]; + } else { + [[DebugLogger sharedLogger] enableFileLogging]; + } + + [PropertyListPreferences setLoggingEnabled:sender.isOn]; + [self.tableView reloadData]; +} + +#pragma mark - Logging + ++ (NSString *)tag +{ + return [NSString stringWithFormat:@"[%@]", self.class]; +} + +- (NSString *)tag +{ + return self.class.tag; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/DebugUITableViewController.h b/Signal/src/ViewControllers/DebugUITableViewController.h index 0f5d2f264..c29a438ef 100644 --- a/Signal/src/ViewControllers/DebugUITableViewController.h +++ b/Signal/src/ViewControllers/DebugUITableViewController.h @@ -2,11 +2,11 @@ // Copyright (c) 2017 Open Whisper Systems. All rights reserved. // -#import +#import "OWSTableViewController.h" @class TSThread; -@interface DebugUITableViewController : UITableViewController +@interface DebugUITableViewController : OWSTableViewController + (void)presentDebugUIForThread:(TSThread *)thread fromViewController:(UIViewController *)fromViewController; diff --git a/Signal/src/ViewControllers/DebugUITableViewController.m b/Signal/src/ViewControllers/DebugUITableViewController.m index 72b9a3b76..5203bf91f 100644 --- a/Signal/src/ViewControllers/DebugUITableViewController.m +++ b/Signal/src/ViewControllers/DebugUITableViewController.m @@ -11,205 +11,8 @@ NS_ASSUME_NONNULL_BEGIN -@class OWSTableItem; -@class OWSTableSection; - -@interface OWSTableContents : NSObject - -@property (nonatomic) NSString *title; -@property (nonatomic) NSMutableArray *sections; - -@end - -#pragma mark - - -@implementation OWSTableContents - --(instancetype)init { - if (self = [super init]) { - _sections = [NSMutableArray new]; - } - return self; -} - -- (void)addSection:(OWSTableSection *)section { - OWSAssert(section); - - [_sections addObject:section]; -} - -@end - -#pragma mark - - -@interface OWSTableSection : NSObject - -@property (nonatomic) NSString *title; -@property (nonatomic) NSMutableArray *items; - -@end - -#pragma mark - - -@implementation OWSTableSection - -+ (OWSTableSection *)sectionWithTitle:(NSString *)title - items:(NSArray *)items { - OWSTableSection *section = [OWSTableSection new]; - section.title = title; - section.items = [items mutableCopy]; - return section; -} - --(instancetype)init { - if (self = [super init]) { - _items = [NSMutableArray new]; - } - return self; -} - -- (void)addItem:(OWSTableItem *)item { - OWSAssert(item); - - if (!_items) { - _items = [NSMutableArray new]; - } - - [_items addObject:item]; -} - -@end - -#pragma mark - - -typedef NS_ENUM(NSInteger, OWSTableItemType) { - OWSTableItemTypeAction, -}; - -typedef void (^OWSTableActionBlock)(); - -@interface OWSTableItem : NSObject - -@property (nonatomic) OWSTableItemType itemType; -@property (nonatomic) NSString *title; -@property (nonatomic) OWSTableActionBlock actionBlock; - -@end - -#pragma mark - - -@implementation OWSTableItem - -+ (OWSTableItem *)actionWithTitle:(NSString *)title - actionBlock:(OWSTableActionBlock)actionBlock { - OWSAssert(title.length > 0); - - OWSTableItem *item = [OWSTableItem new]; - item.itemType = OWSTableItemTypeAction; - item.actionBlock = actionBlock; - item.title = title; - return item; -} - -@end - -#pragma mark - - -NSString * const kDebugUITableCellIdentifier = @"kDebugUITableCellIdentifier"; - -@interface DebugUITableViewController () - -@property (nonatomic) OWSTableContents *contents; - -@end - @implementation DebugUITableViewController -- (void)viewDidLoad { - [super viewDidLoad]; - [self.navigationController.navigationBar setTranslucent:NO]; -} - -- (instancetype)init -{ - return [super initWithStyle:UITableViewStyleGrouped]; -} - -- (void)loadView -{ - [super loadView]; - - OWSAssert(self.contents); - - self.title = self.contents.title; - - OWSAssert(self.tableView); - [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kDebugUITableCellIdentifier]; -} - -- (OWSTableSection *)sectionForIndex:(NSInteger)sectionIndex -{ - OWSAssert(self.contents); - OWSAssert(sectionIndex >= 0 && sectionIndex < (NSInteger) self.contents.sections.count); - - OWSTableSection *section = self.contents.sections[(NSUInteger) sectionIndex]; - return section; -} - -- (OWSTableItem *)itemForIndexPath:(NSIndexPath *)indexPath -{ - OWSAssert(self.contents); - OWSAssert(indexPath.section >= 0 && indexPath.section < (NSInteger) self.contents.sections.count); - - OWSTableSection *section = self.contents.sections[(NSUInteger) indexPath.section]; - OWSAssert(indexPath.item >= 0 && indexPath.item < (NSInteger) section.items.count); - OWSTableItem *item = section.items[(NSUInteger) indexPath.item]; - - return item; -} - -#pragma mark - Table view data source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - OWSAssert(self.contents); - - OWSAssert(self.contents.sections.count > 0); - return (NSInteger) self.contents.sections.count; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex { - OWSTableSection *section = [self sectionForIndex:sectionIndex]; - OWSAssert(section.items.count > 0); - return (NSInteger) section.items.count; -} - -- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)sectionIndex -{ - OWSTableSection *section = [self sectionForIndex:sectionIndex]; - return section.title; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - OWSTableItem *item = [self itemForIndexPath:indexPath]; - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kDebugUITableCellIdentifier]; - OWSAssert(cell); - - cell.textLabel.text = item.title; - - return cell; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [tableView deselectRowAtIndexPath:indexPath animated:YES]; - - OWSTableItem *item = [self itemForIndexPath:indexPath]; - if (item.itemType == OWSTableItemTypeAction) { - OWSAssert(item.actionBlock); - item.actionBlock(); - } -} - #pragma mark - Logging + (NSString *)tag @@ -323,25 +126,6 @@ NSString * const kDebugUITableCellIdentifier = @"kDebugUITableCellIdentifier"; messageSender:messageSender]; } -#pragma mark - Presentation - -- (void)presentFromViewController:(UIViewController *)fromViewController { - OWSAssert(fromViewController); - - UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self]; - self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop - target:self - action:@selector(donePressed:)]; - - [fromViewController presentViewController:navigationController - animated:YES - completion:nil]; -} - -- (void)donePressed:(id)sender { - [self dismissViewControllerAnimated:YES completion:nil]; -} - @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/OWSTableViewController.h b/Signal/src/ViewControllers/OWSTableViewController.h new file mode 100644 index 000000000..7c73c8401 --- /dev/null +++ b/Signal/src/ViewControllers/OWSTableViewController.h @@ -0,0 +1,56 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import + +@class OWSTableItem; +@class OWSTableSection; + +@interface OWSTableContents : NSObject + +@property (nonatomic) NSString *title; + +- (void)addSection:(OWSTableSection *)section; + +@end + +#pragma mark - + +@interface OWSTableSection : NSObject + +@property (nonatomic) NSString *title; + ++ (OWSTableSection *)sectionWithTitle:(NSString *)title + items:(NSArray *)items; + +- (void)addItem:(OWSTableItem *)item; + +@end + +#pragma mark - + +typedef NS_ENUM(NSInteger, OWSTableItemType) { + OWSTableItemTypeAction, +}; + +typedef void (^OWSTableActionBlock)(); + +@interface OWSTableItem : NSObject + ++ (OWSTableItem *)actionWithTitle:(NSString *)title + actionBlock:(OWSTableActionBlock)actionBlock; + +@end + +#pragma mark - + +@interface OWSTableViewController : UITableViewController + +@property (nonatomic) OWSTableContents *contents; + +#pragma mark - Presentation + +- (void)presentFromViewController:(UIViewController *)fromViewController; + +@end diff --git a/Signal/src/ViewControllers/OWSTableViewController.m b/Signal/src/ViewControllers/OWSTableViewController.m new file mode 100644 index 000000000..a93ac7d09 --- /dev/null +++ b/Signal/src/ViewControllers/OWSTableViewController.m @@ -0,0 +1,226 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "OWSTableViewController.h" +//#import "Environment.h" +//#import "Signal-Swift.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OWSTableContents () + +@property (nonatomic) NSMutableArray *sections; + +@end + +#pragma mark - + +@implementation OWSTableContents + +-(instancetype)init { + if (self = [super init]) { + _sections = [NSMutableArray new]; + } + return self; +} + +- (void)addSection:(OWSTableSection *)section { + OWSAssert(section); + + [_sections addObject:section]; +} + +@end + +#pragma mark - + +@interface OWSTableSection () + +@property (nonatomic) NSMutableArray *items; + +@end + +#pragma mark - + +@implementation OWSTableSection + ++ (OWSTableSection *)sectionWithTitle:(NSString *)title + items:(NSArray *)items { + OWSTableSection *section = [OWSTableSection new]; + section.title = title; + section.items = [items mutableCopy]; + return section; +} + +-(instancetype)init { + if (self = [super init]) { + _items = [NSMutableArray new]; + } + return self; +} + +- (void)addItem:(OWSTableItem *)item { + OWSAssert(item); + + if (!_items) { + _items = [NSMutableArray new]; + } + + [_items addObject:item]; +} + +@end + +#pragma mark - + +@interface OWSTableItem () + +@property (nonatomic) OWSTableItemType itemType; +@property (nonatomic) NSString *title; +@property (nonatomic) OWSTableActionBlock actionBlock; + +@end + +#pragma mark - + +@implementation OWSTableItem + ++ (OWSTableItem *)actionWithTitle:(NSString *)title + actionBlock:(OWSTableActionBlock)actionBlock { + OWSAssert(title.length > 0); + + OWSTableItem *item = [OWSTableItem new]; + item.itemType = OWSTableItemTypeAction; + item.actionBlock = actionBlock; + item.title = title; + return item; +} + +@end + +#pragma mark - + +NSString * const kOWSTableCellIdentifier = @"kOWSTableCellIdentifier"; + +@implementation OWSTableViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + [self.navigationController.navigationBar setTranslucent:NO]; +} + +- (instancetype)init +{ + return [super initWithStyle:UITableViewStyleGrouped]; +} + +- (void)loadView +{ + [super loadView]; + + OWSAssert(self.contents); + + self.title = self.contents.title; + + OWSAssert(self.tableView); + [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kOWSTableCellIdentifier]; +} + +- (OWSTableSection *)sectionForIndex:(NSInteger)sectionIndex +{ + OWSAssert(self.contents); + OWSAssert(sectionIndex >= 0 && sectionIndex < (NSInteger) self.contents.sections.count); + + OWSTableSection *section = self.contents.sections[(NSUInteger) sectionIndex]; + return section; +} + +- (OWSTableItem *)itemForIndexPath:(NSIndexPath *)indexPath +{ + OWSAssert(self.contents); + OWSAssert(indexPath.section >= 0 && indexPath.section < (NSInteger) self.contents.sections.count); + + OWSTableSection *section = self.contents.sections[(NSUInteger) indexPath.section]; + OWSAssert(indexPath.item >= 0 && indexPath.item < (NSInteger) section.items.count); + OWSTableItem *item = section.items[(NSUInteger) indexPath.item]; + + return item; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + OWSAssert(self.contents); + + OWSAssert(self.contents.sections.count > 0); + return (NSInteger) self.contents.sections.count; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex { + OWSTableSection *section = [self sectionForIndex:sectionIndex]; + OWSAssert(section.items.count > 0); + return (NSInteger) section.items.count; +} + +- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)sectionIndex +{ + OWSTableSection *section = [self sectionForIndex:sectionIndex]; + return section.title; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + OWSTableItem *item = [self itemForIndexPath:indexPath]; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kOWSTableCellIdentifier]; + OWSAssert(cell); + + cell.textLabel.text = item.title; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + + OWSTableItem *item = [self itemForIndexPath:indexPath]; + if (item.itemType == OWSTableItemTypeAction) { + OWSAssert(item.actionBlock); + item.actionBlock(); + } +} + +#pragma mark - Logging + ++ (NSString *)tag +{ + return [NSString stringWithFormat:@"[%@]", self.class]; +} + +- (NSString *)tag +{ + return self.class.tag; +} + +#pragma mark - Presentation + +- (void)presentFromViewController:(UIViewController *)fromViewController { + OWSAssert(fromViewController); + + UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self]; + self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop + target:self + action:@selector(donePressed:)]; + + [fromViewController presentViewController:navigationController + animated:YES + completion:nil]; +} + +- (void)donePressed:(id)sender { + [self dismissViewControllerAnimated:YES completion:nil]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/SettingsTableViewController.m b/Signal/src/ViewControllers/SettingsTableViewController.m index 254b66a50..0c6fe6a0c 100644 --- a/Signal/src/ViewControllers/SettingsTableViewController.m +++ b/Signal/src/ViewControllers/SettingsTableViewController.m @@ -15,6 +15,7 @@ #import "PrivacySettingsTableViewController.h" #import "PushManager.h" #import "Signal-Swift.h" +#import "BlockListViewController.h" #define kProfileCellHeight 87.0f #define kStandardCellHeight 44.0f @@ -22,12 +23,16 @@ #define kNumberOfSections 4 #define kRegisteredNumberRow 0 -#define kInviteRow 0 -#define kPrivacyRow 1 -#define kNotificationRow 2 -#define kLinkedDevices 3 // we don't actually use this, instead we segue via Interface Builder -#define kAdvancedRow 4 -#define kAboutRow 5 + +typedef enum { + kInviteRow = 0, + kPrivacyRow = 1, + kNotificationRow = 2, + kLinkedDevices = 3, // we don't actually use this, instead we segue via Interface Builder + kAdvancedRow = 4, + kAboutRow = 5, + kBlockListRow = 6, +} kGeneralSectionRows; #define kNetworkRow 0 #define kUnregisterRow 0 @@ -35,7 +40,7 @@ typedef enum { kRegisteredRows = 1, kNetworkStatusRows = 1, - kGeneralRows = 6, + kGeneralRows = 7, kUnregisterRows = 1, } kRowsForSection; @@ -142,7 +147,6 @@ typedef enum { } } - - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; @@ -186,6 +190,13 @@ typedef enum { [self.navigationController pushViewController:vc animated:YES]; break; } + case kBlockListRow: { + BlockListViewController *vc = [[BlockListViewController alloc] init]; + NSAssert(self.navigationController != nil, @"Navigation controller must not be nil"); + NSAssert(vc != nil, @"About View Controller must not be nil"); + [self.navigationController pushViewController:vc animated:YES]; + break; + } default: DDLogError(@"%@ Unhandled row selected at index path: %@", self.tag, indexPath); break;