2021-01-20 23:33:53 +00:00
|
|
|
// Copyright © 2021 Metabolist. All rights reserved.
|
|
|
|
|
|
|
|
import Combine
|
|
|
|
import UIKit
|
|
|
|
import ViewModels
|
|
|
|
|
|
|
|
final class TimelinesViewController: UIPageViewController {
|
2021-01-21 08:45:09 +00:00
|
|
|
private let segmentedControl = UISegmentedControl()
|
2021-04-25 19:38:36 +00:00
|
|
|
private let announcementsButton = UIBarButtonItem()
|
2021-01-20 23:33:53 +00:00
|
|
|
private let timelineViewControllers: [TableViewController]
|
|
|
|
private let viewModel: NavigationViewModel
|
|
|
|
private let rootViewModel: RootViewModel
|
|
|
|
private var cancellables = Set<AnyCancellable>()
|
|
|
|
|
|
|
|
init(viewModel: NavigationViewModel, rootViewModel: RootViewModel) {
|
|
|
|
self.viewModel = viewModel
|
|
|
|
self.rootViewModel = rootViewModel
|
|
|
|
|
2021-01-21 08:45:09 +00:00
|
|
|
var timelineViewControllers = [TableViewController]()
|
2021-01-20 23:33:53 +00:00
|
|
|
|
2021-01-21 08:45:09 +00:00
|
|
|
for (index, timeline) in viewModel.timelines.enumerated() {
|
|
|
|
timelineViewControllers.append(
|
|
|
|
TableViewController(
|
|
|
|
viewModel: viewModel.viewModel(timeline: timeline),
|
2021-01-26 00:45:18 +00:00
|
|
|
rootViewModel: rootViewModel))
|
2021-01-21 08:45:09 +00:00
|
|
|
segmentedControl.insertSegment(withTitle: timeline.title, at: index, animated: false)
|
2021-01-20 23:33:53 +00:00
|
|
|
}
|
|
|
|
|
2021-01-21 08:45:09 +00:00
|
|
|
self.timelineViewControllers = timelineViewControllers
|
|
|
|
|
2021-01-20 23:33:53 +00:00
|
|
|
super.init(transitionStyle: .scroll,
|
|
|
|
navigationOrientation: .horizontal,
|
|
|
|
options: [.interPageSpacing: CGFloat.defaultSpacing])
|
|
|
|
|
|
|
|
if let firstViewController = timelineViewControllers.first {
|
|
|
|
setViewControllers([firstViewController], direction: .forward, animated: false)
|
|
|
|
}
|
2021-01-23 03:48:33 +00:00
|
|
|
|
|
|
|
tabBarItem = UITabBarItem(
|
|
|
|
title: NSLocalizedString("main-navigation.timelines", comment: ""),
|
|
|
|
image: UIImage(systemName: "newspaper"),
|
|
|
|
selectedImage: nil)
|
2021-04-25 19:38:36 +00:00
|
|
|
|
2021-05-10 04:39:36 +00:00
|
|
|
let announcementsAction = UIAction(
|
2021-04-25 19:38:36 +00:00
|
|
|
title: NSLocalizedString("main-navigation.announcements", comment: ""),
|
|
|
|
image: UIImage(systemName: "megaphone")) { [weak self] _ in
|
|
|
|
guard let self = self else { return }
|
|
|
|
|
|
|
|
let announcementsViewController = TableViewController(viewModel: viewModel.announcementsViewModel(),
|
|
|
|
rootViewModel: rootViewModel)
|
|
|
|
|
|
|
|
self.navigationController?.pushViewController(announcementsViewController, animated: true)
|
|
|
|
}
|
|
|
|
|
2021-05-10 04:39:36 +00:00
|
|
|
announcementsButton.primaryAction = announcementsAction
|
|
|
|
|
2021-04-25 19:38:36 +00:00
|
|
|
viewModel.$announcementCount
|
|
|
|
.sink { [weak self] in
|
2021-05-10 04:39:36 +00:00
|
|
|
if $0.unread > 0 {
|
|
|
|
announcementsAction.image = UIImage(systemName: "\($0.unread).circle.fill")
|
|
|
|
?? UIImage(systemName: "megaphone.fill")
|
|
|
|
self?.announcementsButton.primaryAction = announcementsAction
|
|
|
|
self?.announcementsButton.tintColor = .systemRed
|
|
|
|
} else {
|
|
|
|
announcementsAction.image = UIImage(systemName: "megaphone")
|
|
|
|
self?.announcementsButton.primaryAction = announcementsAction
|
|
|
|
self?.announcementsButton.tintColor = nil
|
|
|
|
}
|
|
|
|
|
2021-04-25 19:38:36 +00:00
|
|
|
self?.navigationItem.rightBarButtonItem = $0.total > 0 ? self?.announcementsButton : nil
|
|
|
|
}
|
|
|
|
.store(in: &cancellables)
|
2021-01-20 23:33:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@available(*, unavailable)
|
|
|
|
required init?(coder: NSCoder) {
|
|
|
|
fatalError("init(coder:) has not been implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
override func viewDidLoad() {
|
|
|
|
super.viewDidLoad()
|
|
|
|
|
|
|
|
dataSource = self
|
|
|
|
delegate = self
|
|
|
|
|
2021-01-21 08:45:09 +00:00
|
|
|
navigationItem.titleView = segmentedControl
|
|
|
|
segmentedControl.selectedSegmentIndex = 0
|
|
|
|
segmentedControl.addAction(
|
|
|
|
UIAction { [weak self] _ in
|
2021-01-20 23:33:53 +00:00
|
|
|
guard let self = self,
|
|
|
|
let currentViewController = self.viewControllers?.first as? TableViewController,
|
|
|
|
let currentIndex = self.timelineViewControllers.firstIndex(of: currentViewController),
|
2021-01-21 08:45:09 +00:00
|
|
|
self.segmentedControl.selectedSegmentIndex != currentIndex
|
2021-01-20 23:33:53 +00:00
|
|
|
else { return }
|
|
|
|
|
|
|
|
self.setViewControllers(
|
2021-01-21 08:45:09 +00:00
|
|
|
[self.timelineViewControllers[self.segmentedControl.selectedSegmentIndex]],
|
|
|
|
direction: self.segmentedControl.selectedSegmentIndex > currentIndex ? .forward : .reverse,
|
2021-01-20 23:33:53 +00:00
|
|
|
animated: !UIAccessibility.isReduceMotionEnabled)
|
2021-01-21 08:45:09 +00:00
|
|
|
},
|
|
|
|
for: .valueChanged)
|
2021-01-20 23:33:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension TimelinesViewController: UIPageViewControllerDataSource {
|
|
|
|
func pageViewController(_ pageViewController: UIPageViewController,
|
|
|
|
viewControllerAfter viewController: UIViewController) -> UIViewController? {
|
|
|
|
guard
|
|
|
|
let timelineViewController = viewController as? TableViewController,
|
|
|
|
let index = timelineViewControllers.firstIndex(of: timelineViewController),
|
|
|
|
index + 1 < timelineViewControllers.count
|
|
|
|
else { return nil }
|
|
|
|
|
|
|
|
return timelineViewControllers[index + 1]
|
|
|
|
}
|
|
|
|
|
|
|
|
func pageViewController(_ pageViewController: UIPageViewController,
|
|
|
|
viewControllerBefore viewController: UIViewController) -> UIViewController? {
|
|
|
|
guard
|
|
|
|
let timelineViewController = viewController as? TableViewController,
|
|
|
|
let index = timelineViewControllers.firstIndex(of: timelineViewController),
|
|
|
|
index > 0
|
|
|
|
else { return nil }
|
|
|
|
|
|
|
|
return timelineViewControllers[index - 1]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension TimelinesViewController: UIPageViewControllerDelegate {
|
|
|
|
func pageViewController(_ pageViewController: UIPageViewController,
|
|
|
|
didFinishAnimating finished: Bool,
|
|
|
|
previousViewControllers: [UIViewController],
|
|
|
|
transitionCompleted completed: Bool) {
|
|
|
|
guard let viewController = viewControllers?.first as? TableViewController,
|
|
|
|
let index = timelineViewControllers.firstIndex(of: viewController)
|
|
|
|
else { return }
|
|
|
|
|
2021-01-21 08:45:09 +00:00
|
|
|
segmentedControl.selectedSegmentIndex = index
|
2021-01-20 23:33:53 +00:00
|
|
|
}
|
|
|
|
}
|
2021-02-06 01:16:59 +00:00
|
|
|
|
|
|
|
extension TimelinesViewController: ScrollableToTop {
|
|
|
|
func scrollToTop(animated: Bool) {
|
|
|
|
(viewControllers?.first as? TableViewController)?.scrollToTop(animated: animated)
|
|
|
|
}
|
|
|
|
}
|
2021-03-03 06:55:35 +00:00
|
|
|
|
|
|
|
extension TimelinesViewController: NavigationHandling {
|
|
|
|
func handle(navigation: Navigation) {
|
|
|
|
(viewControllers?.first as? TableViewController)?.handle(navigation: navigation)
|
|
|
|
}
|
|
|
|
}
|