Files
suixinkan_uikit/suixinkan/UI/CloudDrive/CloudDriveFileCell.swift

223 lines
8.7 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// CloudDriveFileCell.swift
// suixinkan
//
import Kingfisher
import SnapKit
import UIKit
/// Cell Android
final class CloudDriveFileCell: UICollectionViewCell {
static let reuseIdentifier = "CloudDriveFileCell"
///
var onDetails: (() -> Void)?
private let thumbnailView = UIImageView()
private let folderIconView = UIImageView(
image: CloudDriveAsset.image(named: "icon_cloud_storage_folder_type", fallbackSystemName: "folder.fill")
)
private let playIconView = UIImageView(
image: CloudDriveAsset.image(named: "icon_cloud_storage_file_play", fallbackSystemName: "play.circle.fill")
)
private let extensionLabel = CloudDrivePaddingLabel()
private let nameLabel = UILabel()
private let detailLabel = UILabel()
private let moreButton = UIButton(type: .system)
private var gridConstraints: [Constraint] = []
private var listConstraints: [Constraint] = []
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
setupConstraints()
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func prepareForReuse() {
super.prepareForReuse()
thumbnailView.kf.cancelDownloadTask()
thumbnailView.image = nil
folderIconView.isHidden = true
playIconView.isHidden = true
extensionLabel.isHidden = true
onDetails = nil
}
///
func apply(file: CloudFile, mode: CloudDriveDisplayMode) {
let isGrid = mode == .grid
gridConstraints.forEach { isGrid ? $0.activate() : $0.deactivate() }
listConstraints.forEach { isGrid ? $0.deactivate() : $0.activate() }
nameLabel.text = file.name
nameLabel.font = .systemFont(ofSize: 15, weight: isGrid ? .semibold : .regular)
nameLabel.lineBreakMode = isGrid ? .byTruncatingTail : .byTruncatingMiddle
detailLabel.text = isGrid ? CloudDriveFormatter.typeName(file.type) : CloudDriveFormatter.fileDescription(file)
detailLabel.textColor = isGrid ? UIColor(hex: 0x4B5563) : UIColor(hex: 0x7B8EAA)
contentView.layer.cornerRadius = isGrid ? 12 : 0
contentView.layer.borderWidth = isGrid ? 1 : 0
contentView.backgroundColor = isGrid ? .white : .clear
thumbnailView.layer.cornerRadius = isGrid ? 12 : 0
thumbnailView.clipsToBounds = isGrid
configureThumbnail(file, mode: mode)
}
private func setupUI() {
backgroundColor = .clear
contentView.clipsToBounds = true
contentView.layer.borderColor = UIColor(hex: 0xF4F4F4).cgColor
thumbnailView.contentMode = .scaleAspectFill
thumbnailView.clipsToBounds = true
folderIconView.contentMode = .scaleAspectFit
folderIconView.isHidden = true
playIconView.contentMode = .scaleAspectFit
playIconView.isHidden = true
extensionLabel.font = .systemFont(ofSize: 12, weight: .bold)
extensionLabel.textColor = .white
extensionLabel.backgroundColor = UIColor.black.withAlphaComponent(0.5)
extensionLabel.layer.cornerRadius = 4
extensionLabel.clipsToBounds = true
extensionLabel.isHidden = true
nameLabel.textColor = UIColor(hex: 0x333333)
nameLabel.numberOfLines = 1
detailLabel.font = .systemFont(ofSize: 12)
detailLabel.numberOfLines = 1
let detailsImage = CloudDriveAsset.resizedImage(
named: "icon_cloud_storage_file_item_details",
fallbackSystemName: "ellipsis",
size: CGSize(width: 16, height: 16)
)
moreButton.setImage(detailsImage, for: .normal)
moreButton.imageView?.contentMode = .scaleAspectFit
moreButton.addTarget(self, action: #selector(moreTapped), for: .touchUpInside)
moreButton.accessibilityLabel = "文件操作"
[thumbnailView, folderIconView, playIconView, extensionLabel, nameLabel, detailLabel, moreButton]
.forEach(contentView.addSubview)
}
private func setupConstraints() {
thumbnailView.snp.makeConstraints { make in
gridConstraints.append(make.top.leading.trailing.equalToSuperview().constraint)
gridConstraints.append(make.height.equalTo(thumbnailView.snp.width).dividedBy(1.77).constraint)
listConstraints.append(make.leading.centerY.equalToSuperview().constraint)
listConstraints.append(make.width.height.equalTo(48).constraint)
}
folderIconView.snp.makeConstraints { make in
make.center.equalTo(thumbnailView)
make.width.height.equalTo(48)
}
playIconView.snp.makeConstraints { make in
make.center.equalTo(thumbnailView)
make.width.height.equalTo(24)
}
extensionLabel.snp.makeConstraints { make in
make.top.leading.equalTo(thumbnailView).offset(8)
}
nameLabel.snp.makeConstraints { make in
gridConstraints.append(make.top.equalTo(thumbnailView.snp.bottom).offset(8).constraint)
gridConstraints.append(make.leading.equalToSuperview().offset(12).constraint)
listConstraints.append(make.top.equalToSuperview().offset(12).constraint)
listConstraints.append(make.leading.equalTo(thumbnailView.snp.trailing).offset(12).constraint)
make.trailing.equalTo(moreButton.snp.leading).offset(-4)
}
detailLabel.snp.makeConstraints { make in
make.top.equalTo(nameLabel.snp.bottom).offset(2)
make.leading.trailing.equalTo(nameLabel)
}
moreButton.snp.makeConstraints { make in
gridConstraints.append(make.trailing.equalToSuperview().inset(10).constraint)
listConstraints.append(make.trailing.equalToSuperview().constraint)
make.centerY.equalTo(nameLabel.snp.bottom).offset(4)
make.width.height.equalTo(28)
}
listConstraints.forEach { $0.deactivate() }
}
private func configureThumbnail(_ file: CloudFile, mode: CloudDriveDisplayMode) {
thumbnailView.kf.cancelDownloadTask()
folderIconView.isHidden = true
playIconView.isHidden = true
extensionLabel.isHidden = true
if mode == .list {
thumbnailView.backgroundColor = .clear
thumbnailView.contentMode = .scaleAspectFit
let assetName: String
let fallbackName: String
if file.isFolder {
assetName = "icon_cloud_storage_file_type_folder"
fallbackName = "folder.fill"
} else if file.isVideo {
assetName = "icon_cloud_storage_file_type_video"
fallbackName = "video.fill"
} else {
assetName = "icon_cloud_storage_file_type_photo"
fallbackName = "photo.fill"
}
thumbnailView.image = CloudDriveAsset.image(named: assetName, fallbackSystemName: fallbackName)
return
}
thumbnailView.contentMode = .scaleAspectFill
if file.isFolder {
thumbnailView.image = nil
thumbnailView.backgroundColor = UIColor(hex: 0xFFF0E2)
folderIconView.isHidden = false
return
}
thumbnailView.backgroundColor = UIColor(hex: 0xF4F4F4)
let previewURL = file.isVideo ? file.coverUrl : file.fileUrl
let placeholder = CloudDriveAsset.image(
named: file.isVideo ? "icon_cloud_storage_file_type_video" : "icon_cloud_storage_file_type_photo",
fallbackSystemName: file.isVideo ? "video" : "photo"
)
if let url = URL(string: previewURL), !previewURL.isEmpty {
thumbnailView.kf.setImage(with: url, placeholder: placeholder)
} else {
thumbnailView.image = placeholder
}
playIconView.isHidden = !file.isVideo
extensionLabel.text = CloudDriveFormatter.fileExtension(file.fileUrl.isEmpty ? file.name : file.fileUrl)
extensionLabel.isHidden = extensionLabel.text?.isEmpty ?? true
}
@objc private func moreTapped() {
onDetails?()
}
}
/// Android
private final class CloudDrivePaddingLabel: UILabel {
private let insets = UIEdgeInsets(top: 4, left: 4, bottom: 4, right: 4)
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: insets))
}
override var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize
return CGSize(
width: size.width + insets.left + insets.right,
height: size.height + insets.top + insets.bottom
)
}
}