mastodon-ios/Mastodon/Scene/Profile/About/ProfileAboutViewController....

168 lines
6.1 KiB
Swift

//
// ProfileAboutViewController.swift
// Mastodon
//
// Created by MainasuK on 2022-1-22.
//
import UIKit
import Combine
import MetaTextKit
import MastodonLocalization
import TabBarPager
import XLPagerTabStrip
import MastodonCore
protocol ProfileAboutViewControllerDelegate: AnyObject {
func profileAboutViewController(_ viewController: ProfileAboutViewController, profileFieldCollectionViewCell: ProfileFieldCollectionViewCell, metaLabel: MetaLabel, didSelectMeta meta: Meta)
}
final class ProfileAboutViewController: UIViewController {
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
weak var delegate: ProfileAboutViewControllerDelegate?
var disposeBag = Set<AnyCancellable>()
var viewModel: ProfileAboutViewModel!
let collectionView: UICollectionView = {
var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
configuration.backgroundColor = .clear
configuration.headerMode = .supplementary
let layout = UICollectionViewCompositionalLayout.list(using: configuration)
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
return collectionView
}()
}
extension ProfileAboutViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
collectionView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(collectionView)
collectionView.pinToParent()
let longPressReorderGesture = UILongPressGestureRecognizer(
target: self,
action: #selector(ProfileAboutViewController.longPressReorderGestureHandler(_:))
)
collectionView.addGestureRecognizer(longPressReorderGesture)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
collectionView.delegate = self
viewModel.setupDiffableDataSource(
collectionView: collectionView,
profileFieldCollectionViewCellDelegate: self,
profileFieldEditCollectionViewCellDelegate: self
)
}
}
extension ProfileAboutViewController {
// seealso: ProfileAboutViewModel.setupProfileDiffableDataSource()
@objc private func longPressReorderGestureHandler(_ sender: UILongPressGestureRecognizer) {
guard sender.view === collectionView else {
assertionFailure()
return
}
guard let diffableDataSource = self.viewModel.diffableDataSource else {
collectionView.cancelInteractiveMovement()
return
}
switch(sender.state) {
case .began:
guard let indexPath = collectionView.indexPathForItem(at: sender.location(in: collectionView)),
let item = diffableDataSource.itemIdentifier(for: indexPath), case .editField = item,
let layoutAttribute = collectionView.layoutAttributesForItem(at: indexPath) else {
break
}
let point = sender.location(in: collectionView)
guard layoutAttribute.frame.contains(point) else {
return
}
collectionView.beginInteractiveMovementForItem(at: indexPath)
case .changed:
guard let indexPath = collectionView.indexPathForItem(at: sender.location(in: collectionView)) else {
break
}
guard let item = diffableDataSource.itemIdentifier(for: indexPath), case .editField = item else {
collectionView.cancelInteractiveMovement()
return
}
var position = sender.location(in: collectionView)
position.x = collectionView.frame.width * 0.5
collectionView.updateInteractiveMovementTargetPosition(position)
case .ended:
collectionView.endInteractiveMovement()
collectionView.reloadData()
default:
collectionView.cancelInteractiveMovement()
}
}
}
// MARK: - UICollectionViewDelegate
extension ProfileAboutViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let diffableDataSource = viewModel.diffableDataSource else { return }
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
switch item {
case .addEntry:
viewModel.appendFieldItem()
default:
break
}
}
}
// MARK: - ProfileFieldCollectionViewCellDelegate
extension ProfileAboutViewController: ProfileFieldCollectionViewCellDelegate {
func profileFieldCollectionViewCell(_ cell: ProfileFieldCollectionViewCell, metaLabel: MetaLabel, didSelectMeta meta: Meta) {
delegate?.profileAboutViewController(self, profileFieldCollectionViewCell: cell, metaLabel: metaLabel, didSelectMeta: meta)
}
}
// MARK: - ProfileFieldEditCollectionViewCellDelegate
extension ProfileAboutViewController: ProfileFieldEditCollectionViewCellDelegate {
func profileFieldEditCollectionViewCell(_ cell: ProfileFieldEditCollectionViewCell, editButtonDidPressed button: UIButton) {
guard let diffableDataSource = viewModel.diffableDataSource else { return }
guard let indexPath = collectionView.indexPath(for: cell) else { return }
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
viewModel.removeFieldItem(item: item)
}
}
// MARK: - ScrollViewContainer
extension ProfileAboutViewController: ScrollViewContainer {
var scrollView: UIScrollView { collectionView }
}
// MARK: - TabBarPage
extension ProfileAboutViewController: TabBarPage {
var pageScrollView: UIScrollView { scrollView }
}
// MARK: - IndicatorInfoProvider
extension ProfileAboutViewController: IndicatorInfoProvider {
func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
return IndicatorInfo(title: L10n.Scene.Profile.SegmentedControl.about)
}
}