mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Merge branch 'charlesmchen/profileForNewAndOldUsers'
This commit is contained in:
commit
636790c991
16 changed files with 346 additions and 61 deletions
|
@ -74,6 +74,7 @@
|
|||
34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */; };
|
||||
34B3F89F1E8DF5490035BE1A /* OWSTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */; };
|
||||
34B3F8A21E8EA6040035BE1A /* ViewControllerUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8A11E8EA6040035BE1A /* ViewControllerUtils.m */; };
|
||||
34C42D5B1F45F7A80072EC04 /* OWSNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C42D5A1F45F7A80072EC04 /* OWSNavigationController.m */; };
|
||||
34CCAF381F0C0599004084F4 /* AppUpdateNag.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CCAF371F0C0599004084F4 /* AppUpdateNag.m */; };
|
||||
34CCAF3B1F0C2748004084F4 /* OWSAddToContactViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CCAF3A1F0C2748004084F4 /* OWSAddToContactViewController.m */; };
|
||||
34CE88E71F2FB9A10098030F /* ProfileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CE88E61F2FB9A10098030F /* ProfileViewController.m */; };
|
||||
|
@ -505,6 +506,8 @@
|
|||
34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSTableViewController.m; sourceTree = "<group>"; };
|
||||
34B3F8A01E8EA6040035BE1A /* ViewControllerUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewControllerUtils.h; sourceTree = "<group>"; };
|
||||
34B3F8A11E8EA6040035BE1A /* ViewControllerUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewControllerUtils.m; sourceTree = "<group>"; };
|
||||
34C42D591F45F7A80072EC04 /* OWSNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSNavigationController.h; sourceTree = "<group>"; };
|
||||
34C42D5A1F45F7A80072EC04 /* OWSNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSNavigationController.m; sourceTree = "<group>"; };
|
||||
34CCAF361F0C0599004084F4 /* AppUpdateNag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppUpdateNag.h; sourceTree = "<group>"; };
|
||||
34CCAF371F0C0599004084F4 /* AppUpdateNag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppUpdateNag.m; sourceTree = "<group>"; };
|
||||
34CCAF391F0C2748004084F4 /* OWSAddToContactViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSAddToContactViewController.h; sourceTree = "<group>"; };
|
||||
|
@ -1026,6 +1029,8 @@
|
|||
34B3F85F1E8DF1700035BE1A /* OWSLinkedDevicesTableViewController.h */,
|
||||
34B3F8601E8DF1700035BE1A /* OWSLinkedDevicesTableViewController.m */,
|
||||
34B3F8611E8DF1700035BE1A /* OWSMessagesToolbarContentView.xib */,
|
||||
34C42D591F45F7A80072EC04 /* OWSNavigationController.h */,
|
||||
34C42D5A1F45F7A80072EC04 /* OWSNavigationController.m */,
|
||||
34B3F8621E8DF1700035BE1A /* OWSQRCodeScanningViewController.h */,
|
||||
34B3F8631E8DF1700035BE1A /* OWSQRCodeScanningViewController.m */,
|
||||
34B3F89D1E8DF5490035BE1A /* OWSTableViewController.h */,
|
||||
|
@ -2307,6 +2312,7 @@
|
|||
341BB7491DB727EE001E2975 /* JSQMediaItem+OWS.m in Sources */,
|
||||
34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */,
|
||||
45F2B1941D9C9F48000D2C69 /* OWSOutgoingMessageCollectionViewCell.m in Sources */,
|
||||
34C42D5B1F45F7A80072EC04 /* OWSNavigationController.m in Sources */,
|
||||
BFB074C919A5611000F2947C /* ObservableValue.m in Sources */,
|
||||
B68EF9BA1C0B1EBD009C3DCD /* FLAnimatedImage.m in Sources */,
|
||||
B68112EA1A4D9EC400BA82FF /* UIImage+normalizeImage.m in Sources */,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#import "NotificationsManager.h"
|
||||
#import "OWSContactsManager.h"
|
||||
#import "OWSContactsSyncing.h"
|
||||
#import "OWSNavigationController.h"
|
||||
#import "OWSProfileManager.h"
|
||||
#import "OWSStaleNotificationObserver.h"
|
||||
#import "Pastelog.h"
|
||||
|
@ -802,8 +803,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
self.window.rootViewController = navigationController;
|
||||
} else {
|
||||
RegistrationViewController *viewController = [RegistrationViewController new];
|
||||
UINavigationController *navigationController =
|
||||
[[UINavigationController alloc] initWithRootViewController:viewController];
|
||||
OWSNavigationController *navigationController =
|
||||
[[OWSNavigationController alloc] initWithRootViewController:viewController];
|
||||
navigationController.navigationBarHidden = YES;
|
||||
self.window.rootViewController = navigationController;
|
||||
}
|
||||
|
|
|
@ -316,8 +316,7 @@
|
|||
|
||||
- (void)showProfile
|
||||
{
|
||||
ProfileViewController *vc = [[ProfileViewController alloc] init];
|
||||
[self.navigationController pushViewController:vc animated:YES];
|
||||
[ProfileViewController presentForAppSettings:self.navigationController];
|
||||
}
|
||||
|
||||
- (void)showAdvanced
|
||||
|
|
|
@ -3,10 +3,8 @@
|
|||
//
|
||||
|
||||
#import "CodeVerificationViewController.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "ProfileViewController.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "SignalsNavigationController.h"
|
||||
#import "SignalsViewController.h"
|
||||
#import "StringUtil.h"
|
||||
#import "UIViewController+OWS.h"
|
||||
#import <PromiseKit/AnyPromise.h>
|
||||
|
@ -269,14 +267,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
DDLogInfo(@"%@ Successfully registered Signal account.", weakSelf.tag);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[weakSelf stopActivityIndicator];
|
||||
|
||||
SignalsViewController *homeView = [SignalsViewController new];
|
||||
homeView.newlyRegisteredUser = YES;
|
||||
SignalsNavigationController *navigationController =
|
||||
[[SignalsNavigationController alloc] initWithRootViewController:homeView];
|
||||
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
|
||||
appDelegate.window.rootViewController = navigationController;
|
||||
OWSAssert([navigationController.topViewController isKindOfClass:[SignalsViewController class]]);
|
||||
[weakSelf vericationWasCompleted];
|
||||
});
|
||||
})
|
||||
.catch(^(NSError *_Nonnull error) {
|
||||
|
@ -290,6 +281,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
});
|
||||
}
|
||||
|
||||
- (void)vericationWasCompleted
|
||||
{
|
||||
[ProfileViewController presentForRegistration:self.navigationController];
|
||||
}
|
||||
|
||||
- (void)presentAlertWithVerificationError:(NSError *)error
|
||||
{
|
||||
|
|
|
@ -158,7 +158,6 @@ typedef enum : NSUInteger {
|
|||
OWSVoiceMemoGestureDelegate,
|
||||
UIDocumentMenuDelegate,
|
||||
UIDocumentPickerDelegate,
|
||||
UIGestureRecognizerDelegate,
|
||||
UIImagePickerControllerDelegate,
|
||||
UINavigationControllerDelegate,
|
||||
UITextViewDelegate>
|
||||
|
@ -549,10 +548,6 @@ typedef enum : NSUInteger {
|
|||
// In case we're dismissing a CNContactViewController which requires default system appearance
|
||||
[UIUtil applySignalAppearence];
|
||||
|
||||
// Since we're using a custom back button, we have to do some extra work to manage the
|
||||
// interactivePopGestureRecognizer
|
||||
self.navigationController.interactivePopGestureRecognizer.delegate = self;
|
||||
|
||||
// We need to recheck on every appearance, since the user may have left the group in the settings VC,
|
||||
// or on another device.
|
||||
[self hideInputIfNeeded];
|
||||
|
@ -992,10 +987,6 @@ typedef enum : NSUInteger {
|
|||
|
||||
self.isViewVisible = NO;
|
||||
|
||||
// Since we're using a custom back button, we have to do some extra work to manage the
|
||||
// interactivePopGestureRecognizer
|
||||
self.navigationController.interactivePopGestureRecognizer.delegate = nil;
|
||||
|
||||
[self.audioAttachmentPlayer stop];
|
||||
self.audioAttachmentPlayer = nil;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#import "ContactsViewHelper.h"
|
||||
#import "Environment.h"
|
||||
#import "OWSContactsManager.h"
|
||||
#import "OWSNavigationController.h"
|
||||
#import "OWSTableViewController.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "SignalKeyingStorage.h"
|
||||
|
@ -34,7 +35,8 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
|
|||
AvatarViewHelperDelegate,
|
||||
AddToGroupViewControllerDelegate,
|
||||
OWSTableViewControllerDelegate,
|
||||
UINavigationControllerDelegate>
|
||||
UINavigationControllerDelegate,
|
||||
OWSNavigationView>
|
||||
|
||||
@property (nonatomic, readonly) OWSMessageSender *messageSender;
|
||||
@property (nonatomic, readonly) ContactsViewHelper *contactsViewHelper;
|
||||
|
@ -97,8 +99,6 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
|
|||
[super loadView];
|
||||
|
||||
self.title = NSLocalizedString(@"NEW_GROUP_DEFAULT_TITLE", @"The navbar title for the 'new group' view.");
|
||||
self.navigationItem.leftBarButtonItem =
|
||||
[self createOWSBackButtonWithTarget:self selector:@selector(backButtonPressed:)];
|
||||
|
||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
|
||||
initWithTitle:NSLocalizedString(@"NEW_GROUP_CREATE_BUTTON", @"The title for the 'create group' button.")
|
||||
|
@ -547,7 +547,7 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
|
|||
|
||||
#pragma mark - Event Handling
|
||||
|
||||
- (void)backButtonPressed:(id)sender
|
||||
- (void)backButtonPressed
|
||||
{
|
||||
[self.groupNameTextField resignFirstResponder];
|
||||
|
||||
|
@ -649,6 +649,17 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
|
|||
return [self.memberRecipientIds containsObject:recipientId];
|
||||
}
|
||||
|
||||
#pragma mark - OWSNavigationView
|
||||
|
||||
- (BOOL)shouldCancelNavigationBack
|
||||
{
|
||||
BOOL result = self.hasUnsavedChanges;
|
||||
if (self.hasUnsavedChanges) {
|
||||
[self backButtonPressed];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -827,10 +827,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
updateGroupViewController.conversationSettingsViewDelegate = self.conversationSettingsViewDelegate;
|
||||
updateGroupViewController.thread = (TSGroupThread *)self.thread;
|
||||
updateGroupViewController.mode = mode;
|
||||
|
||||
UINavigationController *navigationController =
|
||||
[[UINavigationController alloc] initWithRootViewController:updateGroupViewController];
|
||||
[self presentViewController:navigationController animated:YES completion:nil];
|
||||
[self.navigationController pushViewController:updateGroupViewController animated:YES];
|
||||
}
|
||||
|
||||
- (void)presentContactViewController
|
||||
|
|
24
Signal/src/ViewControllers/OWSNavigationController.h
Normal file
24
Signal/src/ViewControllers/OWSNavigationController.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
// Any view controller which wants to be able cancel back button
|
||||
// presses and back gestures should implement this protocol.
|
||||
@protocol OWSNavigationView <NSObject>
|
||||
|
||||
// shouldCancelNavigationBack will be called if the back button was pressed or
|
||||
// if a back gesture was performed but not if the view is popped programmatically.
|
||||
- (BOOL)shouldCancelNavigationBack;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// This navigation controller subclass should be used anywhere we might
|
||||
// want to cancel back button presses or back gestures due to, for example,
|
||||
// unsaved changes.
|
||||
@interface OWSNavigationController : UINavigationController
|
||||
|
||||
@end
|
76
Signal/src/ViewControllers/OWSNavigationController.m
Normal file
76
Signal/src/ViewControllers/OWSNavigationController.m
Normal file
|
@ -0,0 +1,76 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSNavigationController.h"
|
||||
|
||||
// We use a category to expose UINavigationController's private
|
||||
// UINavigationBarDelegate methods.
|
||||
@interface UINavigationController (OWSNavigationController) <UINavigationBarDelegate>
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface OWSNavigationController () <UIGestureRecognizerDelegate>
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSNavigationController
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.interactivePopGestureRecognizer.delegate = self;
|
||||
}
|
||||
|
||||
#pragma mark - UINavigationBarDelegate
|
||||
|
||||
// All UINavigationController serve as the UINavigationBarDelegate for their navbar.
|
||||
// We override shouldPopItem: in order to cancel some back button presses - for example,
|
||||
// if a view has unsaved changes.
|
||||
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
|
||||
{
|
||||
OWSAssert(self.interactivePopGestureRecognizer.delegate == self);
|
||||
UIViewController *topViewController = self.topViewController;
|
||||
|
||||
// wasBackButtonClicked is YES if the back button was pressed but not
|
||||
// if a back gesture was performed or if the view is popped programmatically.
|
||||
BOOL wasBackButtonClicked = topViewController.navigationItem == item;
|
||||
BOOL result = YES;
|
||||
if (wasBackButtonClicked) {
|
||||
if ([topViewController conformsToProtocol:@protocol(OWSNavigationView)]) {
|
||||
id<OWSNavigationView> navigationView = (id<OWSNavigationView>)topViewController;
|
||||
result = ![navigationView shouldCancelNavigationBack];
|
||||
}
|
||||
}
|
||||
|
||||
// If we're not going to cancel the pop/back, we need to call the super
|
||||
// implementation since it has important side effects.
|
||||
if (result) {
|
||||
result = [super navigationBar:navigationBar shouldPopItem:item];
|
||||
OWSAssert(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma mark - UIGestureRecognizerDelegate
|
||||
|
||||
// We serve as the UIGestureRecognizerDelegate of the interactivePopGestureRecognizer
|
||||
// in order to cancel some "back" gestures - for example,
|
||||
// if a view has unsaved changes.
|
||||
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
|
||||
{
|
||||
UIViewController *topViewController = self.topViewController;
|
||||
if ([topViewController conformsToProtocol:@protocol(OWSNavigationView)]) {
|
||||
id<OWSNavigationView> navigationView = (id<OWSNavigationView>)topViewController;
|
||||
return ![navigationView shouldCancelNavigationBack];
|
||||
} else {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
|
@ -6,8 +6,18 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class SignalsViewController;
|
||||
|
||||
@interface ProfileViewController : OWSTableViewController
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
+ (BOOL)shouldDisplayProfileViewOnLaunch;
|
||||
|
||||
+ (void)presentForAppSettings:(UINavigationController *)navigationController;
|
||||
+ (void)presentForRegistration:(UINavigationController *)navigationController;
|
||||
+ (void)presentForUpgradeOrNag:(SignalsViewController *)presentingController;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -3,17 +3,32 @@
|
|||
//
|
||||
|
||||
#import "ProfileViewController.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "AvatarViewHelper.h"
|
||||
#import "OWSNavigationController.h"
|
||||
#import "OWSProfileManager.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "SignalsNavigationController.h"
|
||||
#import "SignalsViewController.h"
|
||||
#import "UIColor+OWS.h"
|
||||
#import "UIFont+OWS.h"
|
||||
#import "UIView+OWS.h"
|
||||
#import "UIViewController+OWS.h"
|
||||
#import <SignalServiceKit/NSDate+OWS.h>
|
||||
#import <SignalServiceKit/TSStorageManager.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ProfileViewController () <UITextFieldDelegate, AvatarViewHelperDelegate>
|
||||
typedef NS_ENUM(NSInteger, ProfileViewMode) {
|
||||
ProfileViewMode_AppSettings = 0,
|
||||
ProfileViewMode_Registration,
|
||||
ProfileViewMode_UpgradeOrNag,
|
||||
};
|
||||
|
||||
NSString *const kProfileView_Collection = @"kProfileView_Collection";
|
||||
NSString *const kProfileView_LastPresentedDate = @"kProfileView_LastPresentedDate";
|
||||
|
||||
@interface ProfileViewController () <UITextFieldDelegate, AvatarViewHelperDelegate, OWSNavigationView>
|
||||
|
||||
@property (nonatomic, readonly) AvatarViewHelper *avatarViewHelper;
|
||||
|
||||
|
@ -29,12 +44,32 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@property (nonatomic) BOOL hasUnsavedChanges;
|
||||
|
||||
@property (nonatomic) ProfileViewMode profileViewMode;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation ProfileViewController
|
||||
|
||||
- (instancetype)initWithMode:(ProfileViewMode)profileViewMode
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
self.profileViewMode = profileViewMode;
|
||||
|
||||
// Use the TSStorageManager.dbReadWriteConnection for consistency with the reads below.
|
||||
[[[TSStorageManager sharedManager] dbReadWriteConnection] setDate:[NSDate new]
|
||||
forKey:kProfileView_LastPresentedDate
|
||||
inCollection:kProfileView_Collection];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)loadView
|
||||
{
|
||||
[super loadView];
|
||||
|
@ -42,8 +77,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
self.view.backgroundColor = [UIColor whiteColor];
|
||||
[self.navigationController.navigationBar setTranslucent:NO];
|
||||
self.title = NSLocalizedString(@"PROFILE_VIEW_TITLE", @"Title for the profile view.");
|
||||
self.navigationItem.leftBarButtonItem =
|
||||
[self createOWSBackButtonWithTarget:self selector:@selector(backButtonPressed:)];
|
||||
|
||||
_avatarViewHelper = [AvatarViewHelper new];
|
||||
_avatarViewHelper.delegate = self;
|
||||
|
@ -51,6 +84,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
_avatar = [OWSProfileManager.sharedManager localProfileAvatarImage];
|
||||
|
||||
[self createViews];
|
||||
[self updateNavigationItem];
|
||||
}
|
||||
|
||||
- (void)createViews
|
||||
|
@ -162,13 +196,18 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
#pragma mark - Event Handling
|
||||
|
||||
- (void)backButtonPressed:(id)sender
|
||||
- (void)backOrSkipButtonPressed
|
||||
{
|
||||
[self leaveViewCheckingForUnsavedChanges];
|
||||
}
|
||||
|
||||
- (void)leaveViewCheckingForUnsavedChanges
|
||||
{
|
||||
[self.nameTextField resignFirstResponder];
|
||||
|
||||
if (!self.hasUnsavedChanges) {
|
||||
// If user made no changes, return to conversation settings view.
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
[self profileCompletedOrSkipped];
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -185,7 +224,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@"The label for the 'discard' button in alerts and action sheets.")
|
||||
style:UIAlertActionStyleDestructive
|
||||
handler:^(UIAlertAction *action) {
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
[self profileCompletedOrSkipped];
|
||||
}]];
|
||||
[controller addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", nil)
|
||||
style:UIAlertActionStyleCancel
|
||||
|
@ -204,14 +243,42 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
{
|
||||
_hasUnsavedChanges = hasUnsavedChanges;
|
||||
|
||||
if (hasUnsavedChanges) {
|
||||
self.navigationItem.rightBarButtonItem = (self.hasUnsavedChanges
|
||||
? [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"EDIT_GROUP_UPDATE_BUTTON",
|
||||
@"The title for the 'update group' button.")
|
||||
style:UIBarButtonItemStylePlain
|
||||
target:self
|
||||
action:@selector(updatePressed)]
|
||||
: nil);
|
||||
[self updateNavigationItem];
|
||||
}
|
||||
|
||||
- (void)updateNavigationItem
|
||||
{
|
||||
// The navigation bar is hidden in the registration workflow.
|
||||
if (self.navigationController.navigationBarHidden) {
|
||||
[self.navigationController setNavigationBarHidden:NO animated:YES];
|
||||
}
|
||||
|
||||
// Always display a left item to leave the view without making changes.
|
||||
// This might be a "back", "skip" or "cancel" button depending on the
|
||||
// context.
|
||||
switch (self.profileViewMode) {
|
||||
case ProfileViewMode_AppSettings:
|
||||
break;
|
||||
case ProfileViewMode_UpgradeOrNag:
|
||||
self.navigationItem.leftBarButtonItem =
|
||||
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
|
||||
target:self
|
||||
action:@selector(backOrSkipButtonPressed)];
|
||||
break;
|
||||
case ProfileViewMode_Registration:
|
||||
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]
|
||||
initWithTitle:NSLocalizedString(@"NAVIGATION_ITEM_SKIP_BUTTON", @"A button to skip a view.")
|
||||
style:UIBarButtonItemStylePlain
|
||||
target:self
|
||||
action:@selector(backOrSkipButtonPressed)];
|
||||
break;
|
||||
}
|
||||
if (self.hasUnsavedChanges) {
|
||||
// If we have a unsaved changes, right item should be a "save" button.
|
||||
self.navigationItem.rightBarButtonItem =
|
||||
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
|
||||
target:self
|
||||
action:@selector(updatePressed)];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,8 +306,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
success:^{
|
||||
[alertController dismissViewControllerAnimated:NO
|
||||
completion:^{
|
||||
[weakSelf.navigationController
|
||||
popViewControllerAnimated:YES];
|
||||
[weakSelf updateProfileCompleted];
|
||||
}];
|
||||
}
|
||||
failure:^{
|
||||
|
@ -265,6 +331,38 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return [self.nameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
}
|
||||
|
||||
- (void)updateProfileCompleted
|
||||
{
|
||||
[self profileCompletedOrSkipped];
|
||||
}
|
||||
|
||||
- (void)profileCompletedOrSkipped
|
||||
{
|
||||
// Dismiss this view.
|
||||
switch (self.profileViewMode) {
|
||||
case ProfileViewMode_AppSettings:
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
break;
|
||||
case ProfileViewMode_Registration:
|
||||
[self showHomeView];
|
||||
break;
|
||||
case ProfileViewMode_UpgradeOrNag:
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showHomeView
|
||||
{
|
||||
SignalsViewController *homeView = [SignalsViewController new];
|
||||
homeView.newlyRegisteredUser = YES;
|
||||
SignalsNavigationController *navigationController =
|
||||
[[SignalsNavigationController alloc] initWithRootViewController:homeView];
|
||||
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
|
||||
appDelegate.window.rootViewController = navigationController;
|
||||
OWSAssert([navigationController.topViewController isKindOfClass:[SignalsViewController class]]);
|
||||
}
|
||||
|
||||
#pragma mark - UITextFieldDelegate
|
||||
|
||||
- (BOOL)textField:(UITextField *)textField
|
||||
|
@ -313,6 +411,53 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
#pragma mark - AvatarViewHelperDelegate
|
||||
|
||||
+ (BOOL)shouldDisplayProfileViewOnLaunch
|
||||
{
|
||||
// Only nag until the user sets a profile _name_. Profile names are
|
||||
// recommended; profile avatars are optional.
|
||||
if ([OWSProfileManager sharedManager].localProfileName.length > 0) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Use the TSStorageManager.dbReadWriteConnection for consistency with the writes above.
|
||||
NSTimeInterval kProfileNagFrequency = kDayInterval * 30;
|
||||
NSDate *_Nullable lastPresentedDate =
|
||||
[[[TSStorageManager sharedManager] dbReadWriteConnection] dateForKey:kProfileView_LastPresentedDate
|
||||
inCollection:kProfileView_Collection];
|
||||
return (!lastPresentedDate || fabs([lastPresentedDate timeIntervalSinceNow]) > kProfileNagFrequency);
|
||||
}
|
||||
|
||||
+ (void)presentForAppSettings:(UINavigationController *)navigationController
|
||||
{
|
||||
OWSAssert(navigationController);
|
||||
OWSAssert([navigationController isKindOfClass:[OWSNavigationController class]]);
|
||||
|
||||
ProfileViewController *vc = [[ProfileViewController alloc] initWithMode:ProfileViewMode_AppSettings];
|
||||
[navigationController pushViewController:vc animated:YES];
|
||||
}
|
||||
|
||||
+ (void)presentForRegistration:(UINavigationController *)navigationController
|
||||
{
|
||||
OWSAssert(navigationController);
|
||||
OWSAssert([navigationController isKindOfClass:[OWSNavigationController class]]);
|
||||
|
||||
ProfileViewController *vc = [[ProfileViewController alloc] initWithMode:ProfileViewMode_Registration];
|
||||
[navigationController pushViewController:vc animated:YES];
|
||||
}
|
||||
|
||||
+ (void)presentForUpgradeOrNag:(SignalsViewController *)presentingController
|
||||
{
|
||||
OWSAssert(presentingController);
|
||||
|
||||
ProfileViewController *vc = [[ProfileViewController alloc] initWithMode:ProfileViewMode_UpgradeOrNag];
|
||||
OWSNavigationController *navigationController = [[OWSNavigationController alloc] initWithRootViewController:vc];
|
||||
[presentingController presentTopLevelModalViewController:navigationController
|
||||
animateDismissal:YES
|
||||
animatePresentation:YES];
|
||||
}
|
||||
|
||||
#pragma mark - AvatarViewHelperDelegate
|
||||
|
||||
- (NSString *)avatarActionSheetTitle
|
||||
{
|
||||
return NSLocalizedString(
|
||||
|
@ -347,6 +492,17 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
self.avatar = nil;
|
||||
}
|
||||
|
||||
#pragma mark - OWSNavigationView
|
||||
|
||||
- (BOOL)shouldCancelNavigationBack
|
||||
{
|
||||
BOOL result = self.hasUnsavedChanges;
|
||||
if (result) {
|
||||
[self backOrSkipButtonPressed];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma mark - Logging
|
||||
|
||||
+ (NSString *)tag
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "OWSNavigationController.h"
|
||||
|
||||
@interface SignalsNavigationController : UINavigationController
|
||||
@interface SignalsNavigationController : OWSNavigationController
|
||||
|
||||
@end
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#import "MessagesViewController.h"
|
||||
#import "NSDate+millisecondTimeStamp.h"
|
||||
#import "OWSContactsManager.h"
|
||||
#import "OWSNavigationController.h"
|
||||
#import "ProfileViewController.h"
|
||||
#import "PropertyListPreferences.h"
|
||||
#import "PushManager.h"
|
||||
#import "Signal-Swift.h"
|
||||
|
@ -49,6 +51,7 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
|
|||
@property (nonatomic) BOOL isViewVisible;
|
||||
@property (nonatomic) BOOL isAppInBackground;
|
||||
@property (nonatomic) BOOL shouldObserveDBModifications;
|
||||
@property (nonatomic) BOOL hasBeenPresented;
|
||||
|
||||
// Dependencies
|
||||
|
||||
|
@ -307,7 +310,7 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
|
|||
|
||||
- (void)settingsButtonPressed:(id)sender {
|
||||
AppSettingsViewController *vc = [AppSettingsViewController new];
|
||||
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:vc];
|
||||
OWSNavigationController *navigationController = [[OWSNavigationController alloc] initWithRootViewController:vc];
|
||||
[self presentViewController:navigationController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
|
@ -351,8 +354,8 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
|
|||
//
|
||||
// We just want to make sure contact access is *complete* before showing the compose
|
||||
// screen to avoid flicker.
|
||||
UINavigationController *navigationController =
|
||||
[[UINavigationController alloc] initWithRootViewController:viewController];
|
||||
OWSNavigationController *navigationController =
|
||||
[[OWSNavigationController alloc] initWithRootViewController:viewController];
|
||||
[self presentTopLevelModalViewController:navigationController animateDismissal:YES animatePresentation:YES];
|
||||
}];
|
||||
}
|
||||
|
@ -528,7 +531,11 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
|
|||
completion:^{
|
||||
[self markAllUpgradeExperiencesAsSeen];
|
||||
}];
|
||||
} else if (!self.hasBeenPresented && [ProfileViewController shouldDisplayProfileViewOnLaunch]) {
|
||||
[ProfileViewController presentForUpgradeOrNag:self];
|
||||
}
|
||||
|
||||
self.hasBeenPresented = YES;
|
||||
}
|
||||
|
||||
- (void)tableViewSetUp {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#import "ContactsViewHelper.h"
|
||||
#import "Environment.h"
|
||||
#import "OWSContactsManager.h"
|
||||
#import "OWSNavigationController.h"
|
||||
#import "OWSTableViewController.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "SignalKeyingStorage.h"
|
||||
|
@ -33,7 +34,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
AvatarViewHelperDelegate,
|
||||
AddToGroupViewControllerDelegate,
|
||||
OWSTableViewControllerDelegate,
|
||||
UINavigationControllerDelegate>
|
||||
UINavigationControllerDelegate,
|
||||
OWSNavigationView>
|
||||
|
||||
@property (nonatomic, readonly) OWSMessageSender *messageSender;
|
||||
@property (nonatomic, readonly) ContactsViewHelper *contactsViewHelper;
|
||||
|
@ -103,8 +105,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
self.previousMemberRecipientIds = [NSSet setWithArray:self.thread.groupModel.groupMemberIds];
|
||||
|
||||
self.title = NSLocalizedString(@"EDIT_GROUP_DEFAULT_TITLE", @"The navbar title for the 'update group' view.");
|
||||
self.navigationItem.leftBarButtonItem =
|
||||
[self createOWSBackButtonWithTarget:self selector:@selector(backButtonPressed:)];
|
||||
|
||||
// First section.
|
||||
|
||||
|
@ -409,13 +409,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
#pragma mark - Event Handling
|
||||
|
||||
- (void)backButtonPressed:(id)sender
|
||||
- (void)backButtonPressed
|
||||
{
|
||||
[self.groupNameTextField resignFirstResponder];
|
||||
|
||||
if (!self.hasUnsavedChanges) {
|
||||
// If user made no changes, return to conversation settings view.
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -441,7 +441,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@"The label for the 'don't save' button in action sheets.")
|
||||
style:UIAlertActionStyleDestructive
|
||||
handler:^(UIAlertAction *action) {
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}]];
|
||||
[self presentViewController:controller animated:YES completion:nil];
|
||||
}
|
||||
|
@ -528,6 +528,17 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return [self.memberRecipientIds containsObject:recipientId];
|
||||
}
|
||||
|
||||
#pragma mark - OWSNavigationView
|
||||
|
||||
- (BOOL)shouldCancelNavigationBack
|
||||
{
|
||||
BOOL result = self.hasUnsavedChanges;
|
||||
if (result) {
|
||||
[self backButtonPressed];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -17,8 +17,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
*/
|
||||
- (UIBarButtonItem *)createOWSBackButton;
|
||||
|
||||
- (UIBarButtonItem *)createOWSBackButtonWithTarget:(id)target selector:(SEL)selector;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -861,6 +861,9 @@
|
|||
/* An explanation of the consequences of muting a thread. */
|
||||
"MUTE_BEHAVIOR_EXPLANATION" = "You will not receive notifications for muted conversations.";
|
||||
|
||||
/* A button to skip a view. */
|
||||
"NAVIGATION_ITEM_SKIP_BUTTON" = "Skip";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"NETWORK_ERROR_RECOVERY" = "Please check you're online and try again.";
|
||||
|
||||
|
|
Loading…
Reference in a new issue