mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
402 lines
14 KiB
Objective-C
402 lines
14 KiB
Objective-C
//
|
|
// UserProfileViewController.m
|
|
// Flickrgram
|
|
//
|
|
// Created by Hannah Troisi on 2/24/16.
|
|
// Copyright © 2016 Hannah Troisi. All rights reserved.
|
|
//
|
|
|
|
#import "UserProfileViewController.h"
|
|
#import "Utilities.h"
|
|
|
|
#define HEADER_HEIGHT 300
|
|
#define USER_AVATAR_HEIGHT 70
|
|
#define HEADER_HORIZONTAL_INSET 15
|
|
|
|
#define DEBUG_LAYOUT 0
|
|
|
|
@implementation UserProfileViewController
|
|
{
|
|
UserModel *_user;
|
|
|
|
UIImageView *_avatarImageView;
|
|
UIButton *_followingStatusBtn;
|
|
UILabel *_fullNameLabel;
|
|
UILabel *_aboutLabel;
|
|
UILabel *_domainLabel;
|
|
UILabel *_followersCountLabel;
|
|
UILabel *_followingCountLabel;
|
|
UILabel *_photoCountLabel;
|
|
|
|
BOOL _animating;
|
|
}
|
|
|
|
//- (instancetype)initWithMe
|
|
//{
|
|
// UserModel *me = [[UserModel alloc] initWithMe];
|
|
//
|
|
// [self initWithUser:me];
|
|
//}
|
|
|
|
- (instancetype)initWithUser:(UserModel *)user
|
|
{
|
|
self = [super initWithNibName:nil bundle:nil];
|
|
|
|
if (self) {
|
|
|
|
self.view.backgroundColor = [UIColor whiteColor];
|
|
|
|
_followingStatusBtn = [UIButton buttonWithType:UIButtonTypeCustom];
|
|
_followingStatusBtn.adjustsImageWhenHighlighted = NO;
|
|
[_followingStatusBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
|
[_followingStatusBtn setTitleColor:[UIColor lightBlueColor] forState:UIControlStateSelected];
|
|
[_followingStatusBtn setTitle:@"Follow" forState:UIControlStateNormal];
|
|
[_followingStatusBtn setTitle:@"Following" forState:UIControlStateSelected];
|
|
[_followingStatusBtn addTarget:self action:@selector(toggleFollowing) forControlEvents:UIControlEventTouchUpInside];
|
|
[self.view addSubview:_followingStatusBtn];
|
|
|
|
_fullNameLabel = [[UILabel alloc] init];
|
|
_fullNameLabel.font = [_fullNameLabel.font fontWithSize:14];
|
|
[self.view addSubview:_fullNameLabel];
|
|
|
|
_aboutLabel = [[UILabel alloc] init];
|
|
_aboutLabel.font = [_aboutLabel.font fontWithSize:14];
|
|
_aboutLabel.numberOfLines = 3;
|
|
[self.view addSubview:_aboutLabel];
|
|
|
|
_domainLabel = [[UILabel alloc] init];
|
|
_domainLabel.font = [_domainLabel.font fontWithSize:14];
|
|
_domainLabel.textColor = [UIColor darkBlueColor];
|
|
[self.view addSubview:_domainLabel];
|
|
|
|
_followersCountLabel = [[UILabel alloc] init];
|
|
_followersCountLabel.font = [_followersCountLabel.font fontWithSize:14];
|
|
_followersCountLabel.textColor = [UIColor lightGrayColor];
|
|
_followersCountLabel.textAlignment = NSTextAlignmentCenter;
|
|
_followersCountLabel.numberOfLines = 2;
|
|
[self.view addSubview:_followersCountLabel];
|
|
|
|
_followingCountLabel = [[UILabel alloc] init];
|
|
_followingCountLabel.font = [_followingCountLabel.font fontWithSize:14];
|
|
_followingCountLabel.textColor = [UIColor lightGrayColor];
|
|
_followingCountLabel.textAlignment = NSTextAlignmentCenter;
|
|
_followingCountLabel.numberOfLines = 2;
|
|
[self.view addSubview:_followingCountLabel];
|
|
|
|
_photoCountLabel = [[UILabel alloc] init];
|
|
_photoCountLabel.font = [_photoCountLabel.font fontWithSize:14];
|
|
_photoCountLabel.textColor = [UIColor lightGrayColor];
|
|
_photoCountLabel.textAlignment = NSTextAlignmentCenter;
|
|
_photoCountLabel.numberOfLines = 2;
|
|
[self.view addSubview:_photoCountLabel];
|
|
|
|
// add to view last so that animation is on top
|
|
_avatarImageView = [[UIImageView alloc] init];
|
|
[self.view addSubview:_avatarImageView];
|
|
|
|
// This is what we have available as soon as we're created, without fetching new metadata from the network.
|
|
_fullNameLabel.text = _user.fullName;
|
|
_user = user;
|
|
self.navigationItem.title = [user.username uppercaseString];
|
|
|
|
// get full set of user data
|
|
[self loadAdditionalProfileFields];
|
|
|
|
// get avatar image
|
|
[self loadAvatarImage];
|
|
|
|
|
|
|
|
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(viewWasLongPressed:)];
|
|
// [self.view addGestureRecognizer:lpgr];
|
|
lpgr.minimumPressDuration = 0.01;
|
|
|
|
if (DEBUG_LAYOUT) {
|
|
_avatarImageView.backgroundColor = [UIColor greenColor];
|
|
_fullNameLabel.backgroundColor = [UIColor greenColor];
|
|
_aboutLabel.backgroundColor = [UIColor greenColor];
|
|
_domainLabel.backgroundColor = [UIColor greenColor];
|
|
_followersCountLabel.backgroundColor = [UIColor greenColor];
|
|
_followingCountLabel.backgroundColor = [UIColor greenColor];
|
|
_photoCountLabel.backgroundColor = [UIColor greenColor];
|
|
}
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)viewDidLayoutSubviews
|
|
{
|
|
[super viewDidLayoutSubviews];
|
|
|
|
CGSize boundsSize = self.view.bounds.size;
|
|
|
|
if (_animating) {
|
|
return;
|
|
}
|
|
|
|
// user avatar
|
|
CGFloat x = HEADER_HORIZONTAL_INSET;
|
|
CGFloat originalY = CGRectGetMaxY(self.navigationController.navigationBar.frame) + HEADER_HORIZONTAL_INSET;
|
|
CGFloat y = originalY;
|
|
_avatarImageView.frame = CGRectMake(x,
|
|
y,
|
|
USER_AVATAR_HEIGHT,
|
|
USER_AVATAR_HEIGHT);
|
|
y += _avatarImageView.frame.size.height;
|
|
|
|
if (!_avatarImageView.image) {
|
|
// We generate the rounded image at layout time (unusually late) so that we can know exactly how large
|
|
// it needs to be. This is the only way to ensure the rounded curve is perfectly smoothed / antialiased.
|
|
// _avatarImageView.image = [avatar makeCircularImageWithSize:CGSizeMake(USER_AVATAR_HEIGHT, USER_AVATAR_HEIGHT)];
|
|
}
|
|
|
|
if (_fullNameLabel.text) {
|
|
[_fullNameLabel sizeToFit];
|
|
y += HEADER_HORIZONTAL_INSET / 2.0;
|
|
_fullNameLabel.frame = CGRectMake(x,
|
|
y,
|
|
boundsSize.width - 2 * HEADER_HORIZONTAL_INSET,
|
|
_fullNameLabel.frame.size.height);
|
|
|
|
y += _fullNameLabel.frame.size.height;
|
|
}
|
|
|
|
if (_aboutLabel.text) {
|
|
[_aboutLabel sizeToFit];
|
|
y += HEADER_HORIZONTAL_INSET / 2.0;
|
|
_aboutLabel.frame = CGRectMake(x,
|
|
y,
|
|
boundsSize.width - 2 * HEADER_HORIZONTAL_INSET,
|
|
_aboutLabel.frame.size.height);
|
|
|
|
y += _aboutLabel.frame.size.height;
|
|
}
|
|
|
|
if (_domainLabel.text) {
|
|
[_domainLabel sizeToFit];
|
|
y += HEADER_HORIZONTAL_INSET / 2.0;
|
|
_domainLabel.frame = CGRectMake(x,
|
|
y,
|
|
boundsSize.width - 2 * HEADER_HORIZONTAL_INSET,
|
|
_domainLabel.frame.size.height);
|
|
}
|
|
|
|
CGFloat availableWidth = boundsSize.width - 3 * HEADER_HORIZONTAL_INSET - USER_AVATAR_HEIGHT;
|
|
CGFloat actualWidth = floorf((availableWidth - 2 * HEADER_HORIZONTAL_INSET / 2.0) / 3.0);
|
|
|
|
y = originalY;
|
|
x += USER_AVATAR_HEIGHT + HEADER_HORIZONTAL_INSET;
|
|
|
|
[_photoCountLabel sizeToFit];
|
|
_photoCountLabel.frame = CGRectMake(x,
|
|
y,
|
|
actualWidth,
|
|
_photoCountLabel.frame.size.height);
|
|
x += actualWidth;
|
|
|
|
[_followersCountLabel sizeToFit];
|
|
x += HEADER_HORIZONTAL_INSET / 2.0;
|
|
_followersCountLabel.frame = CGRectMake(x,
|
|
y,
|
|
actualWidth,
|
|
_followersCountLabel.frame.size.height);
|
|
x += actualWidth;
|
|
|
|
[_followingCountLabel sizeToFit];
|
|
x += HEADER_HORIZONTAL_INSET / 2.0;
|
|
_followingCountLabel.frame = CGRectMake(x,
|
|
y,
|
|
actualWidth,
|
|
_followingCountLabel.frame.size.height);
|
|
|
|
x = USER_AVATAR_HEIGHT + 2 * HEADER_HORIZONTAL_INSET;
|
|
y = originalY + USER_AVATAR_HEIGHT / 2.0;
|
|
_followingStatusBtn.frame = CGRectMake(x,
|
|
y,
|
|
availableWidth,
|
|
USER_AVATAR_HEIGHT / 2.0);
|
|
|
|
[self setFollowingButtonBackgroundsForRect:_followingStatusBtn.frame.size];
|
|
}
|
|
|
|
|
|
#pragma mark - Touch Events
|
|
|
|
- (void)viewWasLongPressed:(UIGestureRecognizer *)sender
|
|
{
|
|
|
|
if (sender.state == UIGestureRecognizerStateBegan) {
|
|
|
|
// determine which area of cell was tapped
|
|
CGPoint tapPoint = [sender locationInView:_avatarImageView];
|
|
|
|
if (tapPoint.y > 0) {
|
|
|
|
NSLog(@"LONG PRESS STARTED");
|
|
|
|
_animating = YES;
|
|
|
|
// FIXME: use pinremote image to download higher res photo
|
|
|
|
[UIView animateWithDuration:0.2
|
|
delay:0
|
|
usingSpringWithDamping:0.5
|
|
initialSpringVelocity:1.0f
|
|
options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut
|
|
animations:^{
|
|
|
|
// FIXME: grey the background
|
|
|
|
_avatarImageView.frame = CGRectMake(100, 100, 100, 100);
|
|
|
|
} completion:^(BOOL finished) {
|
|
_animating = NO;
|
|
}];
|
|
}
|
|
}
|
|
|
|
if (sender.state == UIGestureRecognizerStateEnded) {
|
|
|
|
// determine which area of cell was tapped
|
|
CGPoint tapPoint = [sender locationInView:_avatarImageView];
|
|
|
|
if (tapPoint.y > 0) { // FIXME: all long presses work here
|
|
|
|
NSLog(@"LONG PRESS ENDED");
|
|
|
|
_animating = YES;
|
|
|
|
[UIView animateWithDuration:0.2
|
|
delay:0
|
|
usingSpringWithDamping:0.5
|
|
initialSpringVelocity:1.0f
|
|
options: UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut
|
|
animations:^{
|
|
|
|
CGFloat x = HEADER_HORIZONTAL_INSET;
|
|
CGFloat originalY = CGRectGetMaxY(self.navigationController.navigationBar.frame) + HEADER_HORIZONTAL_INSET;
|
|
CGFloat y = originalY;
|
|
_avatarImageView.frame = CGRectMake(x,
|
|
y,
|
|
USER_AVATAR_HEIGHT,
|
|
USER_AVATAR_HEIGHT);
|
|
|
|
} completion:^(BOOL finished) {
|
|
_animating = NO;
|
|
|
|
}];
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)toggleFollowing
|
|
{
|
|
// toggle button state
|
|
if (_followingStatusBtn.selected) {
|
|
|
|
// stop following
|
|
NSString *urlString = [NSString stringWithFormat:@"https://api.500px.com/v1/users/%lu/friends?consumer_key=Fi13GVb8g53sGvHICzlram7QkKOlSDmAmp9s9aqC", (long)_user.userID];
|
|
NSURL *url = [NSURL URLWithString:urlString];
|
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
|
|
[request setHTTPMethod:@"DELETE"];
|
|
|
|
// FIXME: update user model
|
|
// FIXME: check for success
|
|
|
|
} else {
|
|
|
|
// start following
|
|
NSString *urlString = [NSString stringWithFormat:@"https://api.500px.com/v1/users/%lu/friends?consumer_key=Fi13GVb8g53sGvHICzlram7QkKOlSDmAmp9s9aqC", (long)_user.userID];
|
|
NSURL *url = [NSURL URLWithString:urlString];
|
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
|
|
[request setHTTPMethod:@"POST"];
|
|
}
|
|
|
|
_followingStatusBtn.selected = !_followingStatusBtn.selected;
|
|
}
|
|
|
|
- (void)getFollowers
|
|
{
|
|
NSString *urlString = [NSString stringWithFormat:@"https://api.500px.com/v1/users/%lu/friends?consumer_key=Fi13GVb8g53sGvHICzlram7QkKOlSDmAmp9s9aqC", (long)_user.userID];
|
|
NSURL *url = [NSURL URLWithString:urlString];
|
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
|
|
[request setHTTPMethod:@"GET"];
|
|
}
|
|
|
|
#pragma mark - Helper Methods
|
|
|
|
- (void)loadAdditionalProfileFields
|
|
{
|
|
// fetch full user profile info
|
|
[_user downloadCompleteUserDataWithCompletionBlock:^(UserModel *userModel) {
|
|
|
|
// check that info returning from async download is still applicable to this view
|
|
if (userModel == _user) {
|
|
|
|
_followingStatusBtn.selected = userModel.following;
|
|
_followersCountLabel.text = [NSString stringWithFormat:@"%lu\nfollowers", (long)userModel.followersCount];
|
|
_followingCountLabel.text = [NSString stringWithFormat:@"%lu\nfollowing", (long)userModel.friendsCount];
|
|
_photoCountLabel.text = [NSString stringWithFormat:@"%lu\nphotos", (long)userModel.photoCount];
|
|
_aboutLabel.text = userModel.about;
|
|
_domainLabel.text = userModel.domain;
|
|
|
|
[self.view setNeedsLayout];
|
|
}
|
|
}];
|
|
}
|
|
|
|
- (void)loadAvatarImage
|
|
{
|
|
[_user fetchAvatarImageWithCompletionBlock:^(UserModel *userModel, UIImage *avatar) {
|
|
|
|
// check that info returning from async download is still applicable to this view
|
|
if (userModel == _user) {
|
|
[self.view setNeedsLayout];
|
|
}
|
|
}];
|
|
}
|
|
|
|
#define FOLLOW_BUTTON_CORNER_RADIUS 8
|
|
- (void)setFollowingButtonBackgroundsForRect:(CGSize)size
|
|
{
|
|
CGSize unstretchedSize = CGSizeMake(2 * FOLLOW_BUTTON_CORNER_RADIUS + 1, 2 * FOLLOW_BUTTON_CORNER_RADIUS + 1);
|
|
CGRect rect = (CGRect) {CGPointZero, unstretchedSize};
|
|
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:FOLLOW_BUTTON_CORNER_RADIUS];
|
|
|
|
UIColor *lightBlue = [UIColor colorWithRed:0.0 green:122.0/255.0 blue:1.0 alpha:1.0];
|
|
|
|
// create a graphics context for the following status button
|
|
UIGraphicsBeginImageContextWithOptions(unstretchedSize, NO, 0);
|
|
|
|
[path addClip];
|
|
[lightBlue setFill];
|
|
[path fill];
|
|
|
|
UIImage *notFollowingBtnImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
UIGraphicsEndImageContext();
|
|
|
|
UIImage *notFollowingBtnImageStretchable = [notFollowingBtnImage stretchableImageWithLeftCapWidth:FOLLOW_BUTTON_CORNER_RADIUS topCapHeight:FOLLOW_BUTTON_CORNER_RADIUS];
|
|
[_followingStatusBtn setBackgroundImage:notFollowingBtnImageStretchable forState:UIControlStateNormal];
|
|
|
|
// create a graphics context for the not yet following status button
|
|
UIGraphicsBeginImageContextWithOptions(unstretchedSize, NO, 0);
|
|
|
|
[path addClip];
|
|
|
|
[[UIColor whiteColor] setFill];
|
|
[path fill];
|
|
|
|
path.lineWidth = 3;
|
|
[lightBlue setStroke];
|
|
[path stroke];
|
|
|
|
UIImage *followingBtnImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
UIGraphicsEndImageContext();
|
|
|
|
UIImage *followingBtnImageStretchable = [followingBtnImage stretchableImageWithLeftCapWidth:FOLLOW_BUTTON_CORNER_RADIUS topCapHeight:FOLLOW_BUTTON_CORNER_RADIUS];
|
|
[_followingStatusBtn setBackgroundImage:followingBtnImageStretchable forState:UIControlStateSelected];
|
|
}
|
|
|
|
@end
|