210 lines
11 KiB
Swift
210 lines
11 KiB
Swift
|
//
|
||
|
// ComposeStatusPollTableViewCell.swift
|
||
|
// Mastodon
|
||
|
//
|
||
|
// Created by MainasuK Cirno on 2021-6-29.
|
||
|
//
|
||
|
|
||
|
import os.log
|
||
|
import UIKit
|
||
|
import Combine
|
||
|
import MastodonAsset
|
||
|
import MastodonLocalization
|
||
|
|
||
|
//protocol ComposeStatusPollTableViewCellDelegate: AnyObject {
|
||
|
// func composeStatusPollTableViewCell(_ cell: ComposeStatusPollTableViewCell, pollOptionAttributesDidReorder options: [ComposeStatusPollItem.PollOptionAttribute])
|
||
|
//}
|
||
|
//
|
||
|
//final class ComposeStatusPollTableViewCell: UITableViewCell {
|
||
|
//
|
||
|
// let logger = Logger(subsystem: "ComposeStatusPollTableViewCell", category: "UI")
|
||
|
//
|
||
|
// private(set) var dataSource: UICollectionViewDiffableDataSource<ComposeStatusPollSection, ComposeStatusPollItem>!
|
||
|
// var observations = Set<NSKeyValueObservation>()
|
||
|
//
|
||
|
// weak var customEmojiPickerInputViewModel: CustomEmojiPickerInputViewModel?
|
||
|
// weak var delegate: ComposeStatusPollTableViewCellDelegate?
|
||
|
// weak var composeStatusPollOptionCollectionViewCellDelegate: ComposeStatusPollOptionCollectionViewCellDelegate?
|
||
|
// weak var composeStatusPollOptionAppendEntryCollectionViewCellDelegate: ComposeStatusPollOptionAppendEntryCollectionViewCellDelegate?
|
||
|
// weak var composeStatusPollExpiresOptionCollectionViewCellDelegate: ComposeStatusPollExpiresOptionCollectionViewCellDelegate?
|
||
|
//
|
||
|
// private static func createLayout() -> UICollectionViewLayout {
|
||
|
// let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44))
|
||
|
// let item = NSCollectionLayoutItem(layoutSize: itemSize)
|
||
|
// let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44))
|
||
|
// let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item])
|
||
|
// let section = NSCollectionLayoutSection(group: group)
|
||
|
// section.contentInsetsReference = .readableContent
|
||
|
// return UICollectionViewCompositionalLayout(section: section)
|
||
|
// }
|
||
|
//
|
||
|
// private(set) var collectionViewHeightLayoutConstraint: NSLayoutConstraint!
|
||
|
// let collectionView: UICollectionView = {
|
||
|
// let collectionViewLayout = ComposeStatusPollTableViewCell.createLayout()
|
||
|
// let collectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
||
|
// collectionView.register(ComposeStatusPollOptionCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: ComposeStatusPollOptionCollectionViewCell.self))
|
||
|
// collectionView.register(ComposeStatusPollOptionAppendEntryCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: ComposeStatusPollOptionAppendEntryCollectionViewCell.self))
|
||
|
// collectionView.register(ComposeStatusPollExpiresOptionCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: ComposeStatusPollExpiresOptionCollectionViewCell.self))
|
||
|
// collectionView.backgroundColor = .clear
|
||
|
// collectionView.alwaysBounceVertical = true
|
||
|
// collectionView.isScrollEnabled = false
|
||
|
// collectionView.dragInteractionEnabled = true
|
||
|
// return collectionView
|
||
|
// }()
|
||
|
// let collectionViewHeightDidUpdate = PassthroughSubject<Void, Never>()
|
||
|
//
|
||
|
// override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||
|
// super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||
|
// _init()
|
||
|
// }
|
||
|
//
|
||
|
// required init?(coder: NSCoder) {
|
||
|
// super.init(coder: coder)
|
||
|
// _init()
|
||
|
// }
|
||
|
//
|
||
|
//}
|
||
|
//
|
||
|
//extension ComposeStatusPollTableViewCell {
|
||
|
//
|
||
|
// private func _init() {
|
||
|
// backgroundColor = .clear
|
||
|
// contentView.backgroundColor = .clear
|
||
|
//
|
||
|
// collectionView.translatesAutoresizingMaskIntoConstraints = false
|
||
|
// contentView.addSubview(collectionView)
|
||
|
// collectionViewHeightLayoutConstraint = collectionView.heightAnchor.constraint(equalToConstant: 300).priority(.defaultHigh)
|
||
|
// NSLayoutConstraint.activate([
|
||
|
// collectionView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||
|
// collectionView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
||
|
// collectionView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
||
|
// collectionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||
|
// collectionViewHeightLayoutConstraint,
|
||
|
// ])
|
||
|
//
|
||
|
// collectionView.observe(\.contentSize, options: [.initial, .new]) { [weak self] collectionView, _ in
|
||
|
// guard let self = self else { return }
|
||
|
// self.collectionViewHeightLayoutConstraint.constant = collectionView.contentSize.height
|
||
|
// self.collectionViewHeightDidUpdate.send()
|
||
|
// }
|
||
|
// .store(in: &observations)
|
||
|
//
|
||
|
// self.dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { [
|
||
|
// weak self
|
||
|
// ] collectionView, indexPath, item -> UICollectionViewCell? in
|
||
|
// guard let self = self else { return UICollectionViewCell() }
|
||
|
//
|
||
|
// switch item {
|
||
|
// case .pollOption(let attribute):
|
||
|
// let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: ComposeStatusPollOptionCollectionViewCell.self), for: indexPath) as! ComposeStatusPollOptionCollectionViewCell
|
||
|
// cell.pollOptionView.optionTextField.text = attribute.option.value
|
||
|
// cell.pollOptionView.optionTextField.placeholder = L10n.Scene.Compose.Poll.optionNumber(indexPath.item + 1)
|
||
|
// cell.pollOption
|
||
|
// .receive(on: DispatchQueue.main)
|
||
|
// .assign(to: \.value, on: attribute.option)
|
||
|
// .store(in: &cell.disposeBag)
|
||
|
// cell.delegate = self.composeStatusPollOptionCollectionViewCellDelegate
|
||
|
// if let customEmojiPickerInputViewModel = self.customEmojiPickerInputViewModel {
|
||
|
// ComposeStatusSection.configureCustomEmojiPicker(viewModel: customEmojiPickerInputViewModel, customEmojiReplaceableTextInput: cell.pollOptionView.optionTextField, disposeBag: &cell.disposeBag)
|
||
|
// }
|
||
|
// return cell
|
||
|
// case .pollOptionAppendEntry:
|
||
|
// let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: ComposeStatusPollOptionAppendEntryCollectionViewCell.self), for: indexPath) as! ComposeStatusPollOptionAppendEntryCollectionViewCell
|
||
|
// cell.delegate = self.composeStatusPollOptionAppendEntryCollectionViewCellDelegate
|
||
|
// return cell
|
||
|
// case .pollExpiresOption(let attribute):
|
||
|
// let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: ComposeStatusPollExpiresOptionCollectionViewCell.self), for: indexPath) as! ComposeStatusPollExpiresOptionCollectionViewCell
|
||
|
// cell.durationButton.setTitle(L10n.Scene.Compose.Poll.durationTime(attribute.expiresOption.value.title), for: .normal)
|
||
|
// attribute.expiresOption
|
||
|
// .receive(on: DispatchQueue.main)
|
||
|
// .sink { [weak cell] expiresOption in
|
||
|
// guard let cell = cell else { return }
|
||
|
// cell.durationButton.setTitle(L10n.Scene.Compose.Poll.durationTime(expiresOption.title), for: .normal)
|
||
|
// }
|
||
|
// .store(in: &cell.disposeBag)
|
||
|
// cell.delegate = self.composeStatusPollExpiresOptionCollectionViewCellDelegate
|
||
|
// return cell
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// collectionView.dragDelegate = self
|
||
|
// collectionView.dropDelegate = self
|
||
|
// }
|
||
|
//
|
||
|
//}
|
||
|
//
|
||
|
//// MARK: - UICollectionViewDragDelegate
|
||
|
//extension ComposeStatusPollTableViewCell: UICollectionViewDragDelegate {
|
||
|
//
|
||
|
// func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
|
||
|
// guard let item = dataSource.itemIdentifier(for: indexPath) else { return [] }
|
||
|
// switch item {
|
||
|
// case .pollOption:
|
||
|
// let itemProvider = NSItemProvider(object: String(item.hashValue) as NSString)
|
||
|
// let dragItem = UIDragItem(itemProvider: itemProvider)
|
||
|
// dragItem.localObject = item
|
||
|
// return [dragItem]
|
||
|
// default:
|
||
|
// return []
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// func collectionView(_ collectionView: UICollectionView, dragSessionIsRestrictedToDraggingApplication session: UIDragSession) -> Bool {
|
||
|
// // drag to app should be the same app
|
||
|
// return true
|
||
|
// }
|
||
|
//}
|
||
|
//
|
||
|
//// MARK: - UICollectionViewDropDelegate
|
||
|
//extension ComposeStatusPollTableViewCell: UICollectionViewDropDelegate {
|
||
|
// // didUpdate
|
||
|
// func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
|
||
|
// guard collectionView.hasActiveDrag,
|
||
|
// let destinationIndexPath = destinationIndexPath,
|
||
|
// let item = dataSource.itemIdentifier(for: destinationIndexPath)
|
||
|
// else {
|
||
|
// return UICollectionViewDropProposal(operation: .forbidden)
|
||
|
// }
|
||
|
//
|
||
|
// switch item {
|
||
|
// case .pollOption:
|
||
|
// return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
|
||
|
// default:
|
||
|
// return UICollectionViewDropProposal(operation: .cancel)
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// // performDrop
|
||
|
// func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) {
|
||
|
// guard let dropItem = coordinator.items.first,
|
||
|
// let item = dropItem.dragItem.localObject as? ComposeStatusPollItem,
|
||
|
// case .pollOption = item
|
||
|
// else { return }
|
||
|
//
|
||
|
// guard coordinator.proposal.operation == .move else { return }
|
||
|
// guard let destinationIndexPath = coordinator.destinationIndexPath,
|
||
|
// let _ = collectionView.cellForItem(at: destinationIndexPath) as? ComposeStatusPollOptionCollectionViewCell
|
||
|
// else { return }
|
||
|
//
|
||
|
// var snapshot = dataSource.snapshot()
|
||
|
// guard destinationIndexPath.row < snapshot.itemIdentifiers.count else { return }
|
||
|
// let anchorItem = snapshot.itemIdentifiers[destinationIndexPath.row]
|
||
|
// snapshot.moveItem(item, afterItem: anchorItem)
|
||
|
// dataSource.apply(snapshot)
|
||
|
//
|
||
|
// coordinator.drop(dropItem.dragItem, toItemAt: destinationIndexPath)
|
||
|
// }
|
||
|
//}
|
||
|
//
|
||
|
//extension ComposeStatusPollTableViewCell: UICollectionViewDelegate {
|
||
|
// func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath {
|
||
|
// logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): \(originalIndexPath.debugDescription) -> \(proposedIndexPath.debugDescription)")
|
||
|
//
|
||
|
// guard let _ = collectionView.cellForItem(at: proposedIndexPath) as? ComposeStatusPollOptionCollectionViewCell else {
|
||
|
// return originalIndexPath
|
||
|
// }
|
||
|
//
|
||
|
// return proposedIndexPath
|
||
|
// }
|
||
|
//}
|