mastodon-ios/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift

204 lines
8.8 KiB
Swift
Raw Normal View History

2021-09-22 13:08:09 +02:00
//
// SidebarViewController.swift
// Mastodon
//
// Created by Cirno MainasuK on 2021-9-22.
//
2021-09-24 13:58:50 +02:00
import os.log
2021-09-22 13:08:09 +02:00
import UIKit
import Combine
import CoreDataStack
protocol SidebarViewControllerDelegate: AnyObject {
func sidebarViewController(_ sidebarViewController: SidebarViewController, didSelectTab tab: MainTabBarController.Tab)
}
final class SidebarViewController: UIViewController, NeedsDependency {
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
var disposeBag = Set<AnyCancellable>()
2021-10-28 13:17:41 +02:00
var observations = Set<NSKeyValueObservation>()
2021-09-22 13:08:09 +02:00
var viewModel: SidebarViewModel!
weak var delegate: SidebarViewControllerDelegate?
static func createLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout() { (sectionIndex, layoutEnvironment) -> NSCollectionLayoutSection? in
2021-09-24 13:58:50 +02:00
var configuration = UICollectionLayoutListConfiguration(appearance: .sidebar)
configuration.backgroundColor = .clear
2021-09-22 13:08:09 +02:00
configuration.showsSeparators = false
let section = NSCollectionLayoutSection.list(using: configuration, layoutEnvironment: layoutEnvironment)
2021-10-28 13:17:41 +02:00
switch sectionIndex {
case 0:
let header = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(100)),
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top
)
section.boundarySupplementaryItems = [header]
default:
break
}
2021-09-22 13:08:09 +02:00
return section
}
return layout
}
let collectionView: UICollectionView = {
2021-10-28 13:17:41 +02:00
let layout = SidebarViewController.createLayout()
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.alwaysBounceVertical = false
2021-09-22 13:08:09 +02:00
collectionView.backgroundColor = .clear
return collectionView
}()
2021-10-28 13:17:41 +02:00
static func createSecondaryLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout() { (sectionIndex, layoutEnvironment) -> NSCollectionLayoutSection? in
var configuration = UICollectionLayoutListConfiguration(appearance: .sidebar)
configuration.backgroundColor = .clear
configuration.showsSeparators = false
let section = NSCollectionLayoutSection.list(using: configuration, layoutEnvironment: layoutEnvironment)
return section
}
return layout
}
let secondaryCollectionView: UICollectionView = {
let layout = SidebarViewController.createSecondaryLayout()
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.isScrollEnabled = false
collectionView.alwaysBounceVertical = false
collectionView.backgroundColor = .clear
return collectionView
}()
var secondaryCollectionViewHeightLayoutConstraint: NSLayoutConstraint!
2021-09-22 13:08:09 +02:00
}
extension SidebarViewController {
override func viewDidLoad() {
super.viewDidLoad()
2021-10-28 13:17:41 +02:00
navigationController?.setNavigationBarHidden(true, animated: false)
2021-09-22 13:08:09 +02:00
2021-09-24 13:58:50 +02:00
setupBackground(theme: ThemeService.shared.currentTheme.value)
ThemeService.shared.currentTheme
.receive(on: DispatchQueue.main)
.sink { [weak self] theme in
guard let self = self else { return }
self.setupBackground(theme: theme)
}
.store(in: &disposeBag)
2021-09-22 13:08:09 +02:00
collectionView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: view.topAnchor),
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
2021-10-28 13:17:41 +02:00
secondaryCollectionView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(secondaryCollectionView)
secondaryCollectionViewHeightLayoutConstraint = secondaryCollectionView.heightAnchor.constraint(equalToConstant: 44).priority(.required - 1)
NSLayoutConstraint.activate([
secondaryCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
secondaryCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
view.bottomAnchor.constraint(equalTo: secondaryCollectionView.bottomAnchor),
secondaryCollectionViewHeightLayoutConstraint,
])
2021-09-22 13:08:09 +02:00
collectionView.delegate = self
2021-10-28 13:17:41 +02:00
secondaryCollectionView.delegate = self
viewModel.setupDiffableDataSource(
collectionView: collectionView,
secondaryCollectionView: secondaryCollectionView
)
secondaryCollectionView.observe(\.contentSize, options: [.initial, .new]) { [weak self] secondaryCollectionView, _ in
guard let self = self else { return }
let height = secondaryCollectionView.contentSize.height
self.secondaryCollectionViewHeightLayoutConstraint.constant = height
self.collectionView.contentInset.bottom = height
}
.store(in: &observations)
2021-09-22 13:08:09 +02:00
}
2021-09-24 13:58:50 +02:00
private func setupBackground(theme: Theme) {
let color: UIColor = theme.sidebarBackgroundColor
view.backgroundColor = color
2021-09-24 13:58:50 +02:00
}
2021-10-28 13:17:41 +02:00
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate { context in
self.collectionView.collectionViewLayout.invalidateLayout()
// // do nothing
} completion: { [weak self] context in
// guard let self = self else { return }
}
2021-09-24 13:58:50 +02:00
}
2021-10-28 13:17:41 +02:00
2021-09-22 13:08:09 +02:00
}
// MARK: - UICollectionViewDelegate
extension SidebarViewController: UICollectionViewDelegate {
2021-10-28 13:17:41 +02:00
2021-09-22 13:08:09 +02:00
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
2021-10-28 13:17:41 +02:00
switch collectionView {
case self.collectionView:
guard let diffableDataSource = viewModel.diffableDataSource else { return }
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
switch item {
case .tab(let tab):
delegate?.sidebarViewController(self, didSelectTab: tab)
case .setting:
guard let setting = context.settingService.currentSetting.value else { return }
let settingsViewModel = SettingsViewModel(context: context, setting: setting)
coordinator.present(scene: .settings(viewModel: settingsViewModel), from: self, transition: .modal(animated: true, completion: nil))
case .compose:
assertionFailure()
}
case secondaryCollectionView:
guard let diffableDataSource = viewModel.secondaryDiffableDataSource else { return }
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
switch item {
case .compose:
let composeViewModel = ComposeViewModel(context: context, composeKind: .post)
coordinator.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil))
default:
assertionFailure()
}
default:
assertionFailure()
2021-09-22 13:08:09 +02:00
}
2021-10-28 13:17:41 +02:00
// switch item {
// case .tab(let tab):
// delegate?.sidebarViewController(self, didSelectTab: tab)
// case .searchHistory(let viewModel):
// delegate?.sidebarViewController(self, didSelectSearchHistory: viewModel)
// case .header:
// break
// case .account(let viewModel):
// assert(Thread.isMainThread)
// let authentication = context.managedObjectContext.object(with: viewModel.authenticationObjectID) as! MastodonAuthentication
// context.authenticationService.activeMastodonUser(domain: authentication.domain, userID: authentication.userID)
// .receive(on: DispatchQueue.main)
// .sink { [weak self] result in
// guard let self = self else { return }
// self.coordinator.setup()
// }
// .store(in: &disposeBag)
// case .addAccount:
// coordinator.present(scene: .welcome, from: self, transition: .modal(animated: true, completion: nil))
// }
2021-09-22 13:08:09 +02:00
}
}