diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 6748639f3..fd6af93c0 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -28,6 +28,7 @@ #import #import #import +#import #import #import #import @@ -160,6 +161,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; DDLogInfo(@"%@ application: didFinishLaunchingWithOptions completed.", self.tag); [OWSAnalytics appLaunchDidBegin]; + [OWSProfilesManager sharedManager]; return YES; } diff --git a/Signal/src/ViewControllers/AvatarViewHelper.h b/Signal/src/ViewControllers/AvatarViewHelper.h index 38dda3f92..928164279 100644 --- a/Signal/src/ViewControllers/AvatarViewHelper.h +++ b/Signal/src/ViewControllers/AvatarViewHelper.h @@ -13,6 +13,8 @@ NS_ASSUME_NONNULL_BEGIN @protocol AvatarViewHelperDelegate +- (NSString *)avatarActionSheetTitle; + - (void)avatarDidChange:(UIImage *)image; - (UIViewController *)fromViewController; diff --git a/Signal/src/ViewControllers/AvatarViewHelper.m b/Signal/src/ViewControllers/AvatarViewHelper.m index 5ea311301..3023a310b 100644 --- a/Signal/src/ViewControllers/AvatarViewHelper.m +++ b/Signal/src/ViewControllers/AvatarViewHelper.m @@ -29,8 +29,7 @@ NS_ASSUME_NONNULL_BEGIN OWSAssert(self.delegate); UIAlertController *actionSheetController = - [UIAlertController alertControllerWithTitle:NSLocalizedString(@"NEW_GROUP_ADD_PHOTO_ACTION", - @"Action Sheet title prompting the user for a group avatar") + [UIAlertController alertControllerWithTitle:self.delegate.avatarActionSheetTitle message:nil preferredStyle:UIAlertControllerStyleActionSheet]; UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", @"") diff --git a/Signal/src/ViewControllers/NewGroupViewController.m b/Signal/src/ViewControllers/NewGroupViewController.m index 395a3654b..83eb7f09f 100644 --- a/Signal/src/ViewControllers/NewGroupViewController.m +++ b/Signal/src/ViewControllers/NewGroupViewController.m @@ -608,6 +608,12 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68; #pragma mark - AvatarViewHelperDelegate +- (NSString *)avatarActionSheetTitle +{ + return NSLocalizedString( + @"NEW_GROUP_ADD_PHOTO_ACTION", @"Action Sheet title prompting the user for a group avatar"); +} + - (void)avatarDidChange:(UIImage *)image { OWSAssert(image); diff --git a/Signal/src/ViewControllers/ProfileViewController.m b/Signal/src/ViewControllers/ProfileViewController.m index 12d822bd1..f427bf128 100644 --- a/Signal/src/ViewControllers/ProfileViewController.m +++ b/Signal/src/ViewControllers/ProfileViewController.m @@ -9,6 +9,7 @@ #import "UIFont+OWS.h" #import "UIView+OWS.h" #import "UIViewController+OWS.h" +#import NS_ASSUME_NONNULL_BEGIN @@ -45,6 +46,8 @@ NS_ASSUME_NONNULL_BEGIN _avatarViewHelper = [AvatarViewHelper new]; _avatarViewHelper.delegate = self; + _avatar = [OWSProfilesManager.sharedManager localProfileAvatarImage]; + [self createViews]; } @@ -53,10 +56,12 @@ NS_ASSUME_NONNULL_BEGIN _nameTextField = [UITextField new]; _nameTextField.font = [UIFont ows_mediumFontWithSize:18.f]; _nameTextField.textColor = [UIColor ows_materialBlueColor]; - // TODO: Copy. _nameTextField.placeholder = NSLocalizedString( @"PROFILE_VIEW_NAME_DEFAULT_TEXT", @"Default text for the profile name field of the profile view."); _nameTextField.delegate = self; + _nameTextField.text = [OWSProfilesManager.sharedManager localProfileName]; + DDLogError(@"_nameTextField.text: %@", _nameTextField.text); + [DDLog flushLog]; [_nameTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; _avatarView = [AvatarImageView new]; @@ -95,10 +100,8 @@ NS_ASSUME_NONNULL_BEGIN cell.preservesSuperviewLayoutMargins = YES; cell.contentView.preservesSuperviewLayoutMargins = YES; - // TODO: Use the current avatar. AvatarImageView *avatarView = weakSelf.avatarView; [weakSelf updateAvatarView]; - [cell.contentView addSubview:avatarView]; [avatarView autoHCenterInSuperview]; [avatarView autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:kAvatarTopMargin]; @@ -134,7 +137,6 @@ NS_ASSUME_NONNULL_BEGIN cell.contentView.preservesSuperviewLayoutMargins = YES; UITextField *nameTextField = weakSelf.nameTextField; - // TODO: Use the current profile name. [cell.contentView addSubview:nameTextField]; [nameTextField autoPinLeadingToSuperView]; [nameTextField autoPinTrailingToSuperView]; @@ -211,6 +213,16 @@ NS_ASSUME_NONNULL_BEGIN - (void)updateProfile { + __weak ProfileViewController *weakSelf = self; + [OWSProfilesManager.sharedManager + updateLocalProfileName:self.nameTextField.text + localProfileAvatarImage:self.avatar + success:^{ + [weakSelf.navigationController popViewControllerAnimated:YES]; + } + failure:^{ + // <#code#> + }]; // OWSAssert(self.conversationSettingsViewDelegate); // // [self updateGroup]; @@ -276,6 +288,12 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - AvatarViewHelperDelegate +- (NSString *)avatarActionSheetTitle +{ + return NSLocalizedString( + @"PROFILE_AVATAR_ACTIONSHEET_TITLE", @"Action Sheet title prompting the user for a profile avatar"); +} + - (void)avatarDidChange:(UIImage *)image { OWSAssert(image); diff --git a/Signal/src/ViewControllers/UpdateGroupViewController.m b/Signal/src/ViewControllers/UpdateGroupViewController.m index ea6f6ea15..6b3f1eb93 100644 --- a/Signal/src/ViewControllers/UpdateGroupViewController.m +++ b/Signal/src/ViewControllers/UpdateGroupViewController.m @@ -489,6 +489,12 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - AvatarViewHelperDelegate +- (NSString *)avatarActionSheetTitle +{ + return NSLocalizedString( + @"NEW_GROUP_ADD_PHOTO_ACTION", @"Action Sheet title prompting the user for a group avatar"); +} + - (void)avatarDidChange:(UIImage *)image { OWSAssert(image); diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index af0216c73..01fe53dc4 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -1036,6 +1036,9 @@ /* No comment provided by engineer. */ "PROCEED_BUTTON" = "Proceed"; +/* Action Sheet title prompting the user for a profile avatar */ +"PROFILE_AVATAR_ACTIONSHEET_TITLE" = "Set Profile Avatar"; + /* Instructions for how to change the profile avatar. */ "PROFILE_VIEW_AVATAR_INSTRUCTIONS" = "Tap to Select Avatar"; diff --git a/SignalServiceKit/src/Profiles/OWSProfilesManager.h b/SignalServiceKit/src/Profiles/OWSProfilesManager.h index fe937cb0c..5ce661f71 100644 --- a/SignalServiceKit/src/Profiles/OWSProfilesManager.h +++ b/SignalServiceKit/src/Profiles/OWSProfilesManager.h @@ -13,17 +13,16 @@ extern NSString *const kNSNotificationName_LocalProfileDidChange; + (instancetype)sharedManager; -- (nullable NSString *)localProfileName; - -- (nullable UIImage *)localProfileAvatarImage; +@property (atomic, nullable, readonly) NSString *localProfileName; +@property (atomic, nullable, readonly) UIImage *localProfileAvatarImage; // This method is used to update the "local profile" state on the client // and the service. Client state is only updated if service state is // successfully updated. -- (void)setLocalProfileName:(nullable NSString *)localProfileName - localProfileAvatarImage:(nullable UIImage *)localProfileAvatarImage - success:(void (^)())successBlock - failure:(void (^)())failureBlock; +- (void)updateLocalProfileName:(nullable NSString *)localProfileName + localProfileAvatarImage:(nullable UIImage *)localProfileAvatarImage + success:(void (^)())successBlock + failure:(void (^)())failureBlock; @end diff --git a/SignalServiceKit/src/Profiles/OWSProfilesManager.m b/SignalServiceKit/src/Profiles/OWSProfilesManager.m index 7d2c44650..5558b5a9a 100644 --- a/SignalServiceKit/src/Profiles/OWSProfilesManager.m +++ b/SignalServiceKit/src/Profiles/OWSProfilesManager.m @@ -95,8 +95,8 @@ static const NSInteger kProfileKeyLength = 16; // These properties should only be mutated on the main thread, // but they may be accessed on other threads. @property (atomic, nullable) NSString *localProfileName; -@property (atomic, nullable) AvatarMetadata *localProfileAvatarMetadata; @property (atomic, nullable) UIImage *localProfileAvatarImage; +@property (atomic, nullable) AvatarMetadata *localProfileAvatarMetadata; @end @@ -181,7 +181,7 @@ static const NSInteger kProfileKeyLength = 16; + (NSData *)generateLocalProfileKey { // TODO: - OWSFail(@"Profile key generation is not yet implemented."); + DDLogVerbose(@"%@ Profile key generation is not yet implemented.", self.tag); return [SecurityUtils generateRandomBytes:kProfileKeyLength]; } @@ -230,14 +230,21 @@ static const NSInteger kProfileKeyLength = 16; userInfo:nil]; } -- (void)setLocalProfileName:(nullable NSString *)localProfileName - localProfileAvatarImage:(nullable UIImage *)localProfileAvatarImage - success:(void (^)())successBlock - failure:(void (^)())failureBlock +- (void)updateLocalProfileName:(nullable NSString *)localProfileName + localProfileAvatarImage:(nullable UIImage *)localProfileAvatarImage + success:(void (^)())successBlock + failure:(void (^)())failureBlockParameter { OWSAssert([NSThread isMainThread]); OWSAssert(successBlock); - OWSAssert(failureBlock); + OWSAssert(failureBlockParameter); + + // Ensure that the failure block is called on the main thread. + void (^failureBlock)() = ^{ + dispatch_async(dispatch_get_main_queue(), ^{ + failureBlockParameter(); + }); + }; // The final steps are to: // @@ -247,10 +254,12 @@ static const NSInteger kProfileKeyLength = 16; [self updateProfileOnService:localProfileName avatarMetadata:avatarMetadata success:^{ - [self updateLocalProfileName:localProfileName - localProfileAvatarImage:localProfileAvatarImage - localProfileAvatarMetadata:avatarMetadata]; - successBlock(); + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateLocalProfileName:localProfileName + localProfileAvatarImage:localProfileAvatarImage + localProfileAvatarMetadata:avatarMetadata]; + successBlock(); + }); } failure:^{ failureBlock();