Tusker/Tusker/Screens/Timeline/TimelinesPageViewController...

139 lines
5.5 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// TimelinesPageViewController.swift
// Tusker
//
// Created by Shadowfacts on 9/14/19.
// Copyright © 2019 Shadowfacts. All rights reserved.
//
import UIKit
import SwiftUI
import Pachyderm
import Combine
class TimelinesPageViewController: SegmentedPageViewController<TimelinesPageViewController.Page> {
private let homeTitle = NSLocalizedString("Home", comment: "home timeline tab title")
private let federatedTitle = NSLocalizedString("Federated", comment: "federated timeline tab title")
private let localTitle = NSLocalizedString("Local", comment: "local timeline tab title")
weak var mastodonController: MastodonController!
private var cancellables = Set<AnyCancellable>()
init(mastodonController: MastodonController) {
self.mastodonController = mastodonController
let pages = mastodonController.accountPreferences.pinnedTimelines.map {
Page(mastodonController: mastodonController, timeline: $0)
}
super.init(pages: pages) { page in
let vc: TimelineViewController
if case .instance(let url) = page.timeline {
vc = InstanceTimelineViewController(for: url, parentMastodonController: mastodonController)
} else {
vc = TimelineViewController(for: page.timeline.timeline!, mastodonController: mastodonController)
}
vc.title = page.segmentedControlTitle
vc.persistsState = true
return vc
}
title = homeTitle
tabBarItem.image = UIImage(systemName: "house.fill")
let customizeItem = UIBarButtonItem(image: UIImage(systemName: "slider.horizontal.3"), style: .plain, target: self, action: #selector(customizePressed))
customizeItem.accessibilityLabel = "Customize Timelines"
navigationItem.rightBarButtonItem = customizeItem
let jumpToPresentName = NSMutableAttributedString("Jump to Present")
// otherwise it pronounces it as 'pɹizˈənt'
// its IPA is also bad, this should be an alveolar approximant not a trill
jumpToPresentName.addAttribute(.accessibilitySpeechIPANotation, value: "ˈprɛ.zənt", range: NSRange(location: "Jump to ".count, length: "Present".count))
segmentedControl.accessibilityCustomActions = [
UIAccessibilityCustomAction(attributedName: jumpToPresentName, actionHandler: { [unowned self] _ in
guard let vc = currentViewController as? TimelineViewController else {
return false
}
Task {
await vc.checkPresent(jumpImmediately: true)
}
return true
}),
UIAccessibilityCustomAction(name: "Jump to Sync Position", actionHandler: { [unowned self] _ in
guard let vc = currentViewController as? TimelineViewController else {
return false
}
Task {
_ = await vc.restoreState()
}
return true
}),
]
mastodonController.accountPreferences.publisher(for: \.pinnedTimelinesData)
.map { _ in () }
.merge(with: NotificationCenter.default.publisher(for: .accountPreferencesChangedRemotely).map { _ in () })
.sink { _ in
let pages = self.mastodonController.accountPreferences.pinnedTimelines.map {
Page(mastodonController: self.mastodonController, timeline: $0)
}
self.setPages(pages, animated: false)
}
.store(in: &cancellables)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func selectTimeline(_ timeline: PinnedTimeline, animated: Bool) {
self.selectPage(Page(mastodonController: mastodonController, timeline: timeline), animated: animated)
}
func stateRestorationActivity() -> NSUserActivity? {
return (currentViewController as? TimelineViewController)?.stateRestorationActivity()
}
func restoreActivity(_ activity: NSUserActivity) {
guard let timeline = UserActivityManager.getTimeline(from: activity),
let pinned = PinnedTimeline(timeline: timeline) else {
return
}
let page = Page(mastodonController: mastodonController, timeline: pinned)
// the pinned timelines may have changed after an iCloud sync, in which case don't restore anything
if pages.contains(page) {
selectPage(page, animated: false)
}
}
@objc private func customizePressed() {
present(UIHostingController(rootView: CustomizeTimelinesView(mastodonController: mastodonController)), animated: true)
}
}
extension TimelinesPageViewController {
struct Page: SegmentedPageViewControllerPage {
let mastodonController: MastodonController
let timeline: PinnedTimeline
static func ==(lhs: Page, rhs: Page) -> Bool {
return lhs.timeline == rhs.timeline
}
func hash(into hasher: inout Hasher) {
hasher.combine(timeline)
}
var segmentedControlTitle: String {
if case let .list(id) = timeline,
let list = try? mastodonController.persistentContainer.viewContext.fetch(ListMO.fetchRequest(id: id)).first {
return list.title
} else {
return timeline.title
}
}
}
}