Tusker/Pachyderm/Model/Status.swift

227 lines
7.5 KiB
Swift

//
// Status.swift
// Pachyderm
//
// Created by Shadowfacts on 9/9/18.
// Copyright © 2018 Shadowfacts. All rights reserved.
//
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 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 content: String
public let createdAt: Date
public private(set) var 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 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 language: String?
public var pinned: Bool?
public func getContext(completion: @escaping Client.Callback<ConversationContext>) {
let request = Request<ConversationContext>(method: .get, path: "/api/v1/statuses/\(id)/context")
client.run(request, completion: completion)
}
public func getCard(completion: @escaping Client.Callback<Card>) {
let request = Request<Card>(method: .get, path: "/api/v1/statuses/\(id)/card")
client.run(request, completion: completion)
}
public func getFavourites(range: RequestRange = .default, completion: @escaping Client.Callback<[Account]>) {
var request = Request<[Account]>(method: .get, path: "/api/v1/statuses/\(id)/favourited_by")
request.range = range
client.run(request, completion: completion)
}
public func getReblogs(range: RequestRange = .default, completion: @escaping Client.Callback<[Account]>) {
var request = Request<[Account]>(method: .get, path: "/api/v1/statuses/\(id)/reblogged_by")
request.range = range
client.run(request, completion: completion)
}
public func delete(completion: @escaping Client.Callback<Empty>) {
let request = Request<Empty>(method: .delete, path: "/api/v1/statuses/\(id)")
client.run(request, completion: completion)
}
public func reblog(completion: @escaping Client.Callback<Status>) {
let oldValue = reblogged
let request = Request<Status>(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 func unreblog(completion: @escaping Client.Callback<Status>) {
let oldValue = reblogged
let request = Request<Status>(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 func favourite(completion: @escaping Client.Callback<Status>) {
let oldValue = favourited
let request = Request<Status>(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 func unfavourite(completion: @escaping Client.Callback<Status>) {
let oldValue = favourited
let request = Request<Status>(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 func pin(completion: @escaping Client.Callback<Status>) {
let oldValue = pinned
let request = Request<Status>(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 func unpin(completion: @escaping Client.Callback<Status>) {
let oldValue = pinned
let request = Request<Status>(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 func muteConversation(completion: @escaping Client.Callback<Status>) {
let oldValue = muted
let request = Request<Status>(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 func unmuteConversation(completion: @escaping Client.Callback<Status>) {
let oldValue = muted
let request = Request<Status>(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)
}
}
private enum CodingKeys: String, CodingKey {
case id
case uri
case url
case account
case inReplyToID = "in_reply_to_id"
case inReplyToAccountID = "in_reply_to_account_id"
case reblog
case content
case createdAt = "created_at"
case emojis
// case repliesCount = "replies_count"
case reblogsCount = "reblogs_count"
case favouritesCount = "favourites_count"
case reblogged
case favourited
case muted
case sensitive
case spoilerText = "spoiler_text"
case visibility
case attachments = "media_attachments"
case mentions
case hashtags = "tags"
case application
case language
case pinned
}
}
extension Status {
public enum Visibility: String, Codable, CaseIterable {
case `public`
case unlisted
case `private`
case direct
}
}