mastodon-ios/Mastodon/Scene/Settings/Server Details/ServerDetailsViewController...

166 lines
7.1 KiB
Swift

// Copyright © 2023 Mastodon gGmbH. All rights reserved.
import UIKit
import MastodonSDK
import MastodonLocalization
import MetaTextKit
import MastodonCore
enum ServerDetailsTab: Int, CaseIterable {
case about = 0
case rules = 1
var title: String {
switch self {
case .about: return L10n.Scene.Settings.ServerDetails.about
case .rules: return L10n.Scene.Settings.ServerDetails.rules
}
}
}
protocol ServerDetailsViewControllerDelegate: AnyObject {}
class ServerDetailsViewController: UIViewController {
weak var delegate: (ServerDetailsViewControllerDelegate & AboutInstanceViewControllerDelegate & InstanceRulesViewControllerDelegate & MetaLabelDelegate)? {
didSet {
aboutInstanceViewController.delegate = delegate
aboutInstanceViewController.footerView.contentLabel.linkDelegate = delegate
}
}
let pageController: UIPageViewController
private let segmentedControlWrapper: UIView
let segmentedControl: UISegmentedControl
let aboutInstanceViewController: AboutInstanceViewController
let instanceRulesViewController: InstanceRulesViewController
let containerView: UIView
init(domain: String, appContext: AppContext, authContext: AuthContext, sceneCoordinator: SceneCoordinator) {
segmentedControl = UISegmentedControl()
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
segmentedControlWrapper = UIView()
segmentedControlWrapper.translatesAutoresizingMaskIntoConstraints = false
segmentedControlWrapper.addSubview(segmentedControl)
containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
aboutInstanceViewController = AboutInstanceViewController(context: appContext, authContext: authContext, coordinator: sceneCoordinator)
instanceRulesViewController = InstanceRulesViewController()
pageController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
pageController.setViewControllers([aboutInstanceViewController], direction: .forward, animated: false)
pageController.view.translatesAutoresizingMaskIntoConstraints = false
super.init(nibName: nil, bundle: nil)
view.addSubview(segmentedControlWrapper)
view.addSubview(containerView)
view.backgroundColor = .systemGroupedBackground
containerView.addSubview(pageController.view)
addChild(pageController)
pageController.didMove(toParent: self)
pageController.delegate = self
pageController.dataSource = self
ServerDetailsTab.allCases.forEach {
segmentedControl.insertSegment(withTitle: $0.title, at: $0.rawValue, animated: false)
}
segmentedControl.selectedSegmentIndex = ServerDetailsTab.about.rawValue
segmentedControl.addTarget(self, action: #selector(ServerDetailsViewController.segmentedControlValueChanged(_:)), for: .valueChanged)
setupConstraints()
title = domain
setupNavigationBarAppearance()
setupNavigationBarBackgroundView()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setupConstraints() {
let constraints = [
segmentedControlWrapper.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
segmentedControlWrapper.leadingAnchor.constraint(equalTo: view.leadingAnchor),
view.trailingAnchor.constraint(equalTo: segmentedControlWrapper.trailingAnchor),
containerView.topAnchor.constraint(equalTo: segmentedControlWrapper.bottomAnchor),
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
view.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
segmentedControl.topAnchor.constraint(equalTo: segmentedControlWrapper.topAnchor, constant: 4),
segmentedControl.leadingAnchor.constraint(equalTo: segmentedControlWrapper.leadingAnchor, constant: 16),
segmentedControlWrapper.trailingAnchor.constraint(equalTo: segmentedControl.trailingAnchor, constant: 16),
segmentedControlWrapper.bottomAnchor.constraint(equalTo: segmentedControl.bottomAnchor, constant: 8),
pageController.view.topAnchor.constraint(equalTo: containerView.topAnchor),
pageController.view.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
containerView.trailingAnchor.constraint(equalTo: pageController.view.trailingAnchor),
containerView.bottomAnchor.constraint(equalTo: pageController.view.bottomAnchor),
]
NSLayoutConstraint.activate(constraints)
}
//MARK: - Actions
@objc
func segmentedControlValueChanged(_ sender: UISegmentedControl) {
guard let selectedTab = ServerDetailsTab(rawValue: sender.selectedSegmentIndex) else { return }
switch selectedTab {
case .about:
pageController.setViewControllers([aboutInstanceViewController], direction: .reverse, animated: true)
case .rules:
pageController.setViewControllers([instanceRulesViewController], direction: .forward, animated: true)
}
}
func update(with instance: Mastodon.Entity.V2.Instance) {
aboutInstanceViewController.update(with: instance)
instanceRulesViewController.update(with: instance)
}
func updateFooter(with extendedDescription: Mastodon.Entity.ExtendedDescription) {
aboutInstanceViewController.updateFooter(with: extendedDescription)
}
}
//MARK: - UIPageViewControllerDataSource
extension ServerDetailsViewController: UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
if viewController == instanceRulesViewController {
return aboutInstanceViewController
} else {
return nil
}
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
if viewController == aboutInstanceViewController {
return instanceRulesViewController
} else {
return nil
}
}
}
//MARK: - UIPageViewControllerDelegate
extension ServerDetailsViewController: UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
guard let currentViewController = pageViewController.viewControllers?.first else { return }
if currentViewController == aboutInstanceViewController {
segmentedControl.selectedSegmentIndex = ServerDetailsTab.about.rawValue
} else if currentViewController == instanceRulesViewController {
segmentedControl.selectedSegmentIndex = ServerDetailsTab.rules.rawValue
}
}
}
extension ServerDetailsViewController: OnboardingViewControllerAppearance {}