// // NCGridCell.swift // Nextcloud // // Created by Marino Faggiana on 08/10/2018. // Copyright © 2018 Marino Faggiana. All rights reserved. // // Author Marino Faggiana // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // import UIKit class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProtocol, NCTrashCellProtocol { @IBOutlet weak var imageItem: UIImageView! @IBOutlet weak var imageSelect: UIImageView! @IBOutlet weak var imageStatus: UIImageView! @IBOutlet weak var imageFavorite: UIImageView! @IBOutlet weak var imageLocal: UIImageView! @IBOutlet weak var labelTitle: UILabel! @IBOutlet weak var labelInfo: UILabel! @IBOutlet weak var buttonMore: UIButton! @IBOutlet weak var imageVisualEffect: UIVisualEffectView! @IBOutlet weak var progressView: UIProgressView! var objectId = "" var indexPath = IndexPath() private var user = "" weak var delegate: NCGridCellDelegate? var namedButtonMore = "" var fileObjectId: String? { get { return objectId } set { objectId = newValue ?? "" } } var filePreviewImageView: UIImageView? { get { return imageItem } set { imageItem = newValue } } var fileUser: String? { get { return user } set { user = newValue ?? "" } } var fileTitleLabel: UILabel? { get { return labelTitle } set { labelTitle = newValue } } var fileInfoLabel: UILabel? { get { return labelInfo } set { labelInfo = newValue } } var fileProgressView: UIProgressView? { get { return progressView } set { progressView = newValue } } var fileSelectImage: UIImageView? { get { return imageSelect } set { imageSelect = newValue } } var fileStatusImage: UIImageView? { get { return imageStatus } set { imageStatus = newValue } } var fileLocalImage: UIImageView? { get { return imageLocal } set { imageLocal = newValue } } var fileFavoriteImage: UIImageView? { get { return imageFavorite } set { imageFavorite = newValue } } override func awakeFromNib() { super.awakeFromNib() // use entire cell as accessibility element accessibilityHint = nil accessibilityLabel = nil accessibilityValue = nil isAccessibilityElement = true imageItem.layer.cornerRadius = 6 imageItem.layer.masksToBounds = true imageVisualEffect.layer.cornerRadius = 6 imageVisualEffect.clipsToBounds = true imageVisualEffect.alpha = 0.5 progressView.tintColor = NCBrandColor.shared.brand progressView.transform = CGAffineTransform(scaleX: 1.0, y: 0.5) progressView.trackTintColor = .clear let longPressedGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPress(gestureRecognizer:))) longPressedGesture.minimumPressDuration = 0.5 longPressedGesture.delegate = self longPressedGesture.delaysTouchesBegan = true self.addGestureRecognizer(longPressedGesture) let longPressedGestureMore = UILongPressGestureRecognizer(target: self, action: #selector(longPressInsideMore(gestureRecognizer:))) longPressedGestureMore.minimumPressDuration = 0.5 longPressedGestureMore.delegate = self longPressedGestureMore.delaysTouchesBegan = true buttonMore.addGestureRecognizer(longPressedGestureMore) labelTitle.text = "" labelInfo.text = "" labelTitle.textColor = .label labelInfo.textColor = .systemGray } override func prepareForReuse() { super.prepareForReuse() imageItem.backgroundColor = nil accessibilityHint = nil accessibilityLabel = nil accessibilityValue = nil } override func snapshotView(afterScreenUpdates afterUpdates: Bool) -> UIView? { return nil } @IBAction func touchUpInsideMore(_ sender: Any) { delegate?.tapMoreGridItem(with: objectId, namedButtonMore: namedButtonMore, image: imageItem.image, indexPath: indexPath, sender: sender) } @objc func longPressInsideMore(gestureRecognizer: UILongPressGestureRecognizer) { delegate?.longPressMoreGridItem(with: objectId, namedButtonMore: namedButtonMore, indexPath: indexPath, gestureRecognizer: gestureRecognizer) } @objc func longPress(gestureRecognizer: UILongPressGestureRecognizer) { delegate?.longPressGridItem(with: objectId, indexPath: indexPath, gestureRecognizer: gestureRecognizer) } fileprivate func setA11yActions() { let moreName = namedButtonMore == NCGlobal.shared.buttonMoreStop ? "_cancel_" : "_more_" self.accessibilityCustomActions = [ UIAccessibilityCustomAction( name: NSLocalizedString(moreName, comment: ""), target: self, selector: #selector(touchUpInsideMore)) ] } func setButtonMore(named: String, image: UIImage) { namedButtonMore = named buttonMore.setImage(image, for: .normal) setA11yActions() } func hideButtonMore(_ status: Bool) { buttonMore.isHidden = status } func selectMode(_ status: Bool) { if status { imageSelect.isHidden = false buttonMore.isHidden = true accessibilityCustomActions = nil } else { imageSelect.isHidden = true imageVisualEffect.isHidden = true buttonMore.isHidden = false setA11yActions() } } func selected(_ status: Bool) { guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(objectId), !metadata.isInTransfer else { imageSelect.isHidden = true imageVisualEffect.isHidden = true return } if status { if traitCollection.userInterfaceStyle == .dark { imageVisualEffect.effect = UIBlurEffect(style: .dark) imageVisualEffect.backgroundColor = .black } else { imageVisualEffect.effect = UIBlurEffect(style: .extraLight) imageVisualEffect.backgroundColor = .lightGray } imageSelect.image = NCBrandColor.cacheImages.checkedYes imageVisualEffect.isHidden = false } else { imageSelect.isHidden = true imageVisualEffect.isHidden = true } } func writeInfoDateSize(date: NSDate, size: Int64) { let dateFormatter = DateFormatter() dateFormatter.dateStyle = .short dateFormatter.timeStyle = .none dateFormatter.locale = Locale.current labelInfo.text = dateFormatter.string(from: date as Date) + " · " + CCUtility.transformedSize(size) } func setAccessibility(label: String, value: String) { accessibilityLabel = label accessibilityValue = value } } protocol NCGridCellDelegate: AnyObject { func tapMoreGridItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any) func longPressMoreGridItem(with objectId: String, namedButtonMore: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) func longPressGridItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) } // optional func extension NCGridCellDelegate { func tapMoreGridItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any) {} func longPressMoreGridItem(with objectId: String, namedButtonMore: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {} func longPressGridItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {} } // MARK: - Grid Layout class NCGridLayout: UICollectionViewFlowLayout { var heightLabelPlusButton: CGFloat = 60 var marginLeftRight: CGFloat = 10 var itemForLine: CGFloat = 3 var itemWidthDefault: CGFloat = 140 // MARK: - View Life Cycle override init() { super.init() sectionHeadersPinToVisibleBounds = false minimumInteritemSpacing = 1 minimumLineSpacing = marginLeftRight self.scrollDirection = .vertical self.sectionInset = UIEdgeInsets(top: 10, left: marginLeftRight, bottom: 0, right: marginLeftRight) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override var itemSize: CGSize { get { if let collectionView = collectionView { if collectionView.frame.width < 400 { itemForLine = 3 } else { itemForLine = collectionView.frame.width / itemWidthDefault } let itemWidth: CGFloat = (collectionView.frame.width - marginLeftRight * 2 - marginLeftRight * (itemForLine - 1)) / itemForLine let itemHeight: CGFloat = itemWidth + heightLabelPlusButton return CGSize(width: itemWidth, height: itemHeight) } // Default fallback return CGSize(width: itemWidthDefault, height: itemWidthDefault) } set { super.itemSize = newValue } } override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint { return proposedContentOffset } }