105 lines
2.5 KiB
Swift
105 lines
2.5 KiB
Swift
import Foundation
|
|
|
|
struct SearchDataPayload: Decodable {
|
|
let users: [UserSearchResult]
|
|
}
|
|
|
|
struct UserSearchResult: Decodable, Identifiable {
|
|
let userId: UUID
|
|
// let login: String
|
|
// let fullName: String?
|
|
// let customName: String?
|
|
// let createdAt: Date?
|
|
let profile: SearchProfile?
|
|
|
|
var id: UUID { userId }
|
|
}
|
|
|
|
struct SearchProfile: Decodable {
|
|
let userId: UUID
|
|
let login: String
|
|
let fullName: String?
|
|
let customName: String?
|
|
let bio: String?
|
|
|
|
let isVerified: Bool
|
|
let isSystem: Bool
|
|
|
|
let lastSeen: Int?
|
|
let createdAt: Date?
|
|
}
|
|
|
|
extension UserSearchResult {
|
|
var preferredCustomName: String? {
|
|
trimmed(profile?.customName)
|
|
}
|
|
|
|
var officialFullName: String? {
|
|
trimmed(profile?.fullName)
|
|
}
|
|
|
|
var login: String? {
|
|
trimmed(profile?.login)
|
|
}
|
|
|
|
var loginHandle: String {
|
|
if let login {
|
|
return "@\(login)"
|
|
}
|
|
return "@\(userId.uuidString)"
|
|
}
|
|
|
|
var displayName: String {
|
|
if let official = officialFullName {
|
|
return official
|
|
}
|
|
if let custom = preferredCustomName {
|
|
return custom
|
|
}
|
|
if let login = login {
|
|
return "@\(login)"
|
|
}
|
|
return "@\(userId.uuidString)"
|
|
}
|
|
|
|
var avatarInitial: String {
|
|
let nameSource: String?
|
|
if let customName = preferredCustomName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
nameSource = customName
|
|
} else if let fullName = officialFullName, !fullName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
nameSource = fullName
|
|
} else {
|
|
nameSource = nil
|
|
}
|
|
|
|
if let name = nameSource {
|
|
let components = name.split(separator: " ")
|
|
let nameInitials = components.prefix(2).compactMap { $0.first }
|
|
if !nameInitials.isEmpty {
|
|
return nameInitials.map { String($0) }.joined().uppercased()
|
|
}
|
|
}
|
|
|
|
if let login = login, !login.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
return String(login.prefix(1)).uppercased()
|
|
}
|
|
|
|
return "?"
|
|
}
|
|
|
|
var isOfficial: Bool {
|
|
profile?.isVerified ?? false
|
|
}
|
|
|
|
var createdAt: Date? {
|
|
profile?.createdAt
|
|
}
|
|
|
|
private func trimmed(_ value: String?) -> String? {
|
|
guard let value = value?.trimmingCharacters(in: .whitespacesAndNewlines), !value.isEmpty else {
|
|
return nil
|
|
}
|
|
return value
|
|
}
|
|
}
|