// // HashtagTimelineViewController.swift // Tusker // // Created by Shadowfacts on 12/19/19. // Copyright © 2019 Shadowfacts. All rights reserved. // import UIKit import Pachyderm class HashtagTimelineViewController: TimelineViewController { let hashtagName: String private var hashtag: Hashtag? private var fetchHashtag: Task? var toggleSaveButton: UIBarButtonItem! var isHashtagSaved: Bool { let req = SavedHashtag.fetchRequest(name: hashtagName, account: mastodonController.accountInfo!) return mastodonController.persistentContainer.viewContext.objectExists(for: req) } private var isHashtagFollowed: Bool { mastodonController.followedHashtags.contains(where: { $0.name == hashtagName }) } convenience init(for hashtag: Hashtag, mastodonController: MastodonController) { self.init(forNamed: hashtag.name, mastodonController: mastodonController) self.hashtag = hashtag } init(forNamed name: String, mastodonController: MastodonController) { self.hashtagName = name super.init(for: .tag(hashtag: hashtagName), mastodonController: mastodonController) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() if hashtag == nil { fetchHashtag = Task { let name = hashtagName.lowercased() let hashtag: Hashtag? if mastodonController.instanceFeatures.hasMastodonVersion(4, 0, 0) { let req = Client.getHashtag(name: name) hashtag = try? await mastodonController.run(req).0 } else { let req = Client.search(query: "#\(name)", types: [.hashtags]) let results = try? await mastodonController.run(req).0 hashtag = results?.hashtags.first(where: { $0.name.lowercased() == name }) } self.hashtag = hashtag return hashtag } } let menu = UIMenu(children: [ // uncached so that the saved/followed updates every time UIDeferredMenuElement.uncached({ [unowned self] elementHandler in if let hashtag = self.hashtag { elementHandler(actionsForHashtag(hashtag, source: .barButtonItem(self.navigationItem.rightBarButtonItem!))) } else { Task { if let hashtag = await fetchHashtag?.value { elementHandler(actionsForHashtag(hashtag, source: .barButtonItem(self.navigationItem.rightBarButtonItem!))) } else { elementHandler([]) } } } }) ]) navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "ellipsis"), menu: menu) } private func toggleSave() { let context = mastodonController.persistentContainer.viewContext if let existing = try? context.fetch(SavedHashtag.fetchRequest(name: hashtagName, account: mastodonController.accountInfo!)).first { context.delete(existing) mastodonController.persistentContainer.save(context: context) } else { Task { @MainActor in let hashtag: Hashtag? if let tag = self.hashtag { hashtag = tag } else { hashtag = await fetchHashtag?.value } if let hashtag { _ = SavedHashtag(hashtag: hashtag, account: mastodonController.accountInfo!, context: context) mastodonController.persistentContainer.save(context: context) } } } } private func toggleFollow() { Task { await ToggleFollowHashtagService(hashtagName: hashtagName, presenter: self).toggleFollow() } } }