Skip to content
Snippets Groups Projects
Select Git revision
  • 9065d5aa10807c90f016af9a0af03152b44d3170
  • main default protected
  • dev protected
  • hotfixes-oct-2022
  • refactor/avatar-cell
  • 1.1.5
  • 1.1.4
  • 1.1.3
  • 1.1
  • 1.0.8
  • 1.0.7
  • 1.0.6
12 results

NicknameController.swift

Blame
  • CreateGroupController.swift 6.90 KiB
    import HUD
    import UIKit
    import Models
    import Shared
    import Combine
    import XXModels
    import CollectionView
    import DependencyInjection
    
    public final class CreateGroupController: UIViewController {
        @Dependency private var hud: HUD
        @Dependency private var coordinator: ContactListCoordinating
    
        lazy private var titleLabel = UILabel()
        lazy private var createButton = UIButton()
        lazy private var screenView = CreateGroupView()
    
        private var selectedElements = [Contact]() {
            didSet { screenView.bottomCollectionView.reloadData() }
        }
        private let viewModel = CreateGroupViewModel()
        private var cancellables = Set<AnyCancellable>()
        private var topCollectionDataSource: UICollectionViewDiffableDataSource<Int, Contact>!
        private var bottomCollectionDataSource: UICollectionViewDiffableDataSource<Int, Contact>!
    
        private var count = 0 {
            didSet {
                createButton.isEnabled = count >= 2 && count <= 10
    
                let text = Localized.CreateGroup.title("\(count)")
                let attString = NSMutableAttributedString(string: text)
                attString.addAttribute(.font, value: Fonts.Mulish.semiBold.font(size: 18.0) as Any)
                attString.addAttribute(.foregroundColor, value: Asset.neutralActive.color)
                attString.addAttribute(name: .foregroundColor, value: Asset.neutralDisabled.color, betweenCharacters: "#")
    
                titleLabel.attributedText = attString
            }
        }
    
        public override func loadView() {
            view = screenView
        }
    
        public override func viewDidLoad() {
            super.viewDidLoad()
            setupNavigationBar()
            setupCollectionViews()
            setupBindings()
        }
    
        private func setupNavigationBar() {
            navigationItem.backButtonTitle = " "
    
            let back = UIButton.back()
            back.addTarget(self, action: #selector(didTapBack), for: .touchUpInside)
    
            navigationItem.leftBarButtonItem = UIBarButtonItem(
                customView: UIStackView(arrangedSubviews: [back, titleLabel])
            )
    
            createButton.setTitle(Localized.CreateGroup.create, for: .normal)
            createButton.setTitleColor(Asset.brandPrimary.color, for: .normal)
            createButton.titleLabel?.font = Fonts.Mulish.semiBold.font(size: 16.0)
            createButton.setTitleColor(Asset.neutralDisabled.color, for: .disabled)
            navigationItem.rightBarButtonItem = UIBarButtonItem(customView: createButton)
        }
    
        private func setupCollectionViews() {
            CellFactory.createGroupHeroCellFactory
                .register(in: screenView.topCollectionView)
            CellFactory.createGroupListCellFactory
                .register(in: screenView.bottomCollectionView)
    
            topCollectionDataSource = UICollectionViewDiffableDataSource<Int, Contact>(
                collectionView: screenView.topCollectionView
            ) { collectionView, indexPath, contact in
                CellFactory.createGroupHeroCellFactory.build(
                    for: contact,
                    in: collectionView,
                    at: indexPath
                )
            }
    
            bottomCollectionDataSource = UICollectionViewDiffableDataSource<Int, Contact>(
                collectionView: screenView.bottomCollectionView
            ) { collectionView, indexPath, contact in
                CellFactory.createGroupListCellFactory.build(
                    for: contact,
                    in: collectionView,
                    at: indexPath
                )
            }
    
            screenView.bottomCollectionView.delegate = self
            screenView.topCollectionView.dataSource = topCollectionDataSource
            screenView.bottomCollectionView.tintColor = Asset.brandPrimary.color
            screenView.bottomCollectionView.dataSource = bottomCollectionDataSource
            screenView.bottomCollectionView.allowsMultipleSelectionDuringEditing = true
        }
    
        private func setupBindings() {
            viewModel.hud
                .receive(on: DispatchQueue.main)
                .sink { [hud] in hud.update(with: $0) }
                .store(in: &cancellables)
    
            let selected = viewModel.selected.share()
    
            selected
                .receive(on: DispatchQueue.main)
                .sink { [unowned self] in
                    screenView.topCollectionView.isHidden = $0.count < 1
    
                    count = $0.count
                    selectedElements = $0
                }.store(in: &cancellables)
    
            selected.map { selectedContacts in
                var snapshot = NSDiffableDataSourceSnapshot<Int, Contact>()
                let sections = [0]
                snapshot.appendSections(sections)
                sections.forEach { section in snapshot.appendItems(selectedContacts, toSection: section) }
                return snapshot
            }
            .receive(on: DispatchQueue.main)
            .sink { [unowned self] in topCollectionDataSource.apply($0) }
            .store(in: &cancellables)
    
            viewModel.contacts
                .map { contacts -> NSDiffableDataSourceSnapshot<Int, Contact> in
                    var snapshot = NSDiffableDataSourceSnapshot<Int, Contact>()
                    let sections = [0]
                    snapshot.appendSections(sections)
                    sections.forEach { section in snapshot.appendItems(contacts, toSection: section) }
                    return snapshot
                }
                .receive(on: DispatchQueue.main)
                .sink { [unowned self] in
                    let animating = bottomCollectionDataSource.snapshot().numberOfItems > 0
                    bottomCollectionDataSource.apply($0, animatingDifferences: animating)
                }.store(in: &cancellables)
    
            screenView.searchComponent.textPublisher
                .removeDuplicates()
                .sink { [unowned self] in viewModel.filter($0) }
                .store(in: &cancellables)
    
            viewModel.info
                .receive(on: DispatchQueue.main)
                .sink { [unowned self] in coordinator.toGroupChat(with: $0, from: self) }
                .store(in: &cancellables)
    
            createButton
                .publisher(for: .touchUpInside)
                .receive(on: DispatchQueue.main)
                .sink { [unowned self] in
                    coordinator.toGroupDrawer(
                        with: count + 1,
                        from: self, { (name, welcome) in
                            self.viewModel.create(name: name, welcome: welcome, members: self.selectedElements)
                        }
                    )
                }.store(in: &cancellables)
        }
    
        @objc private func didTapBack() {
            navigationController?.popViewController(animated: true)
        }
    }
    
    extension CreateGroupController: UICollectionViewDelegate {
        public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            if let contact = bottomCollectionDataSource.itemIdentifier(for: indexPath) {
                viewModel.didSelect(contact: contact)
            }
        }
    
        public func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
            if let contact = bottomCollectionDataSource.itemIdentifier(for: indexPath) {
                viewModel.didSelect(contact: contact)
            }
        }
    }