2018-09-11 14:52:21 +00:00
//
// S t a t u s . s w i f t
// P a c h y d e r m
//
// C r e a t e d b y S h a d o w f a c t s o n 9 / 9 / 1 8 .
// C o p y r i g h t © 2 0 1 8 S h a d o w f a c t s . A l l r i g h t s r e s e r v e d .
//
import Foundation
2023-01-02 16:36:06 +00:00
import WebURL
2018-09-11 14:52:21 +00:00
2023-02-19 20:23:25 +00:00
public final class Status : StatusProtocol , Decodable , Sendable {
2018-09-11 14:52:21 +00:00
public let id : String
public let uri : String
2023-01-02 16:36:06 +00:00
public let url : WebURL ?
2018-09-11 14:52:21 +00:00
public let account : Account
public let inReplyToID : String ?
public let inReplyToAccountID : String ?
2018-09-17 23:22:37 +00:00
public let reblog : Status ?
2018-09-11 14:52:21 +00:00
public let content : String
public let createdAt : Date
2018-09-17 23:22:37 +00:00
public let emojis : [ Emoji ]
2018-09-11 14:52:21 +00:00
// TODO: m i s s i n g f r o m p l e r o m a
// p u b l i c l e t r e p l i e s C o u n t : I n t
public let reblogsCount : Int
public let favouritesCount : Int
2020-05-11 21:57:50 +00:00
public let reblogged : Bool ?
public let favourited : Bool ?
2018-09-17 23:22:37 +00:00
public let muted : Bool ?
2018-09-11 14:52:21 +00:00
public let sensitive : Bool
public let spoilerText : String
public let visibility : Visibility
2018-09-17 23:22:37 +00:00
public let attachments : [ Attachment ]
public let mentions : [ Mention ]
public let hashtags : [ Hashtag ]
public let application : Application ?
2018-09-11 14:52:21 +00:00
public let language : String ?
2018-09-17 23:22:37 +00:00
public let pinned : Bool ?
2019-12-14 17:40:50 +00:00
public let bookmarked : Bool ?
2020-03-05 02:14:58 +00:00
public let card : Card ?
2021-04-28 23:00:17 +00:00
public let poll : Poll ?
2022-02-04 04:11:29 +00:00
// H o m e t o w n , G l i t c h o n l y
2022-01-23 15:57:32 +00:00
public let localOnly : Bool ?
2023-05-11 17:10:45 +00:00
public let editedAt : Date ?
2018-09-11 14:52:21 +00:00
2020-05-06 22:40:12 +00:00
public var applicationName : String ? { application ? . name }
2023-01-27 03:10:20 +00:00
public init ( from decoder : Decoder ) throws {
let container = try decoder . container ( keyedBy : CodingKeys . self )
self . id = try container . decode ( String . self , forKey : . id )
self . uri = try container . decode ( String . self , forKey : . uri )
2023-04-23 18:38:00 +00:00
do {
self . url = try container . decodeIfPresent ( WebURL . self , forKey : . url )
} catch {
2023-05-08 21:05:06 +00:00
let s = try ? container . decode ( String . self , forKey : . url )
if s = = " " {
self . url = nil
} else {
throw DecodingError . dataCorrupted ( . init ( codingPath : container . codingPath + [ CodingKeys . url ] , debugDescription : " Could not decode URL ' \( s ? ? " <failed to decode string> " ) ' " , underlyingError : error ) )
}
2023-04-23 18:38:00 +00:00
}
2023-01-27 03:10:20 +00:00
self . account = try container . decode ( Account . self , forKey : . account )
self . inReplyToID = try container . decodeIfPresent ( String . self , forKey : . inReplyToID )
self . inReplyToAccountID = try container . decodeIfPresent ( String . self , forKey : . inReplyToAccountID )
self . reblog = try container . decodeIfPresent ( Status . self , forKey : . reblog )
self . content = try container . decode ( String . self , forKey : . content )
self . createdAt = try container . decode ( Date . self , forKey : . createdAt )
2023-05-10 14:13:34 +00:00
self . emojis = try container . decodeIfPresent ( [ Emoji ] . self , forKey : . emojis ) ? ? [ ]
2023-01-27 03:10:20 +00:00
self . reblogsCount = try container . decode ( Int . self , forKey : . reblogsCount )
self . favouritesCount = try container . decode ( Int . self , forKey : . favouritesCount )
self . reblogged = try container . decodeIfPresent ( Bool . self , forKey : . reblogged )
self . favourited = try container . decodeIfPresent ( Bool . self , forKey : . favourited )
self . muted = try container . decodeIfPresent ( Bool . self , forKey : . muted )
self . sensitive = try container . decode ( Bool . self , forKey : . sensitive )
self . spoilerText = try container . decode ( String . self , forKey : . spoilerText )
2023-03-07 15:14:35 +00:00
if let visibility = try ? container . decode ( Visibility . self , forKey : . visibility ) {
2023-01-27 03:10:20 +00:00
self . visibility = visibility
self . localOnly = try container . decodeIfPresent ( Bool . self , forKey : . localOnly )
} else if let s = try ? container . decode ( String . self , forKey : . visibility ) ,
s = = " local " {
// h a c k y w o r k a r o u n d f o r # 3 3 2 , a k k o m a d e s c r i b e s l o c a l p o s t s w i t h a s e p a r a t e v i s i b i l i t y
self . visibility = . public
self . localOnly = true
} else {
throw DecodingError . dataCorruptedError ( forKey : . visibility , in : container , debugDescription : " Could not decode visibility " )
}
self . attachments = try container . decode ( [ Attachment ] . self , forKey : . attachments )
self . mentions = try container . decode ( [ Mention ] . self , forKey : . mentions )
self . hashtags = try container . decode ( [ Hashtag ] . self , forKey : . hashtags )
self . application = try container . decodeIfPresent ( Application . self , forKey : . application )
self . language = try container . decodeIfPresent ( String . self , forKey : . language )
self . pinned = try container . decodeIfPresent ( Bool . self , forKey : . pinned )
self . bookmarked = try container . decodeIfPresent ( Bool . self , forKey : . bookmarked )
self . card = try container . decodeIfPresent ( Card . self , forKey : . card )
self . poll = try container . decodeIfPresent ( Poll . self , forKey : . poll )
2023-05-11 17:10:45 +00:00
self . editedAt = try container . decodeIfPresent ( Date . self , forKey : . editedAt )
2023-01-27 03:10:20 +00:00
}
2020-04-14 02:41:31 +00:00
public static func getContext ( _ statusID : String ) -> Request < ConversationContext > {
return Request < ConversationContext > ( method : . get , path : " /api/v1/statuses/ \( statusID ) /context " )
2018-09-11 14:52:21 +00:00
}
2018-09-17 23:22:37 +00:00
public static func getCard ( _ status : Status ) -> Request < Card > {
return Request < Card > ( method : . get , path : " /api/v1/statuses/ \( status . id ) /card " )
2018-09-11 14:52:21 +00:00
}
2020-04-27 23:20:09 +00:00
public static func getFavourites ( _ statusID : String , range : RequestRange = . default ) -> Request < [ Account ] > {
var request = Request < [ Account ] > ( method : . get , path : " /api/v1/statuses/ \( statusID ) /favourited_by " )
2018-09-11 14:52:21 +00:00
request . range = range
2018-09-17 23:22:37 +00:00
return request
2018-09-11 14:52:21 +00:00
}
2020-04-27 23:20:09 +00:00
public static func getReblogs ( _ statusID : String , range : RequestRange = . default ) -> Request < [ Account ] > {
var request = Request < [ Account ] > ( method : . get , path : " /api/v1/statuses/ \( statusID ) /reblogged_by " )
2018-09-11 14:52:21 +00:00
request . range = range
2018-09-17 23:22:37 +00:00
return request
2018-09-11 14:52:21 +00:00
}
2023-01-18 00:32:50 +00:00
public static func delete ( _ statusID : String ) -> Request < Empty > {
return Request < Empty > ( method : . delete , path : " /api/v1/statuses/ \( statusID ) " )
2018-09-11 14:52:21 +00:00
}
2022-09-18 04:26:37 +00:00
public static func reblog ( _ statusID : String , visibility : Visibility ? = nil ) -> Request < Status > {
var params : [ Parameter ] = [ ]
if let visibility {
assert ( [ . public , . unlisted , . private ] . contains ( visibility ) )
params . append ( " visibility " = > visibility . rawValue )
}
return Request < Status > ( method : . post , path : " /api/v1/statuses/ \( statusID ) /reblog " , queryParameters : params )
2018-09-11 14:52:21 +00:00
}
2020-04-27 23:32:16 +00:00
public static func unreblog ( _ statusID : String ) -> Request < Status > {
return Request < Status > ( method : . post , path : " /api/v1/statuses/ \( statusID ) /unreblog " )
2018-09-11 14:52:21 +00:00
}
2020-04-27 23:32:16 +00:00
public static func favourite ( _ statusID : String ) -> Request < Status > {
return Request < Status > ( method : . post , path : " /api/v1/statuses/ \( statusID ) /favourite " )
2018-09-11 14:52:21 +00:00
}
2020-04-27 23:32:16 +00:00
public static func unfavourite ( _ statusID : String ) -> Request < Status > {
return Request < Status > ( method : . post , path : " /api/v1/statuses/ \( statusID ) /unfavourite " )
2018-09-11 14:52:21 +00:00
}
2020-05-15 01:57:00 +00:00
public static func pin ( _ statusID : String ) -> Request < Status > {
return Request < Status > ( method : . post , path : " /api/v1/statuses/ \( statusID ) /pin " )
2018-09-11 14:52:21 +00:00
}
2020-05-15 01:57:00 +00:00
public static func unpin ( _ statusID : String ) -> Request < Status > {
return Request < Status > ( method : . post , path : " /api/v1/statuses/ \( statusID ) /unpin " )
2018-09-11 14:52:21 +00:00
}
2020-05-15 01:57:00 +00:00
public static func bookmark ( _ statusID : String ) -> Request < Status > {
return Request < Status > ( method : . post , path : " /api/v1/statuses/ \( statusID ) /bookmark " )
2019-12-14 17:40:50 +00:00
}
2020-04-27 23:25:41 +00:00
public static func unbookmark ( _ statusID : String ) -> Request < Status > {
return Request < Status > ( method : . post , path : " /api/v1/statuses/ \( statusID ) /unbookmark " )
2019-12-14 17:40:50 +00:00
}
2020-05-15 01:57:00 +00:00
public static func muteConversation ( _ statusID : String ) -> Request < Status > {
return Request < Status > ( method : . post , path : " /api/v1/statuses/ \( statusID ) /mute " )
2018-09-11 14:52:21 +00:00
}
2020-05-15 01:57:00 +00:00
public static func unmuteConversation ( _ statusID : String ) -> Request < Status > {
return Request < Status > ( method : . post , path : " /api/v1/statuses/ \( statusID ) /unmute " )
2018-09-11 14:52:21 +00:00
}
2023-05-11 13:59:57 +00:00
public static func source ( _ statusID : String ) -> Request < StatusSource > {
return Request ( method : . get , path : " /api/v1/statuses/ \( statusID ) /source " )
}
2023-05-11 18:57:47 +00:00
public static func history ( _ statusID : String ) -> Request < [ StatusEdit ] > {
return Request ( method : . get , path : " /api/v1/statuses/ \( statusID ) /history " )
}
2018-09-11 14:52:21 +00:00
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
// c a s e r e p l i e s C o u n t = " r e p l i e s _ c o u n t "
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
2019-12-14 17:40:50 +00:00
case bookmarked
2020-03-05 02:14:58 +00:00
case card
2021-04-28 23:00:17 +00:00
case poll
2022-01-23 15:57:32 +00:00
case localOnly = " local_only "
2023-05-11 17:10:45 +00:00
case editedAt = " edited_at "
2018-09-11 14:52:21 +00:00
}
}
2019-09-05 18:33:10 +00:00
extension Status : Identifiable { }