IceCubesApp/Packages/Models/Sources/Models/Account.swift
Thomas Ricouard 058500f91e Swiftformat .
2024-03-11 09:05:52 +01:00

190 lines
6.4 KiB
Swift

import Foundation
public final class Account: Codable, Identifiable, Hashable, Sendable, Equatable {
public static func == (lhs: Account, rhs: Account) -> Bool {
lhs.id == rhs.id &&
lhs.username == rhs.username &&
lhs.note.asRawText == rhs.note.asRawText &&
lhs.statusesCount == rhs.statusesCount &&
lhs.followersCount == rhs.followersCount &&
lhs.followingCount == rhs.followingCount &&
lhs.acct == rhs.acct &&
lhs.displayName == rhs.displayName &&
lhs.fields == rhs.fields &&
lhs.lastStatusAt == rhs.lastStatusAt &&
lhs.discoverable == rhs.discoverable &&
lhs.bot == rhs.bot &&
lhs.locked == rhs.locked &&
lhs.avatar == rhs.avatar &&
lhs.header == rhs.header
}
public func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
public struct Field: Codable, Equatable, Identifiable, Sendable {
public var id: String {
value.asRawText + name
}
public let name: String
public let value: HTMLString
public let verifiedAt: String?
}
public struct Source: Codable, Equatable, Sendable {
public let privacy: Visibility
public let sensitive: Bool
public let language: String?
public let note: String
public let fields: [Field]
}
public let id: String
public let username: String
public let displayName: String?
public let cachedDisplayName: HTMLString
public let avatar: URL
public let header: URL
public let acct: String
public let note: HTMLString
public let createdAt: ServerDate
public let followersCount: Int?
public let followingCount: Int?
public let statusesCount: Int?
public let lastStatusAt: String?
public let fields: [Field]
public let locked: Bool
public let emojis: [Emoji]
public let url: URL?
public let source: Source?
public let bot: Bool
public let discoverable: Bool?
public let moved: Account?
public var haveAvatar: Bool {
avatar.lastPathComponent != "missing.png"
}
public var haveHeader: Bool {
header.lastPathComponent != "missing.png"
}
public init(id: String, username: String, displayName: String?, avatar: URL, header: URL, acct: String, note: HTMLString, createdAt: ServerDate, followersCount: Int, followingCount: Int, statusesCount: Int, lastStatusAt: String? = nil, fields: [Account.Field], locked: Bool, emojis: [Emoji], url: URL? = nil, source: Account.Source? = nil, bot: Bool, discoverable: Bool? = nil, moved: Account? = nil) {
self.id = id
self.username = username
self.displayName = displayName
self.avatar = avatar
self.header = header
self.acct = acct
self.note = note
self.createdAt = createdAt
self.followersCount = followersCount
self.followingCount = followingCount
self.statusesCount = statusesCount
self.lastStatusAt = lastStatusAt
self.fields = fields
self.locked = locked
self.emojis = emojis
self.url = url
self.source = source
self.bot = bot
self.discoverable = discoverable
self.moved = moved
if let displayName, !displayName.isEmpty {
cachedDisplayName = .init(stringValue: displayName)
} else {
cachedDisplayName = .init(stringValue: "@\(username)")
}
}
public enum CodingKeys: CodingKey {
case id
case username
case displayName
case avatar
case header
case acct
case note
case createdAt
case followersCount
case followingCount
case statusesCount
case lastStatusAt
case fields
case locked
case emojis
case url
case source
case bot
case discoverable
case moved
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
username = try container.decode(String.self, forKey: .username)
displayName = try container.decodeIfPresent(String.self, forKey: .displayName)
avatar = try container.decode(URL.self, forKey: .avatar)
header = try container.decode(URL.self, forKey: .header)
acct = try container.decode(String.self, forKey: .acct)
note = try container.decode(HTMLString.self, forKey: .note)
createdAt = try container.decode(ServerDate.self, forKey: .createdAt)
followersCount = try container.decodeIfPresent(Int.self, forKey: .followersCount)
followingCount = try container.decodeIfPresent(Int.self, forKey: .followingCount)
statusesCount = try container.decodeIfPresent(Int.self, forKey: .statusesCount)
lastStatusAt = try container.decodeIfPresent(String.self, forKey: .lastStatusAt)
fields = try container.decode([Account.Field].self, forKey: .fields)
locked = try container.decode(Bool.self, forKey: .locked)
emojis = try container.decode([Emoji].self, forKey: .emojis)
url = try container.decodeIfPresent(URL.self, forKey: .url)
source = try container.decodeIfPresent(Account.Source.self, forKey: .source)
bot = try container.decode(Bool.self, forKey: .bot)
discoverable = try container.decodeIfPresent(Bool.self, forKey: .discoverable)
moved = try container.decodeIfPresent(Account.self, forKey: .moved)
if let displayName, !displayName.isEmpty {
cachedDisplayName = .init(stringValue: displayName)
} else {
cachedDisplayName = .init(stringValue: "@\(username)")
}
}
public static func placeholder() -> Account {
.init(id: UUID().uuidString,
username: "Username",
displayName: "John Mastodon",
avatar: URL(string: "https://files.mastodon.social/media_attachments/files/003/134/405/original/04060b07ddf7bb0b.png")!,
header: URL(string: "https://files.mastodon.social/media_attachments/files/003/134/405/original/04060b07ddf7bb0b.png")!,
acct: "johnm@example.com",
note: .init(stringValue: "Some content"),
createdAt: ServerDate(),
followersCount: 10,
followingCount: 10,
statusesCount: 10,
lastStatusAt: nil,
fields: [],
locked: false,
emojis: [],
url: nil,
source: nil,
bot: false,
discoverable: true)
}
public static func placeholders() -> [Account] {
[.placeholder(), .placeholder(), .placeholder(), .placeholder(), .placeholder(),
.placeholder(), .placeholder(), .placeholder(), .placeholder(), .placeholder()]
}
}
public struct FamiliarAccounts: Decodable {
public let id: String
public let accounts: [Account]
}
extension FamiliarAccounts: Sendable {}