// // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // import UIKit import SessionUIKit public enum PhotoGridItemType { case photo, animated, video } public protocol PhotoGridItem: AnyObject { var type: PhotoGridItemType { get } func asyncThumbnail(completion: @escaping (UIImage?) -> Void) } public class PhotoGridViewCell: UICollectionViewCell { public let imageView: UIImageView private let contentTypeBadgeView: UIImageView private let selectedBadgeView: UIImageView private let highlightedView: UIView private let selectedView: UIView var item: PhotoGridItem? private static let videoBadgeImage = #imageLiteral(resourceName: "ic_gallery_badge_video") private static let animatedBadgeImage = #imageLiteral(resourceName: "ic_gallery_badge_gif") private static let selectedBadgeImage = UIImage(systemName: "checkmark.circle.fill") public var loadingColor: ThemeValue = .textSecondary override public var isSelected: Bool { didSet { self.selectedBadgeView.isHidden = !self.isSelected self.selectedView.isHidden = !self.isSelected } } override public var isHighlighted: Bool { didSet { self.highlightedView.isHidden = !self.isHighlighted } } override init(frame: CGRect) { self.imageView = UIImageView() imageView.contentMode = .scaleAspectFill self.contentTypeBadgeView = UIImageView() contentTypeBadgeView.isHidden = true let kSelectedBadgeSize = CGSize(width: 32, height: 32) self.selectedBadgeView = UIImageView() selectedBadgeView.image = PhotoGridViewCell.selectedBadgeImage?.withRenderingMode(.alwaysTemplate) selectedBadgeView.themeTintColor = .primary selectedBadgeView.themeBorderColor = .textPrimary selectedBadgeView.themeBackgroundColor = .textPrimary selectedBadgeView.isHidden = true selectedBadgeView.layer.cornerRadius = (kSelectedBadgeSize.width / 2) self.highlightedView = UIView() highlightedView.alpha = 0.2 highlightedView.themeBackgroundColor = .black highlightedView.isHidden = true self.selectedView = UIView() selectedView.alpha = 0.3 selectedView.themeBackgroundColor = .black selectedView.isHidden = true super.init(frame: frame) self.clipsToBounds = true self.contentView.addSubview(imageView) self.contentView.addSubview(contentTypeBadgeView) self.contentView.addSubview(highlightedView) self.contentView.addSubview(selectedView) self.contentView.addSubview(selectedBadgeView) imageView.autoPinEdgesToSuperviewEdges() highlightedView.autoPinEdgesToSuperviewEdges() selectedView.autoPinEdgesToSuperviewEdges() // Note assets were rendered to match exactly. We don't want to re-size with // content mode lest they become less legible. let kContentTypeBadgeSize = CGSize(width: 18, height: 12) contentTypeBadgeView.autoPinEdge(toSuperviewEdge: .leading, withInset: 3) contentTypeBadgeView.autoPinEdge(toSuperviewEdge: .bottom, withInset: 3) contentTypeBadgeView.autoSetDimensions(to: kContentTypeBadgeSize) selectedBadgeView.autoPinEdge(toSuperviewEdge: .trailing, withInset: Values.verySmallSpacing) selectedBadgeView.autoPinEdge(toSuperviewEdge: .bottom, withInset: Values.verySmallSpacing) selectedBadgeView.autoSetDimensions(to: kSelectedBadgeSize) } @available(*, unavailable, message: "Unimplemented") required public init?(coder aDecoder: NSCoder) { notImplemented() } var image: UIImage? { get { return imageView.image } set { imageView.image = newValue imageView.themeBackgroundColor = (newValue == nil ? loadingColor : .clear) } } var contentTypeBadgeImage: UIImage? { get { return contentTypeBadgeView.image } set { contentTypeBadgeView.image = newValue contentTypeBadgeView.isHidden = newValue == nil } } public func configure(item: PhotoGridItem) { self.item = item item.asyncThumbnail { [weak self] image in guard let currentItem = self?.item else { return } guard currentItem === item else { return } if image == nil { Logger.debug("image == nil") } DispatchQueue.main.async { self?.image = image } } switch item.type { case .video: self.contentTypeBadgeImage = PhotoGridViewCell.videoBadgeImage case .animated: self.contentTypeBadgeImage = PhotoGridViewCell.animatedBadgeImage case .photo: self.contentTypeBadgeImage = nil } } override public func prepareForReuse() { super.prepareForReuse() self.item = nil self.imageView.image = nil self.contentTypeBadgeView.isHidden = true self.highlightedView.isHidden = true self.selectedView.isHidden = true self.selectedBadgeView.isHidden = true } }