cleaned up model, view files

This commit is contained in:
Hannah Troisi
2016-03-29 13:00:44 -07:00
parent 0f4481718c
commit 53741a4e0a
17 changed files with 44 additions and 524 deletions

View File

@@ -29,7 +29,6 @@
768843911CAA37EF00D8629E /* PhotoTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 768843791CAA37EF00D8629E /* PhotoTableViewCell.m */; };
768843921CAA37EF00D8629E /* PhotoFeedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7688437A1CAA37EF00D8629E /* PhotoFeedViewController.m */; };
768843931CAA37EF00D8629E /* UserModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7688437B1CAA37EF00D8629E /* UserModel.m */; };
768843951CAA37EF00D8629E /* UserRowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7688437D1CAA37EF00D8629E /* UserRowView.m */; };
768843961CAA37EF00D8629E /* Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 7688437E1CAA37EF00D8629E /* Utilities.m */; };
/* End PBXBuildFile section */
@@ -57,7 +56,6 @@
768843611CAA37EF00D8629E /* PhotoTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = PhotoTableViewCell.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
768843621CAA37EF00D8629E /* PhotoFeedViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = PhotoFeedViewController.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
768843631CAA37EF00D8629E /* UserModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = UserModel.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
768843651CAA37EF00D8629E /* UserRowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = UserRowView.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
768843661CAA37EF00D8629E /* Utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Utilities.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
768843671CAA37EF00D8629E /* Flickrgram.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Flickrgram.pch; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
768843681CAA37EF00D8629E /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AppDelegate.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
@@ -76,7 +74,6 @@
768843791CAA37EF00D8629E /* PhotoTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = PhotoTableViewCell.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
7688437A1CAA37EF00D8629E /* PhotoFeedViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = PhotoFeedViewController.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
7688437B1CAA37EF00D8629E /* UserModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = UserModel.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
7688437D1CAA37EF00D8629E /* UserRowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = UserRowView.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
7688437E1CAA37EF00D8629E /* Utilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = Utilities.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
7688437F1CAA37EF00D8629E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C068F1D3F0CC317E895FCDAB /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
@@ -228,8 +225,6 @@
768843741CAA37EF00D8629E /* PhotoCollectionViewCell.m */,
768843551CAA37EF00D8629E /* CommentView.h */,
7688436C1CAA37EF00D8629E /* CommentView.m */,
768843651CAA37EF00D8629E /* UserRowView.h */,
7688437D1CAA37EF00D8629E /* UserRowView.m */,
);
name = UIKit;
sourceTree = "<group>";
@@ -380,7 +375,6 @@
768843811CAA37EF00D8629E /* CommentFeedModel.m in Sources */,
7688438E1CAA37EF00D8629E /* PhotoFeedNodeController.m in Sources */,
768843841CAA37EF00D8629E /* CommentView.m in Sources */,
768843951CAA37EF00D8629E /* UserRowView.m in Sources */,
768843881CAA37EF00D8629E /* LocationModel.m in Sources */,
768843901CAA37EF00D8629E /* PhotoModel.m in Sources */,
768843911CAA37EF00D8629E /* PhotoTableViewCell.m in Sources */,

View File

@@ -30,7 +30,6 @@
BOOL _refreshFeedInProgress;
}
#pragma mark - Properties
- (NSMutableArray *)comments
@@ -38,7 +37,6 @@
return _comments;
}
#pragma mark - Lifecycle
- (instancetype)initWithPhotoID:(NSString *)photoID
@@ -46,14 +44,12 @@
self = [super init];
if (self) {
_photoID = photoID;
_currentPage = 0;
_totalPages = 0;
_totalItems = 0;
_comments = [[NSMutableArray alloc] init];
_urlString = [NSString stringWithFormat:@"https://api.500px.com/v1/photos/%@/comments?",photoID];
_urlString = [NSString stringWithFormat:@"https://api.500px.com/v1/photos/%@/comments?",photoID];
}
return self;
@@ -93,15 +89,9 @@
{
// only one fetch at a time
if (_fetchPageInProgress) {
// NSLog(@"Request COMMENTS: FAIL - fetch page already in progress");
return;
return;
} else {
_fetchPageInProgress = YES;
// NSLog(@"Request COMMENTS: SUCCESS");
[self fetchPageWithCompletionBlock:block];
}
}
@@ -110,12 +100,8 @@
{
// only one fetch at a time
if (_refreshFeedInProgress) {
// NSLog(@"Request Refresh COMMENTS: FAIL - refresh feed already in progress");
return;
} else {
_refreshFeedInProgress = YES;
_currentPage = 0;
@@ -125,7 +111,6 @@
if (block) {
block(newPhotos);
}
_refreshFeedInProgress = NO;
} replaceData:YES];
}
@@ -171,8 +156,6 @@
NSArray *comments = [response valueForKeyPath:@"comments"];
// NSLog(@"Request Refresh COMMENTS: SUCCESS %@", comments);
if ([comments isKindOfClass:[NSArray class]]) {
NSUInteger numComments = [comments count];
@@ -186,7 +169,6 @@
CommentModel *comment = [[CommentModel alloc] initWithDictionary:commentDictionary];
// addObject: will crash with nil (NSArray, NSSet, NSDictionary, URLWithString - most foundation things)
if (comment) {
[newComments addObject:comment];
}
@@ -196,7 +178,6 @@
}
}
}
dispatch_async(dispatch_get_main_queue(), ^{
if (replaceData) {
@@ -204,14 +185,11 @@
} else {
[_comments addObjectsFromArray:newComments];
}
if (block) {
block(newComments);
}
});
_fetchPageInProgress = NO;
});
}

View File

@@ -22,16 +22,14 @@
self = [super init];
if (self) {
_dictionaryRepresentation = photoDictionary;
_ID = [[photoDictionary objectForKey:@"id"] integerValue];
_commenterID = [[photoDictionary objectForKey:@"user_id"] integerValue];
_commenterUsername = [photoDictionary valueForKeyPath:@"user.username"];
_commenterAvatarURL= [photoDictionary valueForKeyPath:@"user.userpic_url"];
_body = [photoDictionary objectForKey:@"body"];
_uploadDateRaw = [photoDictionary valueForKeyPath:@"created_at"];
_uploadDateString = [NSString elapsedTimeStringSinceDate:_uploadDateRaw];
_dictionaryRepresentation = photoDictionary;
_ID = [[photoDictionary objectForKey:@"id"] integerValue];
_commenterID = [[photoDictionary objectForKey:@"user_id"] integerValue];
_commenterUsername = [photoDictionary valueForKeyPath:@"user.username"];
_commenterAvatarURL = [photoDictionary valueForKeyPath:@"user.userpic_url"];
_body = [photoDictionary objectForKey:@"body"];
_uploadDateRaw = [photoDictionary valueForKeyPath:@"created_at"];
_uploadDateString = [NSString elapsedTimeStringSinceDate:_uploadDateRaw];
}
return self;
@@ -47,10 +45,7 @@
- (NSAttributedString *)uploadDateAttributedStringWithFontSize:(CGFloat)size;
{
return [NSAttributedString attributedStringWithString:self.uploadDateString
fontSize:size
color:[UIColor lightGrayColor]
firstWordColor:nil];
return [NSAttributedString attributedStringWithString:self.uploadDateString fontSize:size color:[UIColor lightGrayColor] firstWordColor:nil];
}
@end

View File

@@ -50,17 +50,14 @@
return roundf(height);
}
#pragma mark - Lifecycle
- (instancetype)init
{
self = [super init];
if (self) {
_commentLabels = [[NSMutableArray alloc] init];
}
return self;
}
@@ -78,7 +75,6 @@
}
}
#pragma mark - Instance Methods
- (void)updateWithCommentFeedModel:(CommentFeedModel *)feed
@@ -111,7 +107,6 @@
}
}
#pragma mark - Helper Methods
- (void)removeCommentLabels

View File

@@ -22,11 +22,9 @@
- (instancetype)init
{
self = [super init];
if (self) {
_commentNodes = [[NSMutableArray alloc] init];
}
return self;
}

View File

@@ -15,7 +15,6 @@
BOOL squareImageRequested = (size.width == size.height) ? YES : NO;
NSUInteger imageParameterID;
if (squareImageRequested) {
imageParameterID = [self imageParameterForSquareCroppedSize:size];
}

View File

@@ -31,7 +31,6 @@
self = [super init];
if (self) {
// set coordiantes
_coordinates = CLLocationCoordinate2DMake([latitude floatValue], [longitude floatValue]);
@@ -70,47 +69,11 @@
#pragma mark - Helper Methods
- (nullable NSString *)locationStringFromPhotoLocationDictionary:(NSDictionary *)photoLocationDictionary
{
// early return if no location info
if (!photoLocationDictionary)
{
return nil;
}
NSString *country = [photoLocationDictionary valueForKeyPath:@"country._content"];
NSString *county = [photoLocationDictionary valueForKeyPath:@"county._content"];
NSString *locality = [photoLocationDictionary valueForKeyPath:@"locality._content"];
NSString *neighbourhood = [photoLocationDictionary valueForKeyPath:@"neighbourhood._content"];
NSString *region = [photoLocationDictionary valueForKeyPath:@"region._content"];
NSString *locationString;
if (neighbourhood) {
locationString = [NSString stringWithFormat:@"%@", neighbourhood];
} else if (locality && county) {
locationString = [NSString stringWithFormat:@"%@, %@", locality, county];
} else if (region) {
locationString = [NSString stringWithFormat:@"%@, %@", region, country];
} else if (country) {
locationString = [NSString stringWithFormat:@"%@", country];
} else {
locationString = @"ERROR";
}
// NSLog(@"%@", photoLocationDictionary);
// NSLog(@"%@, %@, %@, %@, %@", neighbourhood, locality, county, region, country);
// NSLog(@"%@", locationString);
return locationString;
}
- (void)beginReverseGeocodingLocationFromCoordinates
{
if (_placemarkFetchInProgress) {
return;
}
_placemarkFetchInProgress = YES;
CLLocation *location = [[CLLocation alloc] initWithLatitude:_coordinates.latitude longitude:_coordinates.longitude];
@@ -157,11 +120,7 @@
if (_placemark.inlandWater) {
locationString = _placemark.inlandWater;
}
// else if (_placemark.name) {
// locationString = [NSString stringWithFormat:@"%@", _placemark.name];
// }
else if (_placemark.subLocality && _placemark.locality) {
} else if (_placemark.subLocality && _placemark.locality) {
locationString = [NSString stringWithFormat:@"%@, %@", _placemark.subLocality, _placemark.locality];
} else if (_placemark.administrativeArea && _placemark.subAdministrativeArea) {
locationString = [NSString stringWithFormat:@"%@, %@", _placemark.subAdministrativeArea, _placemark.administrativeArea];

View File

@@ -1,6 +1,6 @@
//
// PhotoCellNode.h
// ASDKgram
// Flickrgram
//
// Created by Hannah Troisi on 2/17/16.
// Copyright © 2016 Hannah Troisi. All rights reserved.
@@ -15,8 +15,6 @@
@interface PhotoCellNode : ASCellNode
@property (nonatomic, strong, readwrite) id<PhotoTableViewCellProtocol> delegate;
- (instancetype)initWithPhotoObject:(PhotoModel *)photo;
- (void)loadCommentsForPhoto:(PhotoModel *)photo;

View File

@@ -22,7 +22,7 @@
#define VERTICAL_BUFFER 5
#define FONT_SIZE 14
@interface PhotoCellNode () <UIActionSheetDelegate>
@interface PhotoCellNode ()
@end
@implementation PhotoCellNode
@@ -38,7 +38,6 @@
ASTextNode *_photoDescriptionLabel;
}
#pragma mark - Lifecycle
- (instancetype)initWithPhotoObject:(PhotoModel *)photo;
@@ -110,24 +109,12 @@
return self;
}
- (void)doNothing
{
}
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
// username / photo location header vertical stack
CGFloat cellWidth = constrainedSize.max.width;
// CGFloat locationWidth = HORIZONTAL_BUFFER * 3;
//cellWidth - HORIZONTAL_BUFFER - USER_IMAGE_HEIGHT - HORIZONTAL_BUFFER - HORIZONTAL_BUFFER - _photoTimeIntervalSincePostLabel.frame.size.width - HORIZONTAL_BUFFER;
// CGSize maxSize = CGSizeMake(locationWidth, CGFLOAT_MAX);
// CGSize minSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);
// _photoLocationLabel.sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMakeWithCGSize(minSize), ASRelativeSizeMakeWithCGSize(maxSize));
_photoLocationLabel.flexShrink = YES;
_userNameLabel.flexShrink = YES;
_userNameLabel.flexShrink = YES;
ASStackLayoutSpec *headerSubStack = [ASStackLayoutSpec verticalStackLayoutSpec];
headerSubStack.flexShrink = YES;
@@ -143,7 +130,7 @@
_userAvatarImageView.preferredFrameSize = CGSizeMake(USER_IMAGE_HEIGHT, USER_IMAGE_HEIGHT); // constrain avatar image frame size
_photoTimeIntervalSincePostLabel.spacingBefore = HORIZONTAL_BUFFER; // hack to remove double spaces around spacer
ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init]; // FIXME: long locations overflow post time - set max size?
ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init]; // FIXME: long locations overflow post time - set max size?
spacer.flexGrow = YES;
spacer.flexShrink = YES;
@@ -163,7 +150,6 @@
UIEdgeInsets insets = UIEdgeInsetsMake(0, HORIZONTAL_BUFFER, 0, HORIZONTAL_BUFFER);
ASInsetLayoutSpec *headerWithInset = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:headerStack];
headerWithInset.flexShrink = YES;
// footer stack
@@ -179,7 +165,7 @@
// vertical stack
CGFloat cellWidth = constrainedSize.max.width;
_photoImageView.preferredFrameSize = CGSizeMake(cellWidth, cellWidth); // constrain photo frame size
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec];
@@ -190,6 +176,8 @@
return verticalStack;
}
#pragma mark - Instance Methods
- (void)loadCommentsForPhoto:(PhotoModel *)photo
{
if (photo.commentFeed.numberOfItemsInFeed > 0) {

View File

@@ -15,7 +15,6 @@
UIImageView *_photoImageView;
}
#pragma mark - Lifecycle
- (instancetype)initWithFrame:(CGRect)frame
@@ -27,10 +26,6 @@
_photoImageView = [[UIImageView alloc] init];
[_photoImageView setPin_updateWithProgress:YES];
[self.contentView addSubview:_photoImageView];
// tap gesture recognizer
UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cellWasTapped:)];
[self addGestureRecognizer:tgr];
}
return self;
@@ -51,7 +46,6 @@
_photoImageView.image = nil;
}
#pragma mark - Instance Methods
- (void)updateCellWithPhotoObject:(PhotoModel *)photo
@@ -60,12 +54,4 @@
[_photoImageView pin_setImageFromURL:photo.URL];
}
#pragma mark - Gesture Handling
- (void)cellWasTapped:(UIGestureRecognizer *)sender
{
NSLog(@"Photo was tapped");
}
@end

View File

@@ -15,8 +15,6 @@
#define fiveHundredPX_ENDPOINT_USER @"photos?user_id="
#define fiveHundredPX_CONSUMER_KEY_PARAM @"&consumer_key=Fi13GVb8g53sGvHICzlram7QkKOlSDmAmp9s9aqC"
// &exclude='Nude,People'
@implementation PhotoFeedModel
{
PhotoFeedModelType _feedType;
@@ -45,7 +43,6 @@
return _photos;
}
#pragma mark - Lifecycle
- (instancetype)initWithPhotoFeedModelType:(PhotoFeedModelType)type imageSize:(CGSize)size
@@ -53,16 +50,13 @@
self = [super init];
if (self) {
_feedType = type;
_imageSize = size;
_photos = [[NSMutableArray alloc] init];
_ids = [[NSMutableArray alloc] init];
_currentPage = 0;
NSString *apiEndpointString;
switch (type) {
case (PhotoFeedModelTypePopular):
apiEndpointString = fiveHundredPX_ENDPOINT_POPULAR;
@@ -77,17 +71,14 @@
break;
default:
break;
}
_urlString = [[fiveHundredPX_ENDPOINT_HOST stringByAppendingString:apiEndpointString] stringByAppendingString:fiveHundredPX_CONSUMER_KEY_PARAM];
}
return self;
}
#pragma mark - Instance Methods
- (NSUInteger)totalNumberOfPhotos
@@ -140,15 +131,9 @@
{
// only one fetch at a time
if (_fetchPageInProgress) {
// NSLog(@"Request: FAIL - fetch page already in progress");
return;
} else {
_fetchPageInProgress = YES;
// NSLog(@"Request: SUCCESS");
[self fetchPageWithCompletionBlock:block numResultsToReturn:numResults];
}
}
@@ -157,31 +142,24 @@
{
// only one fetch at a time
if (_refreshFeedInProgress) {
// NSLog(@"Request Refresh: FAIL - refresh feed already in progress");
return;
} else {
_refreshFeedInProgress = YES;
_currentPage = 0;
// FIXME: blow away any other requests in progress
// NSLog(@"Request Refresh: SUCCESS");
[self fetchPageWithCompletionBlock:^(NSArray *newPhotos) {
if (block) {
block(newPhotos);
}
_refreshFeedInProgress = NO;
} numResultsToReturn:numResults replaceData:YES];
}
}
#pragma mark - Helper Methods
- (void)fetchPageWithCompletionBlock:(void (^)(NSArray *))block numResultsToReturn:(NSUInteger)numResults
{
[self fetchPageWithCompletionBlock:block numResultsToReturn:numResults replaceData:NO];
@@ -196,47 +174,33 @@
}
}
// rpp cannot be over 100
NSUInteger numPhotos = (numResults < 100) ? numResults : 100;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableArray *newPhotos = [NSMutableArray array];
NSMutableArray *newIDs = [NSMutableArray array];
@synchronized(self) {
NSUInteger nextPage = _currentPage + 1;
NSUInteger nextPage = _currentPage + 1;
NSString *imageSizeParam = [ImageURLModel imageParameterForClosestImageSize:_imageSize];
NSString *urlAdditions = [NSString stringWithFormat:@"&page=%lu&rpp=%lu%@", (unsigned long)nextPage, (long)numPhotos, imageSizeParam];
NSURL *url = [NSURL URLWithString:[_urlString stringByAppendingString:urlAdditions]];
NSData *data = [NSData dataWithContentsOfURL:url];
NSString *urlAdditions = [NSString stringWithFormat:@"&page=%lu&rpp=%lu%@", (unsigned long)nextPage, (long)numPhotos, imageSizeParam];
NSURL *url = [NSURL URLWithString:[_urlString stringByAppendingString:urlAdditions]];
NSData *data = [NSData dataWithContentsOfURL:url];
if (data) {
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
if ([response isKindOfClass:[NSDictionary class]]) {
_currentPage = [[response valueForKeyPath:@"current_page"] integerValue];
_totalPages = [[response valueForKeyPath:@"total_pages"] integerValue];
_totalItems = [[response valueForKeyPath:@"total_items"] integerValue];
NSArray *photos = [response valueForKeyPath:@"photos"];
if ([photos isKindOfClass:[NSArray class]]) {
for (NSDictionary *photoDictionary in photos) {
if ([response isKindOfClass:[NSDictionary class]]) {
PhotoModel *photo = [[PhotoModel alloc] initWith500pxPhoto:photoDictionary];
// addObject: will crash with nil (NSArray, NSSet, NSDictionary, URLWithString - most foundation things)
if (photo) {
if (replaceData || ![_ids containsObject:photo.photoID]) {
[newPhotos addObject:photo];
[newIDs addObject:photo.photoID];
@@ -248,9 +212,7 @@
}
}
}
dispatch_async(dispatch_get_main_queue(), ^{
if (replaceData) {
_photos = [newPhotos mutableCopy];
_ids = [newIDs mutableCopy];
@@ -258,14 +220,11 @@
[_photos addObjectsFromArray:newPhotos];
[_ids addObjectsFromArray:newIDs];
}
if (block) {
block(newPhotos);
}
});
_fetchPageInProgress = NO;
});
}

View File

@@ -13,8 +13,8 @@
@implementation PhotoModel
{
NSDictionary *_dictionaryRepresentation;
NSString *_uploadDateRaw;
NSDictionary *_dictionaryRepresentation;
NSString *_uploadDateRaw;
CommentFeedModel *_commentFeed;
}
@@ -29,7 +29,6 @@
return _commentFeed;
}
#pragma mark - Lifecycle
- (instancetype)initWith500pxPhoto:(NSDictionary *)photoDictionary
@@ -37,36 +36,25 @@
self = [super init];
if (self) {
_dictionaryRepresentation = photoDictionary;
_uploadDateRaw = [photoDictionary objectForKey:@"created_at"];
_photoID = [[photoDictionary objectForKey:@"id"] description];
_title = [photoDictionary objectForKey:@"title"];
_descriptionText = [photoDictionary valueForKeyPath:@"name"];
_commentsCount = [[photoDictionary objectForKey:@"comments_count"] integerValue];
_likesCount = [[photoDictionary objectForKey:@"positive_votes_count"] integerValue];
_dictionaryRepresentation = photoDictionary;
NSString *urlString = [photoDictionary objectForKey:@"image_url"];
_URL = urlString ? [NSURL URLWithString:urlString] : nil;
NSString *urlString = [photoDictionary objectForKey:@"image_url"];
_URL = urlString ? [NSURL URLWithString:urlString] : nil;
_ownerUserProfile = [[UserModel alloc] initWith500pxPhoto:photoDictionary];
_uploadDateRaw = [photoDictionary objectForKey:@"created_at"];
_photoID = [[photoDictionary objectForKey:@"id"] description];
_title = [photoDictionary objectForKey:@"title"];
_descriptionText = [photoDictionary valueForKeyPath:@"name"];
_commentsCount = [[photoDictionary objectForKey:@"comments_count"] integerValue];
_likesCount = [[photoDictionary objectForKey:@"positive_votes_count"] integerValue];
// photo location
_location = [[LocationModel alloc] initWith500pxPhoto:photoDictionary];
// calculate dateString off the main thread
_uploadDateString = [NSString elapsedTimeStringSinceDate:_uploadDateRaw];
_location = [[LocationModel alloc] initWith500pxPhoto:photoDictionary];
_ownerUserProfile = [[UserModel alloc] initWith500pxPhoto:photoDictionary];
_uploadDateString = [NSString elapsedTimeStringSinceDate:_uploadDateRaw];
}
return self;
}
#pragma mark - Instance Methods
- (NSAttributedString *)descriptionAttributedStringWithFontSize:(CGFloat)size
@@ -81,10 +69,7 @@
- (NSAttributedString *)uploadDateAttributedStringWithFontSize:(CGFloat)size
{
return [NSAttributedString attributedStringWithString:self.uploadDateString
fontSize:size
color:[UIColor lightGrayColor]
firstWordColor:nil];
return [NSAttributedString attributedStringWithString:self.uploadDateString fontSize:size color:[UIColor lightGrayColor] firstWordColor:nil];
}
- (NSAttributedString *)likesAttributedStringWithFontSize:(CGFloat)size
@@ -95,18 +80,12 @@
NSString *likesString = [NSString stringWithFormat:@"♥︎ %@ likes", formattedLikesNumber];
return [NSAttributedString attributedStringWithString:likesString
fontSize:size
color:[UIColor darkBlueColor]
firstWordColor:nil];
return [NSAttributedString attributedStringWithString:likesString fontSize:size color:[UIColor darkBlueColor] firstWordColor:nil];
}
- (NSAttributedString *)locationAttributedStringWithFontSize:(CGFloat)size
{
return [NSAttributedString attributedStringWithString:self.location.locationString
fontSize:size
color:[UIColor lightBlueColor]
firstWordColor:nil];
return [NSAttributedString attributedStringWithString:self.location.locationString fontSize:size color:[UIColor lightBlueColor] firstWordColor:nil];
}
- (NSString *)description

View File

@@ -10,18 +10,8 @@
#import <CoreLocation/CLLocation.h>
#import "PhotoModel.h"
@protocol PhotoTableViewCellProtocol <NSObject>
- (void)userProfileWasTouchedWithUser:(UserModel *)user;
- (void)photoLocationWasTouchedWithCoordinate:(CLLocationCoordinate2D)coordiantes name:(NSAttributedString *)name;
- (void)cellWasLongPressedWithPhoto:(PhotoModel *)photo;
- (void)photoLikesWasTouchedWithPhoto:(PhotoModel *)photo;
@end
@interface PhotoTableViewCell : UITableViewCell
@property (nonatomic, strong, readwrite) id<PhotoTableViewCellProtocol> delegate;
+ (CGFloat)heightForPhotoModel:(PhotoModel *)photo withWidth:(CGFloat)width;
- (void)updateCellWithPhotoObject:(PhotoModel *)photo;

View File

@@ -20,9 +20,6 @@
#define VERTICAL_BUFFER 5
#define FONT_SIZE 14
@interface PhotoTableViewCell () <UIActionSheetDelegate>
@end
@implementation PhotoTableViewCell
{
PhotoModel *_photoModel;
@@ -36,7 +33,6 @@
UILabel *_photoDescriptionLabel;
}
#pragma mark - Class Methods
+ (CGFloat)heightForPhotoModel:(PhotoModel *)photo withWidth:(CGFloat)width;
@@ -57,7 +53,6 @@
return HEADER_HEIGHT + photoHeight + likesHeight + descriptionHeight + commentViewHeight + (4 * VERTICAL_BUFFER);
}
#pragma mark - Lifecycle
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
@@ -144,7 +139,6 @@
_photoImageView.frame = CGRectMake(0, HEADER_HEIGHT, boundsSize.width, boundsSize.width);
// FIXME: Make PhotoCellFooterView
rect.size = _photoLikesLabel.bounds.size;
rect.origin = CGPointMake(HORIZONTAL_BUFFER, CGRectGetMaxY(_photoImageView.frame) + VERTICAL_BUFFER);
_photoLikesLabel.frame = rect;
@@ -177,7 +171,6 @@
_photoDescriptionLabel.attributedText = nil;
}
#pragma mark - Instance Methods
- (void)updateCellWithPhotoObject:(PhotoModel *)photo
@@ -218,7 +211,6 @@
}
}
#pragma mark - Helper Methods
- (void)downloadAndProcessUserAvatarForPhoto:(PhotoModel *)photo
@@ -244,20 +236,4 @@
}];
}
- (void)startDownloadingLikesForPhoto:_photoModel
{
// [_photoModel.likesFeed refreshFeedWithCompletionBlock:^(NSArray *newComments) {
//
// NSInteger rowNum = [_photoFeed indexOfPhotoModel:photo];
// PhotoTableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:rowNum inSection:0]];
//
// if (cell) {
// [cell loadCommentsForPhoto:photo];
// [self.tableView beginUpdates];
// [self.tableView endUpdates];
// // FIXME: adjust content offset - iterate over cells above to get heights...
// }
// }];
}
@end

View File

@@ -24,50 +24,38 @@
self = [super init];
if (self) {
_fullUserInfoFetchRequested = NO;
_fullUserInfoFetchDone = NO;
// parse user dictionary
[self loadUserDataFromDictionary:dictionary];
}
return self;
}
#pragma mark - Instance Methods
- (NSAttributedString *)usernameAttributedStringWithFontSize:(CGFloat)size
{
return [NSAttributedString attributedStringWithString:self.username
fontSize:size
color:[UIColor darkBlueColor]
firstWordColor:nil];
return [NSAttributedString attributedStringWithString:self.username fontSize:size color:[UIColor darkBlueColor] firstWordColor:nil];
}
- (NSAttributedString *)fullNameAttributedStringWithFontSize:(CGFloat)size
{
return [NSAttributedString attributedStringWithString:self.fullName
fontSize:size
color:[UIColor lightGrayColor]
firstWordColor:nil];
return [NSAttributedString attributedStringWithString:self.fullName fontSize:size color:[UIColor lightGrayColor] firstWordColor:nil];
}
- (void)fetchAvatarImageWithCompletionBlock:(void(^)(UserModel *, UIImage *))block
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [NSData dataWithContentsOfURL:_userPicURL];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
if (block) {
block(self, image);
}
});
});
}
@@ -75,20 +63,17 @@
{
if (_fullUserInfoFetchDone) {
NSAssert(!_fullUserInfoCompletionBlock, @"Should not have a waiting block at this point");
// complete user info fetch complete - excute completion block
if (block) {
block(self);
}
} else {
NSAssert(!_fullUserInfoCompletionBlock, @"Should not have a waiting block at this point");
// set completion block
_fullUserInfoCompletionBlock = block;
if (!_fullUserInfoFetchRequested) {
// if fetch not in progress, beging
[self fetchCompleteUserData];
}

View File

@@ -1,31 +0,0 @@
//
// UserRowView.h
// ASDKgram
//
// Created by Hannah Troisi on 3/13/16.
// Copyright © 2016 Hannah Troisi. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "UserModel.h"
#import "PhotoModel.h"
typedef NS_ENUM(NSInteger, UserRowViewType) {
UserRowViewTypeLikes,
UserRowViewTypeComments,
UserRowViewTypePhotoCell
};
@interface UserRowView : UIView
+ (CGFloat)heightForUserRowViewType:(UserRowViewType)type;
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE;
- (instancetype)initWithFrame:(CGRect)frame withPhotoFeedModelType:(UserRowViewType)type NS_DESIGNATED_INITIALIZER;
- (void)updateWithPhotoModel:(PhotoModel *)photo;
- (void)updateWithCommentModel:(CommentModel *)comment;
@end

View File

@@ -1,228 +0,0 @@
//
// UserRowView.m
// ASDKgram
//
// Created by Hannah Troisi on 3/13/16.
// Copyright © 2016 Hannah Troisi. All rights reserved.
//
#import "UserRowView.h"
#import "PINImageView+PINRemoteImage.h"
#import "PINButton+PINRemoteImage.h"
#import "Utilities.h"
#define LIKES_VIEW_HEIGHT 50
#define LIKES_IMAGE_HEIGHT 30
#define PHOTOCELL_VIEW_HEIGHT 50
#define PHOTOCELL_IMAGE_HEIGHT 30
#define HORIZONTAL_BUFFER 10
#define VERTICAL_BUFFER 5
#define FONT_SIZE 14
#define FOLLOW_BUTTON_CORNER_RADIUS 8
@implementation UserRowView
{
UserRowViewType _viewType;
PhotoModel *_photo;
CommentModel *_comment;
UIImageView *_userAvatarImageView;
UIButton *_followingStatusBtn;
UILabel *_userNameLabel;
UILabel *_detailLabel; // configurable to be location, comment, full name
UILabel *_photoTimeIntervalSincePostLabel;
}
#pragma mark - Class Methods
+ (CGFloat)heightForUserRowViewType:(UserRowViewType)type
{
if (type && UserRowViewTypeLikes) {
return LIKES_VIEW_HEIGHT;
} else {
return LIKES_IMAGE_HEIGHT;
}
}
#pragma mark - Lifecycle
- (instancetype)initWithFrame:(CGRect)frame withPhotoFeedModelType:(UserRowViewType)type
{
self = [super initWithFrame:frame];
if (self) {
_viewType = type;
_userAvatarImageView = [[UIImageView alloc] init];
[_userAvatarImageView setPin_updateWithProgress:YES];
_userNameLabel = [[UILabel alloc] init];
_detailLabel = [[UILabel alloc] init];
[self addSubview:_userAvatarImageView];
[self addSubview:_userNameLabel];
[self addSubview:_detailLabel];
if (type == UserRowViewTypeLikes) {
_followingStatusBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[self addSubview:_followingStatusBtn];
UIImage *followingImage = [UIImage followingButtonStretchableImageForCornerRadius:FOLLOW_BUTTON_CORNER_RADIUS following:YES];
UIImage *notFollowingImage = [UIImage followingButtonStretchableImageForCornerRadius:FOLLOW_BUTTON_CORNER_RADIUS following:NO];
[_followingStatusBtn setBackgroundImage:followingImage forState:UIControlStateSelected];
[_followingStatusBtn setBackgroundImage:notFollowingImage forState:UIControlStateNormal];
} else {
_photoTimeIntervalSincePostLabel = [[UILabel alloc] init];
[self addSubview:_photoTimeIntervalSincePostLabel];
}
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGSize boundsSize = self.bounds.size;
CGFloat viewHeight = (_viewType && UserRowViewTypeLikes) ? LIKES_VIEW_HEIGHT : PHOTOCELL_VIEW_HEIGHT;
CGFloat avatarHeight = (_viewType && UserRowViewTypeLikes) ? LIKES_IMAGE_HEIGHT : PHOTOCELL_IMAGE_HEIGHT;
CGRect rect = CGRectMake(HORIZONTAL_BUFFER, (viewHeight - avatarHeight) / 2.0, avatarHeight, avatarHeight);
_userAvatarImageView.frame = rect;
if (_viewType == UserRowViewTypeLikes) {
rect.size = _followingStatusBtn.bounds.size;
rect.origin.x = boundsSize.width - HORIZONTAL_BUFFER - rect.size.width;
rect.origin.y = (viewHeight - rect.size.height) / 2.0;
_followingStatusBtn.frame = rect;
} else {
rect.size = _photoTimeIntervalSincePostLabel.bounds.size;
rect.origin.x = boundsSize.width - HORIZONTAL_BUFFER - rect.size.width;
rect.origin.y = (viewHeight - rect.size.height) / 2.0;
_photoTimeIntervalSincePostLabel.frame = rect;
}
CGFloat availableWidth = CGRectGetMinX(rect) - HORIZONTAL_BUFFER;
rect.size = _userNameLabel.bounds.size;
rect.size.width = MIN(availableWidth, rect.size.width);
rect.origin.x = HORIZONTAL_BUFFER + avatarHeight + HORIZONTAL_BUFFER;
if (_detailLabel.attributedText) {
CGSize locationSize = _userNameLabel.bounds.size;
locationSize.width = MIN(availableWidth, locationSize.width);
rect.origin.y = (viewHeight - rect.size.height - locationSize.height) / 2.0;
_userNameLabel.frame = rect;
// FIXME: Name rects at least for this sub-condition
rect.origin.y += rect.size.height;
rect.size = locationSize;
_detailLabel.frame = rect;
} else {
rect.origin.y = (viewHeight - rect.size.height) / 2.0;
_userNameLabel.frame = rect;
}
}
- (void)updateWithPhotoModel:(PhotoModel *)photo
{
[self clearFields];
_photo = photo;
_userNameLabel.attributedText = [photo.ownerUserProfile usernameAttributedStringWithFontSize:FONT_SIZE];
[_userNameLabel sizeToFit];
// [self downloadAndProcessUserAvatarForPhoto:photo];
switch (_viewType) {
case UserRowViewTypeLikes:
_detailLabel.attributedText = [photo.ownerUserProfile fullNameAttributedStringWithFontSize:FONT_SIZE];
[_detailLabel sizeToFit];
_followingStatusBtn.selected = YES; // FIXME:
_followingStatusBtn.frame = CGRectMake(0, 0, 20, 30); // FIXME:
break;
case UserRowViewTypePhotoCell:
[self reverseGeocodeLocationForPhoto:photo];
_photoTimeIntervalSincePostLabel.attributedText = [photo uploadDateAttributedStringWithFontSize:FONT_SIZE];
[_photoTimeIntervalSincePostLabel sizeToFit];
break;
default:
break;
}
[self setNeedsLayout];
}
- (void)updateWithCommentModel:(CommentModel *)comment
{
[self clearFields];
_comment = comment;
_userNameLabel.attributedText = [[NSAttributedString alloc] initWithString:comment.commenterUsername]; // FIXME:
[_userNameLabel sizeToFit];
_detailLabel.attributedText = [comment commentAttributedString]; //FIXME: add userModel to commentModel? don't include user name!!!
[_detailLabel sizeToFit];
_photoTimeIntervalSincePostLabel.attributedText = [comment uploadDateAttributedStringWithFontSize:FONT_SIZE];
[_photoTimeIntervalSincePostLabel sizeToFit];
[self downloadAndProcessUserAvatarForURLString:comment.commenterAvatarURL];
[self setNeedsLayout];
}
#pragma mark - Helper Methods
- (void)downloadAndProcessUserAvatarForURLString:(NSString *)urlString
{
CGFloat avatarHeight = (_viewType == UserRowViewTypeLikes) ? LIKES_IMAGE_HEIGHT : PHOTOCELL_IMAGE_HEIGHT;
[_userAvatarImageView pin_setImageFromURL:[NSURL URLWithString:urlString] processorKey:@"custom" processor:^UIImage * _Nullable(PINRemoteImageManagerResult * _Nonnull result, NSUInteger * _Nonnull cost) {
CGSize profileImageSize = CGSizeMake(avatarHeight, avatarHeight);
return [result.image makeCircularImageWithSize:profileImageSize];
}];
}
- (void)reverseGeocodeLocationForPhoto:(PhotoModel *)photo
{
[photo.location reverseGeocodedLocationWithCompletionBlock:^(LocationModel *locationModel) {
// check and make sure this is still relevant for this cell (and not an old cell)
// make sure to use _photoModel instance variable as photo may change when cell is reused,
// where as local variable will never change
if (locationModel == _photo.location) {
_detailLabel.attributedText = [photo locationAttributedStringWithFontSize:FONT_SIZE];
[_detailLabel sizeToFit];
[self setNeedsLayout];
}
}];
}
- (void)clearFields
{
_photo = nil;
_comment = nil;
_userAvatarImageView.image = nil;
_userNameLabel.attributedText = nil;
_detailLabel.attributedText = nil;
_photoTimeIntervalSincePostLabel.attributedText = nil;
_followingStatusBtn.frame = CGRectZero;
_photoTimeIntervalSincePostLabel.frame = CGRectZero;
}
@end