2017-07-31 22:45:06 +02:00
|
|
|
//
|
|
|
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#import "ProfileViewController.h"
|
2017-08-15 23:55:07 +02:00
|
|
|
#import "AppDelegate.h"
|
2017-07-31 23:12:09 +02:00
|
|
|
#import "AvatarViewHelper.h"
|
2017-08-02 19:12:26 +02:00
|
|
|
#import "OWSProfileManager.h"
|
2017-07-31 22:45:06 +02:00
|
|
|
#import "Signal-Swift.h"
|
2017-08-15 23:55:07 +02:00
|
|
|
#import "SignalsNavigationController.h"
|
|
|
|
#import "SignalsViewController.h"
|
2017-07-31 22:45:06 +02:00
|
|
|
#import "UIColor+OWS.h"
|
|
|
|
#import "UIFont+OWS.h"
|
|
|
|
#import "UIView+OWS.h"
|
2017-07-31 23:12:09 +02:00
|
|
|
#import "UIViewController+OWS.h"
|
2017-07-31 22:45:06 +02:00
|
|
|
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
2017-07-31 23:12:09 +02:00
|
|
|
@interface ProfileViewController () <UITextFieldDelegate, AvatarViewHelperDelegate>
|
2017-07-31 22:45:06 +02:00
|
|
|
|
2017-07-31 23:12:09 +02:00
|
|
|
@property (nonatomic, readonly) AvatarViewHelper *avatarViewHelper;
|
2017-07-31 22:45:06 +02:00
|
|
|
|
|
|
|
@property (nonatomic) UITextField *nameTextField;
|
|
|
|
|
|
|
|
@property (nonatomic) AvatarImageView *avatarView;
|
|
|
|
|
2017-08-14 22:18:54 +02:00
|
|
|
@property (nonatomic) UIImageView *cameraImageView;
|
|
|
|
|
2017-07-31 22:45:06 +02:00
|
|
|
@property (nonatomic) UILabel *avatarLabel;
|
|
|
|
|
2017-07-31 23:12:09 +02:00
|
|
|
@property (nonatomic, nullable) UIImage *avatar;
|
|
|
|
|
|
|
|
@property (nonatomic) BOOL hasUnsavedChanges;
|
|
|
|
|
2017-07-31 22:45:06 +02:00
|
|
|
@end
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
@implementation ProfileViewController
|
|
|
|
|
|
|
|
- (void)loadView
|
|
|
|
{
|
|
|
|
[super loadView];
|
|
|
|
|
|
|
|
self.view.backgroundColor = [UIColor whiteColor];
|
|
|
|
[self.navigationController.navigationBar setTranslucent:NO];
|
|
|
|
self.title = NSLocalizedString(@"PROFILE_VIEW_TITLE", @"Title for the profile view.");
|
|
|
|
|
2017-07-31 23:12:09 +02:00
|
|
|
_avatarViewHelper = [AvatarViewHelper new];
|
|
|
|
_avatarViewHelper.delegate = self;
|
2017-07-31 22:45:06 +02:00
|
|
|
|
2017-08-02 19:12:26 +02:00
|
|
|
_avatar = [OWSProfileManager.sharedManager localProfileAvatarImage];
|
2017-08-01 17:31:00 +02:00
|
|
|
|
2017-07-31 22:45:06 +02:00
|
|
|
[self createViews];
|
2017-08-15 23:55:07 +02:00
|
|
|
[self updateNavigationItem];
|
2017-07-31 22:45:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)createViews
|
|
|
|
{
|
|
|
|
_nameTextField = [UITextField new];
|
|
|
|
_nameTextField.font = [UIFont ows_mediumFontWithSize:18.f];
|
|
|
|
_nameTextField.textColor = [UIColor ows_materialBlueColor];
|
|
|
|
_nameTextField.placeholder = NSLocalizedString(
|
|
|
|
@"PROFILE_VIEW_NAME_DEFAULT_TEXT", @"Default text for the profile name field of the profile view.");
|
|
|
|
_nameTextField.delegate = self;
|
2017-08-02 19:12:26 +02:00
|
|
|
_nameTextField.text = [OWSProfileManager.sharedManager localProfileName];
|
2017-07-31 22:45:06 +02:00
|
|
|
[_nameTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
|
|
|
|
|
|
|
|
_avatarView = [AvatarImageView new];
|
|
|
|
|
2017-08-14 22:18:54 +02:00
|
|
|
UIImage *cameraImage = [UIImage imageNamed:@"settings-avatar-camera"];
|
|
|
|
cameraImage = [cameraImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
|
|
|
_cameraImageView = [[UIImageView alloc] initWithImage:cameraImage];
|
|
|
|
_cameraImageView.tintColor = [UIColor ows_materialBlueColor];
|
|
|
|
|
2017-07-31 22:45:06 +02:00
|
|
|
_avatarLabel = [UILabel new];
|
|
|
|
_avatarLabel.font = [UIFont ows_regularFontWithSize:14.f];
|
|
|
|
_avatarLabel.textColor = [UIColor ows_materialBlueColor];
|
|
|
|
// TODO: Copy.
|
|
|
|
_avatarLabel.text
|
|
|
|
= NSLocalizedString(@"PROFILE_VIEW_AVATAR_INSTRUCTIONS", @"Instructions for how to change the profile avatar.");
|
|
|
|
[_avatarLabel sizeToFit];
|
|
|
|
|
|
|
|
[self updateTableContents];
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark - Table Contents
|
|
|
|
|
|
|
|
- (void)updateTableContents
|
|
|
|
{
|
|
|
|
OWSTableContents *contents = [OWSTableContents new];
|
|
|
|
|
|
|
|
__weak ProfileViewController *weakSelf = self;
|
|
|
|
|
2017-08-01 22:30:24 +02:00
|
|
|
// Profile Avatar
|
2017-07-31 22:45:06 +02:00
|
|
|
OWSTableSection *avatarSection = [OWSTableSection new];
|
|
|
|
avatarSection.headerTitle = NSLocalizedString(
|
|
|
|
@"PROFILE_VIEW_AVATAR_SECTION_HEADER", @"Header title for the profile avatar field of the profile view.");
|
2017-07-31 23:12:09 +02:00
|
|
|
const CGFloat kAvatarSizePoints = 100.f;
|
2017-07-31 22:45:06 +02:00
|
|
|
const CGFloat kAvatarTopMargin = 10.f;
|
|
|
|
const CGFloat kAvatarBottomMargin = 10.f;
|
|
|
|
const CGFloat kAvatarVSpacing = 10.f;
|
2017-07-31 23:12:09 +02:00
|
|
|
CGFloat avatarCellHeight
|
|
|
|
= round(kAvatarSizePoints + kAvatarTopMargin + kAvatarBottomMargin + kAvatarVSpacing + self.avatarLabel.height);
|
2017-07-31 22:45:06 +02:00
|
|
|
[avatarSection addItem:[OWSTableItem itemWithCustomCellBlock:^{
|
|
|
|
UITableViewCell *cell = [UITableViewCell new];
|
|
|
|
cell.preservesSuperviewLayoutMargins = YES;
|
|
|
|
cell.contentView.preservesSuperviewLayoutMargins = YES;
|
|
|
|
|
|
|
|
AvatarImageView *avatarView = weakSelf.avatarView;
|
2017-08-14 22:18:54 +02:00
|
|
|
UIImageView *cameraImageView = weakSelf.cameraImageView;
|
2017-07-31 22:45:06 +02:00
|
|
|
[cell.contentView addSubview:avatarView];
|
2017-08-14 22:18:54 +02:00
|
|
|
[cell.contentView addSubview:cameraImageView];
|
|
|
|
[weakSelf updateAvatarView];
|
2017-07-31 22:45:06 +02:00
|
|
|
[avatarView autoHCenterInSuperview];
|
|
|
|
[avatarView autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:kAvatarTopMargin];
|
2017-07-31 23:12:09 +02:00
|
|
|
[avatarView autoSetDimension:ALDimensionWidth toSize:kAvatarSizePoints];
|
|
|
|
[avatarView autoSetDimension:ALDimensionHeight toSize:kAvatarSizePoints];
|
2017-08-14 22:18:54 +02:00
|
|
|
[cameraImageView autoPinTrailingToView:avatarView];
|
|
|
|
[cameraImageView autoPinEdge:ALEdgeBottom toEdge:ALEdgeBottom ofView:avatarView];
|
2017-07-31 22:45:06 +02:00
|
|
|
|
|
|
|
UILabel *avatarLabel = weakSelf.avatarLabel;
|
|
|
|
[cell.contentView addSubview:avatarLabel];
|
|
|
|
[avatarLabel autoHCenterInSuperview];
|
|
|
|
[avatarLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:kAvatarBottomMargin];
|
|
|
|
|
|
|
|
cell.userInteractionEnabled = YES;
|
|
|
|
[cell
|
|
|
|
addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(avatarTapped:)]];
|
|
|
|
|
|
|
|
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
|
|
|
return cell;
|
|
|
|
}
|
|
|
|
customRowHeight:avatarCellHeight
|
|
|
|
actionBlock:nil]];
|
|
|
|
[contents addSection:avatarSection];
|
|
|
|
|
2017-08-01 22:30:24 +02:00
|
|
|
// Profile Name
|
2017-07-31 22:45:06 +02:00
|
|
|
OWSTableSection *nameSection = [OWSTableSection new];
|
|
|
|
nameSection.headerTitle = NSLocalizedString(
|
|
|
|
@"PROFILE_VIEW_NAME_SECTION_HEADER", @"Label for the profile name field of the profile view.");
|
|
|
|
[nameSection
|
|
|
|
addItem:
|
|
|
|
[OWSTableItem
|
|
|
|
itemWithCustomCellBlock:^{
|
|
|
|
UITableViewCell *cell = [UITableViewCell new];
|
|
|
|
cell.preservesSuperviewLayoutMargins = YES;
|
|
|
|
cell.contentView.preservesSuperviewLayoutMargins = YES;
|
|
|
|
|
|
|
|
UITextField *nameTextField = weakSelf.nameTextField;
|
|
|
|
[cell.contentView addSubview:nameTextField];
|
|
|
|
[nameTextField autoPinLeadingToSuperView];
|
|
|
|
[nameTextField autoPinTrailingToSuperView];
|
|
|
|
[nameTextField autoVCenterInSuperview];
|
|
|
|
|
|
|
|
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
|
|
|
return cell;
|
|
|
|
}
|
|
|
|
actionBlock:nil]];
|
|
|
|
[contents addSection:nameSection];
|
|
|
|
|
|
|
|
self.contents = contents;
|
|
|
|
}
|
|
|
|
|
2017-07-31 23:12:09 +02:00
|
|
|
#pragma mark - Event Handling
|
|
|
|
|
|
|
|
- (void)backButtonPressed:(id)sender
|
|
|
|
{
|
2017-08-15 23:55:07 +02:00
|
|
|
[self leaveViewCheckingForUnsavedChanges:^{
|
|
|
|
[self.navigationController popViewControllerAnimated:YES];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)leaveViewCheckingForUnsavedChanges:(void (^_Nonnull)())leaveViewBlock
|
|
|
|
{
|
|
|
|
OWSAssert(leaveViewBlock);
|
|
|
|
|
2017-07-31 23:12:09 +02:00
|
|
|
[self.nameTextField resignFirstResponder];
|
|
|
|
|
|
|
|
if (!self.hasUnsavedChanges) {
|
|
|
|
// If user made no changes, return to conversation settings view.
|
2017-08-15 23:55:07 +02:00
|
|
|
leaveViewBlock();
|
2017-07-31 23:12:09 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
UIAlertController *controller = [UIAlertController
|
|
|
|
alertControllerWithTitle:
|
|
|
|
NSLocalizedString(@"NEW_GROUP_VIEW_UNSAVED_CHANGES_TITLE",
|
|
|
|
@"The alert title if user tries to exit the new group view without saving changes.")
|
|
|
|
message:
|
|
|
|
NSLocalizedString(@"NEW_GROUP_VIEW_UNSAVED_CHANGES_MESSAGE",
|
|
|
|
@"The alert message if user tries to exit the new group view without saving changes.")
|
|
|
|
preferredStyle:UIAlertControllerStyleAlert];
|
|
|
|
[controller
|
|
|
|
addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"ALERT_DISCARD_BUTTON",
|
|
|
|
@"The label for the 'discard' button in alerts and action sheets.")
|
|
|
|
style:UIAlertActionStyleDestructive
|
|
|
|
handler:^(UIAlertAction *action) {
|
2017-08-15 23:55:07 +02:00
|
|
|
leaveViewBlock();
|
2017-07-31 23:12:09 +02:00
|
|
|
}]];
|
|
|
|
[controller addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", nil)
|
|
|
|
style:UIAlertActionStyleCancel
|
|
|
|
handler:nil]];
|
|
|
|
[self presentViewController:controller animated:YES completion:nil];
|
|
|
|
}
|
2017-07-31 22:45:06 +02:00
|
|
|
|
|
|
|
- (void)avatarTapped:(UIGestureRecognizer *)sender
|
|
|
|
{
|
|
|
|
if (sender.state == UIGestureRecognizerStateRecognized) {
|
2017-07-31 23:12:09 +02:00
|
|
|
[self.avatarViewHelper showChangeAvatarUI];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setHasUnsavedChanges:(BOOL)hasUnsavedChanges
|
|
|
|
{
|
|
|
|
_hasUnsavedChanges = hasUnsavedChanges;
|
|
|
|
|
2017-08-15 23:55:07 +02:00
|
|
|
[self updateNavigationItem];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)updateNavigationItem
|
|
|
|
{
|
|
|
|
// The navigation bar is hidden in the registration workflow.
|
|
|
|
[self.navigationController setNavigationBarHidden:NO animated:YES];
|
|
|
|
|
|
|
|
UIBarButtonItem *rightItem = nil;
|
|
|
|
switch (self.profileViewMode) {
|
|
|
|
case ProfileViewMode_AppSettings:
|
|
|
|
self.navigationItem.leftBarButtonItem =
|
|
|
|
[self createOWSBackButtonWithTarget:self selector:@selector(backButtonPressed:)];
|
|
|
|
break;
|
|
|
|
case ProfileViewMode_Registration:
|
|
|
|
case ProfileViewMode_UpgradeOrNag:
|
|
|
|
// Registration and "upgrade or nag" mode don't need a back button.
|
|
|
|
self.navigationItem.hidesBackButton = YES;
|
|
|
|
|
|
|
|
// Registration and "upgrade or nag" mode have "skip" or "update".
|
|
|
|
//
|
|
|
|
// TODO: Should this be some other verb instead of "update"?
|
|
|
|
rightItem = [[UIBarButtonItem alloc]
|
|
|
|
initWithTitle:NSLocalizedString(@"NAVIGATION_ITEM_SKIP_BUTTON", @"A button to skip a view.")
|
|
|
|
style:UIBarButtonItemStylePlain
|
|
|
|
target:self
|
|
|
|
action:@selector(skipPressed)];
|
|
|
|
break;
|
2017-07-31 22:45:06 +02:00
|
|
|
}
|
2017-08-15 23:55:07 +02:00
|
|
|
if (self.hasUnsavedChanges) {
|
|
|
|
rightItem = [[UIBarButtonItem alloc]
|
|
|
|
initWithTitle:NSLocalizedString(@"EDIT_GROUP_UPDATE_BUTTON", @"The title for the 'update group' button.")
|
|
|
|
style:UIBarButtonItemStylePlain
|
|
|
|
target:self
|
|
|
|
action:@selector(updatePressed)];
|
|
|
|
}
|
|
|
|
self.navigationItem.rightBarButtonItem = rightItem;
|
2017-07-31 22:45:06 +02:00
|
|
|
}
|
|
|
|
|
2017-07-31 23:12:09 +02:00
|
|
|
- (void)updatePressed
|
|
|
|
{
|
|
|
|
[self updateProfile];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)updateProfile
|
|
|
|
{
|
2017-08-01 17:31:00 +02:00
|
|
|
__weak ProfileViewController *weakSelf = self;
|
2017-08-16 17:06:22 +02:00
|
|
|
|
|
|
|
// Show an activity indicator to block the UI during the profile upload.
|
2017-08-16 22:10:07 +02:00
|
|
|
UIAlertController *alertController = [UIAlertController
|
|
|
|
alertControllerWithTitle:NSLocalizedString(@"PROFILE_VIEW_SAVING",
|
|
|
|
@"Alert title that indicates the user's profile view is being saved.")
|
|
|
|
message:nil
|
|
|
|
preferredStyle:UIAlertControllerStyleAlert];
|
2017-08-16 17:06:22 +02:00
|
|
|
|
|
|
|
[self presentViewController:alertController
|
|
|
|
animated:YES
|
|
|
|
completion:^{
|
|
|
|
[OWSProfileManager.sharedManager updateLocalProfileName:[self normalizedProfileName]
|
|
|
|
avatarImage:self.avatar
|
|
|
|
success:^{
|
2017-08-16 22:10:07 +02:00
|
|
|
[alertController dismissViewControllerAnimated:NO
|
|
|
|
completion:^{
|
2017-08-15 23:55:07 +02:00
|
|
|
[weakSelf updateProfileCompleted];
|
2017-08-16 22:10:07 +02:00
|
|
|
}];
|
2017-08-16 17:06:22 +02:00
|
|
|
}
|
|
|
|
failure:^{
|
2017-08-16 22:10:07 +02:00
|
|
|
[alertController
|
|
|
|
dismissViewControllerAnimated:NO
|
|
|
|
completion:^{
|
|
|
|
[OWSAlerts
|
|
|
|
showAlertWithTitle:NSLocalizedString(
|
|
|
|
@"ALERT_ERROR_TITLE", @"")
|
|
|
|
message:
|
|
|
|
NSLocalizedString(
|
|
|
|
@"PROFILE_VIEW_ERROR_UPDATE_FAILED",
|
|
|
|
@"Error message shown when a "
|
|
|
|
@"profile update fails.")];
|
|
|
|
}];
|
2017-08-16 17:06:22 +02:00
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *)normalizedProfileName
|
|
|
|
{
|
|
|
|
return [self.nameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
2017-07-31 23:12:09 +02:00
|
|
|
}
|
|
|
|
|
2017-08-15 23:55:07 +02:00
|
|
|
- (void)updateProfileCompleted
|
|
|
|
{
|
|
|
|
[self profileCompletedOrSkipped];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)skipPressed
|
|
|
|
{
|
|
|
|
[self leaveViewCheckingForUnsavedChanges:^{
|
|
|
|
[self profileCompletedOrSkipped];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)profileCompletedOrSkipped
|
|
|
|
{
|
|
|
|
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]]);
|
|
|
|
}
|
|
|
|
|
2017-07-31 22:45:06 +02:00
|
|
|
#pragma mark - UITextFieldDelegate
|
|
|
|
|
|
|
|
- (BOOL)textField:(UITextField *)textField
|
|
|
|
shouldChangeCharactersInRange:(NSRange)range
|
|
|
|
replacementString:(NSString *)insertionText
|
|
|
|
{
|
2017-08-01 17:34:23 +02:00
|
|
|
// TODO: Possibly filter invalid input.
|
|
|
|
// TODO: Possibly prevent user from typing overlong name.
|
2017-07-31 22:45:06 +02:00
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)textFieldShouldReturn:(UITextField *)textField
|
|
|
|
{
|
2017-08-01 17:34:23 +02:00
|
|
|
[self updateProfile];
|
|
|
|
return NO;
|
2017-07-31 22:45:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)textFieldDidChange:(id)sender
|
|
|
|
{
|
2017-07-31 23:12:09 +02:00
|
|
|
self.hasUnsavedChanges = YES;
|
2017-08-01 17:34:23 +02:00
|
|
|
|
|
|
|
// TODO: Update length warning.
|
2017-07-31 22:45:06 +02:00
|
|
|
}
|
|
|
|
|
2017-07-31 23:12:09 +02:00
|
|
|
#pragma mark - Avatar
|
|
|
|
|
|
|
|
- (void)setAvatar:(nullable UIImage *)avatar
|
|
|
|
{
|
|
|
|
OWSAssert([NSThread isMainThread]);
|
|
|
|
|
|
|
|
_avatar = avatar;
|
|
|
|
|
|
|
|
self.hasUnsavedChanges = YES;
|
|
|
|
|
|
|
|
[self updateAvatarView];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)updateAvatarView
|
|
|
|
{
|
2017-08-14 22:18:54 +02:00
|
|
|
self.avatarView.image = (self.avatar
|
|
|
|
?: [[UIImage imageNamed:@"profile_avatar_default"]
|
|
|
|
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]);
|
|
|
|
self.avatarView.tintColor = (self.avatar ? nil : [UIColor colorWithRGBHex:0x888888]);
|
|
|
|
self.cameraImageView.hidden = self.avatar != nil;
|
2017-07-31 23:12:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark - AvatarViewHelperDelegate
|
|
|
|
|
2017-08-01 17:31:00 +02:00
|
|
|
- (NSString *)avatarActionSheetTitle
|
|
|
|
{
|
|
|
|
return NSLocalizedString(
|
2017-08-01 17:58:51 +02:00
|
|
|
@"PROFILE_VIEW_AVATAR_ACTIONSHEET_TITLE", @"Action Sheet title prompting the user for a profile avatar");
|
2017-08-01 17:31:00 +02:00
|
|
|
}
|
|
|
|
|
2017-07-31 23:12:09 +02:00
|
|
|
- (void)avatarDidChange:(UIImage *)image
|
|
|
|
{
|
|
|
|
OWSAssert(image);
|
|
|
|
|
2017-08-15 21:40:46 +02:00
|
|
|
self.avatar = [image resizedImageToFillPixelSize:CGSizeMake(kOWSProfileManager_MaxAvatarDiameter,
|
|
|
|
kOWSProfileManager_MaxAvatarDiameter)];
|
2017-07-31 23:12:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (UIViewController *)fromViewController
|
|
|
|
{
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2017-08-01 17:58:51 +02:00
|
|
|
- (BOOL)hasClearAvatarAction
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *)clearAvatarActionLabel
|
|
|
|
{
|
|
|
|
return NSLocalizedString(@"PROFILE_VIEW_CLEAR_AVATAR", @"Label for action that clear's the user's profile avatar");
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)clearAvatar
|
|
|
|
{
|
|
|
|
self.avatar = nil;
|
|
|
|
}
|
|
|
|
|
2017-07-31 22:45:06 +02:00
|
|
|
#pragma mark - Logging
|
|
|
|
|
|
|
|
+ (NSString *)tag
|
|
|
|
{
|
|
|
|
return [NSString stringWithFormat:@"[%@]", self.class];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *)tag
|
|
|
|
{
|
|
|
|
return self.class.tag;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
NS_ASSUME_NONNULL_END
|