Tusker/Tusker/Screens/Lists/ListTimelineViewController....

151 lines
5.2 KiB
Swift

//
// 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)
}
}