// // MessageCell.m // Juick // // Created by Vitaly Takmazov on 03/12/2017. // Copyright © 2017 com.juick. All rights reserved. // #import "MessageCell.h" #import "APIClient.h" #import "Entity.h" #import "NSDate+TimeAgo.h" @interface MessageCell() @property(nonatomic, readonly) NSMutableParagraphStyle *quoteStyle; @property(nonatomic, readonly) UIFont *boldFont; @property(nonatomic, readonly) UIFont *italicFont; @end @implementation MessageCell const NSString *unreadMarker = @"●"; - (void)awakeFromNib { [super awakeFromNib]; self.text.dataDetectorTypes = UIDataDetectorTypeAll; self.text.tintColor = [UIColor colorNamed:@"Title"]; self.title.textColor = [UIColor colorNamed:@"Title"]; self.timestamp.textColor = [UIColor colorNamed:@"Muted"]; self.summary.textColor = [UIColor colorNamed:@"Muted"]; UIGestureRecognizer *avatarTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(avatarClicked:)]; [avatarTapRecognizer setEnabled:YES]; [self.avatar addGestureRecognizer:avatarTapRecognizer]; [self.avatar setUserInteractionEnabled:YES]; _quoteStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; _quoteStyle.firstLineHeadIndent = 12.0f; _quoteStyle.headIndent = 12.0f; _quoteStyle.paragraphSpacing = 6.0f; UIFontDescriptor* fontDescriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleBody]; UIFontDescriptor* boldFontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold]; _boldFont = [UIFont fontWithDescriptor:boldFontDescriptor size: 0.0]; UIFontDescriptor* italicFontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitItalic]; _italicFont = [UIFont fontWithDescriptor:italicFontDescriptor size: 0.0]; } - (void) configureWithMessage:(Message *)msg { self.avatar.image = nil; __weak UIImageView *weakAvatar = self.avatar; [[APIClient sharedClient] fetchImageWithURL:[NSURL URLWithString:msg.user.avatar] callback:^(NSData *data) { [UIView transitionWithView:weakAvatar duration:0.3 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ weakAvatar.image = [UIImage imageWithData:data]; } completion:nil]; }]; if ([msg.attach length] > 0) { CGFloat imageHeight = [msg.attachment.small.height floatValue] / [[UIScreen mainScreen] scale]; CGFloat imageWidth = [msg.attachment.small.width floatValue] / [[UIScreen mainScreen] scale]; self.attach.image = [UIImage placeholderImageWithColor:[UIColor colorNamed:@"Muted"] size:CGSizeMake(imageWidth, imageHeight)]; self.attachmentHeight.constant = imageHeight; self.attachmentWidth.constant = imageWidth; __weak UIImageView *weakAttach = self.attach; [[APIClient sharedClient] fetchImageWithURL:[NSURL URLWithString:msg.attachment.small.url] callback:^(NSData *data) { [UIView transitionWithView:weakAttach duration:0.3 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ weakAttach.image = [UIImage imageWithData:data]; } completion:nil]; }]; } else { self.attachmentHeight.constant = 0; self.attach.image = nil; } self.title.text = msg.user.uname; self.timestamp.text = [[[APIClient sharedClient].dateFormatter dateFromString:msg.timestamp] timeAgo]; NSUInteger count = [msg.repliesCount unsignedIntegerValue]; if (count > 0) { if ([msg.repliesBy length] > 0) { self.summary.text = [NSString stringWithFormat:@"%@ replies by %@", msg.repliesCount, msg.repliesBy]; } else { self.summary.text = [NSString stringWithFormat:@"%@ replies", msg.repliesCount]; } } else { self.summary.text = nil; } if (msg.unread) { self.summary.text = [NSString stringWithFormat:@"%@ %@", unreadMarker, self.summary.text]; self.summary.textColor = [UIColor colorNamed:@"Funny"]; } else { self.summary.textColor = [UIColor colorNamed:@"Muted"]; } self.text.attributedText = nil; if (msg.text) { [self.text setHidden:NO]; NSMutableAttributedString *txt = [[NSMutableAttributedString alloc] initWithString:msg.text attributes:@{NSFontAttributeName:[UIFont preferredFontForTextStyle:UIFontTextStyleBody], NSForegroundColorAttributeName:[UIColor colorNamed:@"Text"] }]; [txt beginEditing]; for (Entity *entity in msg.entities) { NSUInteger start = entity.start ? [entity.start unsignedIntegerValue] : 0; NSUInteger end = entity.end ? [entity.end unsignedIntegerValue] : 0; NSString *text = entity.text ? entity.text : @""; NSRange currentRange = NSMakeRange(start, end - start); [txt addAttribute:@"displayText" value:text range:currentRange]; if ([entity.type isEqualToString:@"a"]) { [txt addAttribute:NSLinkAttributeName value:entity.link range:currentRange]; } if ([entity.type isEqualToString:@"q"]) { [txt addAttribute:NSForegroundColorAttributeName value:[UIColor colorNamed:@"Muted"] range:currentRange]; [txt addAttribute:NSParagraphStyleAttributeName value:_quoteStyle range:currentRange]; } if ([entity.type isEqualToString:@"u"]) { [txt addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:currentRange]; } if ([entity.type isEqualToString:@"b"]) { [txt addAttribute:NSFontAttributeName value:_boldFont range:currentRange]; } if ([entity.type isEqualToString:@"i"]) { [txt addAttribute:NSFontAttributeName value:_italicFont range:currentRange]; } } [txt enumerateAttribute:@"displayText" inRange:NSMakeRange(0, [txt length]) options:0 usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) { if (value) { [txt replaceCharactersInRange:range withString:value]; } }]; if ([msg.tags count] > 0) { NSString *tagsList = [NSString stringWithFormat:@"%@\n", [msg.tags componentsJoinedByString:@", "]]; [txt insertAttributedString:[[NSAttributedString alloc] initWithString:tagsList attributes:@{ NSFontAttributeName:_italicFont, NSForegroundColorAttributeName:[UIColor colorNamed:@"Muted"] }] atIndex:0]; } [txt endEditing]; self.text.attributedText = txt; } else { [self.text setHidden:YES]; } } -(void) avatarClicked:(UIGestureRecognizer *)gestureRecognizer { [self.delegate avatarClicked:self.title.text]; } @end