|  |  | @ -8,15 +8,18 @@ import Foundation | 
			
		
	
		
		
			
				
					
					|  |  |  | public class ConversationMediaView: UIView { |  |  |  | public class ConversationMediaView: UIView { | 
			
		
	
		
		
			
				
					
					|  |  |  |     private let mediaCache: NSCache<NSString, AnyObject> |  |  |  |     private let mediaCache: NSCache<NSString, AnyObject> | 
			
		
	
		
		
			
				
					
					|  |  |  |     private let attachment: TSAttachment |  |  |  |     private let attachment: TSAttachment | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     private let isOutgoing: Bool | 
			
		
	
		
		
			
				
					
					|  |  |  |     private var loadBlock : (() -> Void)? |  |  |  |     private var loadBlock : (() -> Void)? | 
			
		
	
		
		
			
				
					
					|  |  |  |     private var unloadBlock : (() -> Void)? |  |  |  |     private var unloadBlock : (() -> Void)? | 
			
		
	
		
		
			
				
					
					|  |  |  |     private var didFailToLoad = false |  |  |  |     private var didFailToLoad = false | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     @objc |  |  |  |     @objc | 
			
		
	
		
		
			
				
					
					|  |  |  |     public required init(mediaCache: NSCache<NSString, AnyObject>, |  |  |  |     public required init(mediaCache: NSCache<NSString, AnyObject>, | 
			
		
	
		
		
			
				
					
					|  |  |  |                          attachment: TSAttachment) { |  |  |  |                          attachment: TSAttachment, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                          isOutgoing: Bool) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         self.mediaCache = mediaCache |  |  |  |         self.mediaCache = mediaCache | 
			
		
	
		
		
			
				
					
					|  |  |  |         self.attachment = attachment |  |  |  |         self.attachment = attachment | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         self.isOutgoing = isOutgoing | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         super.init(frame: .zero) |  |  |  |         super.init(frame: .zero) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -35,8 +38,6 @@ public class ConversationMediaView: UIView { | 
			
		
	
		
		
			
				
					
					|  |  |  |         AssertIsOnMainThread() |  |  |  |         AssertIsOnMainThread() | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         guard let attachmentStream = attachment as? TSAttachmentStream else { |  |  |  |         guard let attachmentStream = attachment as? TSAttachmentStream else { | 
			
		
	
		
		
			
				
					
					|  |  |  |             // TODO: Handle this case. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             owsFailDebug("Missing attachment stream.") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             return |  |  |  |             return | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         if attachmentStream.isAnimated { |  |  |  |         if attachmentStream.isAnimated { | 
			
		
	
	
		
		
			
				
					|  |  | @ -51,10 +52,21 @@ public class ConversationMediaView: UIView { | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     private func addMediaSubview(_ subview: UIView) { |  |  |  |     private func addAttachmentUploadViewIfNecessary(_ subview: UIView, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         addSubview(subview) |  |  |  |                                                     completion: @escaping (Bool) -> Void) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         subview.autoPinEdgesToSuperviewEdges() |  |  |  |         guard isOutgoing else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         // TODO: Possibly add upload/download indicator here. |  |  |  |             return | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         guard let attachmentStream = attachment as? TSAttachmentStream else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         guard !attachmentStream.isUploaded else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         let uploadView = AttachmentUploadView(attachment: attachmentStream) { (_) in | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         subview.addSubview(uploadView) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         uploadView.autoPinEdgesToSuperviewEdges() | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     private func configureForAnimatedImage(attachmentStream: TSAttachmentStream) { |  |  |  |     private func configureForAnimatedImage(attachmentStream: TSAttachmentStream) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -71,7 +83,10 @@ public class ConversationMediaView: UIView { | 
			
		
	
		
		
			
				
					
					|  |  |  |         animatedImageView.layer.minificationFilter = kCAFilterTrilinear |  |  |  |         animatedImageView.layer.minificationFilter = kCAFilterTrilinear | 
			
		
	
		
		
			
				
					
					|  |  |  |         animatedImageView.layer.magnificationFilter = kCAFilterTrilinear |  |  |  |         animatedImageView.layer.magnificationFilter = kCAFilterTrilinear | 
			
		
	
		
		
			
				
					
					|  |  |  |         animatedImageView.backgroundColor = Theme.offBackgroundColor |  |  |  |         animatedImageView.backgroundColor = Theme.offBackgroundColor | 
			
		
	
		
		
			
				
					
					|  |  |  |         addMediaSubview(animatedImageView) |  |  |  |         addSubview(animatedImageView) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         animatedImageView.autoPinEdgesToSuperviewEdges() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         addAttachmentUploadViewIfNecessary(animatedImageView) { (_) in | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         loadBlock = { [weak self] in |  |  |  |         loadBlock = { [weak self] in | 
			
		
	
		
		
			
				
					
					|  |  |  |             guard let strongSelf = self else { |  |  |  |             guard let strongSelf = self else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return |  |  |  |                 return | 
			
		
	
	
		
		
			
				
					|  |  | @ -117,7 +132,10 @@ public class ConversationMediaView: UIView { | 
			
		
	
		
		
			
				
					
					|  |  |  |         stillImageView.layer.minificationFilter = kCAFilterTrilinear |  |  |  |         stillImageView.layer.minificationFilter = kCAFilterTrilinear | 
			
		
	
		
		
			
				
					
					|  |  |  |         stillImageView.layer.magnificationFilter = kCAFilterTrilinear |  |  |  |         stillImageView.layer.magnificationFilter = kCAFilterTrilinear | 
			
		
	
		
		
			
				
					
					|  |  |  |         stillImageView.backgroundColor = Theme.offBackgroundColor |  |  |  |         stillImageView.backgroundColor = Theme.offBackgroundColor | 
			
		
	
		
		
			
				
					
					|  |  |  |         addMediaSubview(stillImageView) |  |  |  |         addSubview(stillImageView) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         stillImageView.autoPinEdgesToSuperviewEdges() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         addAttachmentUploadViewIfNecessary(stillImageView) { (_) in | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         loadBlock = { [weak self] in |  |  |  |         loadBlock = { [weak self] in | 
			
		
	
		
		
			
				
					
					|  |  |  |             guard let strongSelf = self else { |  |  |  |             guard let strongSelf = self else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return |  |  |  |                 return | 
			
		
	
	
		
		
			
				
					|  |  | @ -162,14 +180,18 @@ public class ConversationMediaView: UIView { | 
			
		
	
		
		
			
				
					
					|  |  |  |         stillImageView.layer.minificationFilter = kCAFilterTrilinear |  |  |  |         stillImageView.layer.minificationFilter = kCAFilterTrilinear | 
			
		
	
		
		
			
				
					
					|  |  |  |         stillImageView.layer.magnificationFilter = kCAFilterTrilinear |  |  |  |         stillImageView.layer.magnificationFilter = kCAFilterTrilinear | 
			
		
	
		
		
			
				
					
					|  |  |  |         stillImageView.backgroundColor = Theme.offBackgroundColor |  |  |  |         stillImageView.backgroundColor = Theme.offBackgroundColor | 
			
		
	
		
		
			
				
					
					|  |  |  |         addMediaSubview(stillImageView) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         // TODO: Hide during upload/download. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         let videoPlayIcon = UIImage(named: "play_button") |  |  |  |         let videoPlayIcon = UIImage(named: "play_button") | 
			
		
	
		
		
			
				
					
					|  |  |  |         let videoPlayButton = UIImageView(image: videoPlayIcon) |  |  |  |         let videoPlayButton = UIImageView(image: videoPlayIcon) | 
			
		
	
		
		
			
				
					
					|  |  |  |         stillImageView.addSubview(videoPlayButton) |  |  |  |         stillImageView.addSubview(videoPlayButton) | 
			
		
	
		
		
			
				
					
					|  |  |  |         videoPlayButton.autoCenterInSuperview() |  |  |  |         videoPlayButton.autoCenterInSuperview() | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         addSubview(stillImageView) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         stillImageView.autoPinEdgesToSuperviewEdges() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         addAttachmentUploadViewIfNecessary(stillImageView) { (isAttachmentReady) in | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             videoPlayButton.isHidden = !isAttachmentReady | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         loadBlock = { [weak self] in |  |  |  |         loadBlock = { [weak self] in | 
			
		
	
		
		
			
				
					
					|  |  |  |             guard let strongSelf = self else { |  |  |  |             guard let strongSelf = self else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return |  |  |  |                 return | 
			
		
	
	
		
		
			
				
					|  |  | 
 |