OpenedTabsCollectionViewCell.swift 4.58 KB
//
//  OpenedTabsCellDelegate.swift
//  browser
//
//  Created by Artem Talko on 28.09.2023.
//
//MARK: Checked

import UIKit
import SnapKit

protocol OpenedTabsCellDelegate: AnyObject {
    func deleteTabDelegateFunc(cell: OpenedTabsCollectionViewCell)
}

final class OpenedTabsCollectionViewCell: UICollectionViewCell {
    static let cellID = String(describing: OpenedTabsCollectionViewCell.self)
    
    var model: BrowserTabDataBase? {
        didSet {
            handleUI()
        }
    }

    weak var delegate: OpenedTabsCellDelegate?

    private let siteNameLabel: UILabel = {
        let obj = UILabel()
        obj.font = FontConstants.regularFont_14
        return obj
    }()

    private let sitePreviewImageContainer: UIView = {
        let obj = UIView()
        obj.clipsToBounds = true
        obj.layer.cornerRadius = 10
        return obj
    }()

    private let sitePreviewImage: UIImageView = {
        let obj = UIImageView()
        obj.contentMode = .scaleAspectFill
        return obj
    }()

    let closeTabButton: UIButton = {
        let obj = UIButton()
        obj.setImage(UIImage(systemName: "xmark"), for: .normal)
        obj.contentMode = .scaleAspectFill
        obj.tintColor = .gray
        return obj
    }()
    
    private var panGestureRecognizer: UIPanGestureRecognizer!

    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setup()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setup() {
        self.backgroundColor = .white
        layer.cornerRadius = 10
        contentView.addSubview(siteNameLabel)
        contentView.addSubview(closeTabButton)
        contentView.addSubview(sitePreviewImageContainer)
        
        sitePreviewImageContainer.addSubview(sitePreviewImage)
        
        shadowSetup()
        setupConstraints()
        addingTargets()
        setupPanGesture()
    }

    private func setupConstraints() {
        closeTabButton.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(8)
            make.trailing.equalToSuperview().offset(-8)
            make.height.equalTo(14)
            make.width.equalTo(14)
        }

        siteNameLabel.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(8)
            make.leading.equalToSuperview().offset(16)
            make.trailing.equalTo(closeTabButton.snp.leading).offset(-2)
        }

        sitePreviewImageContainer.snp.makeConstraints { make in
            make.top.equalTo(closeTabButton.snp.bottom).offset(8)
            make.leading.trailing.equalToSuperview().inset(8)
            make.bottom.equalToSuperview().offset(-8)
        }

        sitePreviewImage.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        
        shadowSetup()
    }
}



//MARK: Helpers
extension OpenedTabsCollectionViewCell {
    private func setupPanGesture() {
        panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
        addGestureRecognizer(panGestureRecognizer)
    }
    
    private func shadowSetup() {
        layer.shadowColor = UIColor.black.withAlphaComponent(0.1).cgColor
        layer.shadowOpacity = 1
        layer.shadowRadius = 30
        layer.shadowOffset = CGSize(width: 0, height: 0)
    }
    
    private func addingTargets() {
        closeTabButton.addTarget(self, action: #selector(deleteTab), for: .touchUpInside)
    }
}


//MARK: Handlers
extension OpenedTabsCollectionViewCell {
    private func handleUI() {
        siteNameLabel.text = model?.tabTitle
        sitePreviewImage.image = model?.snapshotImageData?.toImage()
    }
}


//MARK: Actions
extension OpenedTabsCollectionViewCell {
    @objc
    private func deleteTab() {
        delegate?.deleteTabDelegateFunc(cell: self)
        
        if let tabId = model?.tabId {
            TabManager.shared.deleteTab(tabId: tabId)
        }
    }

    @objc
    private func handlePan(_ gesture: UIPanGestureRecognizer) {
        let translation = gesture.translation(in: self)
        let width = self.frame.width
        let threshold = width / 2
        
        if gesture.state == .changed {
            transform = CGAffineTransform(translationX: translation.x, y: 0)
        } else if gesture.state == .ended {
            if abs(translation.x) >= threshold {
                deleteTab()
            } else {
                UIView.animate(withDuration: 0.3) {
                    self.transform = .identity
                }
            }
        }
    }
}