Compare commits

..

No commits in common. "377b5f5c8566ca64d0af45fba128e6c159e108fb" and "ae6a0513e437501ea5dcea3b82dc5cadadddbd95" have entirely different histories.

13 changed files with 21 additions and 296 deletions

View File

@ -81,7 +81,7 @@ public class Client {
} }
func createURLRequest<Result>(request: Request<Result>) -> URLRequest? { func createURLRequest<Result>(request: Request<Result>) -> URLRequest? {
guard var components = URLComponents(url: request.baseURL ?? baseURL, resolvingAgainstBaseURL: true) else { return nil } guard var components = URLComponents(url: baseURL, resolvingAgainstBaseURL: true) else { return nil }
components.path = request.path components.path = request.path
components.queryItems = request.queryParameters.queryItems components.queryItems = request.queryParameters.queryItems
guard let url = components.url else { return nil } guard let url = components.url else { return nil }

View File

@ -11,7 +11,6 @@ import Foundation
public enum Timeline { public enum Timeline {
case home case home
case `public`(local: Bool) case `public`(local: Bool)
case instance(instanceURL: URL)
case tag(hashtag: String) case tag(hashtag: String)
case list(id: String) case list(id: String)
case direct case direct
@ -22,7 +21,7 @@ extension Timeline {
switch self { switch self {
case .home: case .home:
return "/api/v1/timelines/home" return "/api/v1/timelines/home"
case .public, .instance(_): case .public:
return "/api/v1/timelines/public" return "/api/v1/timelines/public"
case let .tag(hashtag): case let .tag(hashtag):
return "/api/v1/timelines/tag/\(hashtag)" return "/api/v1/timelines/tag/\(hashtag)"
@ -34,12 +33,7 @@ extension Timeline {
} }
func request(range: RequestRange) -> Request<[Status]> { func request(range: RequestRange) -> Request<[Status]> {
var request: Request<[Status]> var request = Request<[Status]>(method: .get, path: endpoint)
if case let .instance(instanceURL) = self {
request = Request<[Status]>(method: .get, baseURL: instanceURL, path: endpoint)
} else {
request = Request<[Status]>(method: .get, path: endpoint)
}
if case .public(true) = self { if case .public(true) = self {
request.queryParameters.append("local" => true) request.queryParameters.append("local" => true)
} }
@ -57,8 +51,6 @@ extension Timeline: Codable {
self = .home self = .home
case "public": case "public":
self = .public(local: try container.decode(Bool.self, forKey: .local)) self = .public(local: try container.decode(Bool.self, forKey: .local))
case "instanceURL":
self = .instance(instanceURL: try container.decode(URL.self, forKey: .instanceURL))
case "tag": case "tag":
self = .tag(hashtag: try container.decode(String.self, forKey: .hashtag)) self = .tag(hashtag: try container.decode(String.self, forKey: .hashtag))
case "list": case "list":
@ -78,9 +70,6 @@ extension Timeline: Codable {
case let .public(local): case let .public(local):
try container.encode("public", forKey: .type) try container.encode("public", forKey: .type)
try container.encode(local, forKey: .local) try container.encode(local, forKey: .local)
case let .instance(instanceURL):
try container.encode("instanceURL", forKey: .type)
try container.encode(instanceURL, forKey: .instanceURL)
case let .tag(hashtag): case let .tag(hashtag):
try container.encode("tag", forKey: .type) try container.encode("tag", forKey: .type)
try container.encode(hashtag, forKey: .hashtag) try container.encode(hashtag, forKey: .hashtag)
@ -95,7 +84,6 @@ extension Timeline: Codable {
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case type case type
case local case local
case instanceURL
case hashtag case hashtag
case listID case listID
} }

View File

@ -10,14 +10,12 @@ import Foundation
public struct Request<ResultType: Decodable> { public struct Request<ResultType: Decodable> {
let method: Method let method: Method
let baseURL: URL?
let path: String let path: String
let body: Body let body: Body
var queryParameters: [Parameter] var queryParameters: [Parameter]
init(method: Method, baseURL: URL? = nil, path: String, body: Body = .empty, queryParameters: [Parameter] = []) { init(method: Method, path: String, body: Body = .empty, queryParameters: [Parameter] = []) {
self.method = method self.method = method
self.baseURL = baseURL
self.path = path self.path = path
self.body = body self.body = body
self.queryParameters = queryParameters self.queryParameters = queryParameters

View File

@ -167,9 +167,6 @@
D6945C2F23AC47C3005C403C /* SavedHashtagsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C2E23AC47C3005C403C /* SavedHashtagsManager.swift */; }; D6945C2F23AC47C3005C403C /* SavedHashtagsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C2E23AC47C3005C403C /* SavedHashtagsManager.swift */; };
D6945C3223AC4D36005C403C /* HashtagTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C3123AC4D36005C403C /* HashtagTimelineViewController.swift */; }; D6945C3223AC4D36005C403C /* HashtagTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C3123AC4D36005C403C /* HashtagTimelineViewController.swift */; };
D6945C3423AC6431005C403C /* AddSavedHashtagViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */; }; D6945C3423AC6431005C403C /* AddSavedHashtagViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */; };
D6945C3623AC6C09005C403C /* SavedInstancesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C3523AC6C09005C403C /* SavedInstancesManager.swift */; };
D6945C3823AC739F005C403C /* InstanceTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C3723AC739F005C403C /* InstanceTimelineViewController.swift */; };
D6945C3A23AC75E2005C403C /* FindInstanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C3923AC75E2005C403C /* FindInstanceViewController.swift */; };
D6A3BC7723218E1300FD64D5 /* TimelineSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3BC7323218C6E00FD64D5 /* TimelineSegment.swift */; }; D6A3BC7723218E1300FD64D5 /* TimelineSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3BC7323218C6E00FD64D5 /* TimelineSegment.swift */; };
D6A3BC7923218E9200FD64D5 /* NotificationGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3BC7823218E9200FD64D5 /* NotificationGroup.swift */; }; D6A3BC7923218E9200FD64D5 /* NotificationGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3BC7823218E9200FD64D5 /* NotificationGroup.swift */; };
D6A3BC7C232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3BC7A232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift */; }; D6A3BC7C232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3BC7A232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift */; };
@ -444,9 +441,6 @@
D6945C2E23AC47C3005C403C /* SavedHashtagsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavedHashtagsManager.swift; sourceTree = "<group>"; }; D6945C2E23AC47C3005C403C /* SavedHashtagsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavedHashtagsManager.swift; sourceTree = "<group>"; };
D6945C3123AC4D36005C403C /* HashtagTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineViewController.swift; sourceTree = "<group>"; }; D6945C3123AC4D36005C403C /* HashtagTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineViewController.swift; sourceTree = "<group>"; };
D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSavedHashtagViewController.swift; sourceTree = "<group>"; }; D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSavedHashtagViewController.swift; sourceTree = "<group>"; };
D6945C3523AC6C09005C403C /* SavedInstancesManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavedInstancesManager.swift; sourceTree = "<group>"; };
D6945C3723AC739F005C403C /* InstanceTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceTimelineViewController.swift; sourceTree = "<group>"; };
D6945C3923AC75E2005C403C /* FindInstanceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FindInstanceViewController.swift; path = Tusker/Screens/FindInstanceViewController.swift; sourceTree = SOURCE_ROOT; };
D6A3BC7323218C6E00FD64D5 /* TimelineSegment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineSegment.swift; sourceTree = "<group>"; }; D6A3BC7323218C6E00FD64D5 /* TimelineSegment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineSegment.swift; sourceTree = "<group>"; };
D6A3BC7823218E9200FD64D5 /* NotificationGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationGroup.swift; sourceTree = "<group>"; }; D6A3BC7823218E9200FD64D5 /* NotificationGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationGroup.swift; sourceTree = "<group>"; };
D6A3BC7A232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionNotificationGroupTableViewCell.swift; sourceTree = "<group>"; }; D6A3BC7A232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionNotificationGroupTableViewCell.swift; sourceTree = "<group>"; };
@ -744,7 +738,6 @@
children = ( children = (
D627943D23A564D400D38C68 /* ExploreViewController.swift */, D627943D23A564D400D38C68 /* ExploreViewController.swift */,
D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */, D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */,
D6945C3923AC75E2005C403C /* FindInstanceViewController.swift */,
); );
path = Explore; path = Explore;
sourceTree = "<group>"; sourceTree = "<group>";
@ -795,6 +788,7 @@
D641C782213DD7F0004B4513 /* Main */, D641C782213DD7F0004B4513 /* Main */,
D641C783213DD7FE004B4513 /* Onboarding */, D641C783213DD7FE004B4513 /* Onboarding */,
D641C781213DD7DD004B4513 /* Timeline */, D641C781213DD7DD004B4513 /* Timeline */,
D6945C3023AC4D21005C403C /* Hashtag Timeline */,
D641C784213DD819004B4513 /* Profile */, D641C784213DD819004B4513 /* Profile */,
D641C785213DD83B004B4513 /* Conversation */, D641C785213DD83B004B4513 /* Conversation */,
D641C786213DD852004B4513 /* Notifications */, D641C786213DD852004B4513 /* Notifications */,
@ -818,8 +812,6 @@
children = ( children = (
D6BC9DD6232D7811002CA326 /* TimelinesPageViewController.swift */, D6BC9DD6232D7811002CA326 /* TimelinesPageViewController.swift */,
D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */, D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */,
D6945C3123AC4D36005C403C /* HashtagTimelineViewController.swift */,
D6945C3723AC739F005C403C /* InstanceTimelineViewController.swift */,
); );
path = Timeline; path = Timeline;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1073,6 +1065,14 @@
path = de.lproj; path = de.lproj;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
D6945C3023AC4D21005C403C /* Hashtag Timeline */ = {
isa = PBXGroup;
children = (
D6945C3123AC4D36005C403C /* HashtagTimelineViewController.swift */,
);
path = "Hashtag Timeline";
sourceTree = "<group>";
};
D6A3BC7223218C6E00FD64D5 /* Utilities */ = { D6A3BC7223218C6E00FD64D5 /* Utilities */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -1226,7 +1226,6 @@
D64D0AAC2128D88B005A6F37 /* LocalData.swift */, D64D0AAC2128D88B005A6F37 /* LocalData.swift */,
D627FF75217E923E00CC0648 /* DraftsManager.swift */, D627FF75217E923E00CC0648 /* DraftsManager.swift */,
D6945C2E23AC47C3005C403C /* SavedHashtagsManager.swift */, D6945C2E23AC47C3005C403C /* SavedHashtagsManager.swift */,
D6945C3523AC6C09005C403C /* SavedInstancesManager.swift */,
D6028B9A2150811100F223B9 /* MastodonCache.swift */, D6028B9A2150811100F223B9 /* MastodonCache.swift */,
D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */, D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */,
D6F1F84E2193B9BE00F5FE67 /* Caching */, D6F1F84E2193B9BE00F5FE67 /* Caching */,
@ -1654,7 +1653,6 @@
D68FEC4F232C5BC300C84F23 /* SegmentedPageViewController.swift in Sources */, D68FEC4F232C5BC300C84F23 /* SegmentedPageViewController.swift in Sources */,
0450531F22B0097E00100BA2 /* Timline+UI.swift in Sources */, 0450531F22B0097E00100BA2 /* Timline+UI.swift in Sources */,
D667E5F52135BCD50057A976 /* ConversationTableViewController.swift in Sources */, D667E5F52135BCD50057A976 /* ConversationTableViewController.swift in Sources */,
D6945C3623AC6C09005C403C /* SavedInstancesManager.swift in Sources */,
D6C7D27D22B6EBF800071952 /* AttachmentsContainerView.swift in Sources */, D6C7D27D22B6EBF800071952 /* AttachmentsContainerView.swift in Sources */,
D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */, D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */,
0411610022B442870030A9B7 /* AttachmentViewController.swift in Sources */, 0411610022B442870030A9B7 /* AttachmentViewController.swift in Sources */,
@ -1668,7 +1666,6 @@
D6028B9B2150811100F223B9 /* MastodonCache.swift in Sources */, D6028B9B2150811100F223B9 /* MastodonCache.swift in Sources */,
D6A3BC802321B7E600FD64D5 /* FollowNotificationGroupTableViewCell.swift in Sources */, D6A3BC802321B7E600FD64D5 /* FollowNotificationGroupTableViewCell.swift in Sources */,
D627944D23A9A03D00D38C68 /* ListTimelineViewController.swift in Sources */, D627944D23A9A03D00D38C68 /* ListTimelineViewController.swift in Sources */,
D6945C3823AC739F005C403C /* InstanceTimelineViewController.swift in Sources */,
D62D2422217AA7E1005076CC /* UserActivityManager.swift in Sources */, D62D2422217AA7E1005076CC /* UserActivityManager.swift in Sources */,
D60D2B8223844C71001B87A3 /* BaseStatusTableViewCell.swift in Sources */, D60D2B8223844C71001B87A3 /* BaseStatusTableViewCell.swift in Sources */,
D62D2424217ABF3F005076CC /* NSUserActivity+Extensions.swift in Sources */, D62D2424217ABF3F005076CC /* NSUserActivity+Extensions.swift in Sources */,
@ -1694,7 +1691,6 @@
D6DD353F22F502EC00A9563A /* Preferences+Notification.swift in Sources */, D6DD353F22F502EC00A9563A /* Preferences+Notification.swift in Sources */,
D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */, D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */,
D627944A23A6AD6100D38C68 /* BookmarksTableViewController.swift in Sources */, D627944A23A6AD6100D38C68 /* BookmarksTableViewController.swift in Sources */,
D6945C3A23AC75E2005C403C /* FindInstanceViewController.swift in Sources */,
D6AEBB4523216AF800E5038B /* FollowAccountActivity.swift in Sources */, D6AEBB4523216AF800E5038B /* FollowAccountActivity.swift in Sources */,
D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */, D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */,
D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */, D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */,

View File

@ -16,8 +16,6 @@ extension Timeline {
return "Home" return "Home"
case let .public(local): case let .public(local):
return local ? "Local" : "Federated" return local ? "Local" : "Federated"
case let .instance(instance):
return instance.host!
case let .tag(hashtag): case let .tag(hashtag):
return "#\(hashtag)" return "#\(hashtag)"
case .list: case .list:
@ -37,8 +35,6 @@ extension Timeline {
} else { } else {
return UIImage(systemName: "globe") return UIImage(systemName: "globe")
} }
case .instance(_):
return UIImage(systemName: "globe")
default: default:
return nil return nil
} }

View File

@ -16,7 +16,7 @@ class SavedHashtagsManager: Codable {
private static var archiveURL = SavedHashtagsManager.documentsDirectory.appendingPathComponent("saved_hashtags").appendingPathExtension("plist") private static var archiveURL = SavedHashtagsManager.documentsDirectory.appendingPathComponent("saved_hashtags").appendingPathExtension("plist")
static func save() { static func save() {
DispatchQueue.global(qos: .utility).async { DispatchQueue.global(qos: .userInitiated).async {
let encoder = PropertyListEncoder() let encoder = PropertyListEncoder()
let data = try? encoder.encode(shared) let data = try? encoder.encode(shared)
try? data?.write(to: archiveURL, options: .noFileProtection) try? data?.write(to: archiveURL, options: .noFileProtection)
@ -36,7 +36,7 @@ class SavedHashtagsManager: Codable {
private var savedHashtags: [Hashtag] = [] private var savedHashtags: [Hashtag] = []
var sorted: [Hashtag] { var sorted: [Hashtag] {
return savedHashtags.sorted(by: { $0.name < $1.name }) return savedHashtags.sorted(by: { $0.name > $1.name })
} }
func isSaved(_ hashtag: Hashtag) -> Bool { func isSaved(_ hashtag: Hashtag) -> Bool {

View File

@ -1,61 +0,0 @@
//
// SavedInstancesManager.swift
// Tusker
//
// Created by Shadowfacts on 12/19/19.
// Copyright © 2019 Shadowfacts. All rights reserved.
//
import Foundation
class SavedInstanceManager: Codable {
private(set) static var shared: SavedInstanceManager = load()
private static var documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
private static var archiveURL = SavedInstanceManager.documentsDirectory.appendingPathComponent("saved_instances").appendingPathExtension("plist")
static func save() {
DispatchQueue.global(qos: .utility).async {
let encoder = PropertyListEncoder()
let data = try? encoder.encode(shared)
try? data?.write(to: archiveURL, options: .noFileProtection)
}
}
static func load() -> SavedInstanceManager {
let decoder = PropertyListDecoder()
if let data = try? Data(contentsOf: archiveURL),
let savedInstanceManager = try? decoder.decode(Self.self, from: data) {
return savedInstanceManager
}
return SavedInstanceManager()
}
private init() {}
private(set) var savedInstances: [URL] = []
func isSaved(_ url: URL) -> Bool {
return savedInstances.contains(url)
}
func add(_ url: URL) {
if isSaved(url) {
return
}
savedInstances.append(url)
SavedInstanceManager.save()
NotificationCenter.default.post(name: .savedInstancesChanged, object: nil)
}
func remove(_ url: URL) {
guard isSaved(url) else { return }
savedInstances.removeAll(where: { $0 == url })
SavedInstanceManager.save()
NotificationCenter.default.post(name: .savedInstancesChanged, object: nil)
}
}
extension Notification.Name {
static let savedInstancesChanged = Notification.Name("savedInstancesChanged")
}

View File

@ -61,16 +61,6 @@ class ExploreViewController: EnhancedTableViewController {
cell.imageView!.image = UIImage(systemName: "plus") cell.imageView!.image = UIImage(systemName: "plus")
cell.textLabel!.text = NSLocalizedString("Save Hashtag...", comment: "save hashtag nav item title") cell.textLabel!.text = NSLocalizedString("Save Hashtag...", comment: "save hashtag nav item title")
cell.accessoryType = .none cell.accessoryType = .none
case let .savedInstance(url):
cell.imageView!.image = UIImage(systemName: "globe")
cell.textLabel!.text = url.host!
cell.accessoryType = .disclosureIndicator
case .findInstance:
cell.imageView!.image = UIImage(systemName: "magnifyingglass")
cell.textLabel!.text = NSLocalizedString("Find An Instance...", comment: "find instance nav item title")
cell.accessoryType = .none
} }
return cell return cell
@ -78,11 +68,10 @@ class ExploreViewController: EnhancedTableViewController {
dataSource.exploreController = self dataSource.exploreController = self
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>() var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.bookmarks, .lists, .savedHashtags, .savedInstances]) snapshot.appendSections([.bookmarks, .lists, .savedHashtags])
snapshot.appendItems([.bookmarks], toSection: .bookmarks) snapshot.appendItems([.bookmarks], toSection: .bookmarks)
snapshot.appendItems([.addList], toSection: .lists) snapshot.appendItems([.addList], toSection: .lists)
snapshot.appendItems(SavedHashtagsManager.shared.sorted.map { .savedHashtag($0) } + [.addSavedHashtag], toSection: .savedHashtags) snapshot.appendItems(SavedHashtagsManager.shared.sorted.map { .savedHashtag($0) } + [.addSavedHashtag], toSection: .savedHashtags)
snapshot.appendItems(SavedInstanceManager.shared.savedInstances.map { .savedInstance($0) } + [.findInstance], toSection: .savedInstances)
// the initial, static items should not be displayed with an animation // the initial, static items should not be displayed with an animation
UIView.performWithoutAnimation { UIView.performWithoutAnimation {
dataSource.apply(snapshot) dataSource.apply(snapshot)
@ -100,7 +89,6 @@ class ExploreViewController: EnhancedTableViewController {
navigationItem.hidesSearchBarWhenScrolling = false navigationItem.hidesSearchBarWhenScrolling = false
NotificationCenter.default.addObserver(self, selector: #selector(savedHashtagsChanged), name: .savedHashtagsChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(savedHashtagsChanged), name: .savedHashtagsChanged, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(savedInstancesChanged), name: .savedInstancesChanged, object: nil)
reloadLists() reloadLists()
} }
@ -129,13 +117,6 @@ class ExploreViewController: EnhancedTableViewController {
dataSource.apply(snapshot) dataSource.apply(snapshot)
} }
@objc func savedInstancesChanged() {
var snapshot = dataSource.snapshot()
snapshot.deleteItems(snapshot.itemIdentifiers(inSection: .savedInstances))
snapshot.appendItems(SavedInstanceManager.shared.savedInstances.map { .savedInstance($0) } + [.findInstance], toSection: .savedInstances)
dataSource.apply(snapshot)
}
func deleteList(_ list: List) { func deleteList(_ list: List) {
let title = String(format: NSLocalizedString("Are you sure want to delete the '%@' list?", comment: "delete list alert title"), list.title) let title = String(format: NSLocalizedString("Are you sure want to delete the '%@' list?", comment: "delete list alert title"), list.title)
let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert) let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert)
@ -162,10 +143,6 @@ class ExploreViewController: EnhancedTableViewController {
SavedHashtagsManager.shared.remove(hashtag) SavedHashtagsManager.shared.remove(hashtag)
} }
func removeSavedInstance(_ instanceURL: URL) {
SavedInstanceManager.shared.remove(instanceURL)
}
// MARK: - Table view delegate // MARK: - Table view delegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
@ -196,9 +173,7 @@ class ExploreViewController: EnhancedTableViewController {
self.reloadLists() self.reloadLists()
DispatchQueue.main.async { DispatchQueue.main.async {
let listTimelineController = ListTimelineViewController(for: list) self.show(ListTimelineViewController(for: list), sender: nil)
listTimelineController.presentEditOnAppear = true
self.show(listTimelineController, sender: nil)
} }
} }
})) }))
@ -211,16 +186,6 @@ class ExploreViewController: EnhancedTableViewController {
tableView.selectRow(at: nil, animated: true, scrollPosition: .none) tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
let navController = UINavigationController(rootViewController: AddSavedHashtagViewController()) let navController = UINavigationController(rootViewController: AddSavedHashtagViewController())
present(navController, animated: true) present(navController, animated: true)
case let .savedInstance(url):
show(InstanceTimelineViewController(for: url), sender: nil)
case .findInstance:
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
let findController = FindInstanceViewController()
findController.instanceTimelineDelegate = self
let navController = UINavigationController(rootViewController: findController)
present(navController, animated: true)
} }
} }
@ -235,7 +200,6 @@ extension ExploreViewController {
case bookmarks case bookmarks
case lists case lists
case savedHashtags case savedHashtags
case savedInstances
} }
enum Item: Hashable { enum Item: Hashable {
case bookmarks case bookmarks
@ -243,8 +207,6 @@ extension ExploreViewController {
case addList case addList
case savedHashtag(Hashtag) case savedHashtag(Hashtag)
case addSavedHashtag case addSavedHashtag
case savedInstance(URL)
case findInstance
static func == (lhs: ExploreViewController.Item, rhs: ExploreViewController.Item) -> Bool { static func == (lhs: ExploreViewController.Item, rhs: ExploreViewController.Item) -> Bool {
switch (lhs, rhs) { switch (lhs, rhs) {
@ -258,10 +220,6 @@ extension ExploreViewController {
return a == b return a == b
case (.addSavedHashtag, .addSavedHashtag): case (.addSavedHashtag, .addSavedHashtag):
return true return true
case let (.savedInstance(a), .savedInstance(b)):
return a == b
case (.findInstance, .findInstance):
return true
default: default:
return false return false
} }
@ -280,11 +238,6 @@ extension ExploreViewController {
hasher.combine(hashtag.name) hasher.combine(hashtag.name)
case .addSavedHashtag: case .addSavedHashtag:
hasher.combine("addSavedHashtag") hasher.combine("addSavedHashtag")
case let .savedInstance(url):
hasher.combine("savedInstance")
hasher.combine(url)
case .findInstance:
hasher.combine("findInstance")
} }
} }
} }
@ -299,8 +252,6 @@ extension ExploreViewController {
return NSLocalizedString("Lists", comment: "explore lists section title") return NSLocalizedString("Lists", comment: "explore lists section title")
case 2: case 2:
return NSLocalizedString("Saved Hashtags", comment: "explore saved hashtags section title") return NSLocalizedString("Saved Hashtags", comment: "explore saved hashtags section title")
case 3:
return NSLocalizedString("Instance Timelines", comment: "explore instance timelines section title")
default: default:
return nil return nil
} }
@ -312,8 +263,6 @@ extension ExploreViewController {
return true return true
case .savedHashtag(_): case .savedHashtag(_):
return true return true
case .savedInstance(_):
return true
default: default:
return false return false
} }
@ -330,8 +279,6 @@ extension ExploreViewController {
exploreController.deleteList(list) exploreController.deleteList(list)
case let .savedHashtag(hashtag): case let .savedHashtag(hashtag):
exploreController.removeSavedHashtag(hashtag) exploreController.removeSavedHashtag(hashtag)
case let .savedInstance(url):
exploreController.removeSavedInstance(url)
default: default:
return return
} }
@ -340,15 +287,3 @@ extension ExploreViewController {
} }
} }
extension ExploreViewController: InstanceTimelineViewControllerDelegate {
func didSaveInstance(url: URL) {
dismiss(animated: true) {
self.show(InstanceTimelineViewController(for: url), sender: nil)
}
}
func didUnsaveInstance(url: URL) {
dismiss(animated: true)
}
}

View File

@ -1,39 +0,0 @@
//
// FindInstanceViewController.swift
// Tusker
//
// Created by Shadowfacts on 12/19/19.
// Copyright © 2019 Shadowfacts. All rights reserved.
//
import UIKit
class FindInstanceViewController: InstanceSelectorTableViewController {
var instanceTimelineDelegate: InstanceTimelineViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
searchController.hidesNavigationBarDuringPresentation = false
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelButtonPressed))
}
// MARK: - Interaction
@objc func cancelButtonPressed() {
dismiss(animated: true)
}
}
extension FindInstanceViewController: InstanceSelectorTableViewControllerDelegate {
func didSelectInstance(url: URL) {
let instanceTimelineController = InstanceTimelineViewController(for: url)
instanceTimelineController.delegate = instanceTimelineDelegate
show(instanceTimelineController, sender: self)
}
}

View File

@ -13,8 +13,6 @@ class ListTimelineViewController: TimelineTableViewController {
let list: List let list: List
var presentEditOnAppear = false
init(for list: List) { init(for list: List) {
self.list = list self.list = list
@ -33,25 +31,13 @@ class ListTimelineViewController: TimelineTableViewController {
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editButtonPressed)) navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editButtonPressed))
} }
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if presentEditOnAppear {
presentEdit(animated: animated)
}
}
func presentEdit(animated: Bool) {
let editListAccountsController = EditListAccountsViewController(list: list)
editListAccountsController.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonPressed))
let navController = UINavigationController(rootViewController: editListAccountsController)
present(navController, animated: animated)
}
// MARK: - Interaction // MARK: - Interaction
@objc func editButtonPressed() { @objc func editButtonPressed() {
presentEdit(animated: true) let editListAccountsController = EditListAccountsViewController(list: list)
editListAccountsController.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonPressed))
let navController = UINavigationController(rootViewController: editListAccountsController)
present(navController, animated: true)
} }
@objc func doneButtonPressed() { @objc func doneButtonPressed() {

View File

@ -1,71 +0,0 @@
//
// InstanceTimelineViewController.swift
// Tusker
//
// Created by Shadowfacts on 12/19/19.
// Copyright © 2019 Shadowfacts. All rights reserved.
//
import UIKit
protocol InstanceTimelineViewControllerDelegate {
func didSaveInstance(url: URL)
func didUnsaveInstance(url: URL)
}
class InstanceTimelineViewController: TimelineTableViewController {
var delegate: InstanceTimelineViewControllerDelegate?
let instanceURL: URL
var toggleSaveButton: UIBarButtonItem!
var toggleSaveButtonTitle: String {
if SavedInstanceManager.shared.isSaved(instanceURL) {
return NSLocalizedString("Unsave", comment: "unsave instance button")
} else {
return NSLocalizedString("Save", comment: "save instance button")
}
}
init(for url: URL) {
self.instanceURL = url
super.init(for: .instance(instanceURL: url))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
toggleSaveButton = UIBarButtonItem(title: toggleSaveButtonTitle, style: .plain, target: self, action: #selector(toggleSaveButtonPressed))
navigationItem.rightBarButtonItem = toggleSaveButton
NotificationCenter.default.addObserver(self, selector: #selector(savedInstancesChanged), name: .savedInstancesChanged, object: nil)
}
@objc func savedInstancesChanged() {
toggleSaveButton.title = toggleSaveButtonTitle
}
// MARK: - Table view delegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// no-op, we don't currently support viewing whole conversations from other instances
}
// MARK: - Interaction
@objc func toggleSaveButtonPressed() {
if SavedInstanceManager.shared.isSaved(instanceURL) {
SavedInstanceManager.shared.remove(instanceURL)
delegate?.didUnsaveInstance(url: instanceURL)
} else {
SavedInstanceManager.shared.add(instanceURL)
delegate?.didSaveInstance(url: instanceURL)
}
}
}

View File

@ -100,9 +100,6 @@ class UserActivityManager {
case .public(local: false): case .public(local: false):
activity.title = NSLocalizedString("Show Federated Timeline", comment: "federated timeline shortcut title") activity.title = NSLocalizedString("Show Federated Timeline", comment: "federated timeline shortcut title")
activity.suggestedInvocationPhrase = NSLocalizedString("Show my federated timeline", comment: "federated timeline invocation phrase") activity.suggestedInvocationPhrase = NSLocalizedString("Show my federated timeline", comment: "federated timeline invocation phrase")
case let .instance(instance):
activity.title = String(format: NSLocalizedString("Show %@", comment: "show instance timeline shortcut title"), instance.host!)
activity.suggestedInvocationPhrase = String(format: NSLocalizedString("Show the instance %@", comment: "instance timeline shortcut invocation phrase"), instance.host!)
case let .tag(hashtag): case let .tag(hashtag):
activity.title = String(format: NSLocalizedString("Show #%@", comment: "show hashtag shortcut title"), hashtag) activity.title = String(format: NSLocalizedString("Show #%@", comment: "show hashtag shortcut title"), hashtag)
activity.suggestedInvocationPhrase = String(format: NSLocalizedString("Show the %@ hashtag", comment: "hashtag shortcut invocation phrase"), hashtag) activity.suggestedInvocationPhrase = String(format: NSLocalizedString("Show the %@ hashtag", comment: "hashtag shortcut invocation phrase"), hashtag)