// // ListTimelineViewController.swift // Tusker // // Created by Shadowfacts on 12/17/19. // Copyright © 2019 Shadowfacts. All rights reserved. // import UIKit import Pachyderm import Combine class ListTimelineViewController: TimelineViewController { private(set) var list: List var presentEditOnAppear = false private var noContentView: UIStackView! private var listRenamedCancellable: AnyCancellable? init(for list: List, mastodonController: MastodonController) { self.list = list super.init(for: .list(id: list.id), mastodonController: mastodonController) listChanged() listRenamedCancellable = mastodonController.$lists .compactMap { $0.first { $0.id == list.id } } .removeDuplicates(by: { $0.title == $1.title }) .sink { [unowned self] in self.list = $0 self.listChanged() } } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editListButtonPressed)) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if presentEditOnAppear { presentEdit(animated: true) presentEditOnAppear = false } } private func createNoContentView() { let title = UILabel() title.textColor = .secondaryLabel title.font = .preferredFont(forTextStyle: .title1).withTraits(.traitBold)! title.adjustsFontForContentSizeCategory = true title.text = "No Posts" let subtitle = UILabel() subtitle.textColor = .secondaryLabel subtitle.font = .preferredFont(forTextStyle: .body) subtitle.adjustsFontForContentSizeCategory = true subtitle.numberOfLines = 0 subtitle.textAlignment = .center subtitle.text = "This list doesn't currently have any posts. Edit it to add accounts if necessary." noContentView = UIStackView(arrangedSubviews: [ title, subtitle, ]) noContentView.axis = .vertical noContentView.spacing = 8 noContentView.alignment = .center noContentView.isAccessibilityElement = true noContentView.accessibilityLabel = subtitle.text noContentView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(noContentView) NSLayoutConstraint.activate([ noContentView.centerYAnchor.constraint(equalTo: view.centerYAnchor), noContentView.leadingAnchor.constraint(equalToSystemSpacingAfter: view.safeAreaLayoutGuide.leadingAnchor, multiplier: 1), view.safeAreaLayoutGuide.trailingAnchor.constraint(equalToSystemSpacingAfter: noContentView.trailingAnchor, multiplier: 1), ]) } private func listChanged() { title = list.title } func presentEdit(animated: Bool) { let editListAccountsController = EditListAccountsViewController(list: list, mastodonController: mastodonController) editListAccountsController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(editListDoneButtonPressed)) let navController = UINavigationController(rootViewController: editListAccountsController) navController.sheetPresentationController?.delegate = self present(navController, animated: animated) } private func reloadIfNecessary(editViewController: EditListAccountsViewController) { guard editViewController.shouldReloadListTimeline else { return } noContentView?.removeFromSuperview() noContentView = nil Task { applyInitialSnapshot() await controller.loadInitial() } } // MARK: Interaction @objc func editListButtonPressed() { presentEdit(animated: true) } @objc func editListDoneButtonPressed() { let presented = (presentedViewController as? UINavigationController)?.viewControllers.first as? EditListAccountsViewController dismiss(animated: true) if let presented { self.reloadIfNecessary(editViewController: presented) } } // MARK: TimelineLikeControllerDelegate override func handleReplaceAllItems(_ timelineItems: [String]) async { if timelineItems.isEmpty { createNoContentView() } await super.handleReplaceAllItems(timelineItems) } } extension ListTimelineViewController: UISheetPresentationControllerDelegate { func presentationControllerWillDismiss(_ presentationController: UIPresentationController) { guard let nav = presentationController.presentedViewController as? UINavigationController, let edit = nav.viewControllers.first as? EditListAccountsViewController else { return } reloadIfNecessary(editViewController: edit) } }