From bf09b80a5ae9c111bbd108d233ba98d1f65f9752 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Mon, 17 Sep 2018 19:22:37 -0400 Subject: [PATCH] Change Pachyderm models to be immutable --- Pachyderm/Client.swift | 3 +- Pachyderm/Model/Account.swift | 76 +++----- Pachyderm/Model/Application.swift | 4 +- Pachyderm/Model/Attachment.swift | 15 +- Pachyderm/Model/Card.swift | 4 +- Pachyderm/Model/ConversationContext.swift | 13 +- Pachyderm/Model/Emoji.swift | 4 +- Pachyderm/Model/Filter.swift | 39 ++-- Pachyderm/Model/Hashtag.swift | 4 +- Pachyderm/Model/Instance.swift | 8 +- Pachyderm/Model/List.swift | 34 ++-- Pachyderm/Model/Mention.swift | 4 +- Pachyderm/Model/Notification.swift | 16 +- Pachyderm/Model/PushSubscription.swift | 4 +- Pachyderm/Model/Relationship.swift | 4 +- Pachyderm/Model/Report.swift | 4 +- Pachyderm/Model/SearchResults.swift | 13 +- Pachyderm/Model/Status.swift | 173 ++++-------------- Pachyderm/Request/Request.swift | 2 +- .../ConversationViewController.swift | 3 +- .../Profile/ProfileTableViewController.swift | 3 +- .../TimelineTableViewController.swift | 6 +- .../ConversationMainStatusTableViewCell.swift | 6 +- Tusker/Views/Status/StatusTableViewCell.swift | 12 +- 24 files changed, 142 insertions(+), 312 deletions(-) diff --git a/Pachyderm/Client.swift b/Pachyderm/Client.swift index 48c2e28d7a..a2fbf7fd88 100644 --- a/Pachyderm/Client.swift +++ b/Pachyderm/Client.swift @@ -42,8 +42,7 @@ public class Client { self.session = session } - // MARK: - Internal Helpers - func run(_ request: Request, completion: @escaping Callback) { + public func run(_ request: Request, completion: @escaping Callback) { guard let request = createURLRequest(request: request) else { completion(.failure(Error.invalidRequest)) return diff --git a/Pachyderm/Model/Account.swift b/Pachyderm/Model/Account.swift index 04cd78e7e2..7c7338b9ea 100644 --- a/Pachyderm/Model/Account.swift +++ b/Pachyderm/Model/Account.swift @@ -8,13 +8,7 @@ import Foundation -public class Account: Decodable, ClientModel { - var client: Client! { - didSet { - emojis.client = client - } - } - +public class Account: Decodable { public let id: String public let username: String public let acct: String @@ -35,78 +29,68 @@ public class Account: Decodable, ClientModel { public let fields: [Field]? public let bot: Bool? - public func authorizeFollowRequest(completion: @escaping Client.Callback) { - let request = Request(method: .post, path: "/api/v1/follow_requests/\(id)/authorize") - client.run(request, completion: completion) + public static func authorizeFollowRequest(_ account: Account) -> Request { + return Request(method: .post, path: "/api/v1/follow_requests/\(account.id)/authorize") } - public func rejectFollowRequest(completion: @escaping Client.Callback) { - let request = Request(method: .post, path: "/api/v1/follow_requests/\(id)/reject") - client.run(request, completion: completion) + public static func rejectFollowRequest(_ account: Account) -> Request { + return Request(method: .post, path: "/api/v1/follow_requests/\(account.id)/reject") } - public func removeFromFollowRequests(completion: @escaping Client.Callback) { - let request = Request(method: .delete, path: "/api/v1/suggestions/\(id)") - client.run(request, completion: completion) + public static func removeFromFollowRequests(_ account: Account) -> Request { + return Request(method: .delete, path: "/api/v1/suggestions/\(account.id)") } - public func getFollowers(range: RequestRange = .default, completion: @escaping Client.Callback<[Account]>) { - var request = Request<[Account]>(method: .get, path: "/api/v1/accounts/\(id)/followers") + public static func getFollowers(_ account: Account, range: RequestRange = .default) -> Request<[Account]> { + var request = Request<[Account]>(method: .get, path: "/api/v1/accounts/\(account.id)/followers") request.range = range - client.run(request, completion: completion) + return request } - public func getFollowing(range: RequestRange = .default, completion: @escaping Client.Callback<[Account]>) { - var request = Request<[Account]>(method: .get, path: "/api/v1/accounts/\(id)/following") + public static func getFollowing(_ account: Account, range: RequestRange = .default) -> Request<[Account]> { + var request = Request<[Account]>(method: .get, path: "/api/v1/accounts/\(account.id)/following") request.range = range - client.run(request, completion: completion) + return request } - public func getStatuses(range: RequestRange = .default, onlyMedia: Bool? = nil, pinned: Bool? = nil, excludeReplies: Bool? = nil, completion: @escaping Client.Callback<[Status]>) { - var request = Request<[Status]>(method: .get, path: "/api/v1/accounts/\(id)/statuses", queryParameters: [ + public static func getStatuses(_ account: Account, range: RequestRange = .default, onlyMedia: Bool? = nil, pinned: Bool? = nil, excludeReplies: Bool? = nil) -> Request<[Status]> { + var request = Request<[Status]>(method: .get, path: "/api/v1/accounts/\(account.id)/statuses", queryParameters: [ "only_media" => onlyMedia, "pinned" => pinned, "exclude_replies" => excludeReplies ]) request.range = range - client.run(request, completion: completion) + return request } - public func follow(completion: @escaping Client.Callback) { - let request = Request(method: .post, path: "/api/v1/accounts/\(id)/follow") - client.run(request, completion: completion) + public static func follow(_ account: Account) -> Request { + return Request(method: .post, path: "/api/v1/accounts/\(account.id)/follow") } - public func unfollow(completion: @escaping Client.Callback) { - let request = Request(method: .post, path: "/api/v1/accounts/\(id)/unfollow") - client.run(request, completion: completion) + public static func unfollow(_ account: Account) -> Request { + return Request(method: .post, path: "/api/v1/accounts/\(account.id)/unfollow") } - public func block(completion: @escaping Client.Callback) { - let request = Request(method: .post, path: "/api/v1/accounts/\(id)/block") - client.run(request, completion: completion) + public static func block(_ account: Account) -> Request { + return Request(method: .post, path: "/api/v1/accounts/\(account.id)/block") } - public func unblock(completion: @escaping Client.Callback) { - let request = Request(method: .post, path: "/api/v1/accounts/\(id)/unblock") - client.run(request, completion: completion) + public static func unblock(_ account: Account) -> Request { + return Request(method: .post, path: "/api/v1/accounts/\(account.id)/unblock") } - public func mute(notifications: Bool? = nil, completion: @escaping Client.Callback) { - let request = Request(method: .post, path: "/api/v1/accounts/\(id)/mute", body: .parameters([ + public static func mute(_ account: Account, notifications: Bool? = nil) -> Request { + return Request(method: .post, path: "/api/v1/accounts/\(account.id)/mute", body: .parameters([ "notifications" => notifications ])) - client.run(request, completion: completion) } - public func unmute(completion: @escaping Client.Callback) { - let request = Request(method: .post, path: "/api/v1/accounts/\(id)/unmute") - client.run(request, completion: completion) + public static func unmute(_ account: Account) -> Request { + return Request(method: .post, path: "/api/v1/accounts/\(account.id)/unmute") } - public func getLists(completion: @escaping Client.Callback<[List]>) { - let request = Request<[List]>(method: .get, path: "/api/v1/accounts/\(id)/lists") - client.run(request, completion: completion) + public static func getLists(_ account: Account) -> Request<[List]> { + return Request<[List]>(method: .get, path: "/api/v1/accounts/\(account.id)/lists") } private enum CodingKeys: String, CodingKey { diff --git a/Pachyderm/Model/Application.swift b/Pachyderm/Model/Application.swift index 560791857f..fa6401359f 100644 --- a/Pachyderm/Model/Application.swift +++ b/Pachyderm/Model/Application.swift @@ -8,9 +8,7 @@ import Foundation -public class Application: Decodable, ClientModel { - var client: Client! - +public class Application: Decodable { public let name: String public let website: URL? diff --git a/Pachyderm/Model/Attachment.swift b/Pachyderm/Model/Attachment.swift index 83700a90d1..063f70650f 100644 --- a/Pachyderm/Model/Attachment.swift +++ b/Pachyderm/Model/Attachment.swift @@ -8,9 +8,7 @@ import Foundation -public class Attachment: Decodable, ClientModel { - var client: Client! - +public class Attachment: Decodable { public let id: String public let kind: Kind public let url: URL @@ -18,16 +16,13 @@ public class Attachment: Decodable, ClientModel { public let previewURL: URL public let textURL: URL? public let meta: Metadata? - public var description: String? + public let description: String? - public func update(focus: (Float, Float)?, completion: Client.Callback?) { - let request = Request(method: .put, path: "/api/v1/media/\(id)", body: .formData([ - "description" => description, + public static func update(_ attachment: Attachment, focus: (Float, Float)?, description: String?) -> Request { + return Request(method: .put, path: "/api/v1/media/\(attachment.id)", body: .formData([ + "description" => (description ?? attachment.description), "focus" => focus ], nil)) - client.run(request) { result in - completion?(result) - } } private enum CodingKeys: String, CodingKey { diff --git a/Pachyderm/Model/Card.swift b/Pachyderm/Model/Card.swift index e75f35890a..16f4de8679 100644 --- a/Pachyderm/Model/Card.swift +++ b/Pachyderm/Model/Card.swift @@ -8,9 +8,7 @@ import Foundation -public class Card: Decodable, ClientModel { - var client: Client! - +public class Card: Decodable { public let url: URL public let title: String public let description: String diff --git a/Pachyderm/Model/ConversationContext.swift b/Pachyderm/Model/ConversationContext.swift index 4fa407b23c..014a12925a 100644 --- a/Pachyderm/Model/ConversationContext.swift +++ b/Pachyderm/Model/ConversationContext.swift @@ -8,16 +8,9 @@ import Foundation -public class ConversationContext: Decodable, ClientModel { - var client: Client! { - didSet { - ancestors.client = client - descendants.client = client - } - } - - public private(set) var ancestors: [Status] - public private(set) var descendants: [Status] +public class ConversationContext: Decodable { + public let ancestors: [Status] + public let descendants: [Status] private enum CodingKeys: String, CodingKey { case ancestors diff --git a/Pachyderm/Model/Emoji.swift b/Pachyderm/Model/Emoji.swift index 4bf47fece5..2ea10b605c 100644 --- a/Pachyderm/Model/Emoji.swift +++ b/Pachyderm/Model/Emoji.swift @@ -8,9 +8,7 @@ import Foundation -public class Emoji: Decodable, ClientModel { - var client: Client! - +public class Emoji: Decodable { let shortcode: String let url: URL let staticURL: URL diff --git a/Pachyderm/Model/Filter.swift b/Pachyderm/Model/Filter.swift index 17decf5470..7035b47453 100644 --- a/Pachyderm/Model/Filter.swift +++ b/Pachyderm/Model/Filter.swift @@ -8,40 +8,31 @@ import Foundation -public class Filter: Decodable, ClientModel { - var client: Client! - +public class Filter: Decodable { public let id: String - public var phrase: String - private var context: [String] - public var expiresAt: Date? - public var irreversible: Bool - public var wholeWord: Bool + public let phrase: String + private let context: [String] + public let expiresAt: Date? + public let irreversible: Bool + public let wholeWord: Bool public var contexts: [Context] { get { return context.compactMap(Context.init) } - set { - context = contexts.contextStrings - } } - public func update(completion: Client.Callback?) { - let request = Request(method: .put, path: "/api/v1/filters/\(id)", body: .parameters([ - "phrase" => phrase, - "irreversible" => irreversible, - "whole_word" => wholeWord, - "expires_at" => expiresAt - ] + "context" => context)) - client.run(request) { result in - completion?(result) - } + public static func update(_ filter: Filter, phrase: String? = nil, context: [Context]? = nil, irreversible: Bool? = nil, wholeWord: Bool? = nil, expiresAt: Date? = nil) -> Request { + return Request(method: .put, path: "/api/v1/filters/\(filter.id)", body: .parameters([ + "phrase" => (phrase ?? filter.phrase), + "irreversible" => (irreversible ?? filter.irreversible), + "whole_word" => (wholeWord ?? filter.wholeWord), + "expires_at" => (expiresAt ?? filter.expiresAt) + ] + "context" => (context?.contextStrings ?? filter.context))) } - public func delete(completion: @escaping Client.Callback) { - let request = Request(method: .delete, path: "/api/v1/filters/\(id)") - client.run(request, completion: completion) + public static func delete(_ filter: Filter) -> Request { + return Request(method: .delete, path: "/api/v1/filters/\(filter.id)") } private enum CodingKeys: String, CodingKey { diff --git a/Pachyderm/Model/Hashtag.swift b/Pachyderm/Model/Hashtag.swift index be93e06217..315f28d793 100644 --- a/Pachyderm/Model/Hashtag.swift +++ b/Pachyderm/Model/Hashtag.swift @@ -8,9 +8,7 @@ import Foundation -public class Hashtag: Decodable, ClientModel { - var client: Client! - +public class Hashtag: Decodable { public let name: String public let url: URL public let history: [History]? diff --git a/Pachyderm/Model/Instance.swift b/Pachyderm/Model/Instance.swift index 8adfa99fa0..4f907f4d18 100644 --- a/Pachyderm/Model/Instance.swift +++ b/Pachyderm/Model/Instance.swift @@ -8,13 +8,7 @@ import Foundation -public class Instance: Decodable, ClientModel { - var client: Client! { - didSet { - contactAccount.client = client - } - } - +public class Instance: Decodable { public let uri: String public let title: String public let description: String diff --git a/Pachyderm/Model/List.swift b/Pachyderm/Model/List.swift index f723d475e3..19804c0617 100644 --- a/Pachyderm/Model/List.swift +++ b/Pachyderm/Model/List.swift @@ -8,42 +8,34 @@ import Foundation -public class List: Decodable, ClientModel { - var client: Client! - +public class List: Decodable { public let id: String - public var title: String + public let title: String - public func getAccounts(range: RequestRange = .default, completion: @escaping Client.Callback<[Account]>) { - var request = Request<[Account]>(method: .get, path: "/api/v1/lists/\(id)/accounts") + public static func getAccounts(_ list: List, range: RequestRange = .default) -> Request<[Account]> { + var request = Request<[Account]>(method: .get, path: "/api/v1/lists/\(list.id)/accounts") request.range = range - client.run(request, completion: completion) + return request } - public func update(completion: Client.Callback?) { - let request = Request(method: .put, path: "/api/v1/lists/\(id)", body: .parameters(["title" => title])) - client.run(request) { result in - completion?(result) - } + public static func update(_ list: List, title: String) -> Request { + return Request(method: .put, path: "/api/v1/lists/\(list.id)", body: .parameters(["title" => title])) } - public func delete(completion: @escaping Client.Callback) { - let request = Request(method: .delete, path: "/api/v1/lists/\(id)") - client.run(request, completion: completion) + public static func delete(_ list: List) -> Request { + return Request(method: .delete, path: "/api/v1/lists/\(list.id)") } - public func add(accounts: [Account], completion: @escaping Client.Callback) { - let request = Request(method: .post, path: "/api/v1/lists/\(id)/accounts", body: .parameters( + public static func add(_ list: List, accounts: [Account]) -> Request { + return Request(method: .post, path: "/api/v1/lists/\(list.id)/accounts", body: .parameters( "account_ids" => accounts.map { $0.id } )) - client.run(request, completion: completion) } - public func remove(accounts: [Account], completion: @escaping Client.Callback) { - let request = Request(method: .delete, path: "/api/v1/lists/\(id)/accounts", body: .parameters( + public static func remove(_ list: List, accounts: [Account]) -> Request { + return Request(method: .delete, path: "/api/v1/lists/\(list.id)/accounts", body: .parameters( "account_ids" => accounts.map { $0.id } )) - client.run(request, completion: completion) } private enum CodingKeys: String, CodingKey { diff --git a/Pachyderm/Model/Mention.swift b/Pachyderm/Model/Mention.swift index 1935e89b98..ea086f34d4 100644 --- a/Pachyderm/Model/Mention.swift +++ b/Pachyderm/Model/Mention.swift @@ -8,9 +8,7 @@ import Foundation -public class Mention: Decodable, ClientModel { - var client: Client! - +public class Mention: Decodable { public let url: URL public let username: String public let acct: String diff --git a/Pachyderm/Model/Notification.swift b/Pachyderm/Model/Notification.swift index b282b417af..5a2b09b6dc 100644 --- a/Pachyderm/Model/Notification.swift +++ b/Pachyderm/Model/Notification.swift @@ -8,25 +8,17 @@ import Foundation -public class Notification: Decodable, ClientModel { - var client: Client! { - didSet { - account.client = client - status?.client = client - } - } - +public class Notification: Decodable { public let id: String public let kind: Kind public let createdAt: Date public let account: Account public let status: Status? - public func dismiss(completion: @escaping Client.Callback) { - let request = Request(method: .post, path: "/api/v1/notifications/dismiss", body: .parameters([ - "id" => id + public static func dismiss(_ notification: Notification) -> Request { + return Request(method: .post, path: "/api/v1/notifications/dismiss", body: .parameters([ + "id" => notification.id ])) - client.run(request, completion: completion) } private enum CodingKeys: String, CodingKey { diff --git a/Pachyderm/Model/PushSubscription.swift b/Pachyderm/Model/PushSubscription.swift index 95a8ddbfb8..b6812966dd 100644 --- a/Pachyderm/Model/PushSubscription.swift +++ b/Pachyderm/Model/PushSubscription.swift @@ -8,9 +8,7 @@ import Foundation -public class PushSubscription: Decodable, ClientModel { - var client: Client! - +public class PushSubscription: Decodable { public let id: String public let endpoint: URL public let serverKey: String diff --git a/Pachyderm/Model/Relationship.swift b/Pachyderm/Model/Relationship.swift index 53eb90d6a6..39f4f99caa 100644 --- a/Pachyderm/Model/Relationship.swift +++ b/Pachyderm/Model/Relationship.swift @@ -8,9 +8,7 @@ import Foundation -public class Relationship: Decodable, ClientModel { - var client: Client! - +public class Relationship: Decodable { public let id: String public let following: Bool public let followedBy: Bool diff --git a/Pachyderm/Model/Report.swift b/Pachyderm/Model/Report.swift index 2748f6dacf..c95582fc8a 100644 --- a/Pachyderm/Model/Report.swift +++ b/Pachyderm/Model/Report.swift @@ -8,9 +8,7 @@ import Foundation -public class Report: Decodable, ClientModel { - var client: Client! - +public class Report: Decodable { public let id: String public let actionTaken: Bool diff --git a/Pachyderm/Model/SearchResults.swift b/Pachyderm/Model/SearchResults.swift index 4494b6845b..07806b8286 100644 --- a/Pachyderm/Model/SearchResults.swift +++ b/Pachyderm/Model/SearchResults.swift @@ -8,16 +8,9 @@ import Foundation -public class SearchResults: Decodable, ClientModel { - var client: Client! { - didSet { - accounts.client = client - statuses.client = client - } - } - - public private(set) var accounts: [Account] - public private(set) var statuses: [Status] +public class SearchResults: Decodable { + public let accounts: [Account] + public let statuses: [Status] public let hashtags: [String] private enum CodingKeys: String, CodingKey { diff --git a/Pachyderm/Model/Status.swift b/Pachyderm/Model/Status.swift index ca65c03fc4..0cbc248b04 100644 --- a/Pachyderm/Model/Status.swift +++ b/Pachyderm/Model/Status.swift @@ -8,183 +8,88 @@ import Foundation -public class Status: Decodable, ClientModel { - var client: Client! { - didSet { - didSetClient() - } - } - // when reblog.client is set directly from self.client didSet, reblog.client didSet is never called - private func didSetClient() { - account.client = client - reblog?.client = client - emojis.client = client - attachments.client = client - mentions.client = client - hashtags.client = client - application?.client = client - } - +public class Status: Decodable { public let id: String public let uri: String public let url: URL? public let account: Account public let inReplyToID: String? public let inReplyToAccountID: String? - public private(set) var reblog: Status? + public let reblog: Status? public let content: String public let createdAt: Date - public private(set) var emojis: [Emoji] + public let emojis: [Emoji] // TODO: missing from pleroma // public let repliesCount: Int public let reblogsCount: Int public let favouritesCount: Int - public var reblogged: Bool? - public var favourited: Bool? - public var muted: Bool? + public let reblogged: Bool? + public let favourited: Bool? + public let muted: Bool? public let sensitive: Bool public let spoilerText: String public let visibility: Visibility - public private(set) var attachments: [Attachment] - public private(set) var mentions: [Mention] - public private(set) var hashtags: [Hashtag] - public private(set) var application: Application? + public let attachments: [Attachment] + public let mentions: [Mention] + public let hashtags: [Hashtag] + public let application: Application? public let language: String? - public var pinned: Bool? + public let pinned: Bool? - public func getContext(completion: @escaping Client.Callback) { - let request = Request(method: .get, path: "/api/v1/statuses/\(id)/context") - client.run(request, completion: completion) + public static func getContext(_ status: Status) -> Request { + return Request(method: .get, path: "/api/v1/statuses/\(status.id)/context") } - public func getCard(completion: @escaping Client.Callback) { - let request = Request(method: .get, path: "/api/v1/statuses/\(id)/card") - client.run(request, completion: completion) + public static func getCard(_ status: Status) -> Request { + return Request(method: .get, path: "/api/v1/statuses/\(status.id)/card") } - public func getFavourites(range: RequestRange = .default, completion: @escaping Client.Callback<[Account]>) { - var request = Request<[Account]>(method: .get, path: "/api/v1/statuses/\(id)/favourited_by") + public static func getFavourites(_ status: Status, range: RequestRange = .default) -> Request<[Account]> { + var request = Request<[Account]>(method: .get, path: "/api/v1/statuses/\(status.id)/favourited_by") request.range = range - client.run(request, completion: completion) + return request } - public func getReblogs(range: RequestRange = .default, completion: @escaping Client.Callback<[Account]>) { - var request = Request<[Account]>(method: .get, path: "/api/v1/statuses/\(id)/reblogged_by") + public static func getReblogs(_ status: Status, range: RequestRange = .default) -> Request<[Account]> { + var request = Request<[Account]>(method: .get, path: "/api/v1/statuses/\(status.id)/reblogged_by") request.range = range - client.run(request, completion: completion) + return request } - public func delete(completion: @escaping Client.Callback) { - let request = Request(method: .delete, path: "/api/v1/statuses/\(id)") - client.run(request, completion: completion) + public static func delete(_ status: Status) -> Request { + return Request(method: .delete, path: "/api/v1/statuses/\(status.id)") } - public func reblog(completion: @escaping Client.Callback) { - let oldValue = reblogged - let request = Request(method: .post, path: "/api/v1/statuses/\(id)/reblog") - client.run(request) { response in - if case .success = response { - self.reblogged = true - } else { - self.reblogged = oldValue - } - completion(response) - } + public static func reblog(_ status: Status) -> Request { + return Request(method: .post, path: "/api/v1/statuses/\(status.id)/reblog") } - public func unreblog(completion: @escaping Client.Callback) { - let oldValue = reblogged - let request = Request(method: .post, path: "/api/v1/statuses/\(id)/unreblog") - client.run(request) { response in - if case .success = response { - self.reblogged = false - } else { - self.reblogged = oldValue - } - completion(response) - } + public static func unreblog(_ status: Status) -> Request { + return Request(method: .post, path: "/api/v1/statuses/\(status.id)/unreblog") } - public func favourite(completion: @escaping Client.Callback) { - let oldValue = favourited - let request = Request(method: .post, path: "/api/v1/statuses/\(id)/favourite") - client.run(request) { response in - if case .success = response { - self.favourited = true - self.reblog?.favourited = true - } else { - self.favourited = oldValue - self.reblog?.favourited = oldValue - } - completion(response) - } + public static func favourite(_ status: Status) -> Request { + return Request(method: .post, path: "/api/v1/statuses/\(status.id)/favourite") } - public func unfavourite(completion: @escaping Client.Callback) { - let oldValue = favourited - let request = Request(method: .post, path: "/api/v1/statuses/\(id)/unfavourite") - client.run(request) { response in - if case .success = response { - self.favourited = false - self.reblog?.favourited = false - } else { - self.favourited = oldValue - self.reblog?.favourited = oldValue - } - completion(response) - } + public static func unfavourite(_ status: Status) -> Request { + return Request(method: .post, path: "/api/v1/statuses/\(status.id)/unfavourite") } - public func pin(completion: @escaping Client.Callback) { - let oldValue = pinned - let request = Request(method: .post, path: "/api/v1/statuses/\(id)/pin") - client.run(request) { response in - if case .success = response { - self.pinned = true - } else { - self.pinned = oldValue - } - completion(response) - } + public static func pin(_ status: Status) -> Request { + return Request(method: .post, path: "/api/v1/statuses/\(status.id)/pin") } - public func unpin(completion: @escaping Client.Callback) { - let oldValue = pinned - let request = Request(method: .post, path: "/api/v1/statuses/\(id)/unpin") - client.run(request) { response in - if case .success = response { - self.pinned = false - } else { - self.pinned = oldValue - } - completion(response) - } + public static func unpin(_ status: Status) -> Request { + return Request(method: .post, path: "/api/v1/statuses/\(status.id)/unpin") } - public func muteConversation(completion: @escaping Client.Callback) { - let oldValue = muted - let request = Request(method: .post, path: "/api/v1/statuses/\(id)/mute") - client.run(request) { response in - if case .success = response { - self.muted = true - } else { - self.muted = oldValue - } - completion(response) - } + public static func muteConversation(_ status: Status) -> Request { + return Request(method: .post, path: "/api/v1/statuses/\(status.id)/mute") } - public func unmuteConversation(completion: @escaping Client.Callback) { - let oldValue = muted - let request = Request(method: .post, path: "/api/v1/statuses/\(id)/unmute") - client.run(request) { response in - if case .success = response { - self.muted = false - } else { - self.muted = oldValue - } - completion(response) - } + public static func unmuteConversation(_ status: Status) -> Request { + return Request(method: .post, path: "/api/v1/statuses/\(status.id)/unmute") } private enum CodingKeys: String, CodingKey { diff --git a/Pachyderm/Request/Request.swift b/Pachyderm/Request/Request.swift index 522369d3d7..56ee5e04c1 100644 --- a/Pachyderm/Request/Request.swift +++ b/Pachyderm/Request/Request.swift @@ -8,7 +8,7 @@ import Foundation -struct Request { +public struct Request { let method: Method let path: String let body: Body diff --git a/Tusker/Screens/Conversation/ConversationViewController.swift b/Tusker/Screens/Conversation/ConversationViewController.swift index 99c4f6cd07..a88a74cf6f 100644 --- a/Tusker/Screens/Conversation/ConversationViewController.swift +++ b/Tusker/Screens/Conversation/ConversationViewController.swift @@ -40,7 +40,8 @@ class ConversationViewController: UIViewController, UITableViewDataSource, UITab statuses = [mainStatus] - mainStatus.getContext { response in + let request = Status.getContext(mainStatus) + MastodonController.shared.client.run(request) { response in guard case let .success(context, _) = response else { fatalError() } var statuses = self.getDirectParents(of: self.mainStatus, from: context.ancestors) statuses.append(self.mainStatus) diff --git a/Tusker/Screens/Profile/ProfileTableViewController.swift b/Tusker/Screens/Profile/ProfileTableViewController.swift index 4927442e0e..99edf9d78e 100644 --- a/Tusker/Screens/Profile/ProfileTableViewController.swift +++ b/Tusker/Screens/Profile/ProfileTableViewController.swift @@ -32,7 +32,8 @@ class ProfileTableViewController: UITableViewController, PreferencesAdaptive { var newer: RequestRange? func getStatuses(for range: RequestRange = .default, completion: @escaping Client.Callback<[Status]>) { - account.getStatuses(range: range, onlyMedia: false, pinned: false, excludeReplies: !Preferences.shared.showRepliesInProfiles, completion: completion) + let request = Account.getStatuses(account, range: range, onlyMedia: false, pinned: false, excludeReplies: !Preferences.shared.showRepliesInProfiles) + MastodonController.shared.client.run(request, completion: completion) } override func viewDidLoad() { diff --git a/Tusker/Screens/Timeline/TimelineTableViewController.swift b/Tusker/Screens/Timeline/TimelineTableViewController.swift index 6596357843..ac940bb588 100644 --- a/Tusker/Screens/Timeline/TimelineTableViewController.swift +++ b/Tusker/Screens/Timeline/TimelineTableViewController.swift @@ -131,7 +131,8 @@ class TimelineTableViewController: UITableViewController { let status = statuses[indexPath.row] let favorite = UIContextualAction(style: .normal, title: "Favorite") { (action, view, completion) in - status.favourite(completion: { response in + let request = Status.favourite(status) + MastodonController.shared.client.run(request, completion: { response in DispatchQueue.main.async { if case .success = response { completion(true) @@ -146,7 +147,8 @@ class TimelineTableViewController: UITableViewController { favorite.image = favoriteActionImage favorite.backgroundColor = UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1) let reblog = UIContextualAction(style: .normal, title: "Reblog") { (action, view, completion) in - status.reblog(completion: { response in + let request = Status.reblog(status) + MastodonController.shared.client.run(request, completion: { response in DispatchQueue.main.async { if case .success = response { completion(true) diff --git a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift index 51c01d9d96..62cf1f9117 100644 --- a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift +++ b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift @@ -166,7 +166,8 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive let realStatus: Status = status.reblog ?? status - (favorited ? realStatus.favourite : realStatus.unfavourite)() { response in + let request = (favorited ? Status.favourite : Status.unfavourite)(realStatus) + MastodonController.shared.client.run(request) { response in self.favorited = realStatus.favourited ?? false DispatchQueue.main.async { if case .success = response { @@ -186,7 +187,8 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive let realStatus: Status = status.reblog ?? status - (reblogged ? realStatus.reblog : realStatus.unreblog)() { response in + let request = (reblogged ? Status.reblog : Status.unreblog)(realStatus) + MastodonController.shared.client.run(request) { response in self.reblogged = realStatus.reblogged ?? false DispatchQueue.main.async { if case .success = response { diff --git a/Tusker/Views/Status/StatusTableViewCell.swift b/Tusker/Views/Status/StatusTableViewCell.swift index 72fdd75896..b226516243 100644 --- a/Tusker/Views/Status/StatusTableViewCell.swift +++ b/Tusker/Views/Status/StatusTableViewCell.swift @@ -210,16 +210,18 @@ class StatusTableViewCell: UITableViewCell, PreferencesAdaptive { } @IBAction func favoritePressed(_ sender: Any) { + let oldValue = favorited favorited = !favorited let realStatus: Status = status.reblog ?? status - - (favorited ? realStatus.favourite : realStatus.unfavourite)() { response in - self.favorited = realStatus.favourited ?? false + let request = (favorited ? Status.favourite : Status.unfavourite)(realStatus) + MastodonController.shared.client.run(request) { response in DispatchQueue.main.async { if case .success = response { + self.favorited = realStatus.favourited ?? false UIImpactFeedbackGenerator(style: .light).impactOccurred() } else { + self.favorited = oldValue print("Couldn't favorite status \(realStatus.id)") // todo: display error message UINotificationFeedbackGenerator().notificationOccurred(.error) @@ -233,8 +235,8 @@ class StatusTableViewCell: UITableViewCell, PreferencesAdaptive { reblogged = !reblogged let realStatus: Status = status.reblog ?? status - - (reblogged ? realStatus.reblog : realStatus.unreblog)() { response in + let request = (reblogged ? Status.reblog : Status.unreblog)(realStatus) + MastodonController.shared.client.run(request) { response in self.reblogged = realStatus.reblogged ?? false DispatchQueue.main.async { if case .success = response {