session-ios/Session/Media Viewing & Editing/PhotoGridViewCell.swift

156 lines
5.1 KiB
Swift

//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import UIKit
import SessionUIKit
import SignalCoreKit
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
}
}