// // MLChatImageCell.m // Monal // // Created by Anurodh Pokharel on 12/24/17. // Copyright © 2017 Monal.im. All rights reserved. // #import "FLAnimatedImage.h" #import "MLChatImageCell.h" #import "MLImageManager.h" #import "MLFiletransfer.h" #import "MLMessage.h" #import "HelperTools.h" @import QuartzCore; @import UIKit; @interface MLChatImageCell() { FLAnimatedImageView* _animatedImageView; } @property (nonatomic, weak) IBOutlet UIImageView* thumbnailImage; @property (nonatomic, weak) IBOutlet UIActivityIndicatorView* spinner; @property (nonatomic, weak) IBOutlet NSLayoutConstraint* imageWidth; @property (nonatomic, weak) IBOutlet NSLayoutConstraint* imageHeight; @end @implementation MLChatImageCell -(void) awakeFromNib { [super awakeFromNib]; // Initialization code self.thumbnailImage.layer.cornerRadius = 15.0f; self.thumbnailImage.layer.masksToBounds = YES; } // init a image cell if needed -(void) initCellWithMLMessage:(MLMessage*) message { if(_animatedImageView != nil) [_animatedImageView removeFromSuperview]; // reset image view if we open a new message if(self.messageHistoryId != message.messageDBId) self.thumbnailImage.image = nil; // init base cell [super initCell:message]; // load image and display it in the UI if needed [self loadImage:message]; } /// Load the image from messageText (link) and display it in the UI -(void) loadImage:(MLMessage*) msg { if(_animatedImageView != nil) [_animatedImageView removeFromSuperview]; if(msg.messageText && self.thumbnailImage.image == nil) { [self.spinner startAnimating]; NSDictionary* info = [MLFiletransfer getFileInfoForMessage:msg]; if(info && [info[@"mimeType"] hasPrefix:@"image/gif"]) { self.link = msg.messageText; // uses cached file if the file was already downloaded FLAnimatedImage* image = [FLAnimatedImage animatedImageWithGIFData:[NSData dataWithContentsOfFile:info[@"cacheFile"]]]; if(!image) return; _animatedImageView = [FLAnimatedImageView new]; DDLogVerbose(@"image %@\n--> %fx%f", info, image.size.height, image.size.width); CGFloat wi = image.size.width; CGFloat hi = image.size.height; CGFloat ws = 225.0; CGFloat hs = 200.0; CGFloat ri = wi / hi; CGFloat rs = ws / hs; if(rs > ri) _animatedImageView.frame = CGRectMake(0.0, 0.0, wi * hs/hi, hs); else _animatedImageView.frame = CGRectMake(0.0, 0.0, ws, hi * ws/wi); self.imageWidth.constant = _animatedImageView.frame.size.width; self.imageHeight.constant = _animatedImageView.frame.size.height; _animatedImageView.animatedImage = image; [self.thumbnailImage addSubview:_animatedImageView]; self.thumbnailImage.contentMode = UIViewContentModeScaleAspectFit; } else if(info && [info[@"mimeType"] hasPrefix:@"image/"]) { self.link = msg.messageText; AnyPromise* imagePromise = nil; // this code already runs in the main queue --> we can't use PMKHang if([info[@"mimeType"] hasPrefix:@"image/svg"]) imagePromise = [HelperTools renderUIImageFromSVGURL:[NSURL fileURLWithPath:info[@"cacheFile"]]]; else imagePromise = [AnyPromise promiseWithValue:[[UIImage alloc] initWithContentsOfFile:info[@"cacheFile"]]]; imagePromise.then(^(UIImage* image) { if(!nilExtractor(image)) return; DDLogVerbose(@"image %@\n--> %fx%f", info, image.size.height, image.size.width); CGFloat wi = image.size.width; CGFloat hi = image.size.height; CGFloat ws = 225.0; CGFloat hs = 200.0; CGFloat ri = wi / hi; CGFloat rs = ws / hs; if(rs > ri) self.thumbnailImage.frame = CGRectMake(0.0, 0.0, wi * hs/hi, hs); else self.thumbnailImage.frame = CGRectMake(0.0, 0.0, ws, hi * ws/wi); self.imageWidth.constant = self.thumbnailImage.frame.size.width; self.imageHeight.constant = self.thumbnailImage.frame.size.height; [self.thumbnailImage setImage:image]; }).catch(^(NSError* error) { DDLogWarn(@"Image promise returned an error: %@", error); }); } else unreachable(); [self.spinner stopAnimating]; } } -(UIImage*) getDisplayedImage { return self.thumbnailImage.image; } -(void) setSelected:(BOOL) selected animated:(BOOL) animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } -(BOOL) canPerformAction:(SEL) action withSender:(id) sender { return (action == @selector(copy:)); } -(void) copy:(id) sender { UIPasteboard* pboard = [UIPasteboard generalPasteboard]; pboard.image = [self getDisplayedImage]; } -(void) prepareForReuse { [super prepareForReuse]; self.imageHeight.constant = 200; [self.spinner stopAnimating]; if(_animatedImageView != nil) [_animatedImageView removeFromSuperview]; } @end